Skip to content

Commit cc613e5

Browse files
committed
feat: sw-emulator: add active mode
Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
1 parent 07929ed commit cc613e5

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

rom/dev/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,19 @@ run: build-emu build-fw-image build-rom
128128
--recovery-image-fw $(TARGET_DIR)/caliptra-rom-test-fw \
129129
--device-lifecycle unprovisioned \
130130

131+
run-active: build-emu build-fw-image build-rom
132+
cargo \
133+
"--config=$(EXTRA_CARGO_CONFIG)" \
134+
run \
135+
-p caliptra-emu \
136+
-- \
137+
--req-idevid-csr \
138+
--idevid-key-id-algo sha1 \
139+
--rom $(TARGET_DIR)/caliptra-rom.bin \
140+
--recovery-image-fw $(TARGET_DIR)/caliptra-rom-test-fw \
141+
--device-lifecycle unprovisioned \
142+
--active-mode \
143+
131144
run-update: build-emu build-fw-image build-rom
132145
cargo \
133146
"--config=$(EXTRA_CARGO_CONFIG)" \

sw-emulator/app/src/main.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ use tock_registers::register_bitfields;
3939
/// Firmware Load Command Opcode
4040
const FW_LOAD_CMD_OPCODE: u32 = 0x4657_4C44;
4141

42+
/// Recovery register interface download Command Opcode
43+
const RI_DOWNLOAD_FIRMWARE: u32 = 0x5249_4644;
44+
4245
/// The number of CPU clock cycles it takes to write the firmware to the mailbox.
4346
const FW_WRITE_TICKS: u64 = 1000;
4447

@@ -162,6 +165,11 @@ fn main() -> io::Result<()> {
162165
.value_parser(value_parser!(u64))
163166
.default_value(&(EXPECTED_CALIPTRA_BOOT_TIME_IN_CYCLES.to_string()))
164167
)
168+
.arg(
169+
arg!(--"active-mode" ... "Active mode: get image update via recovery register interface")
170+
.required(false)
171+
.action(ArgAction::SetTrue)
172+
)
165173
.get_matches();
166174

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

278+
let active_mode = args.get_flag("active-mode");
279+
280+
// Clippy seems wrong about this clone not being necessary
281+
#[allow(clippy::redundant_clone)]
282+
let firmware_buffer = current_fw_buf.clone();
270283
let bus_args = CaliptraRootBusArgs {
271284
rom: rom_buffer,
272285
log_dir: args_log_dir.clone(),
@@ -275,12 +288,20 @@ fn main() -> io::Result<()> {
275288
0xFF => exit(0x00),
276289
_ => print!("{}", val as char),
277290
}),
278-
ready_for_fw_cb: ReadyForFwCb::new(move |args| {
279-
let firmware_buffer = current_fw_buf.clone();
280-
args.schedule_later(FW_WRITE_TICKS, move |mailbox: &mut MailboxInternal| {
281-
upload_fw_to_mailbox(mailbox, firmware_buffer);
282-
});
283-
}),
291+
ready_for_fw_cb: if active_mode {
292+
ReadyForFwCb::new(move |args| {
293+
args.schedule_later(FW_WRITE_TICKS, move |mailbox: &mut MailboxInternal| {
294+
rri_download(mailbox)
295+
})
296+
})
297+
} else {
298+
ReadyForFwCb::new(move |args| {
299+
let firmware_buffer = firmware_buffer.clone();
300+
args.schedule_later(FW_WRITE_TICKS, move |mailbox: &mut MailboxInternal| {
301+
upload_fw_to_mailbox(mailbox, firmware_buffer)
302+
});
303+
})
304+
},
284305
security_state,
285306
upload_update_fw: UploadUpdateFwCb::new(move |mailbox: &mut MailboxInternal| {
286307
upload_fw_to_mailbox(mailbox, update_fw_buf.clone());
@@ -294,10 +315,16 @@ fn main() -> io::Result<()> {
294315
download_idev_id_csr(mailbox, log_dir.clone(), cptra_dbg_manuf_service_reg);
295316
},
296317
),
318+
active_mode,
297319
..Default::default()
298320
};
299321

300-
let root_bus = CaliptraRootBus::new(&clock, bus_args);
322+
let mut root_bus = CaliptraRootBus::new(&clock, bus_args);
323+
// Populate the RRI data
324+
if active_mode {
325+
root_bus.dma.axi.recovery.cms_data = Some(current_fw_buf);
326+
}
327+
301328
let soc_ifc = unsafe {
302329
caliptra_registers::soc_ifc::RegisterBlock::new_with_mmio(
303330
0x3003_0000 as *mut u32,
@@ -457,6 +484,22 @@ fn upload_fw_to_mailbox(mailbox: &mut MailboxInternal, firmware_buffer: Rc<Vec<u
457484
soc_mbox.execute().write(|w| w.execute(true));
458485
}
459486

487+
fn rri_download(mailbox: &mut MailboxInternal) {
488+
let soc_mbox = mailbox.as_external().regs();
489+
// Write the cmd to mailbox.
490+
491+
assert!(!soc_mbox.lock().read().lock());
492+
493+
// Set command
494+
soc_mbox.cmd().write(|_| RI_DOWNLOAD_FIRMWARE);
495+
496+
// No data to send so set len to 0
497+
soc_mbox.dlen().write(|_| 0);
498+
499+
// Execute
500+
soc_mbox.execute().write(|w| w.execute(true));
501+
}
502+
460503
fn download_idev_id_csr(
461504
mailbox: &mut MailboxInternal,
462505
path: Rc<PathBuf>,

sw-emulator/lib/periph/src/root_bus.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ pub struct CaliptraRootBusArgs {
226226

227227
pub itrng_nibbles: Option<Box<dyn Iterator<Item = u8>>>,
228228
pub etrng_responses: Box<dyn Iterator<Item = EtrngResponse>>,
229+
pub active_mode: bool,
229230
}
230231
impl Default for CaliptraRootBusArgs {
231232
fn default() -> Self {
@@ -241,6 +242,7 @@ impl Default for CaliptraRootBusArgs {
241242
cptra_obf_key: words_from_bytes_be(&DEFAULT_DOE_KEY),
242243
itrng_nibbles: Some(Box::new(RandomNibbles::new_from_thread_rng())),
243244
etrng_responses: Box::new(RandomEtrngResponses::new_from_stdrng()),
245+
active_mode: false,
244246
}
245247
}
246248
}

sw-emulator/lib/periph/src/soc_reg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ impl SocRegistersImpl {
882882
cptra_generic_output_wires: Default::default(),
883883
cptra_hw_rev_id: ReadOnlyRegister::new(0x11), // TODO 2.0
884884
cptra_fw_rev_id: Default::default(),
885-
cptra_hw_config: ReadWriteRegister::new(0), // [TODO][CAP2] Program this
885+
cptra_hw_config: ReadWriteRegister::new(if args.active_mode { 1 << 5 } else { 0 }),
886886
cptra_wdt_timer1_en: ReadWriteRegister::new(0),
887887
cptra_wdt_timer1_ctrl: ReadWriteRegister::new(0),
888888
cptra_wdt_timer1_timeout_period: [0xffff_ffff; 2],

0 commit comments

Comments
 (0)