aboutsummaryrefslogtreecommitdiffstats
path: root/util/flashrom_tester
diff options
context:
space:
mode:
Diffstat (limited to 'util/flashrom_tester')
-rw-r--r--util/flashrom_tester/flashrom/src/cmd.rs290
-rw-r--r--util/flashrom_tester/flashrom/src/lib.rs300
-rw-r--r--util/flashrom_tester/src/main.rs9
-rw-r--r--util/flashrom_tester/src/tester.rs51
-rw-r--r--util/flashrom_tester/src/tests.rs25
5 files changed, 356 insertions, 319 deletions
diff --git a/util/flashrom_tester/flashrom/src/cmd.rs b/util/flashrom_tester/flashrom/src/cmd.rs
index 37f8a72f..f0466da8 100644
--- a/util/flashrom_tester/flashrom/src/cmd.rs
+++ b/util/flashrom_tester/flashrom/src/cmd.rs
@@ -33,10 +33,39 @@
// Software Foundation.
//
-use crate::{FlashChip, FlashromError, FlashromOpt};
+use crate::{FlashChip, FlashromError, ROMWriteSpecifics};
use std::process::Command;
+#[derive(Default)]
+pub struct FlashromOpt<'a> {
+ pub wp_opt: WPOpt,
+ pub io_opt: IOOpt<'a>,
+
+ pub layout: Option<&'a str>, // -l <file>
+ pub image: Option<&'a str>, // -i <name>
+
+ pub flash_name: bool, // --flash-name
+ pub verbose: bool, // -V
+}
+
+#[derive(Default)]
+pub struct WPOpt {
+ pub range: Option<(i64, i64)>, // --wp-range x0 x1
+ pub status: bool, // --wp-status
+ pub list: bool, // --wp-list
+ pub enable: bool, // --wp-enable
+ pub disable: bool, // --wp-disable
+}
+
+#[derive(Default)]
+pub struct IOOpt<'a> {
+ pub read: Option<&'a str>, // -r <file>
+ pub write: Option<&'a str>, // -w <file>
+ pub verify: Option<&'a str>, // -v <file>
+ pub erase: bool, // -E
+}
+
#[derive(PartialEq, Debug)]
pub struct FlashromCmd {
pub path: String,
@@ -65,6 +94,13 @@ fn flashrom_extract_size(stdout: &str) -> Result<i64, FlashromError> {
}
}
+impl FlashromCmd {
+ fn dispatch(&self, fropt: FlashromOpt) -> Result<(Vec<u8>, Vec<u8>), FlashromError> {
+ let params = flashrom_decode_opts(fropt);
+ flashrom_dispatch(self.path.as_str(), &params, self.fc)
+ }
+}
+
impl crate::Flashrom for FlashromCmd {
fn get_size(&self) -> Result<i64, FlashromError> {
let (stdout, _) = flashrom_dispatch(self.path.as_str(), &["--flash-size"], self.fc)?;
@@ -73,9 +109,208 @@ impl crate::Flashrom for FlashromCmd {
flashrom_extract_size(&sz)
}
- fn dispatch(&self, fropt: FlashromOpt) -> Result<(Vec<u8>, Vec<u8>), FlashromError> {
- let params = flashrom_decode_opts(fropt);
- flashrom_dispatch(self.path.as_str(), &params, self.fc)
+ fn name(&self) -> Result<(String, String), FlashromError> {
+ let opts = FlashromOpt {
+ io_opt: IOOpt {
+ ..Default::default()
+ },
+
+ flash_name: true,
+
+ ..Default::default()
+ };
+
+ let (stdout, stderr) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ let eoutput = String::from_utf8_lossy(stderr.as_slice());
+ debug!("name()'stdout: {:#?}.", output);
+ debug!("name()'stderr: {:#?}.", eoutput);
+
+ match extract_flash_name(&output) {
+ None => Err("Didn't find chip vendor/name in flashrom output".into()),
+ Some((vendor, name)) => Ok((vendor.into(), name.into())),
+ }
+ }
+
+ fn write_file_with_layout(&self, rws: &ROMWriteSpecifics) -> Result<bool, FlashromError> {
+ let opts = FlashromOpt {
+ io_opt: IOOpt {
+ write: rws.write_file,
+ ..Default::default()
+ },
+
+ layout: rws.layout_file,
+ image: rws.name_file,
+
+ ..Default::default()
+ };
+
+ let (stdout, stderr) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ let eoutput = String::from_utf8_lossy(stderr.as_slice());
+ debug!("write_file_with_layout()'stdout:\n{}.", output);
+ debug!("write_file_with_layout()'stderr:\n{}.", eoutput);
+ Ok(true)
+ }
+
+ fn wp_range(&self, range: (i64, i64), wp_enable: bool) -> Result<bool, FlashromError> {
+ let opts = FlashromOpt {
+ wp_opt: WPOpt {
+ range: Some(range),
+ enable: wp_enable,
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, stderr) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ let eoutput = String::from_utf8_lossy(stderr.as_slice());
+ debug!("wp_range()'stdout:\n{}.", output);
+ debug!("wp_range()'stderr:\n{}.", eoutput);
+ Ok(true)
+ }
+
+ fn wp_list(&self) -> Result<String, FlashromError> {
+ let opts = FlashromOpt {
+ wp_opt: WPOpt {
+ list: true,
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, _) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ if output.len() == 0 {
+ return Err(
+ "wp_list isn't supported on platforms using the Linux kernel SPI driver wp_list"
+ .into(),
+ );
+ }
+ Ok(output.to_string())
+ }
+
+ fn wp_status(&self, en: bool) -> Result<bool, FlashromError> {
+ let status = if en { "en" } else { "dis" };
+ info!("See if chip write protect is {}abled", status);
+
+ let opts = FlashromOpt {
+ wp_opt: WPOpt {
+ status: true,
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, _) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+
+ debug!("wp_status():\n{}", output);
+
+ let s = std::format!("write protect is {}abled", status);
+ Ok(output.contains(&s))
+ }
+
+ fn wp_toggle(&self, en: bool) -> Result<bool, FlashromError> {
+ let status = if en { "en" } else { "dis" };
+
+ // For MTD, --wp-range and --wp-enable must be used simultaneously.
+ let range = if en {
+ let rom_sz: i64 = self.get_size()?;
+ Some((0, rom_sz)) // (start, len)
+ } else {
+ None
+ };
+
+ let opts = FlashromOpt {
+ wp_opt: WPOpt {
+ range: range,
+ enable: en,
+ disable: !en,
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, stderr) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ let eoutput = String::from_utf8_lossy(stderr.as_slice());
+
+ debug!("wp_toggle()'stdout:\n{}.", output);
+ debug!("wp_toggle()'stderr:\n{}.", eoutput);
+
+ match self.wp_status(true) {
+ Ok(_ret) => {
+ info!("Successfully {}abled write-protect", status);
+ Ok(true)
+ }
+ Err(e) => Err(format!("Cannot {}able write-protect: {}", status, e)),
+ }
+ }
+
+ fn read(&self, path: &str) -> Result<(), FlashromError> {
+ let opts = FlashromOpt {
+ io_opt: IOOpt {
+ read: Some(path),
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, _) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ debug!("read():\n{}", output);
+ Ok(())
+ }
+
+ fn write(&self, path: &str) -> Result<(), FlashromError> {
+ let opts = FlashromOpt {
+ io_opt: IOOpt {
+ write: Some(path),
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, _) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ debug!("write():\n{}", output);
+ Ok(())
+ }
+
+ fn verify(&self, path: &str) -> Result<(), FlashromError> {
+ let opts = FlashromOpt {
+ io_opt: IOOpt {
+ verify: Some(path),
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, _) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ debug!("verify():\n{}", output);
+ Ok(())
+ }
+
+ fn erase(&self) -> Result<(), FlashromError> {
+ let opts = FlashromOpt {
+ io_opt: IOOpt {
+ erase: true,
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ let (stdout, _) = self.dispatch(opts)?;
+ let output = String::from_utf8_lossy(stdout.as_slice());
+ debug!("erase():\n{}", output);
+ Ok(())
+ }
+
+ fn can_control_hw_wp(&self) -> bool {
+ self.fc.can_control_hw_wp()
}
}
@@ -209,10 +444,33 @@ fn hex_range_string(s: i64, l: i64) -> String {
format!("{:#08X},{:#08X}", s, l).to_string()
}
+/// Get a flash vendor and name from the first matching line of flashrom output.
+///
+/// The target line looks like 'vendor="foo" name="bar"', as output by flashrom --flash-name.
+/// This is usually the last line of output.
+fn extract_flash_name(stdout: &str) -> Option<(&str, &str)> {
+ for line in stdout.lines() {
+ if !line.starts_with("vendor=\"") {
+ continue;
+ }
+
+ let tail = line.trim_start_matches("vendor=\"");
+ let mut split = tail.splitn(2, "\" name=\"");
+ let vendor = split.next();
+ let name = split.next().map(|s| s.trim_end_matches('"'));
+
+ match (vendor, name) {
+ (Some(v), Some(n)) => return Some((v, n)),
+ _ => continue,
+ }
+ }
+ None
+}
+
#[cfg(test)]
mod tests {
use super::flashrom_decode_opts;
- use crate::{FlashromOpt, IOOpt, WPOpt};
+ use super::{FlashromOpt, IOOpt, WPOpt};
#[test]
fn decode_wp_opt() {
@@ -347,4 +605,26 @@ mod tests {
Err("Found no purely-numeric lines in flashrom output".into())
);
}
+
+ #[test]
+ fn extract_flash_name() {
+ use super::extract_flash_name;
+
+ assert_eq!(
+ extract_flash_name(
+ "coreboot table found at 0x7cc13000\n\
+ Found chipset \"Intel Braswell\". Enabling flash write... OK.\n\
+ vendor=\"Winbond\" name=\"W25Q64DW\"\n"
+ ),
+ Some(("Winbond", "W25Q64DW"))
+ );
+
+ assert_eq!(
+ extract_flash_name(
+ "vendor name is TEST\n\
+ Something failed!"
+ ),
+ None
+ )
+ }
}
diff --git a/util/flashrom_tester/flashrom/src/lib.rs b/util/flashrom_tester/flashrom/src/lib.rs
index 75797d39..924a7131 100644
--- a/util/flashrom_tester/flashrom/src/lib.rs
+++ b/util/flashrom_tester/flashrom/src/lib.rs
@@ -83,296 +83,46 @@ impl FlashChip {
pub type FlashromError = String;
-#[derive(Default)]
-pub struct FlashromOpt<'a> {
- pub wp_opt: WPOpt,
- pub io_opt: IOOpt<'a>,
-
- pub layout: Option<&'a str>, // -l <file>
- pub image: Option<&'a str>, // -i <name>
-
- pub flash_name: bool, // --flash-name
- pub verbose: bool, // -V
-}
-
-#[derive(Default)]
-pub struct WPOpt {
- pub range: Option<(i64, i64)>, // --wp-range x0 x1
- pub status: bool, // --wp-status
- pub list: bool, // --wp-list
- pub enable: bool, // --wp-enable
- pub disable: bool, // --wp-disable
-}
-
-#[derive(Default)]
-pub struct IOOpt<'a> {
- pub read: Option<&'a str>, // -r <file>
- pub write: Option<&'a str>, // -w <file>
- pub verify: Option<&'a str>, // -v <file>
- pub erase: bool, // -E
-}
-
-pub trait Flashrom {
- fn get_size(&self) -> Result<i64, FlashromError>;
- fn dispatch(&self, fropt: FlashromOpt) -> Result<(Vec<u8>, Vec<u8>), FlashromError>;
-}
-
-pub fn name(cmd: &cmd::FlashromCmd) -> Result<(String, String), FlashromError> {
- let opts = FlashromOpt {
- io_opt: IOOpt {
- ..Default::default()
- },
-
- flash_name: true,
-
- ..Default::default()
- };
-
- let (stdout, stderr) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- let eoutput = String::from_utf8_lossy(stderr.as_slice());
- debug!("name()'stdout: {:#?}.", output);
- debug!("name()'stderr: {:#?}.", eoutput);
-
- match extract_flash_name(&output) {
- None => Err("Didn't find chip vendor/name in flashrom output".into()),
- Some((vendor, name)) => Ok((vendor.into(), name.into())),
- }
-}
-
-/// Get a flash vendor and name from the first matching line of flashrom output.
-///
-/// The target line looks like 'vendor="foo" name="bar"', as output by flashrom --flash-name.
-/// This is usually the last line of output.
-fn extract_flash_name(stdout: &str) -> Option<(&str, &str)> {
- for line in stdout.lines() {
- if !line.starts_with("vendor=\"") {
- continue;
- }
-
- let tail = line.trim_start_matches("vendor=\"");
- let mut split = tail.splitn(2, "\" name=\"");
- let vendor = split.next();
- let name = split.next().map(|s| s.trim_end_matches('"'));
-
- match (vendor, name) {
- (Some(v), Some(n)) => return Some((v, n)),
- _ => continue,
- }
- }
- None
-}
-
pub struct ROMWriteSpecifics<'a> {
pub layout_file: Option<&'a str>,
pub write_file: Option<&'a str>,
pub name_file: Option<&'a str>,
}
-pub fn write_file_with_layout(
- cmd: &cmd::FlashromCmd,
- rws: &ROMWriteSpecifics,
-) -> Result<bool, FlashromError> {
- let opts = FlashromOpt {
- io_opt: IOOpt {
- write: rws.write_file,
- ..Default::default()
- },
-
- layout: rws.layout_file,
- image: rws.name_file,
-
- ..Default::default()
- };
-
- let (stdout, stderr) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- let eoutput = String::from_utf8_lossy(stderr.as_slice());
- debug!("write_file_with_layout()'stdout:\n{}.", output);
- debug!("write_file_with_layout()'stderr:\n{}.", eoutput);
- Ok(true)
-}
-
-pub fn wp_range(
- cmd: &cmd::FlashromCmd,
- range: (i64, i64),
- wp_enable: bool,
-) -> Result<bool, FlashromError> {
- let opts = FlashromOpt {
- wp_opt: WPOpt {
- range: Some(range),
- enable: wp_enable,
- ..Default::default()
- },
- ..Default::default()
- };
-
- let (stdout, stderr) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- let eoutput = String::from_utf8_lossy(stderr.as_slice());
- debug!("wp_range()'stdout:\n{}.", output);
- debug!("wp_range()'stderr:\n{}.", eoutput);
- Ok(true)
-}
-
-pub fn wp_list(cmd: &cmd::FlashromCmd) -> Result<String, FlashromError> {
- let opts = FlashromOpt {
- wp_opt: WPOpt {
- list: true,
- ..Default::default()
- },
- ..Default::default()
- };
-
- let (stdout, _) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- if output.len() == 0 {
- return Err(
- "wp_list isn't supported on platforms using the Linux kernel SPI driver wp_list".into(),
- );
- }
- Ok(output.to_string())
-}
-
-pub fn wp_status(cmd: &cmd::FlashromCmd, en: bool) -> Result<bool, FlashromError> {
- let status = if en { "en" } else { "dis" };
- info!("See if chip write protect is {}abled", status);
-
- let opts = FlashromOpt {
- wp_opt: WPOpt {
- status: true,
- ..Default::default()
- },
- ..Default::default()
- };
-
- let (stdout, _) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
-
- debug!("wp_status():\n{}", output);
-
- let s = std::format!("write protect is {}abled", status);
- Ok(output.contains(&s))
-}
-
-pub fn wp_toggle(cmd: &cmd::FlashromCmd, en: bool) -> Result<bool, FlashromError> {
- let status = if en { "en" } else { "dis" };
-
- // For MTD, --wp-range and --wp-enable must be used simultaneously.
- let range = if en {
- let rom_sz: i64 = cmd.get_size()?;
- Some((0, rom_sz)) // (start, len)
- } else {
- None
- };
-
- let opts = FlashromOpt {
- wp_opt: WPOpt {
- range: range,
- enable: en,
- disable: !en,
- ..Default::default()
- },
- ..Default::default()
- };
-
- let (stdout, stderr) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- let eoutput = String::from_utf8_lossy(stderr.as_slice());
-
- debug!("wp_toggle()'stdout:\n{}.", output);
- debug!("wp_toggle()'stderr:\n{}.", eoutput);
-
- match wp_status(&cmd, true) {
- Ok(_ret) => {
- info!("Successfully {}abled write-protect", status);
- Ok(true)
- }
- Err(e) => Err(format!("Cannot {}able write-protect: {}", status, e)),
- }
-}
+pub trait Flashrom {
+ /// Returns the size of the flash in bytes.
+ fn get_size(&self) -> Result<i64, FlashromError>;
-pub fn read(cmd: &cmd::FlashromCmd, path: &str) -> Result<(), FlashromError> {
- let opts = FlashromOpt {
- io_opt: IOOpt {
- read: Some(path),
- ..Default::default()
- },
- ..Default::default()
- };
+ /// Returns the vendor name and the flash name.
+ fn name(&self) -> Result<(String, String), FlashromError>;
- let (stdout, _) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- debug!("read():\n{}", output);
- Ok(())
-}
+ /// Write only a region of the flash.
+ fn write_file_with_layout(&self, rws: &ROMWriteSpecifics) -> Result<bool, FlashromError>;
-pub fn write(cmd: &cmd::FlashromCmd, path: &str) -> Result<(), FlashromError> {
- let opts = FlashromOpt {
- io_opt: IOOpt {
- write: Some(path),
- ..Default::default()
- },
- ..Default::default()
- };
+ /// Set write protect status for a range.
+ fn wp_range(&self, range: (i64, i64), wp_enable: bool) -> Result<bool, FlashromError>;
- let (stdout, _) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- debug!("write():\n{}", output);
- Ok(())
-}
+ /// Read the write protect regions for the flash.
+ fn wp_list(&self) -> Result<String, FlashromError>;
-pub fn verify(cmd: &cmd::FlashromCmd, path: &str) -> Result<(), FlashromError> {
- let opts = FlashromOpt {
- io_opt: IOOpt {
- verify: Some(path),
- ..Default::default()
- },
- ..Default::default()
- };
+ /// Return true if the flash write protect status matches `en`.
+ fn wp_status(&self, en: bool) -> Result<bool, FlashromError>;
- let (stdout, _) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- debug!("verify():\n{}", output);
- Ok(())
-}
+ /// Set write protect status.
+ fn wp_toggle(&self, en: bool) -> Result<bool, FlashromError>;
-pub fn erase(cmd: &cmd::FlashromCmd) -> Result<(), FlashromError> {
- let opts = FlashromOpt {
- io_opt: IOOpt {
- erase: true,
- ..Default::default()
- },
- ..Default::default()
- };
+ /// Read the whole flash to the file specified by `path`.
+ fn read(&self, path: &str) -> Result<(), FlashromError>;
- let (stdout, _) = cmd.dispatch(opts)?;
- let output = String::from_utf8_lossy(stdout.as_slice());
- debug!("erase():\n{}", output);
- Ok(())
-}
+ /// Write the whole flash to the file specified by `path`.
+ fn write(&self, path: &str) -> Result<(), FlashromError>;
-#[cfg(test)]
-mod tests {
- #[test]
- fn extract_flash_name() {
- use super::extract_flash_name;
+ /// Verify the whole flash against the file specified by `path`.
+ fn verify(&self, path: &str) -> Result<(), FlashromError>;
- assert_eq!(
- extract_flash_name(
- "coreboot table found at 0x7cc13000\n\
- Found chipset \"Intel Braswell\". Enabling flash write... OK.\n\
- vendor=\"Winbond\" name=\"W25Q64DW\"\n"
- ),
- Some(("Winbond", "W25Q64DW"))
- );
+ /// Erase the whole flash.
+ fn erase(&self) -> Result<(), FlashromError>;
- assert_eq!(
- extract_flash_name(
- "vendor name is TEST\n\
- Something failed!"
- ),
- None
- )
- }
+ /// Return true if the hardware write protect of this flash can be controlled.
+ fn can_control_hw_wp(&self) -> bool;
}
diff --git a/util/flashrom_tester/src/main.rs b/util/flashrom_tester/src/main.rs
index 80484d20..69bb92db 100644
--- a/util/flashrom_tester/src/main.rs
+++ b/util/flashrom_tester/src/main.rs
@@ -39,7 +39,7 @@ extern crate log;
mod logger;
use clap::{App, Arg};
-use flashrom::FlashChip;
+use flashrom::{FlashChip, Flashrom, FlashromCmd};
use flashrom_tester::{tester, tests};
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
@@ -123,6 +123,11 @@ fn main() {
)
.expect("ccd_target_type should admit only known types");
+ let cmd: Box<dyn Flashrom> = Box::new(FlashromCmd {
+ path: flashrom_path.to_string(),
+ fc: ccd_type,
+ });
+
let print_layout = matches.is_present("print-layout");
let output_format = matches
.value_of("output-format")
@@ -132,7 +137,7 @@ fn main() {
let test_names = matches.values_of("test_name");
if let Err(e) = tests::generic(
- flashrom_path,
+ cmd.as_ref(),
ccd_type,
print_layout,
output_format,
diff --git a/util/flashrom_tester/src/tester.rs b/util/flashrom_tester/src/tester.rs
index 3150a435..172f9958 100644
--- a/util/flashrom_tester/src/tester.rs
+++ b/util/flashrom_tester/src/tester.rs
@@ -36,7 +36,7 @@
use super::rand_util;
use super::types;
use super::utils::{self, LayoutSizes};
-use flashrom::{FlashChip, Flashrom, FlashromCmd};
+use flashrom::{FlashChip, Flashrom};
use serde_json::json;
use std::mem::MaybeUninit;
use std::sync::atomic::{AtomicBool, Ordering};
@@ -52,7 +52,7 @@ pub struct TestEnv<'a> {
///
/// Where possible, prefer to use methods on the TestEnv rather than delegating
/// to the raw flashrom functions.
- pub cmd: &'a FlashromCmd,
+ pub cmd: &'a dyn Flashrom,
layout: LayoutSizes,
pub wp: WriteProtectState<'a, 'static>,
@@ -65,20 +65,20 @@ pub struct TestEnv<'a> {
}
impl<'a> TestEnv<'a> {
- pub fn create(chip_type: FlashChip, cmd: &'a FlashromCmd) -> Result<Self, String> {
+ pub fn create(chip_type: FlashChip, cmd: &'a dyn Flashrom) -> Result<Self, String> {
let rom_sz = cmd.get_size()?;
let out = TestEnv {
chip_type: chip_type,
cmd: cmd,
layout: utils::get_layout_sizes(rom_sz)?,
- wp: WriteProtectState::from_hardware(cmd)?,
+ wp: WriteProtectState::from_hardware(cmd, chip_type)?,
original_flash_contents: "/tmp/flashrom_tester_golden.bin".into(),
random_data: "/tmp/random_content.bin".into(),
};
info!("Stashing golden image for verification/recovery on completion");
- flashrom::read(&out.cmd, &out.original_flash_contents)?;
- flashrom::verify(&out.cmd, &out.original_flash_contents)?;
+ out.cmd.read(&out.original_flash_contents)?;
+ out.cmd.verify(&out.original_flash_contents)?;
info!("Generating random flash-sized data");
rand_util::gen_rand_testdata(&out.random_data, rom_sz as usize)
@@ -123,19 +123,19 @@ impl<'a> TestEnv<'a> {
/// Return true if the current Flash contents are the same as the golden image
/// that was present at the start of testing.
pub fn is_golden(&self) -> bool {
- flashrom::verify(&self.cmd, &self.original_flash_contents).is_ok()
+ self.cmd.verify(&self.original_flash_contents).is_ok()
}
/// Do whatever is necessary to make the current Flash contents the same as they
/// were at the start of testing.
pub fn ensure_golden(&mut self) -> Result<(), String> {
self.wp.set_hw(false)?.set_sw(false)?;
- flashrom::write(&self.cmd, &self.original_flash_contents)
+ self.cmd.write(&self.original_flash_contents)
}
/// Attempt to erase the flash.
pub fn erase(&self) -> Result<(), String> {
- flashrom::erase(self.cmd)
+ self.cmd.erase()
}
/// Verify that the current Flash contents are the same as the file at the given
@@ -143,11 +143,11 @@ impl<'a> TestEnv<'a> {
///
/// Returns Err if they are not the same.
pub fn verify(&self, contents_path: &str) -> Result<(), String> {
- flashrom::verify(self.cmd, contents_path)
+ self.cmd.verify(contents_path)
}
}
-impl Drop for TestEnv<'_> {
+impl<'a> Drop for TestEnv<'a> {
fn drop(&mut self) {
info!("Verifying flash remains unmodified");
if !self.is_golden() {
@@ -177,7 +177,8 @@ pub struct WriteProtectState<'a, 'p> {
initial: InitialState<'p>,
// Tuples are (hardware, software)
current: (bool, bool),
- cmd: &'a FlashromCmd,
+ cmd: &'a dyn Flashrom,
+ fc: FlashChip,
}
enum InitialState<'p> {
@@ -199,7 +200,7 @@ impl<'a> WriteProtectState<'a, 'static> {
///
/// Panics if there is already a live state derived from hardware. In such a situation the
/// new state must be derived from the live one, or the live one must be dropped first.
- pub fn from_hardware(cmd: &'a FlashromCmd) -> Result<Self, String> {
+ pub fn from_hardware(cmd: &'a dyn Flashrom, fc: FlashChip) -> Result<Self, String> {
let mut lock = Self::get_liveness_lock()
.lock()
.expect("Somebody panicked during WriteProtectState init from hardware");
@@ -217,12 +218,13 @@ impl<'a> WriteProtectState<'a, 'static> {
initial: InitialState::Hardware(hw, sw),
current: (hw, sw),
cmd,
+ fc,
})
}
/// Get the actual hardware write protect state.
- fn get_hw(cmd: &FlashromCmd) -> Result<bool, String> {
- if cmd.fc.can_control_hw_wp() {
+ fn get_hw(cmd: &dyn Flashrom) -> Result<bool, String> {
+ if cmd.can_control_hw_wp() {
super::utils::get_hardware_wp()
} else {
Ok(false)
@@ -230,8 +232,8 @@ impl<'a> WriteProtectState<'a, 'static> {
}
/// Get the actual software write protect state.
- fn get_sw(cmd: &FlashromCmd) -> Result<bool, String> {
- flashrom::wp_status(cmd, true)
+ fn get_sw(cmd: &dyn Flashrom) -> Result<bool, String> {
+ cmd.wp_status(true)
}
}
@@ -241,14 +243,14 @@ impl<'a, 'p> WriteProtectState<'a, 'p> {
///
/// If false, calls to set_hw() will do nothing.
pub fn can_control_hw_wp(&self) -> bool {
- self.cmd.fc.can_control_hw_wp()
+ self.cmd.can_control_hw_wp()
}
/// Set the software write protect.
pub fn set_sw(&mut self, enable: bool) -> Result<&mut Self, String> {
info!("request={}, current={}", enable, self.current.1);
if self.current.1 != enable {
- flashrom::wp_toggle(self.cmd, /* en= */ enable)?;
+ self.cmd.wp_toggle(/* en= */ enable)?;
self.current.1 = enable;
}
Ok(self)
@@ -263,7 +265,7 @@ impl<'a, 'p> WriteProtectState<'a, 'p> {
} else if enable {
info!(
"Ignoring attempt to enable hardware WP with {:?} programmer",
- self.cmd.fc
+ self.fc
);
}
}
@@ -277,7 +279,7 @@ impl<'a, 'p> WriteProtectState<'a, 'p> {
/// ```no_run
/// # fn main() -> Result<(), String> {
/// # let cmd: flashrom::FlashromCmd = unimplemented!();
- /// let wp = flashrom_tester::tester::WriteProtectState::from_hardware(&cmd)?;
+ /// let wp = flashrom_tester::tester::WriteProtectState::from_hardware(&cmd, flashrom::FlashChip::SERVO)?;
/// {
/// let mut wp = wp.push();
/// wp.set_sw(false)?;
@@ -297,6 +299,7 @@ impl<'a, 'p> WriteProtectState<'a, 'p> {
initial: InitialState::Previous(self),
current: self.current,
cmd: self.cmd,
+ fc: self.fc,
}
}
@@ -376,7 +379,7 @@ impl<'a, 'p> WriteProtectState<'a, 'p> {
)
})?;
}
- flashrom::wp_toggle(self.cmd, /* en= */ sw).map_err(|e| {
+ self.cmd.wp_toggle(/* en= */ sw).map_err(|e| {
format!(
"Failed to {}able software write protect: {}",
enable_str(sw),
@@ -386,7 +389,7 @@ impl<'a, 'p> WriteProtectState<'a, 'p> {
}
assert!(
- self.cmd.fc.can_control_hw_wp() || (!self.current.0 && !hw),
+ self.cmd.can_control_hw_wp() || (!self.current.0 && !hw),
"HW WP must be disabled if it cannot be controlled"
);
if hw != self.current.0 {
@@ -479,7 +482,7 @@ fn decode_test_result(res: TestResult, con: TestConclusion) -> (TestConclusion,
pub fn run_all_tests<T, TS>(
chip: FlashChip,
- cmd: &FlashromCmd,
+ cmd: &dyn Flashrom,
ts: TS,
terminate_flag: Option<&AtomicBool>,
) -> Vec<(String, (TestConclusion, Option<TestError>))>
diff --git a/util/flashrom_tester/src/tests.rs b/util/flashrom_tester/src/tests.rs
index 86c0da5b..208e98cb 100644
--- a/util/flashrom_tester/src/tests.rs
+++ b/util/flashrom_tester/src/tests.rs
@@ -36,7 +36,7 @@
use super::cros_sysinfo;
use super::tester::{self, OutputFormat, TestCase, TestEnv, TestResult};
use super::utils::{self, LayoutNames};
-use flashrom::{FlashChip, Flashrom, FlashromCmd};
+use flashrom::{FlashChip, Flashrom};
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::{BufRead, Write};
@@ -78,16 +78,13 @@ fn filter_tests<'n, 't: 'n, T: TestCase>(
/// tests are run. Provided names that don't match any known test will be logged
/// as a warning.
pub fn generic<'a, TN: Iterator<Item = &'a str>>(
- path: &str,
+ cmd: &dyn Flashrom,
fc: FlashChip,
print_layout: bool,
output_format: OutputFormat,
test_names: Option<TN>,
terminate_flag: Option<&AtomicBool>,
) -> Result<(), Box<dyn std::error::Error>> {
- let p = path.to_string();
- let cmd = FlashromCmd { path: p, fc };
-
utils::ac_power_warning();
info!("Calculate ROM partition sizes & Create the layout file.");
@@ -142,18 +139,20 @@ pub fn generic<'a, TN: Iterator<Item = &'a str>>(
};
let tests = filter_tests(tests, &mut filter_names);
+ let chip_name = cmd
+ .name()
+ .map(|x| format!("vendor=\"{}\" name=\"{}\"", x.0, x.1))
+ .unwrap_or("<Unknown chip>".into());
+
// ------------------------.
// Run all the tests and collate the findings:
- let results = tester::run_all_tests(fc, &cmd, tests, terminate_flag);
+ let results = tester::run_all_tests(fc, cmd, tests, terminate_flag);
// Any leftover filtered names were specified to be run but don't exist
for leftover in filter_names.iter().flatten() {
warn!("No test matches filter name \"{}\"", leftover);
}
- let chip_name = flashrom::name(&cmd)
- .map(|x| format!("vendor=\"{}\" name=\"{}\"", x.0, x.1))
- .unwrap_or("<Unknown chip>".into());
let os_rel = sys_info::os_release().unwrap_or("<Unknown OS>".to_string());
let system_info = cros_sysinfo::system_info().unwrap_or("<Unknown System>".to_string());
let bios_info = cros_sysinfo::bios_info().unwrap_or("<Unknown BIOS>".to_string());
@@ -170,7 +169,7 @@ pub fn generic<'a, TN: Iterator<Item = &'a str>>(
fn get_device_name_test(env: &mut TestEnv) -> TestResult {
// Success means we got something back, which is good enough.
- flashrom::name(env.cmd)?;
+ env.cmd.name()?;
Ok(())
}
@@ -178,7 +177,7 @@ fn wp_toggle_test(env: &mut TestEnv) -> TestResult {
// NOTE: This is not strictly a 'test' as it is allowed to fail on some platforms.
// However, we will warn when it does fail.
// List the write-protected regions of flash.
- match flashrom::wp_list(env.cmd) {
+ match env.cmd.wp_list() {
Ok(list_str) => info!("\n{}", list_str),
Err(e) => warn!("{}", e),
};
@@ -289,7 +288,7 @@ fn partial_lock_test(section: LayoutNames) -> impl Fn(&mut TestEnv) -> TestResul
// Disable software WP so we can do range protection, but hardware WP
// must remain enabled for (most) range protection to do anything.
env.wp.set_hw(false)?.set_sw(false)?;
- flashrom::wp_range(env.cmd, (start, len), true)?;
+ env.cmd.wp_range((start, len), true)?;
env.wp.set_hw(true)?;
let rws = flashrom::ROMWriteSpecifics {
@@ -297,7 +296,7 @@ fn partial_lock_test(section: LayoutNames) -> impl Fn(&mut TestEnv) -> TestResul
write_file: Some(env.random_data_file()),
name_file: Some(name),
};
- if flashrom::write_file_with_layout(env.cmd, &rws).is_ok() {
+ if env.cmd.write_file_with_layout(&rws).is_ok() {
return Err(
"Section should be locked, should not have been overwritable with random data"
.into(),