Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 62 additions & 37 deletions framework_lib/src/chromium_ec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ const EC_MEMMAP_ID: u16 = 0x20;
const FLASH_BASE: u32 = 0x0;
const FLASH_SIZE: u32 = 0x80000;
const FLASH_RO_BASE: u32 = 0x0;
const FLASH_RO_SIZE: u32 = 0x3C000;
const FLASH_RW_BASE: u32 = 0x40000;
const FLASH_RW_SIZE: u32 = 0x39000;
const MEC_FLASH_FLAGS: u32 = 0x80000;
const MEC_FLASH_RO_SIZE: u32 = 0x3A000;
const MEC_FLASH_RW_SIZE: u32 = 0x3F000;
const NPC_FLASH_RO_SIZE: u32 = 0x3F000;
const NPC_FLASH_RW_SIZE: u32 = 0x3F000;
const MEC_FLASH_FLAGS_RO: u32 = 0x3F000;
const MEC_FLASH_FLAGS_RW: u32 = 0x7F000;
const NPC_FLASH_FLAGS: u32 = 0x7F000;
const FLASH_PROGRAM_OFFSET: u32 = 0x1000;

Expand Down Expand Up @@ -869,19 +872,25 @@ impl CrosEc {

/// Overwrite RO and RW regions of EC flash
/// MEC/Legacy EC
/// | Start | End | Size | Region |
/// | 00000 | 3BFFF | 3C000 | RO Region |
/// | 3C000 | 3FFFF | 04000 | Preserved |
/// | 40000 | 78FFF | 39000 | RW Region |
/// | 79000 | 79FFF | 01000 | Preserved |
/// | 80000 | 80FFF | 01000 | Flash Flags |
/// | Start | Length | Region |
/// | 00000 | 3A000 | RO Firmware |
/// | 3A000 | 02000 | Blank |
/// | 3C000 | 01000 | Factory Usage |
/// | 3D000 | 01000 | System Serial Struct A |
/// | 3E000 | 01000 | System Serial Struct B |
/// | 3F000 | 01000 | EC Flags Region RO Image |
/// | 40000 | 3F000 | RW Firmware |
/// | 7F000 | 01000 | EC Flags Region RW Image |
///
/// NPC/Zephyr
/// | Start | End | Size | Region |
/// | 00000 | 3BFFF | 3C000 | RO Region |
/// | 3C000 | 3FFFF | 04000 | Preserved |
/// | 40000 | 78FFF | 39000 | RW Region |
/// | 7F000 | 7FFFF | 01000 | Flash Flags |
/// | Start | Length | Region |
/// | 00000 | 3F000 | RO Firmware |
/// | 3F000 | 01000 | Reserved |
/// | 40000 | 3F000 | RW Firmware |
/// | 7F000 | 01000 | Framework EC Flash Storage |
///
/// The Framework EC Flash Storage (flash flags) is not updated during EC
/// firmware update. It is erased by EC_CMD_FACTORY_MODE.
pub fn reflash(&self, data: &[u8], ft: EcFlashType, dry_run: bool) -> EcResult<()> {
let mut res = Ok(());

Expand All @@ -894,6 +903,13 @@ impl CrosEc {
));
};

let has_mec = matches!(platform.as_str(), "hx20" | "hx30");
let (flash_ro_size, flash_rw_size) = if has_mec {
(MEC_FLASH_RO_SIZE, MEC_FLASH_RW_SIZE)
} else {
(NPC_FLASH_RO_SIZE, NPC_FLASH_RW_SIZE)
};

if matches!(ft, EcFlashType::Full | EcFlashType::Both | EcFlashType::Ro) {
if let Some(version) = ec_binary::read_ec_version(data, true) {
println!("EC RO Version in File: {:?}", version.version);
Expand Down Expand Up @@ -929,13 +945,13 @@ impl CrosEc {
let info = EcRequestFlashInfo {}.send_command(self)?;

// Check that our hardcoded offsets are valid for the available flash
if FLASH_RO_SIZE + FLASH_RW_SIZE > info.flash_size {
if flash_ro_size + flash_rw_size > info.flash_size {
return Err(EcError::DeviceError(format!(
"RO+RW larger than flash 0x{:X}",
{ info.flash_size }
)));
}
if FLASH_RW_BASE + FLASH_RW_SIZE > info.flash_size {
if FLASH_RW_BASE + flash_rw_size > info.flash_size {
return Err(EcError::DeviceError(format!(
"RW overruns end of flash 0x{:X}",
{ info.flash_size }
Expand Down Expand Up @@ -986,15 +1002,15 @@ impl CrosEc {
}

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

println!(
"Erasing RW region{}",
if dry_run { " (DRY RUN)" } else { "" }
);
self.erase_ec_flash(
FLASH_BASE + FLASH_RW_BASE,
FLASH_RW_SIZE,
flash_rw_size,
dry_run,
info.erase_block_size,
)?;
Expand All @@ -1008,7 +1024,7 @@ impl CrosEc {
println!(" Done");

println!("Verifying RW region");
let flash_rw_data = self.read_ec_flash(FLASH_BASE + FLASH_RW_BASE, FLASH_RW_SIZE)?;
let flash_rw_data = self.read_ec_flash(FLASH_BASE + FLASH_RW_BASE, flash_rw_size)?;
if rw_data == flash_rw_data {
println!(" RW verify success");
} else {
Expand All @@ -1018,12 +1034,12 @@ impl CrosEc {
}

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

println!("Erasing RO region");
self.erase_ec_flash(
FLASH_BASE + FLASH_RO_BASE,
FLASH_RO_SIZE,
flash_ro_size,
dry_run,
info.erase_block_size,
)?;
Expand All @@ -1034,7 +1050,7 @@ impl CrosEc {
println!(" Done");

println!("Verifying RO region");
let flash_ro_data = self.read_ec_flash(FLASH_BASE + FLASH_RO_BASE, FLASH_RO_SIZE)?;
let flash_ro_data = self.read_ec_flash(FLASH_BASE + FLASH_RO_BASE, flash_ro_size)?;
if ro_data == flash_ro_data {
println!(" RO verify success");
} else {
Expand Down Expand Up @@ -1323,23 +1339,32 @@ impl CrosEc {

// ===== Test 4 =====
println!(" Read flash flags");
let data = if has_mec {
self.read_ec_flash(MEC_FLASH_FLAGS, 0x80).unwrap()
let flag_regions: &[(&str, u32)] = if has_mec {
&[
("RO Image ", MEC_FLASH_FLAGS_RO),
("RW Image ", MEC_FLASH_FLAGS_RW),
]
} else {
self.read_ec_flash(NPC_FLASH_FLAGS, 0x80).unwrap()
&[("", NPC_FLASH_FLAGS)]
};
let flash_flags_magic = [0xA3, 0xF1, 0x00, 0x00];
let flash_flags_ver = [0x01, 0x0, 0x00, 0x00];
// All 0xFF if just reflashed and not reinitialized by EC
if data[0..4] == flash_flags_magic && data[8..12] == flash_flags_ver {
println!(" Valid flash flags");
} else if data.iter().all(|x| *x == 0xFF) {
println!(" Erased flash flags");
res = Err(EcError::DeviceError("Erased flash flags".to_string()));
} else {
println!(" INVALID flash flags: {:02X?}", &data[0..12]);
// TODO: Disable error until I confirm flash flags on MEC
// res = Err(EcError::DeviceError("INVALID flash flags".to_string()));
for (region, addr) in flag_regions {
let data = self.read_ec_flash(*addr, 0x80).unwrap();
let flash_flags_magic = [0xA3, 0xF1, 0x00, 0x00];
let flash_flags_ver = [0x01, 0x0, 0x00, 0x00];
// All 0xFF if just reflashed and not reinitialized by EC
if data[0..4] == flash_flags_magic && data[8..12] == flash_flags_ver {
println!(" Valid {}flash flags", region);
} else if data.iter().all(|x| *x == 0xFF) {
println!(" Erased {}flash flags", region);
res = Err(EcError::DeviceError(format!(
"Erased {}flash flags",
region
)));
} else {
println!(" INVALID {}flash flags: {:02X?}", region, &data[0..12]);
// TODO: Disable error until I confirm flash flags on MEC
// res = Err(EcError::DeviceError("INVALID flash flags".to_string()));
}
}

self.flash_notify(MecFlashNotify::AccessSpiDone)?;
Expand Down
Loading