Skip to content

Commit e1f40f1

Browse files
committed
flash
Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent 63870c6 commit e1f40f1

1 file changed

Lines changed: 62 additions & 41 deletions

File tree

  • framework_lib/src/chromium_ec

framework_lib/src/chromium_ec/mod.rs

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +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 NPC_FLASH_RORW_SIZE: u32 = 0x3F000;
75-
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;
7678
const NPC_FLASH_FLAGS: u32 = 0x7F000;
7779
const FLASH_PROGRAM_OFFSET: u32 = 0x1000;
7880

@@ -870,22 +872,25 @@ impl CrosEc {
870872

871873
/// Overwrite RO and RW regions of EC flash
872874
/// MEC/Legacy EC
873-
/// | Start | End | Size | Region |
874-
/// | 00000 | 3BFFF | 3C000 | RO Region |
875-
/// | 3C000 | | 01000 | Preserved |
876-
/// | 3D000 | | 01000 | Serial Struct Slot A |
877-
/// | 3E000 | | 01000 | Serial Struct Slot A |
878-
/// | 3F000 | 3FFFF | 01000 | Preserved |
879-
/// | 40000 | 78FFF | 39000 | RW Region |
880-
/// | 79000 | 79FFF | 01000 | Preserved |
881-
/// | 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 |
882884
///
883885
/// NPC/Zephyr
884-
/// | Start | End | Size | Region |
885-
/// | 00000 | 3EFFF | 3F000 | RO Region |
886-
/// | 3F000 | 3FFFF | 01000 | Reserved |
887-
/// | 40000 | 7EFFF | 3F000 | RW Region |
888-
/// | 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.
889894
pub fn reflash(&self, data: &[u8], ft: EcFlashType, dry_run: bool) -> EcResult<()> {
890895
let mut res = Ok(());
891896

@@ -898,6 +903,13 @@ impl CrosEc {
898903
));
899904
};
900905

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+
901913
if matches!(ft, EcFlashType::Full | EcFlashType::Both | EcFlashType::Ro) {
902914
if let Some(version) = ec_binary::read_ec_version(data, true) {
903915
println!("EC RO Version in File: {:?}", version.version);
@@ -933,13 +945,13 @@ impl CrosEc {
933945
let info = EcRequestFlashInfo {}.send_command(self)?;
934946

935947
// Check that our hardcoded offsets are valid for the available flash
936-
if FLASH_RO_SIZE + FLASH_RW_SIZE > info.flash_size {
948+
if flash_ro_size + flash_rw_size > info.flash_size {
937949
return Err(EcError::DeviceError(format!(
938950
"RO+RW larger than flash 0x{:X}",
939951
{ info.flash_size }
940952
)));
941953
}
942-
if FLASH_RW_BASE + FLASH_RW_SIZE > info.flash_size {
954+
if FLASH_RW_BASE + flash_rw_size > info.flash_size {
943955
return Err(EcError::DeviceError(format!(
944956
"RW overruns end of flash 0x{:X}",
945957
{ info.flash_size }
@@ -990,15 +1002,15 @@ impl CrosEc {
9901002
}
9911003

9921004
if ft == EcFlashType::Both || ft == EcFlashType::Rw {
993-
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];
9941006

9951007
println!(
9961008
"Erasing RW region{}",
9971009
if dry_run { " (DRY RUN)" } else { "" }
9981010
);
9991011
self.erase_ec_flash(
10001012
FLASH_BASE + FLASH_RW_BASE,
1001-
FLASH_RW_SIZE,
1013+
flash_rw_size,
10021014
dry_run,
10031015
info.erase_block_size,
10041016
)?;
@@ -1012,7 +1024,7 @@ impl CrosEc {
10121024
println!(" Done");
10131025

10141026
println!("Verifying RW region");
1015-
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)?;
10161028
if rw_data == flash_rw_data {
10171029
println!(" RW verify success");
10181030
} else {
@@ -1022,12 +1034,12 @@ impl CrosEc {
10221034
}
10231035

10241036
if ft == EcFlashType::Both || ft == EcFlashType::Ro {
1025-
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];
10261038

10271039
println!("Erasing RO region");
10281040
self.erase_ec_flash(
10291041
FLASH_BASE + FLASH_RO_BASE,
1030-
FLASH_RO_SIZE,
1042+
flash_ro_size,
10311043
dry_run,
10321044
info.erase_block_size,
10331045
)?;
@@ -1038,7 +1050,7 @@ impl CrosEc {
10381050
println!(" Done");
10391051

10401052
println!("Verifying RO region");
1041-
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)?;
10421054
if ro_data == flash_ro_data {
10431055
println!(" RO verify success");
10441056
} else {
@@ -1327,23 +1339,32 @@ impl CrosEc {
13271339

13281340
// ===== Test 4 =====
13291341
println!(" Read flash flags");
1330-
let data = if has_mec {
1331-
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+
]
13321347
} else {
1333-
self.read_ec_flash(NPC_FLASH_FLAGS, 0x80).unwrap()
1348+
&[("", NPC_FLASH_FLAGS)]
13341349
};
1335-
let flash_flags_magic = [0xA3, 0xF1, 0x00, 0x00];
1336-
let flash_flags_ver = [0x01, 0x0, 0x00, 0x00];
1337-
// All 0xFF if just reflashed and not reinitialized by EC
1338-
if data[0..4] == flash_flags_magic && data[8..12] == flash_flags_ver {
1339-
println!(" Valid flash flags");
1340-
} else if data.iter().all(|x| *x == 0xFF) {
1341-
println!(" Erased flash flags");
1342-
res = Err(EcError::DeviceError("Erased flash flags".to_string()));
1343-
} else {
1344-
println!(" INVALID flash flags: {:02X?}", &data[0..12]);
1345-
// TODO: Disable error until I confirm flash flags on MEC
1346-
// 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+
}
13471368
}
13481369

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

0 commit comments

Comments
 (0)