diff --git a/hw-model/src/lib.rs b/hw-model/src/lib.rs index 2f3fa27fa7..383f7e3a6f 100644 --- a/hw-model/src/lib.rs +++ b/hw-model/src/lib.rs @@ -20,6 +20,7 @@ use caliptra_hw_model_types::{ }; use zerocopy::{AsBytes, FromBytes, LayoutVerified, Unalign}; +use caliptra_emu_periph::MailboxRequester; use caliptra_registers::mbox; use caliptra_registers::mbox::enums::{MboxFsmE, MboxStatusE}; use caliptra_registers::soc_ifc::regs::{ @@ -176,6 +177,8 @@ pub struct InitParams<'a> { // A trace path to use. If None, the CPTRA_TRACE_PATH environment variable // will be used pub trace_path: Option, + + pub soc_user: MailboxRequester, } impl<'a> Default for InitParams<'a> { fn default() -> Self { @@ -210,6 +213,7 @@ impl<'a> Default for InitParams<'a> { }), random_sram_puf: true, trace_path: None, + soc_user: MailboxRequester::SocUser(1u32), } } } diff --git a/hw-model/src/model_emulated.rs b/hw-model/src/model_emulated.rs index 881bec4001..8a716de373 100644 --- a/hw-model/src/model_emulated.rs +++ b/hw-model/src/model_emulated.rs @@ -13,8 +13,11 @@ use caliptra_emu_bus::Clock; use caliptra_emu_cpu::CoverageBitmaps; use caliptra_emu_cpu::{Cpu, InstrTracer}; use caliptra_emu_periph::ActionCb; +use caliptra_emu_periph::MailboxExternal; use caliptra_emu_periph::ReadyForFwCb; -use caliptra_emu_periph::{CaliptraRootBus, CaliptraRootBusArgs, SocToCaliptraBus, TbServicesCb}; +use caliptra_emu_periph::{ + CaliptraRootBus, CaliptraRootBusArgs, MailboxRequester, SocToCaliptraBus, TbServicesCb, +}; use caliptra_emu_types::{RvAddr, RvData, RvSize}; use caliptra_hw_model_types::ErrorInjectionMode; use caliptra_image_types::IMAGE_MANIFEST_BYTE_SIZE; @@ -186,7 +189,7 @@ impl HwModel for ModelEmulated { }; dccm_dest.copy_from_slice(params.dccm); } - let soc_to_caliptra_bus = root_bus.soc_to_caliptra_bus(); + let soc_to_caliptra_bus = root_bus.soc_to_caliptra_bus(params.soc_user); let cpu = Cpu::new(BusLogger::new(root_bus), clock); let mut hasher = DefaultHasher::new(); @@ -282,8 +285,11 @@ impl HwModel for ModelEmulated { } } - fn set_apb_pauser(&mut self, _pauser: u32) { - unimplemented!(); + fn set_apb_pauser(&mut self, pauser: u32) { + self.soc_to_caliptra_bus.mailbox = MailboxExternal { + soc_user: MailboxRequester::from(pauser), + regs: self.soc_to_caliptra_bus.mailbox.regs.clone(), + }; } fn warm_reset(&mut self) { diff --git a/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs b/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs index d97506b605..07c443e956 100644 --- a/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs +++ b/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs @@ -251,6 +251,54 @@ fn test_pl1_init_ctx_dpe_context_thresholds() { } } +#[test] +fn test_change_locality() { + let args = RuntimeTestArgs { + ..Default::default() + }; + + let mut model = run_rt_test(args); + + model.step_until(|m| { + m.soc_ifc().cptra_boot_status().read() == u32::from(RtBootStatus::RtReadyForCommands) + }); + model.set_apb_pauser(0x01); + + let derive_context_cmd = DeriveContextCmd { + handle: ContextHandle::default(), + data: DATA, + flags: DeriveContextFlags::CHANGE_LOCALITY + | DeriveContextFlags::MAKE_DEFAULT + | DeriveContextFlags::INPUT_ALLOW_X509, + tci_type: 0, + target_locality: 2, + }; + + let _ = execute_dpe_cmd( + &mut model, + &mut Command::DeriveContext(derive_context_cmd), + DpeResult::Success, + ) + .unwrap(); + + model.set_apb_pauser(0x02); + + let derive_context_cmd = DeriveContextCmd { + handle: ContextHandle::default(), + data: DATA, + flags: DeriveContextFlags::MAKE_DEFAULT, + tci_type: 0, + target_locality: 2, + }; + + let _ = execute_dpe_cmd( + &mut model, + &mut Command::DeriveContext(derive_context_cmd), + DpeResult::Success, + ) + .unwrap(); +} + #[test] fn test_populate_idev_cannot_be_called_from_pl1() { let mut image_opts = ImageOptions::default(); diff --git a/sw-emulator/app/src/main.rs b/sw-emulator/app/src/main.rs index 9da4e00897..274d88aeca 100644 --- a/sw-emulator/app/src/main.rs +++ b/sw-emulator/app/src/main.rs @@ -17,8 +17,8 @@ use caliptra_emu_bus::Clock; use caliptra_emu_cpu::{Cpu, RvInstr, StepAction}; use caliptra_emu_periph::soc_reg::DebugManufService; use caliptra_emu_periph::{ - CaliptraRootBus, CaliptraRootBusArgs, DownloadIdevidCsrCb, MailboxInternal, ReadyForFwCb, - TbServicesCb, UploadUpdateFwCb, + CaliptraRootBus, CaliptraRootBusArgs, DownloadIdevidCsrCb, MailboxInternal, MailboxRequester, + ReadyForFwCb, TbServicesCb, UploadUpdateFwCb, }; use caliptra_hw_model::BusMmio; use clap::{arg, value_parser, ArgAction}; @@ -283,7 +283,7 @@ fn main() -> io::Result<()> { let soc_ifc = unsafe { caliptra_registers::soc_ifc::RegisterBlock::new_with_mmio( 0x3003_0000 as *mut u32, - BusMmio::new(root_bus.soc_to_caliptra_bus()), + BusMmio::new(root_bus.soc_to_caliptra_bus(MailboxRequester::SocUser(1u32))), ) }; @@ -405,7 +405,7 @@ fn change_dword_endianess(data: &mut Vec) { } fn upload_fw_to_mailbox(mailbox: &mut MailboxInternal, firmware_buffer: Rc>) { - let soc_mbox = mailbox.as_external().regs(); + let soc_mbox = mailbox.as_external(MailboxRequester::SocUser(1u32)).regs(); // Write the cmd to mailbox. assert!(!soc_mbox.lock().read().lock()); @@ -449,7 +449,7 @@ fn download_idev_id_csr( let mut file = std::fs::File::create(path).unwrap(); - let soc_mbox = mailbox.as_external().regs(); + let soc_mbox = mailbox.as_external(MailboxRequester::SocUser(1u32)).regs(); let byte_count = soc_mbox.dlen().read() as usize; let remainder = byte_count % core::mem::size_of::(); diff --git a/sw-emulator/lib/periph/src/lib.rs b/sw-emulator/lib/periph/src/lib.rs index dd82d71880..157470cf4b 100644 --- a/sw-emulator/lib/periph/src/lib.rs +++ b/sw-emulator/lib/periph/src/lib.rs @@ -41,7 +41,7 @@ pub use hmac_sha384::HmacSha384; pub use iccm::Iccm; pub use key_vault::KeyUsage; pub use key_vault::KeyVault; -pub use mailbox::{MailboxExternal, MailboxInternal, MailboxRam}; +pub use mailbox::{MailboxExternal, MailboxInternal, MailboxRam, MailboxRequester}; pub use root_bus::{ ActionCb, CaliptraRootBus, CaliptraRootBusArgs, DownloadIdevidCsrCb, ReadyForFwCb, SocToCaliptraBus, TbServicesCb, UploadUpdateFwCb, diff --git a/sw-emulator/lib/periph/src/mailbox.rs b/sw-emulator/lib/periph/src/mailbox.rs index f11ed9297b..ebfec4cc01 100644 --- a/sw-emulator/lib/periph/src/mailbox.rs +++ b/sw-emulator/lib/periph/src/mailbox.rs @@ -90,7 +90,8 @@ impl Default for MailboxRam { #[derive(Clone)] pub struct MailboxExternal { - regs: Rc>, + pub soc_user: MailboxRequester, + pub regs: Rc>, } impl MailboxExternal { pub fn regs(&mut self) -> caliptra_registers::mbox::RegisterBlock> { @@ -107,7 +108,7 @@ impl Bus for MailboxExternal { /// Read data of specified size from given address fn read(&mut self, size: RvSize, addr: RvAddr) -> Result { let mut regs = self.regs.borrow_mut(); - regs.set_request(MailboxRequester::Soc); + regs.set_request(self.soc_user); let result = regs.read(size, addr); regs.set_request(MailboxRequester::Caliptra); result @@ -116,7 +117,7 @@ impl Bus for MailboxExternal { /// Write data of specified size to given address fn write(&mut self, size: RvSize, addr: RvAddr, val: RvData) -> Result<(), BusError> { let mut regs = self.regs.borrow_mut(); - regs.set_request(MailboxRequester::Soc); + regs.set_request(self.soc_user); let result = regs.write(size, addr, val); regs.set_request(MailboxRequester::Caliptra); result @@ -146,8 +147,9 @@ impl MailboxInternal { } } - pub fn as_external(&self) -> MailboxExternal { + pub fn as_external(&self, soc_user: MailboxRequester) -> MailboxExternal { MailboxExternal { + soc_user, regs: self.regs.clone(), } } @@ -182,15 +184,24 @@ impl Bus for MailboxInternal { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum MailboxRequester { - Caliptra = 0, - Soc = 1, + Caliptra, + SocUser(u32), +} + +impl From for MailboxRequester { + fn from(value: u32) -> Self { + match value { + 0 => MailboxRequester::Caliptra, + _ => MailboxRequester::SocUser(value), + } + } } impl From for u32 { fn from(val: MailboxRequester) -> Self { match val { MailboxRequester::Caliptra => 0, - MailboxRequester::Soc => 1, + MailboxRequester::SocUser(pauser) => pauser, } } } @@ -706,7 +717,7 @@ mod tests { #[test] fn test_soc_to_caliptra_lock() { let mut caliptra = MailboxInternal::new(&Clock::new(), MailboxRam::new()); - let mut soc = caliptra.as_external(); + let mut soc = caliptra.as_external(MailboxRequester::SocUser(1u32)); let soc_regs = soc.regs(); assert!(!soc_regs.lock().read().lock()); @@ -723,7 +734,7 @@ mod tests { let request_to_send: [u32; 4] = [0x1111_1111, 0x2222_2222, 0x3333_3333, 0x4444_4444]; let mut caliptra = MailboxInternal::new(&Clock::new(), MailboxRam::new()); - let mut soc = caliptra.as_external(); + let mut soc = caliptra.as_external(MailboxRequester::SocUser(1u32)); let soc_regs = soc.regs(); let uc_regs = caliptra.regs(); @@ -731,7 +742,10 @@ mod tests { // Confirm it is locked assert!(soc_regs.lock().read().lock()); - assert_eq!(soc_regs.user().read(), MailboxRequester::Soc as u32); + assert_eq!( + MailboxRequester::SocUser(soc_regs.user().read()), + MailboxRequester::SocUser(1u32) + ); // Write command soc_regs.cmd().write(|_| 0x55); @@ -873,7 +887,7 @@ mod tests { assert!(uc_regs.lock().read().lock()); let user = uc_regs.user().read(); - assert_eq!(user, MailboxRequester::Caliptra as u32); + assert_eq!(MailboxRequester::from(user), MailboxRequester::Caliptra); // Write command uc_regs.cmd().write(|_| 0x55); diff --git a/sw-emulator/lib/periph/src/root_bus.rs b/sw-emulator/lib/periph/src/root_bus.rs index d6d5c35f6c..87a0e87a07 100644 --- a/sw-emulator/lib/periph/src/root_bus.rs +++ b/sw-emulator/lib/periph/src/root_bus.rs @@ -12,6 +12,7 @@ Abstract: --*/ +use crate::MailboxRequester; use crate::{ helpers::words_from_bytes_be, iccm::Iccm, @@ -345,9 +346,9 @@ impl CaliptraRootBus { } } - pub fn soc_to_caliptra_bus(&self) -> SocToCaliptraBus { + pub fn soc_to_caliptra_bus(&self, soc_user: MailboxRequester) -> SocToCaliptraBus { SocToCaliptraBus { - mailbox: self.mailbox.as_external(), + mailbox: self.mailbox.as_external(soc_user), sha512_acc: self.sha512_acc.clone(), soc_ifc: self.soc_reg.external_regs(), } @@ -357,7 +358,7 @@ impl CaliptraRootBus { #[derive(Bus)] pub struct SocToCaliptraBus { #[peripheral(offset = 0x3002_0000, mask = 0x0000_0fff)] - mailbox: MailboxExternal, + pub mailbox: MailboxExternal, #[peripheral(offset = 0x3002_1000, mask = 0x0000_0fff)] sha512_acc: Sha512Accelerator, diff --git a/sw-emulator/lib/periph/src/soc_reg.rs b/sw-emulator/lib/periph/src/soc_reg.rs index 1202999579..6d1cb6fcce 100644 --- a/sw-emulator/lib/periph/src/soc_reg.rs +++ b/sw-emulator/lib/periph/src/soc_reg.rs @@ -13,6 +13,7 @@ Abstract: --*/ use crate::helpers::{bytes_from_words_be, words_from_bytes_be}; +use crate::mailbox::MailboxRequester; use crate::root_bus::ReadyForFwCbArgs; use crate::{CaliptraRootBusArgs, Iccm, MailboxInternal}; use caliptra_emu_bus::BusError::{LoadAccessFault, StoreAccessFault}; @@ -1186,7 +1187,10 @@ impl SocRegistersImpl { } if self.timer.fired(&mut self.op_fw_read_complete_action) { - let soc_mbox = self.mailbox.as_external().regs(); + let soc_mbox = self + .mailbox + .as_external(MailboxRequester::SocUser(1)) + .regs(); // uC will set status to CMD_COMPLETE after reading the // mailbox data; we can't clear the execute bit until that is done.` if !soc_mbox.status().read().status().cmd_busy() {