Skip to content

Commit

Permalink
chromium_ec: Allow flashing single EC FW
Browse files Browse the repository at this point in the history
Only RO, only RW or both.

Signed-off-by: Daniel Schaefer <[email protected]>
  • Loading branch information
JohnAZoidberg committed Apr 28, 2024
1 parent bc530fb commit 31cdb6f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 27 deletions.
57 changes: 38 additions & 19 deletions framework_lib/src/chromium_ec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<u8> = 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");
Expand Down
14 changes: 14 additions & 0 deletions framework_lib/src/commandline/clap_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ struct ClapCli {
#[arg(long)]
flash_ec: Option<std::path::PathBuf>,

/// Flash EC with new RO firmware from file
#[arg(long)]
flash_ro_ec: Option<std::path::PathBuf>,

/// Flash EC with new RW firmware from file
#[arg(long)]
flash_rw_ec: Option<std::path::PathBuf>,

/// Show status of intrusion switch
#[arg(long)]
intrusion: bool,
Expand Down Expand Up @@ -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,
Expand Down
22 changes: 15 additions & 7 deletions framework_lib/src/commandline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -130,6 +129,8 @@ pub struct Cli {
pub ho2_capsule: Option<String>,
pub dump_ec_flash: Option<String>,
pub flash_ec: Option<String>,
pub flash_ro_ec: Option<String>,
pub flash_rw_ec: Option<String>,
pub driver: Option<CrosEcDriverType>,
pub test: bool,
pub intrusion: bool,
Expand Down Expand Up @@ -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"))]
Expand All @@ -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!");
Expand Down Expand Up @@ -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")]
Expand Down Expand Up @@ -751,6 +757,9 @@ Options:
--pd-bin <PD_BIN> Parse versions from PD firmware binary file
--ec-bin <EC_BIN> Parse versions from EC firmware binary file
--capsule <CAPSULE> Parse UEFI Capsule information from binary file
--flash-ec <FLASH_EC> Flash EC with new firmware from file
--flash-ro-ec <FLASH_EC> Flash EC with new firmware from file
--flash-rw-ec <FLASH_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 [<VAL>] Get or set battery charge limit (Percentage number as arg, e.g. '100')
Expand All @@ -759,7 +768,6 @@ Options:
--console <CONSOLE> Get EC console, choose whether recent or to follow the output [possible values: recent, follow]
--reboot-ec <REBOOT_EC>Control EC RO/RW jump [possible values: ro, rw, cancel-jump, disable-jump]
--dump-ec-flash <DUMP_EC_FLASH> Dump EC flash contents
--flash-ec <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
"#
Expand Down
20 changes: 19 additions & 1 deletion framework_lib/src/commandline/uefi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 31cdb6f

Please sign in to comment.