From edeb9e2789392ac9928a3e934cb7325874e56a55 Mon Sep 17 00:00:00 2001 From: Anthony Rocha <116300062+rusty1968@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:04:00 -0800 Subject: [PATCH] Emulation code coverage : persist and merge coverage bitmaps (#992) * This commit extends sw-emulator coverage functionality so the coverage bitmap of indiividual test runs can be dumped to the file system and subsequently merged so the coverage can be calculated. * misc fixes * Remove expensive .clone() call. --------- Co-authored-by: Kor Nielsen --- .github/workflows/build-test.yml | 6 + Cargo.lock | 19 ++ Cargo.toml | 2 + coverage/Cargo.toml | 18 ++ coverage/src/lib.rs | 302 ++++++++++++++++++ coverage/src/main.rs | 47 +++ .../tests/drivers_integration_tests/main.rs | 2 +- hw-model/Cargo.toml | 1 + hw-model/c-binding/examples/Makefile | 2 +- hw-model/src/model_emulated.rs | 25 +- libcaliptra/examples/hwmodel/Makefile | 2 +- .../rom_integration_tests/test_fake_rom.rs | 4 +- .../test_fmcalias_derivation.rs | 34 +- .../test_image_validation.rs | 184 +++++------ .../test_update_reset.rs | 18 +- test/Cargo.toml | 1 + test/dpe_verification/transport.go | 2 +- test/src/coverage.rs | 155 --------- test/src/lib.rs | 1 - .../test_code_coverage.rs | 4 +- 20 files changed, 547 insertions(+), 282 deletions(-) create mode 100644 coverage/Cargo.toml create mode 100644 coverage/src/lib.rs create mode 100644 coverage/src/main.rs delete mode 100644 test/src/coverage.rs diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 49c4cc65b5..ebfb3fd4a2 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -19,6 +19,7 @@ jobs: SCCACHE_VERSION: 0.3.3 SCCACHE_GHA_CACHE_TO: sccache-caliptra-sw SCCACHE_GHA_CACHE_FROM: sccache-caliptra-sw + # CPTRA_COVERAGE_PATH: /tmp # Change this to a new random value if you suspect the cache is corrupted SCCACHE_C_CUSTOM_CACHE_BUSTER: 8b42a6e70ec4 @@ -154,6 +155,10 @@ jobs: run: | (cd rom/dev && make run) + - name: ROM Coverage + run: | + CPTRA_COVERAGE_PATH=/tmp cargo test --manifest-path ./rom/dev/Cargo.toml && CPTRA_COVERAGE_PATH=/tmp cargo run --manifest-path ./coverage/Cargo.toml + - name: Caliptra HW-Model C Binding Smoke Test run: | git submodule update --init @@ -165,3 +170,4 @@ jobs: - name: DPE Verification Tests run: | (cd test/dpe_verification && make run) + diff --git a/Cargo.lock b/Cargo.lock index 7367f3ce91..ee311367cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,6 +138,9 @@ name = "bit-vec" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +dependencies = [ + "serde", +] [[package]] name = "bitfield" @@ -236,6 +239,20 @@ dependencies = [ "ufmt", ] +[[package]] +name = "caliptra-coverage" +version = "0.1.0" +dependencies = [ + "anyhow", + "bit-vec", + "caliptra-builder", + "elf", + "hex", + "rand", + "serde", + "serde_json", +] + [[package]] name = "caliptra-cpu" version = "0.1.0" @@ -429,6 +446,7 @@ dependencies = [ "bitfield", "caliptra-api", "caliptra-builder", + "caliptra-coverage", "caliptra-emu-bus", "caliptra-emu-cpu", "caliptra-emu-periph", @@ -727,6 +745,7 @@ dependencies = [ "anyhow", "asn1", "caliptra-builder", + "caliptra-coverage", "caliptra-hw-model", "caliptra-hw-model-types", "caliptra-runtime", diff --git a/Cargo.toml b/Cargo.toml index 1fe3bf14a6..565f17e58b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ members = [ "ci-tools/file-header-fix", "ci-tools/size-history", "common", + "coverage", "cpu", "drivers", "drivers/test-fw", @@ -88,6 +89,7 @@ caliptra-api = { path = "api" } caliptra-cfi-lib = { path = "cfi/lib", default-features = false, features = ["cfi", "cfi-counter" ] } caliptra-cfi-derive = { path = "cfi/derive" } caliptra_common = { path = "common", default-features = false } +caliptra-coverage = { path = "coverage" } caliptra-builder = { path = "builder" } caliptra-cpu = { path = "cpu" } caliptra-drivers = { path = "drivers" } diff --git a/coverage/Cargo.toml b/coverage/Cargo.toml new file mode 100644 index 0000000000..100da0acc1 --- /dev/null +++ b/coverage/Cargo.toml @@ -0,0 +1,18 @@ +# Licensed under the Apache-2.0 license + +[package] +name = "caliptra-coverage" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow.workspace = true +serde = {workspace = true, features = ["derive"]} +serde_json.workspace = true +hex.workspace = true +rand.workspace = true +bit-vec = { workspace = true, features = ["serde"] } +caliptra-builder.workspace = true +elf.workspace = true \ No newline at end of file diff --git a/coverage/src/lib.rs b/coverage/src/lib.rs new file mode 100644 index 0000000000..8fcb72cac7 --- /dev/null +++ b/coverage/src/lib.rs @@ -0,0 +1,302 @@ +// Licensed under the Apache-2.0 license + +use anyhow::Context; +use bit_vec::BitVec; +use caliptra_builder::{build_firmware_elf, FwId, SymbolType}; +use elf::endian::AnyEndian; +use elf::ElfBytes; +use std::collections::hash_map::{DefaultHasher, Entry}; +use std::collections::{HashMap, HashSet}; +use std::fs::File; +use std::hash::Hasher; +use std::io::{BufRead, BufReader, BufWriter, Write}; +use std::path::{Path, PathBuf}; + +pub const CPTRA_COVERAGE_PATH: &str = "CPTRA_COVERAGE_PATH"; + +pub struct CoverageMap { + pub map: HashMap, +} + +impl CoverageMap { + pub fn new(paths: Vec) -> Self { + let mut map = HashMap::::default(); + for path in paths { + let new_entry = get_entry_from_path(&path); + match map.entry(new_entry.0) { + Entry::Vacant(e) => { + e.insert(new_entry.1); + } + Entry::Occupied(mut e) => { + e.get_mut().or(&new_entry.1); + } + } + } + Self { map } + } +} +pub struct CoverageMapEntry(u64, BitVec); +pub fn get_entry_from_path(path: &PathBuf) -> CoverageMapEntry { + let filename = path.file_name().unwrap().to_str().unwrap(); + let tag = filename + .split('-') + .nth(1) + .unwrap() + .strip_suffix(".bitvec") + .unwrap() + .parse() + .unwrap(); + let bitmap = read_bitvec_from_file(path).unwrap(); + CoverageMapEntry(tag, bitmap) +} + +pub fn dump_emu_coverage_to_file( + coverage_path: &str, + tag: u64, + bitmap: &BitVec, +) -> std::io::Result<()> { + let mut filename = format!("CovData{}", hex::encode(rand::random::<[u8; 16]>())); + filename.push_str(&'-'.to_string()); + filename.push_str(&tag.to_string()); + filename.push_str(".bitvec"); + + let path = std::path::Path::new(coverage_path).join(filename); + + let file = File::create(path)?; + let mut writer = BufWriter::new(file); + serde_json::to_writer(&mut writer, &bitmap)?; + writer.flush()?; + Ok(()) +} + +pub fn uncovered_functions<'a>(elf_bytes: &'a [u8], bitmap: &'a BitVec) -> std::io::Result<()> { + let symbols = caliptra_builder::elf_symbols(elf_bytes)?; + + let filter = symbols + .iter() + .filter(|sym| sym.ty == SymbolType::Func) + .filter(|function| { + let mut pc_range = function.value..function.value + function.size; + !pc_range.any(|pc| bitmap.get(pc as usize).unwrap_or(false)) + }); + + for f in filter { + println!( + "not covered : (NAME:{}) (start:{}) (size:{})", + f.name, f.value, f.size + ); + } + + Ok(()) +} + +pub fn get_bitvec_paths(dir: &str) -> Result, Box> { + let paths = std::fs::read_dir(dir)? + // Filter out all those directory entries which couldn't be read + .filter_map(|res| res.ok()) + // Map the directory entries to paths + .map(|dir_entry| dir_entry.path()) + // Filter out all paths with extensions other than `bitvec` + .filter_map(|path| { + if path.extension().map_or(false, |ext| ext == "bitvec") { + Some(path) + } else { + None + } + }) + .collect::>(); + Ok(paths) +} + +pub fn read_bitvec_from_file>( + path: P, +) -> Result> { + // Open the file in read-only mode with buffer. + let file = File::open(path)?; + let reader = BufReader::new(file); + + // Read the JSON contents of the file as an instance of `User`. + let coverage = serde_json::from_reader(reader)?; + + // Return the bitmap + Ok(coverage) +} + +pub fn get_tag_from_image(image: &[u8]) -> u64 { + let mut hasher = DefaultHasher::new(); + std::hash::Hash::hash_slice(image, &mut hasher); + hasher.finish() +} + +pub fn get_tag_from_fw_id(id: &FwId<'static>) -> u64 { + let rom = caliptra_builder::build_firmware_rom(id).unwrap(); + get_tag_from_image(&rom) +} + +pub fn collect_instr_pcs(id: &FwId<'static>) -> anyhow::Result> { + let elf_bytes = build_firmware_elf(id).unwrap(); + + let elf_file = ElfBytes::::minimal_parse(&elf_bytes) + .with_context(|| "Failed to parse elf file")?; + + let (load_addr, text_section) = read_section(&elf_file, ".text", true).unwrap(); + + let mut index = 0_usize; + + let mut instr_pcs = Vec::::new(); + + while index < text_section.len() { + let instruction = &text_section[index..index + 2]; + let instruction = u16::from_le_bytes([instruction[0], instruction[1]]); + + match instruction & 0b11 { + 0 | 1 | 2 => { + index += 2; + } + _ => { + index += 4; + } + } + instr_pcs.push(load_addr + index as u32); + } + Ok(instr_pcs) +} + +/// Read a section from ELF file +fn read_section<'a>( + elf_file: &'a ElfBytes, + name: &str, + required: bool, +) -> anyhow::Result<(u32, &'a [u8])> { + let load_addr: u32; + let section = elf_file + .section_header_by_name(name) + .with_context(|| format!("Failed to find {name} section"))?; + if let Some(section) = section { + let data = elf_file + .section_data(§ion) + .with_context(|| format!("Failed to read {name} section"))? + .0; + load_addr = section.sh_addr as u32; + Ok((load_addr, data)) + } else { + if required { + anyhow::bail!("{} section not found", name) + } + Ok((0, &[])) + } +} + +pub fn parse_trace_file(trace_file_path: &str) -> HashSet { + let mut unique_pcs = HashSet::new(); + + // Open the trace file + if let Ok(file) = File::open(trace_file_path) { + let reader = BufReader::new(file); + + // Iterate through each line in the trace file + for line in reader.lines() { + match line { + Ok(line) => { + // Check if the line starts with "pc=" + if line.starts_with("pc=") { + // Extract the PC by splitting the line at '=' and parsing the hexadecimal value + if let Some(pc_str) = line.strip_prefix("pc=") { + if let Ok(pc) = u32::from_str_radix(pc_str.trim_start_matches("0x"), 16) + { + unique_pcs.insert(pc); + } + } + } + } + Err(_) => println!("Trace is malformed"), + } + } + } + + unique_pcs +} + +pub mod calculator { + use bit_vec::BitVec; + + use super::*; + + pub fn coverage_from_bitmap(coverage: &BitVec, instr_pcs: &[u32]) -> i32 { + let mut hit = 0; + for pc in instr_pcs { + if coverage[*pc as usize] { + hit += 1; + } + } + hit + } + + pub fn coverage_from_instr_trace(trace_path: &str, instr_pcs: &[u32]) -> i32 { + // Count the nunmer of instructions executed + let unique_executed_pcs = parse_trace_file(trace_path); + let mut hit = 0; + for pc in unique_executed_pcs.iter() { + if instr_pcs.contains(pc) { + hit += 1; + } + } + hit + } +} + +#[test] +fn test_parse_trace_file() { + // Create a temporary trace file for testing + let temp_trace_file = "temp_trace.txt"; + let trace_data = vec![ + "SoC write4 *0x300300bc <- 0x0", + "SoC write4 *0x30030110 <- 0x2625a00", + "SoC write4 *0x30030114 <- 0x0", + "SoC write4 *0x300300b8 <- 0x1", + "pc=0x0", + "pc=0x4", + "pc=0x4", + "pc=0x4", + "pc=0x0", + ]; + + // Write the test data to the temporary trace file + std::fs::write(temp_trace_file, trace_data.join("\n")) + .expect("Failed to write test trace file"); + + // Call the function to parse the test trace file + let unique_pcs = parse_trace_file(temp_trace_file); + + // Define the expected unique PCs based on the test data + let expected_pcs: HashSet = vec![0x0, 0x4].into_iter().collect(); + + // Assert that the result matches the expected unique PCs + assert_eq!(unique_pcs, expected_pcs); + + // Clean up: remove the temporary trace file + std::fs::remove_file(temp_trace_file).expect("Failed to remove test trace file"); +} + +#[test] +fn test_coverage_map_creation_no_data_files_found() { + let tag = 123_u64; + + let paths = Vec::new(); + + let cv = CoverageMap::new(paths); + assert_eq!(None, cv.map.get(&tag)); +} + +#[test] +fn test_coverage_map_creation_data_files() { + let tag = 123_u64; + + let bitmap = BitVec::from_elem(1024, false); + assert!(dump_emu_coverage_to_file("/tmp", tag, &bitmap).is_ok()); + + let paths = get_bitvec_paths("/tmp").unwrap(); + + let cv = CoverageMap::new(paths); + assert!(cv.map.get(&tag).is_some()); +} diff --git a/coverage/src/main.rs b/coverage/src/main.rs new file mode 100644 index 0000000000..36d9fd48ad --- /dev/null +++ b/coverage/src/main.rs @@ -0,0 +1,47 @@ +// Licensed under the Apache-2.0 license + +use caliptra_builder::build_firmware_elf; +use caliptra_coverage::calculator; +use caliptra_coverage::collect_instr_pcs; +use caliptra_coverage::get_bitvec_paths; +use caliptra_coverage::CoverageMap; +use caliptra_coverage::CPTRA_COVERAGE_PATH; + +use caliptra_builder::firmware::ROM_WITH_UART; +use caliptra_coverage::get_tag_from_fw_id; +use caliptra_coverage::uncovered_functions; + +fn main() -> std::io::Result<()> { + let cov_path = std::env::var(CPTRA_COVERAGE_PATH).unwrap_or_else(|_| "".into()); + if cov_path.is_empty() { + return Ok(()); + } + + let paths = get_bitvec_paths(cov_path.as_str()).unwrap(); + if paths.is_empty() { + println!("{} coverage files found", paths.len()); + return Ok(()); + } + + let tag = get_tag_from_fw_id(&ROM_WITH_UART); + + println!("{} coverage files found", paths.len()); + let instr_pcs = collect_instr_pcs(&ROM_WITH_UART).unwrap(); + println!("ROM instruction count = {}", instr_pcs.len()); + + let cv = CoverageMap::new(paths); + let bv = cv + .map + .get(&tag) + .expect("Coverage data not found for image"); + + let elf_bytes = build_firmware_elf(&ROM_WITH_UART)?; + + uncovered_functions(&elf_bytes, bv)?; + + println!( + "Coverage for ROM_WITH_UART is {}%", + (100 * calculator::coverage_from_bitmap(bv, &instr_pcs)) as f32 / instr_pcs.len() as f32 + ); + Ok(()) +} diff --git a/drivers/tests/drivers_integration_tests/main.rs b/drivers/tests/drivers_integration_tests/main.rs index bff35a7a0f..8240d9602f 100644 --- a/drivers/tests/drivers_integration_tests/main.rs +++ b/drivers/tests/drivers_integration_tests/main.rs @@ -618,7 +618,7 @@ fn test_mailbox_soc_to_uc() { model .step_until_output_and_take("cmd: 0xd0000000\n") .unwrap(); - assert_eq!(resp, []); + assert_eq!(resp, [] as [u8; 0]); } // Ensure there isn't any unexpected output for _i in 0..100000 { diff --git a/hw-model/Cargo.toml b/hw-model/Cargo.toml index 8b57295f60..2da6acc07e 100644 --- a/hw-model/Cargo.toml +++ b/hw-model/Cargo.toml @@ -30,6 +30,7 @@ ureg.workspace = true zerocopy.workspace = true nix.workspace = true libc.workspace = true +caliptra-coverage.workspace = true [dev-dependencies] caliptra-builder.workspace = true diff --git a/hw-model/c-binding/examples/Makefile b/hw-model/c-binding/examples/Makefile index 477e5d97cd..51e3d9d3c2 100644 --- a/hw-model/c-binding/examples/Makefile +++ b/hw-model/c-binding/examples/Makefile @@ -37,7 +37,7 @@ $(OUT)/%.o: $(SOURCE) $(CC) ${CFLAGS} -g -c $< -o $@ $(TARGET): $(OUT)/caliptra_model.h $(OBJS) - $(CC) -o $(TARGET) $(OBJS) $(CFLAGS) -Wl,-L$(OUT)/debug -lcaliptra_hw_model_c_binding -lpthread -lstdc++ -ldl -lm + $(CC) -o $(TARGET) $(OBJS) $(CFLAGS) -Wl,-L$(OUT)/debug -lcaliptra_hw_model_c_binding -lpthread -lstdc++ -ldl -lrt -lm clean: $(RM) -rf $(OUT) diff --git a/hw-model/src/model_emulated.rs b/hw-model/src/model_emulated.rs index 2d56be0f8b..29f9120310 100644 --- a/hw-model/src/model_emulated.rs +++ b/hw-model/src/model_emulated.rs @@ -55,6 +55,21 @@ pub struct ModelEmulated { ready_for_fw: Rc>, cpu_enabled: Rc>, trace_path: Option, + + image_tag: u64, +} +impl Drop for ModelEmulated { + fn drop(&mut self) { + let cov_path = + std::env::var(caliptra_coverage::CPTRA_COVERAGE_PATH).unwrap_or_else(|_| "".into()); + if cov_path.is_empty() { + return; + } + + let bitmap = self.code_coverage_bitmap(); + let _ = + caliptra_coverage::dump_emu_coverage_to_file(cov_path.as_str(), self.image_tag, bitmap); + } } impl ModelEmulated { @@ -70,6 +85,9 @@ impl crate::HwModel for ModelEmulated { where Self: Sized, { + use std::collections::hash_map::DefaultHasher; + use std::hash::Hasher; + let clock = Clock::new(); let timer = clock.timer(); @@ -125,6 +143,10 @@ impl crate::HwModel for ModelEmulated { let soc_to_caliptra_bus = root_bus.soc_to_caliptra_bus(); let cpu = Cpu::new(BusLogger::new(root_bus), clock); + let mut hasher = DefaultHasher::new(); + std::hash::Hash::hash_slice(params.rom, &mut hasher); + let image_tag = hasher.finish(); + let mut m = ModelEmulated { output, cpu, @@ -133,6 +155,7 @@ impl crate::HwModel for ModelEmulated { ready_for_fw, cpu_enabled, trace_path: trace_path_or_env(params.trace_path), + image_tag, }; // Turn tracing on if the trace path was set m.tracing_hint(true); @@ -155,7 +178,7 @@ impl crate::HwModel for ModelEmulated { fn output(&mut self) -> &mut Output { // In case the caller wants to log something, make sure the log has the - // correct time. + // correct time.env:: self.output.sink().set_now(self.cpu.clock.now()); &mut self.output } diff --git a/libcaliptra/examples/hwmodel/Makefile b/libcaliptra/examples/hwmodel/Makefile index efff47f6c8..5644c43321 100644 --- a/libcaliptra/examples/hwmodel/Makefile +++ b/libcaliptra/examples/hwmodel/Makefile @@ -29,7 +29,7 @@ HWMODEL_DIR = $(OUTPUT_DIR) HWMODEL_HEADER_DIR = ../../../hw-model/c-binding/out HWMODEL_INCLUDE = -I$(HWMODEL_HEADER_DIR) HWMODEL_LIB = -Wl,-L$(HWMODEL_DIR) -lcaliptra_hw_model_c_binding -HWMODEL_FLAGS = -lpthread -lstdc++ -ldl -lm +HWMODEL_FLAGS = -lpthread -lstdc++ -ldl -lrt -lm HWMODEL_HEADER = $(HWMODEL_HEADER_DIR)/caliptra_model.h HWMODEL_BINDING_LIB_OBJ = $(HWMODEL_DIR)/libcaliptra_hw_model_c_binding.a diff --git a/rom/dev/tests/rom_integration_tests/test_fake_rom.rs b/rom/dev/tests/rom_integration_tests/test_fake_rom.rs index d650e23328..5c0a2037b7 100644 --- a/rom/dev/tests/rom_integration_tests/test_fake_rom.rs +++ b/rom/dev/tests/rom_integration_tests/test_fake_rom.rs @@ -67,7 +67,7 @@ fn test_fake_rom_production_error() { // Make sure we see the right fatal error assert_eq!( hw.soc_ifc().cptra_fw_error_fatal().read(), - CaliptraError::ROM_GLOBAL_FAKE_ROM_IN_PRODUCTION.into() + u32::from(CaliptraError::ROM_GLOBAL_FAKE_ROM_IN_PRODUCTION) ); } @@ -202,6 +202,6 @@ fn test_image_verify() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } diff --git a/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs b/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs index 3920d66bfa..bf9b0064cd 100644 --- a/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs +++ b/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs @@ -38,15 +38,15 @@ fn test_zero_firmware_size() { // Zero-sized firmware. assert_eq!( hw.upload_firmware(&[]).unwrap_err(), - ModelError::MailboxCmdFailed(CaliptraError::FW_PROC_INVALID_IMAGE_SIZE.into()) + ModelError::MailboxCmdFailed(u32::from(CaliptraError::FW_PROC_INVALID_IMAGE_SIZE)) ); assert_eq!( hw.soc_ifc().cptra_fw_error_fatal().read(), - CaliptraError::FW_PROC_INVALID_IMAGE_SIZE.into() + u32::from(CaliptraError::FW_PROC_INVALID_IMAGE_SIZE) ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - LDevIdDerivationComplete.into() + u32::from(LDevIdDerivationComplete) ); } @@ -75,11 +75,11 @@ fn test_firmware_gt_max_size() { assert_eq!( hw.soc_ifc().cptra_fw_error_fatal().read(), - CaliptraError::FW_PROC_INVALID_IMAGE_SIZE.into() + u32::from(CaliptraError::FW_PROC_INVALID_IMAGE_SIZE) ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - LDevIdDerivationComplete.into() + u32::from(LDevIdDerivationComplete) ); } @@ -171,7 +171,7 @@ fn test_pcr_log() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let pcr_entry_arr = hw.mailbox_execute(0x1000_0000, &[]).unwrap().unwrap(); @@ -271,7 +271,7 @@ fn test_pcr_log_no_owner_key_digest_fuse() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let pcr_entry_arr = hw.mailbox_execute(0x1000_0000, &[]).unwrap().unwrap(); @@ -362,7 +362,7 @@ fn test_pcr_log_fmc_fuse_svn() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let pcr_entry_arr = hw.mailbox_execute(0x1000_0000, &[]).unwrap().unwrap(); @@ -501,7 +501,7 @@ fn test_pcr_log_across_update_reset() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let pcr_entry_arr = hw.mailbox_execute(0x1000_0000, &[]).unwrap().unwrap(); @@ -603,7 +603,7 @@ fn test_fuse_log() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let fuse_entry_arr = hw.mailbox_execute(0x1000_0002, &[]).unwrap().unwrap(); @@ -727,7 +727,7 @@ fn test_fht_info() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let data = hw.mailbox_execute(0x1000_0003, &[]).unwrap().unwrap(); let fht = FirmwareHandoffTable::read_from_prefix(data.as_bytes()).unwrap(); @@ -768,7 +768,7 @@ fn test_check_no_lms_info_in_datavault_on_lms_unavailable() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let coldresetentry4_array = hw.mailbox_execute(0x1000_0005, &[]).unwrap().unwrap(); let mut coldresetentry4_offset = core::mem::size_of::() * 8; // Skip first 4 entries @@ -814,7 +814,7 @@ fn test_check_rom_cold_boot_status_reg() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); let coldresetentry4_array = hw.mailbox_execute(0x1000_0005, &[]).unwrap().unwrap(); let mut coldresetentry4_offset = core::mem::size_of::() * 2; // Skip first entry @@ -829,7 +829,7 @@ fn test_check_rom_cold_boot_status_reg() { coldresetentry4_offset += core::mem::size_of::(); let coldresetentry4_value = u32::read_from_prefix(coldresetentry4_array[coldresetentry4_offset..].as_bytes()).unwrap(); - assert_eq!(coldresetentry4_value, ColdResetComplete.into()); + assert_eq!(coldresetentry4_value, u32::from(ColdResetComplete)); } #[test] @@ -878,7 +878,7 @@ fn test_upload_single_measurement() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); // Check if the measurement was present in the measurement log. let measurement_log = hw.mailbox_execute(0x1000_000A, &[]).unwrap().unwrap(); @@ -958,7 +958,7 @@ fn test_upload_measurement_limit() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); // Check the measurement log. let measurement_log = hw.mailbox_execute(0x1000_000A, &[]).unwrap().unwrap(); @@ -1010,7 +1010,7 @@ fn test_upload_no_measurement() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); // Check whether the fake measurement was extended to PCR31. let pcr31 = hw.mailbox_execute(0x1000_0009, &[]).unwrap().unwrap(); diff --git a/rom/dev/tests/rom_integration_tests/test_image_validation.rs b/rom/dev/tests/rom_integration_tests/test_image_validation.rs index f2f5590a28..2a3e9a4763 100644 --- a/rom/dev/tests/rom_integration_tests/test_image_validation.rs +++ b/rom/dev/tests/rom_integration_tests/test_image_validation.rs @@ -76,7 +76,7 @@ fn test_invalid_manifest_marker() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -96,7 +96,7 @@ fn test_invalid_manifest_size() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -120,7 +120,7 @@ fn test_preamble_zero_vendor_pubkey_digest() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -144,7 +144,7 @@ fn test_preamble_vendor_pubkey_digest_mismatch() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -159,16 +159,16 @@ fn test_preamble_owner_pubkey_digest_mismatch() { helpers::build_hw_model_and_image_bundle(fuses, ImageOptions::default()); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_OWNER_PUB_KEY_DIGEST_MISMATCH.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_PUB_KEY_DIGEST_MISMATCH + )), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -214,7 +214,7 @@ fn test_preamble_vendor_ecc_pubkey_revocation() { // Last key is never revoked. hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); } else { assert_eq!( ModelError::MailboxCmdFailed( @@ -226,7 +226,7 @@ fn test_preamble_vendor_ecc_pubkey_revocation() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } } @@ -275,7 +275,7 @@ fn test_preamble_vendor_lms_pubkey_revocation() { // Last key is never revoked. hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); } else { assert_eq!( ModelError::MailboxCmdFailed( @@ -328,7 +328,7 @@ fn test_preamble_vendor_lms_optional_no_pubkey_revocation_check() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); } } @@ -348,7 +348,7 @@ fn test_preamble_vendor_ecc_pubkey_out_of_bounds() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -383,7 +383,7 @@ fn test_preamble_vendor_lms_optional_no_pubkey_out_of_bounds_check() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); } #[test] @@ -409,7 +409,7 @@ fn test_header_verify_vendor_sig_zero_ecc_pubkey() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); drop(hw); @@ -433,7 +433,7 @@ fn test_header_verify_vendor_sig_zero_ecc_pubkey() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -456,7 +456,7 @@ fn test_header_verify_vendor_sig_zero_ecc_signature() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); drop(hw); @@ -477,7 +477,7 @@ fn test_header_verify_vendor_sig_zero_ecc_signature() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -508,7 +508,7 @@ fn test_header_verify_vendor_ecc_sig_mismatch() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); drop(hw); @@ -543,7 +543,7 @@ fn test_header_verify_vendor_ecc_sig_mismatch() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -594,7 +594,7 @@ fn test_header_verify_vendor_lms_sig_mismatch() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -616,7 +616,7 @@ fn test_header_verify_vendor_lms_optional_no_sig_mismatch_check() { [Default::default(); 6]; hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); drop(hw); let fuses = caliptra_hw_model::Fuses { @@ -633,7 +633,7 @@ fn test_header_verify_vendor_lms_optional_no_sig_mismatch_check() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); } #[test] @@ -703,7 +703,7 @@ fn test_header_verify_owner_lms_optional_no_sig_mismatch_check() { .digest = [Default::default(); 6]; hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); drop(hw); let fuses = caliptra_hw_model::Fuses { @@ -719,7 +719,7 @@ fn test_header_verify_owner_lms_optional_no_sig_mismatch_check() { hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); } #[test] @@ -742,7 +742,7 @@ fn test_header_verify_vendor_ecc_pub_key_in_preamble_and_header() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -785,7 +785,7 @@ fn test_header_verify_vendor_lms_optional_no_pub_key_in_preamble_and_header_chec hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap(); - hw.step_until_boot_status(ColdResetComplete.into(), true); + hw.step_until_boot_status(u32::from(ColdResetComplete), true); } #[test] @@ -866,7 +866,7 @@ fn test_header_verify_owner_ecc_sig_zero_pubkey_x() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -919,7 +919,7 @@ fn test_header_verify_owner_ecc_sig_zero_pubkey_y() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -966,7 +966,7 @@ fn test_header_verify_owner_ecc_sig_zero_signature_r() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1013,7 +1013,7 @@ fn test_header_verify_owner_ecc_sig_zero_signature_s() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1060,7 +1060,7 @@ fn test_header_verify_owner_ecc_sig_invalid_signature_r() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1107,7 +1107,7 @@ fn test_header_verify_owner_ecc_sig_invalid_signature_s() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1130,7 +1130,7 @@ fn test_toc_invalid_entry_count() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1151,7 +1151,7 @@ fn test_toc_invalid_toc_digest() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1247,7 +1247,7 @@ fn test_toc_fmc_range_overlap() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1276,7 +1276,7 @@ fn test_toc_fmc_range_incorrect_order() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1298,7 +1298,7 @@ fn test_fmc_rt_load_address_range_overlap() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); drop(hw); @@ -1318,7 +1318,7 @@ fn test_fmc_rt_load_address_range_overlap() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1338,7 +1338,7 @@ fn test_fmc_digest_mismatch() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1357,7 +1357,7 @@ fn test_fmc_invalid_load_addr_before_iccm() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1376,7 +1376,7 @@ fn test_fmc_invalid_load_addr_after_iccm() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1409,7 +1409,7 @@ fn test_fmc_load_addr_unaligned() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1428,7 +1428,7 @@ fn test_fmc_invalid_entry_point_before_iccm() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1447,7 +1447,7 @@ fn test_fmc_invalid_entry_point_after_iccm() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1467,7 +1467,7 @@ fn test_fmc_entry_point_unaligned() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1502,7 +1502,7 @@ fn test_fmc_svn_greater_than_32() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1528,16 +1528,16 @@ fn test_fmc_svn_less_than_min_svn() { }; let (mut hw, image_bundle) = helpers::build_hw_model_and_image_bundle(fuses, image_options); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_MIN_SUPPORTED.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_MIN_SUPPORTED + )), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1564,16 +1564,16 @@ fn test_fmc_svn_less_than_fuse_svn() { let (mut hw, image_bundle) = helpers::build_hw_model_and_image_bundle(fuses, image_options); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE + )), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1597,7 +1597,9 @@ fn test_toc_rt_size_zero() { runtime_new_size, ); assert_eq!( - ModelError::MailboxCmdFailed(CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SIZE_ZERO.into()), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SIZE_ZERO + )), hw.upload_firmware(&image).unwrap_err() ); } @@ -1610,16 +1612,16 @@ fn test_runtime_digest_mismatch() { // Change the FMC image. image_bundle.runtime[0..4].copy_from_slice(0xDEADBEEFu32.as_bytes()); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_DIGEST_MISMATCH.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_DIGEST_MISMATCH + )), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1632,15 +1634,15 @@ fn test_runtime_invalid_load_addr_before_iccm() { - (image_bundle.manifest.fmc.load_addr - ICCM_ORG + image_bundle.manifest.runtime.size); let image = update_load_addr(&mut image_bundle, false, rt_new_load_addr); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID + )), hw.upload_firmware(&image).unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1651,15 +1653,15 @@ fn test_runtime_invalid_load_addr_after_iccm() { let image = update_load_addr(&mut image_bundle, false, ICCM_END_ADDR + 1); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID + )), hw.upload_firmware(&image).unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1670,9 +1672,9 @@ fn test_runtime_not_contained_in_iccm() { let image = update_load_addr(&mut image_bundle, false, ICCM_END_ADDR - 3); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID + )), hw.upload_firmware(&image).unwrap_err() ); } @@ -1684,15 +1686,15 @@ fn test_runtime_load_addr_unaligned() { let load_addr = image_bundle.manifest.runtime.load_addr; let image = update_load_addr(&mut image_bundle, false, load_addr + 1); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_UNALIGNED.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_UNALIGNED + )), hw.upload_firmware(&image).unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1703,15 +1705,15 @@ fn test_runtime_invalid_entry_point_before_iccm() { let image = update_entry_point(&mut image_bundle, false, ICCM_ORG - 4); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID + )), hw.upload_firmware(&image).unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1722,15 +1724,15 @@ fn test_runtime_invalid_entry_point_after_iccm() { let image = update_entry_point(&mut image_bundle, false, ICCM_END_ADDR + 1); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID + )), hw.upload_firmware(&image).unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1741,15 +1743,15 @@ fn test_runtime_entry_point_unaligned() { let entry_point = image_bundle.manifest.runtime.entry_point; let image = update_entry_point(&mut image_bundle, false, entry_point + 1); assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_UNALIGNED.into() - ), + ModelError::MailboxCmdFailed(u32::from( + CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_UNALIGNED + )), hw.upload_firmware(&image).unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1783,7 +1785,7 @@ fn test_runtime_svn_greater_than_max() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1819,7 +1821,7 @@ fn test_runtime_svn_less_than_min_svn() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } @@ -1854,12 +1856,12 @@ fn test_runtime_svn_less_than_fuse_svn() { ); assert_eq!( hw.soc_ifc().cptra_fw_error_fatal().read(), - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE.into() + u32::from(CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE) ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - FwProcessorManifestLoadComplete.into() + u32::from(FwProcessorManifestLoadComplete) ); } diff --git a/rom/dev/tests/rom_integration_tests/test_update_reset.rs b/rom/dev/tests/rom_integration_tests/test_update_reset.rs index beea99c570..86e3fa6bb7 100644 --- a/rom/dev/tests/rom_integration_tests/test_update_reset.rs +++ b/rom/dev/tests/rom_integration_tests/test_update_reset.rs @@ -98,7 +98,7 @@ fn test_update_reset_no_mailbox_cmd() { hw.step_until(|m| m.soc_ifc().cptra_fw_error_non_fatal().read() != 0); assert_eq!( hw.soc_ifc().cptra_fw_error_non_fatal().read(), - CaliptraError::ROM_UPDATE_RESET_FLOW_MAILBOX_ACCESS_FAILURE.into() + u32::from(CaliptraError::ROM_UPDATE_RESET_FLOW_MAILBOX_ACCESS_FAILURE) ); let _ = hw.mailbox_execute(0xDEADBEEF, &[]); @@ -106,7 +106,7 @@ fn test_update_reset_no_mailbox_cmd() { assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - UpdateResetStarted.into() + u32::from(UpdateResetStarted) ); } @@ -144,12 +144,12 @@ fn test_update_reset_non_fw_load_cmd() { assert_eq!( hw.soc_ifc().cptra_fw_error_non_fatal().read(), - CaliptraError::ROM_UPDATE_RESET_FLOW_INVALID_FIRMWARE_COMMAND.into() + u32::from(CaliptraError::ROM_UPDATE_RESET_FLOW_INVALID_FIRMWARE_COMMAND) ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - UpdateResetStarted.into() + u32::from(UpdateResetStarted) ); } @@ -193,12 +193,12 @@ fn test_update_reset_verify_image_failure() { assert_eq!( hw.soc_ifc().cptra_fw_error_non_fatal().read(), - CaliptraError::IMAGE_VERIFIER_ERR_MANIFEST_MARKER_MISMATCH.into() + u32::from(CaliptraError::IMAGE_VERIFIER_ERR_MANIFEST_MARKER_MISMATCH) ); assert_eq!( hw.soc_ifc().cptra_boot_status().read(), - UpdateResetLoadManifestComplete.into() + u32::from(UpdateResetLoadManifestComplete) ); } @@ -320,7 +320,7 @@ fn test_update_reset_vendor_ecc_pub_key_idx_dv_mismatch() { assert_eq!( hw.soc_ifc().cptra_fw_error_non_fatal().read(), - CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_ECC_PUB_KEY_IDX_MISMATCH.into() + u32::from(CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_ECC_PUB_KEY_IDX_MISMATCH) ); } @@ -388,7 +388,7 @@ fn test_update_reset_vendor_lms_pub_key_idx_dv_mismatch() { assert_eq!( hw.soc_ifc().cptra_fw_error_non_fatal().read(), - CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH.into() + u32::from(CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH) ); } @@ -444,5 +444,5 @@ fn test_check_rom_update_reset_status_reg() { warmresetentry4_offset += core::mem::size_of::(); let warmresetentry4_value = u32::read_from_prefix(warmresetentry4_array[warmresetentry4_offset..].as_bytes()).unwrap(); - assert_eq!(warmresetentry4_value, UpdateResetComplete.into()); + assert_eq!(warmresetentry4_value, u32::from(UpdateResetComplete)); } diff --git a/test/Cargo.toml b/test/Cargo.toml index 4f66afdae4..304684e48b 100644 --- a/test/Cargo.toml +++ b/test/Cargo.toml @@ -12,6 +12,7 @@ anyhow.workspace = true asn1.workspace = true caliptra-builder.workspace = true caliptra_common = { workspace = true, default-features = false } +caliptra-coverage.workspace = true caliptra-hw-model-types.workspace = true caliptra-runtime = { workspace = true, default-features = false } elf.workspace = true diff --git a/test/dpe_verification/transport.go b/test/dpe_verification/transport.go index cb149a272a..64b997219b 100644 --- a/test/dpe_verification/transport.go +++ b/test/dpe_verification/transport.go @@ -4,7 +4,7 @@ package dpe /* #cgo CFLAGS: -I../../libcaliptra/inc -I../../hw-model/c-binding/out -g -#cgo LDFLAGS: -L../../target/debug -L../../libcaliptra -lcaliptra -lcaliptra_hw_model_c_binding -ldl +#cgo LDFLAGS: -L../../target/debug -L../../libcaliptra -lcaliptra -lcaliptra_hw_model_c_binding -ldl -lrt #define HWMODEL #include #include diff --git a/test/src/coverage.rs b/test/src/coverage.rs deleted file mode 100644 index d5e4f52e98..0000000000 --- a/test/src/coverage.rs +++ /dev/null @@ -1,155 +0,0 @@ -// Licensed under the Apache-2.0 license - -use anyhow::Context; -use caliptra_builder::{build_firmware_elf, FwId}; -use elf::endian::AnyEndian; -use elf::ElfBytes; -use std::collections::HashSet; -use std::fs::File; -use std::io::{BufRead, BufReader}; - -pub fn collect_instr_pcs(id: &FwId<'static>) -> anyhow::Result> { - let elf_bytes = build_firmware_elf(id).unwrap(); - - let elf_file = ElfBytes::::minimal_parse(&elf_bytes) - .with_context(|| "Failed to parse elf file")?; - - let (load_addr, text_section) = read_section(&elf_file, ".text", true).unwrap(); - - let mut index = 0_usize; - - let mut instr_pcs = Vec::::new(); - - while index < text_section.len() { - let instruction = &text_section[index..index + 2]; - let instruction = u16::from_le_bytes([instruction[0], instruction[1]]); - - match instruction & 0b11 { - 0 | 1 | 2 => { - index += 2; - } - _ => { - index += 4; - } - } - instr_pcs.push(load_addr + index as u32); - } - Ok(instr_pcs) -} - -/// Read a section from ELF file -fn read_section<'a>( - elf_file: &'a ElfBytes, - name: &str, - required: bool, -) -> anyhow::Result<(u32, &'a [u8])> { - let load_addr: u32; - let section = elf_file - .section_header_by_name(name) - .with_context(|| format!("Failed to find {name} section"))?; - if let Some(section) = section { - let data = elf_file - .section_data(§ion) - .with_context(|| format!("Failed to read {name} section"))? - .0; - load_addr = section.sh_addr as u32; - Ok((load_addr, data)) - } else { - if required { - anyhow::bail!("{} section not found", name) - } - Ok((0, &[])) - } -} - -pub fn parse_trace_file(trace_file_path: &str) -> HashSet { - let mut unique_pcs = HashSet::new(); - - // Open the trace file - if let Ok(file) = File::open(trace_file_path) { - let reader = BufReader::new(file); - - // Iterate through each line in the trace file - for line in reader.lines() { - match line { - Ok(line) => { - // Check if the line starts with "pc=" - if line.starts_with("pc=") { - // Extract the PC by splitting the line at '=' and parsing the hexadecimal value - if let Some(pc_str) = line.strip_prefix("pc=") { - if let Ok(pc) = u32::from_str_radix(pc_str.trim_start_matches("0x"), 16) - { - unique_pcs.insert(pc); - } - } - } - } - Err(_) => println!("Trace is malformed"), - } - } - } - - unique_pcs -} - -#[cfg(all(not(feature = "verilator"), not(feature = "fpga_realtime")))] -pub mod calculator { - use super::*; - - pub fn coverage_from_bitmap(hw: &caliptra_hw_model::ModelEmulated, instr_pcs: &[u32]) -> i32 { - let coverage = hw.code_coverage_bitmap(); - - let mut hit = 0; - for pc in instr_pcs { - if coverage[*pc as usize] { - hit += 1; - } - } - hit - } - - pub fn coverage_from_instr_trace(trace_path: &str, instr_pcs: &[u32]) -> i32 { - // Count the nunmer of instructions executed - let unique_executed_pcs = parse_trace_file(trace_path); - let mut hit = 0; - for pc in unique_executed_pcs.iter() { - if instr_pcs.contains(pc) { - hit += 1; - } - } - hit - } -} - -#[test] -fn test_parse_trace_file() { - // Create a temporary trace file for testing - let temp_trace_file = "temp_trace.txt"; - let trace_data = vec![ - "SoC write4 *0x300300bc <- 0x0", - "SoC write4 *0x30030110 <- 0x2625a00", - "SoC write4 *0x30030114 <- 0x0", - "SoC write4 *0x300300b8 <- 0x1", - "pc=0x0", - "pc=0x4", - "pc=0x4", - "pc=0x4", - "pc=0x0", - ]; - - // Write the test data to the temporary trace file - std::fs::write(temp_trace_file, trace_data.join("\n")) - .expect("Failed to write test trace file"); - - // Call the function to parse the test trace file - let unique_pcs = parse_trace_file(temp_trace_file); - - // Define the expected unique PCs based on the test data - let expected_pcs: HashSet = vec![0x0, 0x4].into_iter().collect(); - - // Assert that the result matches the expected unique PCs - assert_eq!(unique_pcs, expected_pcs); - - // Clean up: remove the temporary trace file - std::fs::remove_file(temp_trace_file).expect("Failed to remove test trace file"); -} diff --git a/test/src/lib.rs b/test/src/lib.rs index f6d65c7a92..db0dd57d9d 100644 --- a/test/src/lib.rs +++ b/test/src/lib.rs @@ -6,7 +6,6 @@ use caliptra_builder::{ }; use caliptra_hw_model::{BootParams, DefaultHwModel, HwModel, InitParams}; -pub mod coverage; pub mod crypto; pub mod derive; pub mod x509; diff --git a/test/tests/caliptra_integration_tests/test_code_coverage.rs b/test/tests/caliptra_integration_tests/test_code_coverage.rs index 6e1f9c9e43..796e65933d 100644 --- a/test/tests/caliptra_integration_tests/test_code_coverage.rs +++ b/test/tests/caliptra_integration_tests/test_code_coverage.rs @@ -6,9 +6,9 @@ fn test_emu_coverage() { use std::path::PathBuf; use caliptra_builder::firmware::ROM_WITH_UART; + use caliptra_coverage::{calculator, collect_instr_pcs}; use caliptra_hw_model::HwModel; use caliptra_hw_model::{BootParams, InitParams}; - use caliptra_test::coverage::{calculator, collect_instr_pcs}; const TRACE_PATH: &str = "/tmp/caliptra_coverage_trace.txt"; @@ -27,7 +27,7 @@ fn test_emu_coverage() { .unwrap(); // Upload FW hw.step_until(|m| m.soc_ifc().cptra_flow_status().read().ready_for_fw()); - calculator::coverage_from_bitmap(&hw, &instr_pcs) + calculator::coverage_from_bitmap(hw.code_coverage_bitmap(), &instr_pcs) }; println!(