Skip to content

Commit

Permalink
feat: sw-emulator: add active mode
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Heymans <[email protected]>
  • Loading branch information
ArthurHeymans committed Jan 22, 2025
1 parent 016703a commit 95d1122
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
13 changes: 13 additions & 0 deletions rom/dev/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ run: build-emu build-fw-image build-rom
--recovery-image-fw $(TARGET_DIR)/caliptra-rom-test-fw \
--device-lifecycle unprovisioned \

run-active: build-emu build-fw-image build-rom
cargo \
"--config=$(EXTRA_CARGO_CONFIG)" \
run \
-p caliptra-emu \
-- \
--req-idevid-csr \
--idevid-key-id-algo sha1 \
--rom $(TARGET_DIR)/caliptra-rom.bin \
--recovery-image-fw $(TARGET_DIR)/caliptra-rom-test-fw \
--device-lifecycle unprovisioned \
--active-mode \

run-update: build-emu build-fw-image build-rom
cargo \
"--config=$(EXTRA_CARGO_CONFIG)" \
Expand Down
57 changes: 50 additions & 7 deletions sw-emulator/app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ use tock_registers::register_bitfields;
/// Firmware Load Command Opcode
const FW_LOAD_CMD_OPCODE: u32 = 0x4657_4C44;

/// Recovery register interface download Command Opcode
const RI_DOWNLOAD_FIRMWARE: u32 = 0x5249_4644;

/// The number of CPU clock cycles it takes to write the firmware to the mailbox.
const FW_WRITE_TICKS: u64 = 1000;

Expand Down Expand Up @@ -162,6 +165,11 @@ fn main() -> io::Result<()> {
.value_parser(value_parser!(u64))
.default_value(&(EXPECTED_CALIPTRA_BOOT_TIME_IN_CYCLES.to_string()))
)
.arg(
arg!(--"active-mode" ... "Active mode: get image update via recovery register interface")
.required(false)
.action(ArgAction::SetTrue)
)
.get_matches();

let args_rom = args.get_one::<PathBuf>("rom").unwrap();
Expand Down Expand Up @@ -267,6 +275,11 @@ fn main() -> io::Result<()> {
},
);

let active_mode = args.get_flag("active-mode");

// Clippy seems wrong about this clone not being necessary
#[allow(clippy::redundant_clone)]
let firmware_buffer = current_fw_buf.clone();
let bus_args = CaliptraRootBusArgs {
rom: rom_buffer,
log_dir: args_log_dir.clone(),
Expand All @@ -275,12 +288,20 @@ fn main() -> io::Result<()> {
0xFF => exit(0x00),
_ => print!("{}", val as char),
}),
ready_for_fw_cb: ReadyForFwCb::new(move |args| {
let firmware_buffer = current_fw_buf.clone();
args.schedule_later(FW_WRITE_TICKS, move |mailbox: &mut MailboxInternal| {
upload_fw_to_mailbox(mailbox, firmware_buffer);
});
}),
ready_for_fw_cb: if active_mode {
ReadyForFwCb::new(move |args| {
args.schedule_later(FW_WRITE_TICKS, move |mailbox: &mut MailboxInternal| {
rri_download(mailbox)
})
})
} else {
ReadyForFwCb::new(move |args| {
let firmware_buffer = firmware_buffer.clone();
args.schedule_later(FW_WRITE_TICKS, move |mailbox: &mut MailboxInternal| {
upload_fw_to_mailbox(mailbox, firmware_buffer)
});
})
},
security_state,
upload_update_fw: UploadUpdateFwCb::new(move |mailbox: &mut MailboxInternal| {
upload_fw_to_mailbox(mailbox, update_fw_buf.clone());
Expand All @@ -294,10 +315,16 @@ fn main() -> io::Result<()> {
download_idev_id_csr(mailbox, log_dir.clone(), cptra_dbg_manuf_service_reg);
},
),
active_mode,
..Default::default()
};

let root_bus = CaliptraRootBus::new(&clock, bus_args);
let mut root_bus = CaliptraRootBus::new(&clock, bus_args);
// Populate the RRI data
if active_mode {
root_bus.dma.axi.recovery.cms_data = Some(current_fw_buf);
}

let soc_ifc = unsafe {
caliptra_registers::soc_ifc::RegisterBlock::new_with_mmio(
0x3003_0000 as *mut u32,
Expand Down Expand Up @@ -457,6 +484,22 @@ fn upload_fw_to_mailbox(mailbox: &mut MailboxInternal, firmware_buffer: Rc<Vec<u
soc_mbox.execute().write(|w| w.execute(true));
}

fn rri_download(mailbox: &mut MailboxInternal) {
let soc_mbox = mailbox.as_external().regs();
// Write the cmd to mailbox.

assert!(!soc_mbox.lock().read().lock());

// Set command
soc_mbox.cmd().write(|_| RI_DOWNLOAD_FIRMWARE);

// No data to send so set len to 0
soc_mbox.dlen().write(|_| 0);

// Execute
soc_mbox.execute().write(|w| w.execute(true));
}

fn download_idev_id_csr(
mailbox: &mut MailboxInternal,
path: Rc<PathBuf>,
Expand Down
2 changes: 2 additions & 0 deletions sw-emulator/lib/periph/src/root_bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ pub struct CaliptraRootBusArgs {

pub itrng_nibbles: Option<Box<dyn Iterator<Item = u8>>>,
pub etrng_responses: Box<dyn Iterator<Item = EtrngResponse>>,
pub active_mode: bool,
}
impl Default for CaliptraRootBusArgs {
fn default() -> Self {
Expand All @@ -241,6 +242,7 @@ impl Default for CaliptraRootBusArgs {
cptra_obf_key: words_from_bytes_be(&DEFAULT_DOE_KEY),
itrng_nibbles: Some(Box::new(RandomNibbles::new_from_thread_rng())),
etrng_responses: Box::new(RandomEtrngResponses::new_from_stdrng()),
active_mode: false,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion sw-emulator/lib/periph/src/soc_reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ impl SocRegistersImpl {
cptra_generic_output_wires: Default::default(),
cptra_hw_rev_id: ReadOnlyRegister::new(0x11), // TODO 2.0
cptra_fw_rev_id: Default::default(),
cptra_hw_config: ReadWriteRegister::new(0), // [TODO][CAP2] Program this
cptra_hw_config: ReadWriteRegister::new(if args.active_mode { 1 << 5 } else { 0 }),
cptra_wdt_timer1_en: ReadWriteRegister::new(0),
cptra_wdt_timer1_ctrl: ReadWriteRegister::new(0),
cptra_wdt_timer1_timeout_period: [0xffff_ffff; 2],
Expand Down

0 comments on commit 95d1122

Please sign in to comment.