diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index a9e9691..7921830 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -64,7 +64,8 @@ const EC_MEMMAP_SIZE: u16 = 0xFF; /// representing 'EC' in ASCII (0x20 == 'E', 0x21 == 'C') const EC_MEMMAP_ID: u16 = 0x20; -const FLASH_BASE: u32 = 0x0; // 0x80000 +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; @@ -76,6 +77,7 @@ const FLASH_PROGRAM_OFFSET: u32 = 0x1000; #[derive(Clone, Debug, PartialEq)] pub enum EcFlashType { Full, + Both, Ro, Rw, } @@ -817,7 +819,7 @@ impl CrosEc { )); }; - if ft == EcFlashType::Full || ft == EcFlashType::Ro { + 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); if version.details.platform != platform { @@ -832,7 +834,7 @@ impl CrosEc { )); } } - if ft == EcFlashType::Full || ft == EcFlashType::Rw { + if matches!(ft, EcFlashType::Full | EcFlashType::Both | EcFlashType::Rw) { if let Some(version) = ec_binary::read_ec_version(data, false) { println!("EC RW Version in File: {:?}", version.version); if version.details.platform != platform { @@ -874,7 +876,41 @@ impl CrosEc { // 2. Read back two rows and make sure it's all 0xFF // 3. Write each row (128B) individually - if ft == EcFlashType::Full || ft == EcFlashType::Rw { + if ft == EcFlashType::Full { + if data.len() < FLASH_SIZE as usize { + return Err(EcError::DeviceError(format!( + "Firmware file too small for full flash. Expected {} bytes, got {}", + FLASH_SIZE, + data.len() + ))); + } + let data = &data[..FLASH_SIZE as usize]; + + println!( + "Erasing full flash{}", + if dry_run { " (DRY RUN)" } else { "" } + ); + self.erase_ec_flash(FLASH_BASE, FLASH_SIZE, dry_run, info.erase_block_size)?; + println!(" Done"); + + println!( + "Writing full flash{}", + if dry_run { " (DRY RUN)" } else { "" } + ); + self.write_ec_flash(FLASH_BASE, data, dry_run)?; + println!(" Done"); + + println!("Verifying full flash region"); + let flash_data = self.read_ec_flash(FLASH_BASE, FLASH_SIZE)?; + if data == flash_data { + println!(" flash verify success"); + } else { + error!("Flash verify fail!"); + res = Err(EcError::DeviceError("Flash verify fail!".to_string())); + } + } + + if ft == EcFlashType::Both || ft == EcFlashType::Rw { let rw_data = &data[FLASH_RW_BASE as usize..(FLASH_RW_BASE + FLASH_RW_SIZE) as usize]; println!( @@ -906,7 +942,7 @@ impl CrosEc { } } - if ft == EcFlashType::Full || ft == EcFlashType::Ro { + if ft == EcFlashType::Both || ft == EcFlashType::Ro { let ro_data = &data[FLASH_RO_BASE as usize..(FLASH_RO_BASE + FLASH_RO_SIZE) as usize]; println!("Erasing RO region"); diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index ba1cc43..df1bb77 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -143,6 +143,10 @@ struct ClapCli { #[arg(long)] dump_ec_flash: Option, + /// Flash full EC flash with new firmware from file - may render your hardware unbootable! + #[arg(long)] + flash_full_ec: Option, + /// Flash EC (RO+RW) with new firmware from file - may render your hardware unbootable! #[arg(long)] flash_ec: Option, @@ -497,6 +501,9 @@ pub fn parse(args: &[String]) -> Cli { dump_ec_flash: args .dump_ec_flash .map(|x| x.into_os_string().into_string().unwrap()), + flash_full_ec: args + .flash_full_ec + .map(|x| x.into_os_string().into_string().unwrap()), flash_ec: args .flash_ec .map(|x| x.into_os_string().into_string().unwrap()), diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index e006d27..fa47287 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -185,6 +185,7 @@ pub struct Cli { pub dump: Option, pub h2o_capsule: Option, pub dump_ec_flash: Option, + pub flash_full_ec: Option, pub flash_ec: Option, pub flash_ro_ec: Option, pub flash_rw_ec: Option, @@ -273,6 +274,7 @@ pub fn parse(args: &[String]) -> Cli { dump: cli.dump, h2o_capsule: cli.h2o_capsule, // dump_ec_flash + // flash_full_ec // flash_ec // flash_ro_ec // flash_rw_ec @@ -1722,9 +1724,15 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { 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 { + } else if let Some(ec_bin_path) = &args.flash_full_ec { if args.force { flash_ec(&ec, ec_bin_path, EcFlashType::Full, args.dry_run); + } else { + error!("Flashing full EC flash is unsafe. Use --flash-ec instead"); + } + } else if let Some(ec_bin_path) = &args.flash_ec { + if args.force { + flash_ec(&ec, ec_bin_path, EcFlashType::Both, args.dry_run); } else { error!("Flashing EC RO region is unsafe. Use --flash-ec-rw instead"); } diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index faf34b1..fc8467e 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -57,6 +57,7 @@ pub fn parse(args: &[String]) -> Cli { pd_bin: None, ec_bin: None, dump_ec_flash: None, + flash_full_ec: None, flash_ec: None, flash_ro_ec: None, flash_rw_ec: None, @@ -654,6 +655,14 @@ pub fn parse(args: &[String]) -> Cli { None }; found_an_option = true; + } else if arg == "--flash-full-ec" { + cli.flash_full_ec = if args.len() > i + 1 { + Some(args[i + 1].clone()) + } else { + println!("--flash-full-ec requires extra argument to denote input file"); + None + }; + found_an_option = true; } else if arg == "--flash-ec" { cli.flash_ec = if args.len() > i + 1 { Some(args[i + 1].clone()) diff --git a/framework_tool/completions/bash/framework_tool b/framework_tool/completions/bash/framework_tool index ade3813..968a93c 100755 --- a/framework_tool/completions/bash/framework_tool +++ b/framework_tool/completions/bash/framework_tool @@ -23,7 +23,7 @@ _framework_tool() { case "${cmd}" in framework_tool) - opts="-v -q -t -f -h --flash-gpu-descriptor --verbose --quiet --versions --version --features --esrt --device --compare-version --power --thermal --sensors --fansetduty --fansetrpm --autofanctrl --pdports --info --meinfo --pd-info --pd-reset --pd-disable --pd-enable --dp-hdmi-info --dp-hdmi-update --audio-card-info --privacy --pd-bin --ec-bin --capsule --dump --h2o-capsule --dump-ec-flash --flash-ec --flash-ro-ec --flash-rw-ec --intrusion --inputdeck --inputdeck-mode --expansion-bay --charge-limit --charge-current-limit --charge-rate-limit --get-gpio --fp-led-level --fp-brightness --kblight --remap-key --rgbkbd --ps2-enable --tablet-mode --touchscreen-enable --stylus-battery --console --reboot-ec --ec-hib-delay --uptimeinfo --s0ix-counter --hash --driver --pd-addrs --pd-ports --test --test-retimer --boardid --force --dry-run --flash-gpu-descriptor-file --dump-gpu-descriptor-file --nvidia --host-command --generate-completions --help" + opts="-v -q -t -f -h --flash-gpu-descriptor --verbose --quiet --versions --version --features --esrt --device --compare-version --power --thermal --sensors --fansetduty --fansetrpm --autofanctrl --pdports --info --meinfo --pd-info --pd-reset --pd-disable --pd-enable --dp-hdmi-info --dp-hdmi-update --audio-card-info --privacy --pd-bin --ec-bin --capsule --dump --h2o-capsule --dump-ec-flash --flash-full-ec --flash-ec --flash-ro-ec --flash-rw-ec --intrusion --inputdeck --inputdeck-mode --expansion-bay --charge-limit --charge-current-limit --charge-rate-limit --get-gpio --fp-led-level --fp-brightness --kblight --remap-key --rgbkbd --ps2-enable --tablet-mode --touchscreen-enable --stylus-battery --console --reboot-ec --ec-hib-delay --uptimeinfo --s0ix-counter --hash --driver --pd-addrs --pd-ports --test --test-retimer --boardid --force --dry-run --flash-gpu-descriptor-file --dump-gpu-descriptor-file --nvidia --host-command --generate-completions --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -97,6 +97,10 @@ _framework_tool() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --flash-full-ec) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --flash-ec) COMPREPLY=($(compgen -f "${cur}")) return 0 diff --git a/framework_tool/completions/fish/framework_tool.fish b/framework_tool/completions/fish/framework_tool.fish index 00a70a9..9bb27b5 100644 --- a/framework_tool/completions/fish/framework_tool.fish +++ b/framework_tool/completions/fish/framework_tool.fish @@ -22,6 +22,7 @@ complete -c framework_tool -l capsule -d 'Parse UEFI Capsule information from bi complete -c framework_tool -l dump -d 'Dump extracted UX capsule bitmap image to a file' -r -F complete -c framework_tool -l h2o-capsule -d 'Parse UEFI Capsule information from binary file' -r -F complete -c framework_tool -l dump-ec-flash -d 'Dump EC flash contents' -r -F +complete -c framework_tool -l flash-full-ec -d 'Flash full EC flash with new firmware from file - may render your hardware unbootable!' -r -F complete -c framework_tool -l flash-ec -d 'Flash EC (RO+RW) with new firmware from file - may render your hardware unbootable!' -r -F complete -c framework_tool -l flash-ro-ec -d 'Flash EC with new RO firmware from file - may render your hardware unbootable!' -r -F complete -c framework_tool -l flash-rw-ec -d 'Flash EC with new RW firmware from file' -r -F diff --git a/framework_tool/completions/zsh/_framework_tool b/framework_tool/completions/zsh/_framework_tool index 3b80dcd..6a67a10 100644 --- a/framework_tool/completions/zsh/_framework_tool +++ b/framework_tool/completions/zsh/_framework_tool @@ -32,6 +32,7 @@ _framework_tool() { '--dump=[Dump extracted UX capsule bitmap image to a file]:DUMP:_files' \ '--h2o-capsule=[Parse UEFI Capsule information from binary file]:H2O_CAPSULE:_files' \ '--dump-ec-flash=[Dump EC flash contents]:DUMP_EC_FLASH:_files' \ +'--flash-full-ec=[Flash full EC flash with new firmware from file - may render your hardware unbootable!]:FLASH_FULL_EC:_files' \ '--flash-ec=[Flash EC (RO+RW) with new firmware from file - may render your hardware unbootable!]:FLASH_EC:_files' \ '--flash-ro-ec=[Flash EC with new RO firmware from file - may render your hardware unbootable!]:FLASH_RO_EC:_files' \ '--flash-rw-ec=[Flash EC with new RW firmware from file]:FLASH_RW_EC:_files' \