From 31cdb6f07fb92bebe57d52d4d8c0e5bf6f4bfa78 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sat, 6 Apr 2024 22:07:17 +0800 Subject: [PATCH] chromium_ec: Allow flashing single EC FW Only RO, only RW or both. Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/mod.rs | 57 +++++++++++++++-------- framework_lib/src/commandline/clap_std.rs | 14 ++++++ framework_lib/src/commandline/mod.rs | 22 ++++++--- framework_lib/src/commandline/uefi.rs | 20 +++++++- 4 files changed, 86 insertions(+), 27 deletions(-) diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 4889ac88..9da39b66 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -59,6 +59,13 @@ const FLASH_RW_BASE: u32 = 0x40000; const FLASH_RW_SIZE: u32 = 0x39000; const FLASH_PROGRAM_OFFSET: u32 = 0x1000; +#[derive(Clone, Debug, PartialEq)] +pub enum EcFlashType { + Full, + Ro, + Rw, +} + #[derive(PartialEq)] pub enum MecFlashNotify { AccessSpi = 0x00, @@ -385,37 +392,49 @@ impl CrosEc { /// | 3C000 | 3FFFF | 04000 | Preserved | /// | 40000 | 3C000 | 39000 | RO Region | /// | 79000 | 79FFF | 07000 | Preserved | - pub fn reflash(&self, data: &[u8]) -> EcResult<()> { + pub fn reflash(&self, data: &[u8], ft: EcFlashType) -> EcResult<()> { let mut _flash_bin: Vec = Vec::with_capacity(EC_FLASH_SIZE); println!("Unlocking flash"); self.flash_notify(MecFlashNotify::AccessSpi)?; self.flash_notify(MecFlashNotify::FirmwareStart)?; - //println!("Erasing RO region"); - //self.erase_ec_flash(FLASH_BASE + FLASH_RO_BASE, FLASH_RO_SIZE)?; - println!("Erasing RW region"); - self.erase_ec_flash(FLASH_BASE + FLASH_RW_BASE, FLASH_RW_SIZE)?; + if ft == EcFlashType::Full || ft == EcFlashType::Ro { + println!("Erasing RO region"); + self.erase_ec_flash(FLASH_BASE + FLASH_RO_BASE, FLASH_RO_SIZE)?; + } + if ft == EcFlashType::Full || ft == EcFlashType::Rw { + println!("Erasing RW region"); + self.erase_ec_flash(FLASH_BASE + FLASH_RW_BASE, FLASH_RW_SIZE)?; + } let ro_data = &data[FLASH_RO_BASE as usize..(FLASH_RO_BASE + FLASH_RO_SIZE) as usize]; - //println!("Writing RO region"); - //self.write_ec_flash(FLASH_BASE + FLASH_RO_BASE, ro_data); + if ft == EcFlashType::Full || ft == EcFlashType::Ro { + println!("Writing RO region"); + self.write_ec_flash(FLASH_BASE + FLASH_RO_BASE, ro_data)?; + } let rw_data = &data[FLASH_RW_BASE as usize..(FLASH_RW_BASE + FLASH_RW_SIZE) as usize]; - println!("Writing RW region"); - self.write_ec_flash(FLASH_BASE + FLASH_RW_BASE, rw_data)?; + if ft == EcFlashType::Full || ft == EcFlashType::Rw { + println!("Writing RW region"); + self.write_ec_flash(FLASH_BASE + FLASH_RW_BASE, rw_data)?; + } println!("Verifying"); - 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 { - println!("RO verify fail"); + if ft == EcFlashType::Full || ft == EcFlashType::Ro { + 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 { + println!("RO verify fail"); + } } - 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 { - println!("RW verify fail"); + if ft == EcFlashType::Full || ft == EcFlashType::Rw { + 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 { + println!("RW verify fail"); + } } println!("Locking flash"); diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index 182b0531..26e27de0 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -85,6 +85,14 @@ struct ClapCli { #[arg(long)] flash_ec: Option, + /// Flash EC with new RO firmware from file + #[arg(long)] + flash_ro_ec: Option, + + /// Flash EC with new RW firmware from file + #[arg(long)] + flash_rw_ec: Option, + /// Show status of intrusion switch #[arg(long)] intrusion: bool, @@ -170,6 +178,12 @@ pub fn parse(args: &[String]) -> Cli { flash_ec: args .flash_ec .map(|x| x.into_os_string().into_string().unwrap()), + flash_ro_ec: args + .flash_ro_ec + .map(|x| x.into_os_string().into_string().unwrap()), + flash_rw_ec: args + .flash_rw_ec + .map(|x| x.into_os_string().into_string().unwrap()), intrusion: args.intrusion, inputmodules: args.inputmodules, input_deck_mode: args.input_deck_mode, diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 0e7c2f14..e238f842 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -32,9 +32,8 @@ use crate::ccgx::{self, SiliconId::*}; use crate::chromium_ec; use crate::chromium_ec::commands::DeckStateMode; use crate::chromium_ec::commands::FpLedBrightnessLevel; -use crate::chromium_ec::print_err; -use crate::chromium_ec::EcError; -use crate::chromium_ec::EcResult; +use crate::chromium_ec::{print_err, EcFlashType}; +use crate::chromium_ec::{EcError, EcResult}; #[cfg(feature = "linux")] use crate::csme; use crate::ec_binary; @@ -130,6 +129,8 @@ pub struct Cli { pub ho2_capsule: Option, pub dump_ec_flash: Option, pub flash_ec: Option, + pub flash_ro_ec: Option, + pub flash_rw_ec: Option, pub driver: Option, pub test: bool, pub intrusion: bool, @@ -395,7 +396,7 @@ fn print_esrt() { } } -fn flash_ec(ec: &CrosEc, ec_bin_path: &str) { +fn flash_ec(ec: &CrosEc, ec_bin_path: &str, flash_type: EcFlashType) { #[cfg(feature = "uefi")] let data = crate::uefi::fs::shell_read_file(ec_bin_path); #[cfg(not(feature = "uefi"))] @@ -412,7 +413,7 @@ fn flash_ec(ec: &CrosEc, ec_bin_path: &str) { println!("File"); println!(" Size: {:>20} B", data.len()); println!(" Size: {:>20} KB", data.len() / 1024); - if let Err(err) = ec.reflash(&data) { + if let Err(err) = ec.reflash(&data, flash_type) { println!("Error: {:?}", err); } else { println!("Success!"); @@ -701,9 +702,14 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } } else if let Some(dump_path) = &args.dump_ec_flash { println!("Dumping to {}", dump_path); + // TODO: Should have progress indicator dump_ec_flash(&ec, dump_path); } else if let Some(ec_bin_path) = &args.flash_ec { - flash_ec(&ec, ec_bin_path); + flash_ec(&ec, ec_bin_path, EcFlashType::Full); + } else if let Some(ec_bin_path) = &args.flash_ro_ec { + flash_ec(&ec, ec_bin_path, EcFlashType::Ro); + } else if let Some(ec_bin_path) = &args.flash_rw_ec { + flash_ec(&ec, ec_bin_path, EcFlashType::Rw); } else if let Some(hash_file) = &args.hash { println!("Hashing file: {}", hash_file); #[cfg(feature = "uefi")] @@ -751,6 +757,9 @@ Options: --pd-bin Parse versions from PD firmware binary file --ec-bin Parse versions from EC firmware binary file --capsule Parse UEFI Capsule information from binary file + --flash-ec Flash EC with new firmware from file + --flash-ro-ec Flash EC with new firmware from file + --flash-rw-ec Flash EC with new firmware from file --intrusion Show status of intrusion switch --inputmodules Show status of the input modules (Framework 16 only) --charge-limit [] Get or set battery charge limit (Percentage number as arg, e.g. '100') @@ -759,7 +768,6 @@ Options: --console Get EC console, choose whether recent or to follow the output [possible values: recent, follow] --reboot-ec Control EC RO/RW jump [possible values: ro, rw, cancel-jump, disable-jump] --dump-ec-flash Dump EC flash contents - --flash-ec Flash EC with new firmware from file -t, --test Run self-test to check if interaction with EC is possible -h, --help Print help information "# diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index ac1fe379..097c75e7 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -69,6 +69,8 @@ pub fn parse(args: &[String]) -> Cli { ec_bin: None, dump_ec_flash: None, flash_ec: None, + flash_ro_ec: None, + flash_rw_ec: None, capsule: None, dump: None, ho2_capsule: None, @@ -304,7 +306,23 @@ pub fn parse(args: &[String]) -> Cli { cli.flash_ec = if args.len() > i + 1 { Some(args[i + 1].clone()) } else { - println!("--flash_ec requires extra argument to denote input file"); + println!("--flash-ec requires extra argument to denote input file"); + None + }; + found_an_option = true; + } else if arg == "--flash-ro-ec" { + cli.flash_ro_ec = if args.len() > i + 1 { + Some(args[i + 1].clone()) + } else { + println!("--flash-ro-ec requires extra argument to denote input file"); + None + }; + found_an_option = true; + } else if arg == "--flash-rw-ec" { + cli.flash_rw_ec = if args.len() > i + 1 { + Some(args[i + 1].clone()) + } else { + println!("--flash-rw-ec requires extra argument to denote input file"); None }; found_an_option = true;