Skip to content

Commit 1069bd6

Browse files
committed
Fix npcx/zephyr flash layout
It wasn't exactly correct. On sunflower the RO and RW are larger than the previously defined regions and EC wouldn't boot after flashing. Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent fdd553b commit 1069bd6

1 file changed

Lines changed: 62 additions & 37 deletions

File tree

  • framework_lib/src/chromium_ec

framework_lib/src/chromium_ec/mod.rs

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,13 @@ const EC_MEMMAP_ID: u16 = 0x20;
6868
const FLASH_BASE: u32 = 0x0;
6969
const FLASH_SIZE: u32 = 0x80000;
7070
const FLASH_RO_BASE: u32 = 0x0;
71-
const FLASH_RO_SIZE: u32 = 0x3C000;
7271
const FLASH_RW_BASE: u32 = 0x40000;
73-
const FLASH_RW_SIZE: u32 = 0x39000;
74-
const MEC_FLASH_FLAGS: u32 = 0x80000;
72+
const MEC_FLASH_RO_SIZE: u32 = 0x3A000;
73+
const MEC_FLASH_RW_SIZE: u32 = 0x3F000;
74+
const NPC_FLASH_RO_SIZE: u32 = 0x3F000;
75+
const NPC_FLASH_RW_SIZE: u32 = 0x3F000;
76+
const MEC_FLASH_FLAGS_RO: u32 = 0x3F000;
77+
const MEC_FLASH_FLAGS_RW: u32 = 0x7F000;
7578
const NPC_FLASH_FLAGS: u32 = 0x7F000;
7679
const FLASH_PROGRAM_OFFSET: u32 = 0x1000;
7780

@@ -869,19 +872,25 @@ impl CrosEc {
869872

870873
/// Overwrite RO and RW regions of EC flash
871874
/// MEC/Legacy EC
872-
/// | Start | End | Size | Region |
873-
/// | 00000 | 3BFFF | 3C000 | RO Region |
874-
/// | 3C000 | 3FFFF | 04000 | Preserved |
875-
/// | 40000 | 78FFF | 39000 | RW Region |
876-
/// | 79000 | 79FFF | 01000 | Preserved |
877-
/// | 80000 | 80FFF | 01000 | Flash Flags |
875+
/// | Start | Length | Region |
876+
/// | 00000 | 3A000 | RO Firmware |
877+
/// | 3A000 | 02000 | Blank |
878+
/// | 3C000 | 01000 | Factory Usage |
879+
/// | 3D000 | 01000 | System Serial Struct A |
880+
/// | 3E000 | 01000 | System Serial Struct B |
881+
/// | 3F000 | 01000 | EC Flags Region RO Image |
882+
/// | 40000 | 3F000 | RW Firmware |
883+
/// | 7F000 | 01000 | EC Flags Region RW Image |
878884
///
879885
/// NPC/Zephyr
880-
/// | Start | End | Size | Region |
881-
/// | 00000 | 3BFFF | 3C000 | RO Region |
882-
/// | 3C000 | 3FFFF | 04000 | Preserved |
883-
/// | 40000 | 78FFF | 39000 | RW Region |
884-
/// | 7F000 | 7FFFF | 01000 | Flash Flags |
886+
/// | Start | Length | Region |
887+
/// | 00000 | 3F000 | RO Firmware |
888+
/// | 3F000 | 01000 | Reserved |
889+
/// | 40000 | 3F000 | RW Firmware |
890+
/// | 7F000 | 01000 | Framework EC Flash Storage |
891+
///
892+
/// The Framework EC Flash Storage (flash flags) is not updated during EC
893+
/// firmware update. It is erased by EC_CMD_FACTORY_MODE.
885894
pub fn reflash(&self, data: &[u8], ft: EcFlashType, dry_run: bool) -> EcResult<()> {
886895
let mut res = Ok(());
887896

@@ -894,6 +903,13 @@ impl CrosEc {
894903
));
895904
};
896905

906+
let has_mec = matches!(platform.as_str(), "hx20" | "hx30");
907+
let (flash_ro_size, flash_rw_size) = if has_mec {
908+
(MEC_FLASH_RO_SIZE, MEC_FLASH_RW_SIZE)
909+
} else {
910+
(NPC_FLASH_RO_SIZE, NPC_FLASH_RW_SIZE)
911+
};
912+
897913
if matches!(ft, EcFlashType::Full | EcFlashType::Both | EcFlashType::Ro) {
898914
if let Some(version) = ec_binary::read_ec_version(data, true) {
899915
println!("EC RO Version in File: {:?}", version.version);
@@ -929,13 +945,13 @@ impl CrosEc {
929945
let info = EcRequestFlashInfo {}.send_command(self)?;
930946

931947
// Check that our hardcoded offsets are valid for the available flash
932-
if FLASH_RO_SIZE + FLASH_RW_SIZE > info.flash_size {
948+
if flash_ro_size + flash_rw_size > info.flash_size {
933949
return Err(EcError::DeviceError(format!(
934950
"RO+RW larger than flash 0x{:X}",
935951
{ info.flash_size }
936952
)));
937953
}
938-
if FLASH_RW_BASE + FLASH_RW_SIZE > info.flash_size {
954+
if FLASH_RW_BASE + flash_rw_size > info.flash_size {
939955
return Err(EcError::DeviceError(format!(
940956
"RW overruns end of flash 0x{:X}",
941957
{ info.flash_size }
@@ -986,15 +1002,15 @@ impl CrosEc {
9861002
}
9871003

9881004
if ft == EcFlashType::Both || ft == EcFlashType::Rw {
989-
let rw_data = &data[FLASH_RW_BASE as usize..(FLASH_RW_BASE + FLASH_RW_SIZE) as usize];
1005+
let rw_data = &data[FLASH_RW_BASE as usize..(FLASH_RW_BASE + flash_rw_size) as usize];
9901006

9911007
println!(
9921008
"Erasing RW region{}",
9931009
if dry_run { " (DRY RUN)" } else { "" }
9941010
);
9951011
self.erase_ec_flash(
9961012
FLASH_BASE + FLASH_RW_BASE,
997-
FLASH_RW_SIZE,
1013+
flash_rw_size,
9981014
dry_run,
9991015
info.erase_block_size,
10001016
)?;
@@ -1008,7 +1024,7 @@ impl CrosEc {
10081024
println!(" Done");
10091025

10101026
println!("Verifying RW region");
1011-
let flash_rw_data = self.read_ec_flash(FLASH_BASE + FLASH_RW_BASE, FLASH_RW_SIZE)?;
1027+
let flash_rw_data = self.read_ec_flash(FLASH_BASE + FLASH_RW_BASE, flash_rw_size)?;
10121028
if rw_data == flash_rw_data {
10131029
println!(" RW verify success");
10141030
} else {
@@ -1018,12 +1034,12 @@ impl CrosEc {
10181034
}
10191035

10201036
if ft == EcFlashType::Both || ft == EcFlashType::Ro {
1021-
let ro_data = &data[FLASH_RO_BASE as usize..(FLASH_RO_BASE + FLASH_RO_SIZE) as usize];
1037+
let ro_data = &data[FLASH_RO_BASE as usize..(FLASH_RO_BASE + flash_ro_size) as usize];
10221038

10231039
println!("Erasing RO region");
10241040
self.erase_ec_flash(
10251041
FLASH_BASE + FLASH_RO_BASE,
1026-
FLASH_RO_SIZE,
1042+
flash_ro_size,
10271043
dry_run,
10281044
info.erase_block_size,
10291045
)?;
@@ -1034,7 +1050,7 @@ impl CrosEc {
10341050
println!(" Done");
10351051

10361052
println!("Verifying RO region");
1037-
let flash_ro_data = self.read_ec_flash(FLASH_BASE + FLASH_RO_BASE, FLASH_RO_SIZE)?;
1053+
let flash_ro_data = self.read_ec_flash(FLASH_BASE + FLASH_RO_BASE, flash_ro_size)?;
10381054
if ro_data == flash_ro_data {
10391055
println!(" RO verify success");
10401056
} else {
@@ -1323,23 +1339,32 @@ impl CrosEc {
13231339

13241340
// ===== Test 4 =====
13251341
println!(" Read flash flags");
1326-
let data = if has_mec {
1327-
self.read_ec_flash(MEC_FLASH_FLAGS, 0x80).unwrap()
1342+
let flag_regions: &[(&str, u32)] = if has_mec {
1343+
&[
1344+
("RO Image ", MEC_FLASH_FLAGS_RO),
1345+
("RW Image ", MEC_FLASH_FLAGS_RW),
1346+
]
13281347
} else {
1329-
self.read_ec_flash(NPC_FLASH_FLAGS, 0x80).unwrap()
1348+
&[("", NPC_FLASH_FLAGS)]
13301349
};
1331-
let flash_flags_magic = [0xA3, 0xF1, 0x00, 0x00];
1332-
let flash_flags_ver = [0x01, 0x0, 0x00, 0x00];
1333-
// All 0xFF if just reflashed and not reinitialized by EC
1334-
if data[0..4] == flash_flags_magic && data[8..12] == flash_flags_ver {
1335-
println!(" Valid flash flags");
1336-
} else if data.iter().all(|x| *x == 0xFF) {
1337-
println!(" Erased flash flags");
1338-
res = Err(EcError::DeviceError("Erased flash flags".to_string()));
1339-
} else {
1340-
println!(" INVALID flash flags: {:02X?}", &data[0..12]);
1341-
// TODO: Disable error until I confirm flash flags on MEC
1342-
// res = Err(EcError::DeviceError("INVALID flash flags".to_string()));
1350+
for (region, addr) in flag_regions {
1351+
let data = self.read_ec_flash(*addr, 0x80).unwrap();
1352+
let flash_flags_magic = [0xA3, 0xF1, 0x00, 0x00];
1353+
let flash_flags_ver = [0x01, 0x0, 0x00, 0x00];
1354+
// All 0xFF if just reflashed and not reinitialized by EC
1355+
if data[0..4] == flash_flags_magic && data[8..12] == flash_flags_ver {
1356+
println!(" Valid {}flash flags", region);
1357+
} else if data.iter().all(|x| *x == 0xFF) {
1358+
println!(" Erased {}flash flags", region);
1359+
res = Err(EcError::DeviceError(format!(
1360+
"Erased {}flash flags",
1361+
region
1362+
)));
1363+
} else {
1364+
println!(" INVALID {}flash flags: {:02X?}", region, &data[0..12]);
1365+
// TODO: Disable error until I confirm flash flags on MEC
1366+
// res = Err(EcError::DeviceError("INVALID flash flags".to_string()));
1367+
}
13431368
}
13441369

13451370
self.flash_notify(MecFlashNotify::AccessSpiDone)?;

0 commit comments

Comments
 (0)