[test] Add rom_e2e_bootstrap_phase1_read
Fixes #14462
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/rom/data/rom_testplan.hjson b/sw/device/silicon_creator/rom/data/rom_testplan.hjson
index 501401f..6ce1cec 100644
--- a/sw/device/silicon_creator/rom/data/rom_testplan.hjson
+++ b/sw/device/silicon_creator/rom/data/rom_testplan.hjson
@@ -361,15 +361,18 @@
- Apply bootstrap pin strapping and reset the chip.
- Send `CHIP_ERASE` (`0xc7`).
- - Write `0x4552544f` (ASCII "OTRE") at byte offset `0x334`.
+ - Write `0x4552544f_00000000` (ASCII "\0\0\0\0OTRE") at byte offset `0x80330`.
+ - Note: Writes must start at a flash-word-aligned address and we
+ must write to the second slot since ROM returns the last error.
- Reset the chip.
- - Verify that the chip outputs the expected `BFV`: `024d410d` over UART.
+ - Verify that the chip outputs the expected `BFV`: `0242500d` over
+ UART (`kErrorBootPolicyBadLength`).
- ROM will continously reset the chip and output the same `BFV` and `LCV`.
- Apply bootstrap pin strapping and reset the chip.
- - Send `READ` (`0x03`) followed by the 3-byte address 0x000334.
- - This is the address of the identifier that was written earlier.
- - Verify that the chip does not respond for the next 4 bytes.
- - The data on the CIPO line must be `0xff`.
+ - Verify that the chip responds to `READ_STATUS` (`0x05`) with `0x00`.
+ - Send `READ` (`0x03`) followed by the 3-byte address 0x80330.
+ - This is the start address of the write operation performed above.
+ - Verify that the data on the CIPO line does not match `0x4552544f_00000000`.
'''
tags: ["rom", "verilator", "dv", "fpga", "silicon"]
stage: V2
diff --git a/sw/host/tests/rom/e2e_bootstrap_entry/src/main.rs b/sw/host/tests/rom/e2e_bootstrap_entry/src/main.rs
index 3f70b58..1be8ba1 100644
--- a/sw/host/tests/rom/e2e_bootstrap_entry/src/main.rs
+++ b/sw/host/tests/rom/e2e_bootstrap_entry/src/main.rs
@@ -393,6 +393,42 @@
Ok(())
}
+fn test_bootstrap_phase1_read(opts: &Opts, transport: &TransportWrapper) -> Result<()> {
+ let _bs = BootstrapTest::start(transport, opts.init.bootstrap.options.reset_delay)?;
+ let spi = transport.spi("0")?;
+ let uart = transport.uart("0")?;
+ let mut console = UartConsole {
+ timeout: Some(Duration::new(1, 0)),
+ ..Default::default()
+ };
+
+ SpiFlash::from_spi(&*spi)?
+ // Send CHIP_ERASE to transition to phase 2.
+ .chip_erase(&*spi)?
+ // Write "OTRE" to the identifier field of the manifest in the second slot.
+ .program(&*spi, 0x80330, &0x4552544f_00000000u64.to_le_bytes())?;
+
+ // Remove strapping so that chip fails to boot instead of going into bootstrap.
+ transport.remove_pin_strapping("ROM_BOOTSTRAP")?;
+ transport.reset_target(opts.init.bootstrap.options.reset_delay, true)?;
+ // `kErrorBootPolicyBadLength` (0242500d) is defined in `error.h`.
+ console.exit_success = Some(Regex::new("0242500d")?);
+ let result = console.interact(&*uart, None, Some(&mut std::io::stdout()))?;
+ if result != ExitStatus::ExitSuccess {
+ bail!("FAIL: {:?}", result);
+ }
+
+ transport.apply_pin_strapping("ROM_BOOTSTRAP")?;
+ transport.reset_target(opts.init.bootstrap.options.reset_delay, true)?;
+ assert_eq!(SpiFlash::read_status(&*spi)?, 0x00);
+ let mut buf: [u8; 8] = [0xa5; 8];
+ SpiFlash::from_spi(&*spi)?.read(&*spi, 0x80330, &mut buf)?;
+ log::info!("Received: {:?}", &buf);
+ assert_ne!(u64::from_le_bytes(buf), 0x4552544f_00000000u64);
+
+ Ok(())
+}
+
fn main() -> Result<()> {
let opts = Opts::from_args();
opts.init.init_logging();
@@ -416,6 +452,7 @@
for erase_cmd in [SpiFlash::SECTOR_ERASE, SpiFlash::CHIP_ERASE] {
execute_test!(test_bootstrap_phase1_erase, &opts, &transport, erase_cmd);
}
+ execute_test!(test_bootstrap_phase1_read, &opts, &transport);
Ok(())
}