diff --git a/Cargo.lock b/Cargo.lock index 9ed174ff5..8234f5358 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -894,7 +894,7 @@ name = "capsules-emulator" version = "0.1.0" dependencies = [ "bitfield", - "dma-driver", + "capsules-runtime", "flash-driver", "kernel", "mcu-platforms-common", @@ -1493,6 +1493,7 @@ name = "dma-driver" version = "0.1.0" dependencies = [ "capsules-core", + "capsules-runtime", "kernel", "registers-generated", "romtime", @@ -1788,6 +1789,7 @@ dependencies = [ "emulator-consts", "emulator-registers-generated", "lazy_static", + "mcu-config-emulator", "mcu-testing-common", "num_enum", "registers-generated", diff --git a/common/config/src/lib.rs b/common/config/src/lib.rs index b7ffe57a0..9f0b39b17 100644 --- a/common/config/src/lib.rs +++ b/common/config/src/lib.rs @@ -49,6 +49,9 @@ pub struct McuMemoryMap { pub lc_offset: u32, pub lc_size: u32, pub lc_properties: MemoryRegionType, + + pub staging_sram_offset: u32, + pub staging_sram_size: u32, } impl Default for McuMemoryMap { @@ -94,6 +97,9 @@ impl Default for McuMemoryMap { lc_offset: 0x7000_0400, lc_size: 0x8c, lc_properties: MemoryRegionType::MMIO, + + staging_sram_offset: 0xb00c_0000, + staging_sram_size: 1024 * 1024, } } } diff --git a/emulator/periph/Cargo.toml b/emulator/periph/Cargo.toml index 19109b0d3..95d616261 100644 --- a/emulator/periph/Cargo.toml +++ b/emulator/periph/Cargo.toml @@ -18,6 +18,7 @@ caliptra-emu-periph.workspace = true emulator-consts.workspace = true emulator-registers-generated.workspace = true lazy_static.workspace = true +mcu-config-emulator.workspace = true mcu-testing-common.workspace = true num_enum.workspace = true registers-generated.workspace = true diff --git a/emulator/periph/src/axicdma.rs b/emulator/periph/src/axicdma.rs index a5df5df4f..c80686914 100644 --- a/emulator/periph/src/axicdma.rs +++ b/emulator/periph/src/axicdma.rs @@ -8,6 +8,7 @@ use caliptra_emu_bus::{ActionHandle, Clock, Ram, ReadWriteRegister, Timer}; use caliptra_emu_cpu::Irq; use emulator_consts::{RAM_ORG, RAM_SIZE}; use emulator_registers_generated::axicdma::{AxicdmaGenerated, AxicdmaPeripheral}; +use mcu_config_emulator::EMULATOR_MEMORY_MAP; use registers_generated::axicdma::bits::{AxicdmaBytesToTransfer, AxicdmaControl, AxicdmaStatus}; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; @@ -37,8 +38,9 @@ pub enum DmaOpError { const MCU_SRAM_START_ADDR: u64 = RAM_ORG as u64; const MCU_SRAM_END_ADDR: u64 = (RAM_ORG + RAM_SIZE) as u64; -const EXTERNAL_SRAM_START_ADDR: u64 = 0xB00C_0000; -const EXTERNAL_SRAM_END_ADDR: u64 = 0xB010_0000; +const EXTERNAL_SRAM_START_ADDR: u64 = EMULATOR_MEMORY_MAP.staging_sram_offset as u64; +const EXTERNAL_SRAM_END_ADDR: u64 = + (EMULATOR_MEMORY_MAP.staging_sram_offset + EMULATOR_MEMORY_MAP.staging_sram_size) as u64; const MCU_MBOX0_SRAM_START_ADDR: u64 = 0xA840_0000; const MCU_MBOX0_SRAM_END_ADDR: u64 = 0xA860_0000; @@ -214,15 +216,11 @@ impl AxiCDMA { let source_data = &source_ram.data()[source_addr..source_addr + xfer_size]; if let Some(mbox0) = &self.mcu_mailbox0 { - for (index, chunk) in source_data.chunks(4).enumerate() { - let mut data = [0u8; 4]; - data[..chunk.len()].copy_from_slice(chunk); - let value = u32::from_le_bytes(data); - let regs = &mbox0.regs; - regs.lock() - .unwrap() - .write_mcu_mbox0_csr_mbox_sram(value, index + dest_addr); - } + mbox0 + .regs + .lock() + .unwrap() + .write_mcu_mbox0_csr_mbox_sram_block(source_data, dest_addr); return Ok(()); } else { return Err(DmaOpError::WriteError); @@ -233,15 +231,11 @@ impl AxiCDMA { let source_data = &source_ram.data()[source_addr..source_addr + xfer_size]; if let Some(mbox1) = &self.mcu_mailbox1 { - for (index, chunk) in source_data.chunks(4).enumerate() { - let mut data = [0u8; 4]; - data[..chunk.len()].copy_from_slice(chunk); - let value = u32::from_le_bytes(data); - let regs = &mbox1.regs; - regs.lock() - .unwrap() - .write_mcu_mbox0_csr_mbox_sram(value, index + dest_addr.div_ceil(4)); - } + mbox1 + .regs + .lock() + .unwrap() + .write_mcu_mbox0_csr_mbox_sram_block(source_data, dest_addr); return Ok(()); } else { return Err(DmaOpError::WriteError); diff --git a/emulator/periph/src/mcu_mbox0.rs b/emulator/periph/src/mcu_mbox0.rs index 7b6a1dc25..08f35f05e 100644 --- a/emulator/periph/src/mcu_mbox0.rs +++ b/emulator/periph/src/mcu_mbox0.rs @@ -239,6 +239,18 @@ impl MciMailboxImpl { self.lock.reg.set(0); // Release lock after clearing } + pub fn read_mcu_mbox0_csr_mbox_sram_block(&mut self, index: usize, len: usize) -> Vec { + if index + len > MCU_MAILBOX0_SRAM_SIZE as usize { + panic!( + "Read length {len} exceeds mcu_mbox0 SRAM size of {}", + MCU_MAILBOX0_SRAM_SIZE + ); + } + let sram = self.sram.ram.lock().unwrap(); + let mem = sram.data(); + mem[index..index + len].to_vec() + } + pub fn read_mcu_mbox0_csr_mbox_sram(&mut self, index: usize) -> caliptra_emu_types::RvData { if index >= (MCU_MAILBOX0_SRAM_SIZE as usize / 4) { panic!("Index out of bounds for mcu_mbox0 SRAM: {index}"); @@ -278,6 +290,23 @@ impl MciMailboxImpl { } } + pub fn write_mcu_mbox0_csr_mbox_sram_block(&mut self, data: &[u8], index: usize) { + if !self.is_locked() { + panic!("Cannot write to mcu_mbox0 SRAM when mailbox is unlocked"); + } + + let dlen = data.len(); + if index + dlen > MCU_MAILBOX0_SRAM_SIZE as usize { + panic!( + "Data length {dlen} exceeds mcu_mbox0 SRAM size of {}", + MCU_MAILBOX0_SRAM_SIZE + ); + } + let mut sram = self.sram.ram.lock().unwrap(); + let mem = sram.data_mut(); + mem[index..index + dlen].copy_from_slice(data); + } + pub fn read_mcu_mbox0_csr_mbox_lock( &mut self, ) -> caliptra_emu_bus::ReadWriteRegister diff --git a/emulator/periph/src/root_bus.rs b/emulator/periph/src/root_bus.rs index 865471dc8..62aea4408 100644 --- a/emulator/periph/src/root_bus.rs +++ b/emulator/periph/src/root_bus.rs @@ -392,18 +392,12 @@ impl Bus for McuRootBus { start + len ); } else { - let data = (start..start + len).step_by(4).map(|index| { - self.mcu_mailbox0 - .regs - .lock() - .unwrap() - .read_mcu_mbox0_csr_mbox_sram(index) - }); - let data: Vec = data - .flat_map(|val| val.to_be_bytes().to_vec()) - .take(len) - .collect(); - + let data = self + .mcu_mailbox0 + .regs + .lock() + .unwrap() + .read_mcu_mbox0_csr_mbox_sram_block(start, len); if let Some(event_sender) = self.event_sender.as_ref() { event_sender .send(Event { @@ -430,18 +424,12 @@ impl Bus for McuRootBus { start + len ); } else { - let data = (start..start + len).step_by(4).map(|index| { - self.mcu_mailbox1 - .regs - .lock() - .unwrap() - .read_mcu_mbox0_csr_mbox_sram(index.div_ceil(4)) - }); - let data: Vec = data - .flat_map(|val| val.to_be_bytes().to_vec()) - .take(len) - .collect(); - + let data = self + .mcu_mailbox1 + .regs + .lock() + .unwrap() + .read_mcu_mbox0_csr_mbox_sram_block(start, len); if let Some(event_sender) = self.event_sender.as_ref() { event_sender .send(Event { @@ -472,19 +460,6 @@ impl Bus for McuRootBus { let ram_size = ram.len() as usize; let len = len.min(ram_size - start); let data = ram.data()[start..start + len].to_vec(); - - // Caliptra DMA processes the data in 4-byte chunks - let data: Vec = data - .chunks(4) - .flat_map(|chunk| { - if chunk.len() == 4 { - chunk.iter().rev().cloned().collect::>() - } else { - chunk.to_vec() - } - }) - .collect(); - if let Some(event_sender) = self.event_sender.as_ref() { event_sender .send(Event { diff --git a/platforms/emulator/config/src/lib.rs b/platforms/emulator/config/src/lib.rs index 04ccdd083..31db859db 100644 --- a/platforms/emulator/config/src/lib.rs +++ b/platforms/emulator/config/src/lib.rs @@ -46,6 +46,9 @@ pub const EMULATOR_MEMORY_MAP: McuMemoryMap = McuMemoryMap { lc_offset: 0x7000_0400, lc_size: 0x8c, lc_properties: MemoryRegionType::MMIO, + + staging_sram_offset: 0xb00c_0000, + staging_sram_size: 1024 * 1024, }; pub const EMULATOR_MCU_STRAPS: McuStraps = McuStraps::default(); diff --git a/platforms/emulator/runtime/kernel/capsules/Cargo.toml b/platforms/emulator/runtime/kernel/capsules/Cargo.toml index bea1a6e75..f636d031f 100644 --- a/platforms/emulator/runtime/kernel/capsules/Cargo.toml +++ b/platforms/emulator/runtime/kernel/capsules/Cargo.toml @@ -8,7 +8,7 @@ edition.workspace = true [dependencies] bitfield.workspace = true -dma-driver.workspace = true +capsules-runtime.workspace = true flash-driver.workspace = true mcu-platforms-common.workspace = true kernel.workspace = true diff --git a/platforms/emulator/runtime/kernel/capsules/src/dma.rs b/platforms/emulator/runtime/kernel/capsules/src/dma.rs index 909628921..507d29104 100644 --- a/platforms/emulator/runtime/kernel/capsules/src/dma.rs +++ b/platforms/emulator/runtime/kernel/capsules/src/dma.rs @@ -2,6 +2,7 @@ //! This provides the dma syscall driver +use capsules_runtime::dma::hil::{Dma as DmaHal, DmaClient, DmaError, DmaRoute, DmaStatus}; use kernel::grant::{AllowRoCount, AllowRwCount, Grant, UpcallCount}; use kernel::syscall::{CommandReturn, SyscallDriver}; use kernel::utilities::cells::OptionalCell; @@ -36,7 +37,7 @@ pub struct App { pub struct Dma<'a> { // The underlying dma storage driver. - driver: &'a dyn dma_driver::hil::DMA, + driver: &'a dyn DmaHal, // Per-app state. apps: Grant, AllowRoCount<0>, AllowRwCount<0>>, current_app: OptionalCell, @@ -44,7 +45,7 @@ pub struct Dma<'a> { impl<'a> Dma<'a> { pub fn new( - driver: &'a dyn dma_driver::hil::DMA, + driver: &'a dyn DmaHal, grant: Grant, AllowRoCount<0>, AllowRwCount<0>>, ) -> Dma<'a> { Dma { @@ -114,19 +115,16 @@ impl<'a> Dma<'a> { app.source_address, app.dest_address, )?; - self.driver.start_transfer( - dma_driver::hil::DmaRoute::AxiToAxi, - dma_driver::hil::DmaRoute::AxiToAxi, - false, - ) + self.driver + .start_transfer(DmaRoute::AxiToAxi, DmaRoute::AxiToAxi, false) }) .unwrap_or_else(|err| Err(err.into())) }) } } -impl dma_driver::hil::DMAClient for Dma<'_> { - fn transfer_complete(&self, status: dma_driver::hil::DMAStatus) { +impl DmaClient for Dma<'_> { + fn transfer_complete(&self, status: DmaStatus) { if let Some(processid) = self.current_app.take() { let _ = self.apps.enter(processid, move |_, kernel_data| { // Signal the app. @@ -137,7 +135,7 @@ impl dma_driver::hil::DMAClient for Dma<'_> { }; } - fn transfer_error(&self, error: dma_driver::hil::DMAError) { + fn transfer_error(&self, error: DmaError) { if let Some(processid) = self.current_app.take() { let _ = self.apps.enter(processid, move |_, kernel_data| { // Signal the app. diff --git a/platforms/emulator/runtime/kernel/drivers/dma/Cargo.toml b/platforms/emulator/runtime/kernel/drivers/dma/Cargo.toml index 6a9df5405..513a4e12a 100644 --- a/platforms/emulator/runtime/kernel/drivers/dma/Cargo.toml +++ b/platforms/emulator/runtime/kernel/drivers/dma/Cargo.toml @@ -11,6 +11,7 @@ kernel.workspace = true # [target.'cfg(target_arch = "riscv32")'.dependencies] capsules-core.workspace = true +capsules-runtime.workspace = true registers-generated.workspace = true romtime.workspace = true tock-registers.workspace = true diff --git a/platforms/emulator/runtime/kernel/drivers/dma/src/axicdma.rs b/platforms/emulator/runtime/kernel/drivers/dma/src/axicdma.rs index ddd254bb8..fbe95cfc0 100755 --- a/platforms/emulator/runtime/kernel/drivers/dma/src/axicdma.rs +++ b/platforms/emulator/runtime/kernel/drivers/dma/src/axicdma.rs @@ -6,8 +6,8 @@ use core::cell::RefCell; -use crate::hil::{DMAClient, DMAError, DMA}; use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; +use capsules_runtime::dma::hil::{Dma, DmaClient, DmaError, DmaRoute, DmaStatus}; use kernel::hil::time::{Alarm, AlarmClient, Time}; use kernel::utilities::cells::OptionalCell; use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable}; @@ -20,24 +20,24 @@ pub const DMA_CTRL_BASE: StaticRef = pub struct AxiCDMA<'a, A: Alarm<'a>> { registers: StaticRef, - dma_client: OptionalCell<&'a dyn DMAClient>, + dma_client: OptionalCell<&'a dyn DmaClient>, btt: RefCell, use_interrupt: bool, - alarm: VirtualMuxAlarm<'a, A>, + alarm: Option>, } impl<'a, A: Alarm<'a>> AxiCDMA<'a, A> { pub fn new( base: StaticRef, use_interrupt: bool, - alarm: &'a MuxAlarm<'a, A>, + alarm: Option<&'a MuxAlarm<'a, A>>, ) -> AxiCDMA<'a, A> { AxiCDMA { registers: base, dma_client: OptionalCell::empty(), btt: RefCell::new(0), use_interrupt, - alarm: VirtualMuxAlarm::new(alarm), + alarm: alarm.map(|a| VirtualMuxAlarm::new(a)), } } @@ -45,8 +45,11 @@ impl<'a, A: Alarm<'a>> AxiCDMA<'a, A> { self.reset(); self.clear_error_interrupt(); self.clear_event_interrupt(); - self.alarm.setup(); - self.alarm.set_alarm_client(self); + + if let Some(alarm) = &self.alarm { + alarm.setup(); + alarm.set_alarm_client(self); + } } fn enable_interrupts(&self) { @@ -91,7 +94,7 @@ impl<'a, A: Alarm<'a>> AxiCDMA<'a, A> { if dmactrl_intr.is_set(AxicdmaStatus::IrqError) { self.clear_error_interrupt(); self.dma_client.map(move |client| { - client.transfer_error(DMAError::AxiWriteError); + client.transfer_error(DmaError::AxiWriteError); }); } @@ -99,19 +102,21 @@ impl<'a, A: Alarm<'a>> AxiCDMA<'a, A> { if dmactrl_intr.is_set(AxicdmaStatus::IrqIoc) { self.clear_event_interrupt(); self.dma_client.map(move |client| { - client.transfer_complete(crate::hil::DMAStatus::TxnDone); + client.transfer_complete(DmaStatus::TxnDone); }); } } fn schedule_alarm(&self) { - let now = self.alarm.now(); - let dt = A::Ticks::from(10000); - self.alarm.set_alarm(now, dt); + if let Some(alarm) = &self.alarm { + let now = alarm.now(); + let dt = A::Ticks::from(20000); + alarm.set_alarm(now, dt); + } } } -impl<'a, A: Alarm<'a>> crate::hil::DMA for AxiCDMA<'a, A> { +impl<'a, A: Alarm<'a>> Dma for AxiCDMA<'a, A> { fn configure_transfer( &self, byte_count: usize, @@ -159,15 +164,15 @@ impl<'a, A: Alarm<'a>> crate::hil::DMA for AxiCDMA<'a, A> { fn start_transfer( &self, - read_route: crate::hil::DmaRoute, - write_route: crate::hil::DmaRoute, + read_route: DmaRoute, + write_route: DmaRoute, _fixed_addr: bool, ) -> Result<(), ErrorCode> { - if read_route != crate::hil::DmaRoute::AxiToAxi { + if read_route != DmaRoute::AxiToAxi { // Only AxiToAxi route is supported return Err(ErrorCode::INVAL); } - if write_route != crate::hil::DmaRoute::AxiToAxi { + if write_route != DmaRoute::AxiToAxi { // Only AxiToAxi route is supported return Err(ErrorCode::INVAL); } @@ -186,30 +191,30 @@ impl<'a, A: Alarm<'a>> crate::hil::DMA for AxiCDMA<'a, A> { Ok(()) } - fn poll_status(&self) -> Result { + fn poll_status(&self) -> Result { // Read the op_status register let op_status = self.registers.axicdma_status.extract(); if op_status.is_set(AxicdmaStatus::Idle) { - return Ok(crate::hil::DMAStatus::TxnDone); + return Ok(DmaStatus::TxnDone); } if op_status.is_set(AxicdmaStatus::ErrInternal) || op_status.is_set(AxicdmaStatus::ErrSlave) || op_status.is_set(AxicdmaStatus::ErrDecode) { - return Err(DMAError::CommandError); + return Err(DmaError::CommandError); } - Ok(crate::hil::DMAStatus::RdFifoNotEmpty) + Ok(DmaStatus::RdFifoNotEmpty) } - fn write_fifo(&self, _data: &[u8]) -> Result<(), DMAError> { - Err(DMAError::CommandError) + fn write_fifo(&self, _data: &[u8]) -> Result<(), DmaError> { + Err(DmaError::CommandError) } - fn read_fifo(&self, _buffer: &mut [u8]) -> Result { - Err(DMAError::CommandError) + fn read_fifo(&self, _buffer: &mut [u8]) -> Result { + Err(DmaError::CommandError) } - fn set_client(&self, client: &'static dyn DMAClient) { + fn set_client(&self, client: &'static dyn DmaClient) { self.dma_client.set(client); } } @@ -217,9 +222,9 @@ impl<'a, A: Alarm<'a>> crate::hil::DMA for AxiCDMA<'a, A> { impl<'a, A: Alarm<'a>> AlarmClient for AxiCDMA<'a, A> { fn alarm(&self) { match self.poll_status() { - Ok(crate::hil::DMAStatus::TxnDone) => { + Ok(DmaStatus::TxnDone) => { self.dma_client.map(move |client| { - client.transfer_complete(crate::hil::DMAStatus::TxnDone); + client.transfer_complete(DmaStatus::TxnDone); }); self.disable_interrupts(); } @@ -228,7 +233,7 @@ impl<'a, A: Alarm<'a>> AlarmClient for AxiCDMA<'a, A> { } Err(_e) => { self.dma_client.map(move |client| { - client.transfer_error(DMAError::AxiWriteError); + client.transfer_error(DmaError::AxiWriteError); }); self.disable_interrupts(); } diff --git a/platforms/emulator/runtime/kernel/drivers/dma/src/lib.rs b/platforms/emulator/runtime/kernel/drivers/dma/src/lib.rs index e61291364..b3d205b62 100644 --- a/platforms/emulator/runtime/kernel/drivers/dma/src/lib.rs +++ b/platforms/emulator/runtime/kernel/drivers/dma/src/lib.rs @@ -4,5 +4,4 @@ //#[cfg(target_arch = "riscv32")] pub mod axicdma; -pub mod hil; pub mod nodma; diff --git a/platforms/emulator/runtime/kernel/drivers/dma/src/nodma.rs b/platforms/emulator/runtime/kernel/drivers/dma/src/nodma.rs index ca824dc1f..eeb6bf9d2 100644 --- a/platforms/emulator/runtime/kernel/drivers/dma/src/nodma.rs +++ b/platforms/emulator/runtime/kernel/drivers/dma/src/nodma.rs @@ -7,14 +7,14 @@ use core::cell::RefCell; -use crate::hil::{DMAClient, DMAError}; use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; +use capsules_runtime::dma::hil::{Dma, DmaClient, DmaError, DmaRoute, DmaStatus}; use kernel::hil::time::{Alarm, AlarmClient, Time}; use kernel::utilities::cells::OptionalCell; use kernel::ErrorCode; pub struct NoDMA<'a, A: Alarm<'a>> { - dma_client: OptionalCell<&'a dyn DMAClient>, + dma_client: OptionalCell<&'a dyn DmaClient>, src_addr: RefCell, dest_addr: RefCell, btt: RefCell, @@ -46,7 +46,7 @@ impl<'a, A: Alarm<'a>> NoDMA<'a, A> { } } -impl<'a, A: Alarm<'a>> crate::hil::DMA for NoDMA<'a, A> { +impl<'a, A: Alarm<'a>> Dma for NoDMA<'a, A> { fn configure_transfer( &self, byte_count: usize, @@ -79,15 +79,15 @@ impl<'a, A: Alarm<'a>> crate::hil::DMA for NoDMA<'a, A> { fn start_transfer( &self, - read_route: crate::hil::DmaRoute, - write_route: crate::hil::DmaRoute, + read_route: DmaRoute, + write_route: DmaRoute, _fixed_addr: bool, ) -> Result<(), ErrorCode> { - if read_route != crate::hil::DmaRoute::AxiToAxi { + if read_route != DmaRoute::AxiToAxi { // Only AxiToAxi route is supported return Err(ErrorCode::INVAL); } - if write_route != crate::hil::DmaRoute::AxiToAxi { + if write_route != DmaRoute::AxiToAxi { // Only AxiToAxi route is supported return Err(ErrorCode::INVAL); } @@ -101,20 +101,20 @@ impl<'a, A: Alarm<'a>> crate::hil::DMA for NoDMA<'a, A> { Ok(()) } - fn poll_status(&self) -> Result { + fn poll_status(&self) -> Result { // Not supported - Err(DMAError::CommandError) + Err(DmaError::CommandError) } - fn write_fifo(&self, _data: &[u8]) -> Result<(), DMAError> { - Err(DMAError::CommandError) + fn write_fifo(&self, _data: &[u8]) -> Result<(), DmaError> { + Err(DmaError::CommandError) } - fn read_fifo(&self, _buffer: &mut [u8]) -> Result { - Err(DMAError::CommandError) + fn read_fifo(&self, _buffer: &mut [u8]) -> Result { + Err(DmaError::CommandError) } - fn set_client(&self, client: &'static dyn DMAClient) { + fn set_client(&self, client: &'static dyn DmaClient) { self.dma_client.set(client); } } @@ -138,7 +138,7 @@ impl<'a, A: Alarm<'a>> AlarmClient for NoDMA<'a, A> { *self.busy.borrow_mut() = false; self.dma_client.map(move |client| { - client.transfer_complete(crate::hil::DMAStatus::TxnDone); + client.transfer_complete(DmaStatus::TxnDone); }); } } diff --git a/platforms/emulator/runtime/src/board.rs b/platforms/emulator/runtime/src/board.rs index e88bdcd9a..bf4f0c096 100644 --- a/platforms/emulator/runtime/src/board.rs +++ b/platforms/emulator/runtime/src/board.rs @@ -461,16 +461,27 @@ pub unsafe fn main() { ); hil::time::Alarm::set_alarm_client(virtual_alarm_user, alarm); + let mbox_dma_driver = static_init!( + dma_driver::axicdma::AxiCDMA<'static, InternalTimers<'static>>, + dma_driver::axicdma::AxiCDMA::new(dma_driver::axicdma::DMA_CTRL_BASE, false, None,) + ); + let mbox_staging_addr = if cfg!(feature = "hw-2-1") { + Some(MCU_MEMORY_MAP.staging_sram_offset as u64) + } else { + None + }; let mailbox = mcu_components::mailbox::MailboxComponent::new( board_kernel, capsules_runtime::mailbox::DRIVER_NUM, mux_alarm, + mbox_dma_driver, ) .finalize(mailbox_component_static!( InternalTimers<'static>, Some(MCU_MEMORY_MAP.soc_offset), Some(MCU_MEMORY_MAP.soc_offset), - Some(MCU_MEMORY_MAP.mbox_offset) + Some(MCU_MEMORY_MAP.mbox_offset), + mbox_staging_addr )); mailbox.alarm.set_alarm_client(mailbox); diff --git a/platforms/emulator/runtime/src/interrupts.rs b/platforms/emulator/runtime/src/interrupts.rs index a237577b2..522700a2f 100644 --- a/platforms/emulator/runtime/src/interrupts.rs +++ b/platforms/emulator/runtime/src/interrupts.rs @@ -35,7 +35,7 @@ impl<'a> EmulatorPeripherals<'a> { dma: dma_driver::axicdma::AxiCDMA::new( dma_driver::axicdma::DMA_CTRL_BASE, false, - alarm, + Some(alarm), ), doe_transport: doe_mbox_driver::EmulatedDoeTransport::new( doe_mbox_driver::DOE_MBOX_BASE, diff --git a/platforms/emulator/runtime/userspace/apps/example/src/test_dma.rs b/platforms/emulator/runtime/userspace/apps/example/src/test_dma.rs index 88cd2adee..ac677a6d5 100644 --- a/platforms/emulator/runtime/userspace/apps/example/src/test_dma.rs +++ b/platforms/emulator/runtime/userspace/apps/example/src/test_dma.rs @@ -5,11 +5,9 @@ use libsyscall_caliptra::dma::{DMASource, DMATransaction, DMA as DMASyscall}; use libsyscall_caliptra::system::System; use libsyscall_caliptra::DefaultSyscalls; use libtock_console::Console; -use romtime::println; - -const MCU_SRAM_HI_OFFSET: u64 = 0x0000_0000; -const TEST_EXTERNAL_SRAM_DEST_ADDRESS: u32 = 0xB00C_0000; +use mcu_config_emulator::EMULATOR_MEMORY_MAP; +const TEST_EXTERNAL_SRAM_DEST_ADDRESS: u32 = EMULATOR_MEMORY_MAP.staging_sram_offset; fn local_ram_to_axi_address(addr: u32) -> u64 { // Convert a local address to an AXI address addr as u64 diff --git a/platforms/fpga/config/src/lib.rs b/platforms/fpga/config/src/lib.rs index ba3af2f1c..e4d38294c 100644 --- a/platforms/fpga/config/src/lib.rs +++ b/platforms/fpga/config/src/lib.rs @@ -46,6 +46,9 @@ pub const FPGA_MEMORY_MAP: McuMemoryMap = McuMemoryMap { lc_offset: 0xa404_0000, lc_size: 0x8c, lc_properties: MemoryRegionType::MMIO, + + staging_sram_offset: 0xb00c_0000, + staging_sram_size: 256 * 1024, }; pub const FPGA_MCU_STRAPS: McuStraps = McuStraps { diff --git a/platforms/fpga/runtime/Cargo.toml b/platforms/fpga/runtime/Cargo.toml index 457ba1449..ed7be735e 100644 --- a/platforms/fpga/runtime/Cargo.toml +++ b/platforms/fpga/runtime/Cargo.toml @@ -38,6 +38,7 @@ rv32i.workspace = true [features] default = [] debug = [] +hw-2-1 = [] test-caliptra-certs = [] test-caliptra-crypto = [] test-caliptra-mailbox = [] diff --git a/platforms/fpga/runtime/src/board.rs b/platforms/fpga/runtime/src/board.rs index 4f557e8bb..f7428c62d 100644 --- a/platforms/fpga/runtime/src/board.rs +++ b/platforms/fpga/runtime/src/board.rs @@ -376,8 +376,8 @@ pub unsafe fn main() { // Staging SRAM platform_regions.push(PlatformRegion { - start_addr: 0xB00C0000 as *const u8, - size: 0x40000, + start_addr: MCU_MEMORY_MAP.staging_sram_offset as *const u8, + size: MCU_MEMORY_MAP.staging_sram_size as usize, is_mmio: true, user_accessible: true, read: true, @@ -449,17 +449,30 @@ pub unsafe fn main() { hil::time::Alarm::set_alarm_client(virtual_alarm_user, alarm); romtime::println!("[mcu-runtime] Alarm initialized"); + let mbox_dma_driver = static_init!( + dma_driver::nodma::NoDMA<'static, InternalTimers<'static>>, + dma_driver::nodma::NoDMA::new(mux_alarm) + ); + let mbox_staging_addr = if cfg!(feature = "hw-2-1") { + Some(MCU_MEMORY_MAP.staging_sram_offset as u64) + } else { + None + }; + let mailbox = mcu_components::mailbox::MailboxComponent::new( board_kernel, capsules_runtime::mailbox::DRIVER_NUM, mux_alarm, + mbox_dma_driver, ) .finalize(mcu_components::mailbox_component_static!( InternalTimers<'static>, Some(MCU_MEMORY_MAP.soc_offset), Some(MCU_MEMORY_MAP.soc_offset), - Some(MCU_MEMORY_MAP.mbox_offset) + Some(MCU_MEMORY_MAP.mbox_offset), + mbox_staging_addr )); + mailbox.alarm.set_alarm_client(mailbox); romtime::println!("[mcu-runtime] Mailbox initialized"); diff --git a/romtime/src/soc_manager.rs b/romtime/src/soc_manager.rs index a7bb29d13..f699022f4 100644 --- a/romtime/src/soc_manager.rs +++ b/romtime/src/soc_manager.rs @@ -2,9 +2,14 @@ use core::mem; -use caliptra_api::{mailbox::MailboxRespHeader, CaliptraApiError, SocManager}; +use caliptra_api::mailbox::Request; +use caliptra_api::{ + mailbox::{ExternalMailboxCmdReq, MailboxRespHeader}, + CaliptraApiError, SocManager, +}; use registers_generated::{mbox, soc}; use ureg::RealMmioMut; +use zerocopy::{transmute, IntoBytes}; const MAILBOX_SIZE: usize = 256 * 1024; pub struct CaliptraSoC { @@ -115,6 +120,34 @@ impl CaliptraSoC { Ok(()) } + pub fn execute_ext_mailbox_req( + &mut self, + cmd: u32, + len_bytes: usize, + staging_axi_addr: u64, + ) -> core::result::Result<(), CaliptraApiError> { + self.lock_mailbox()?; + self.set_command( + ExternalMailboxCmdReq::ID.into(), + core::mem::size_of::(), + )?; + + let mut req = ExternalMailboxCmdReq { + command_id: cmd, + command_size: len_bytes as u32, + axi_address_start_low: staging_axi_addr as u32, + axi_address_start_high: (staging_axi_addr >> 32) as u32, + ..Default::default() + }; + let chksum = caliptra_api::calc_checksum(ExternalMailboxCmdReq::ID.into(), req.as_bytes()); + req.hdr.chksum = chksum; + let words: [u32; core::mem::size_of::() / 4] = transmute!(req); + for word in words { + self.write_data(word)?; + } + self.execute_command() + } + pub fn initiate_request( &mut self, cmd: u32, diff --git a/platforms/emulator/runtime/kernel/drivers/dma/src/hil.rs b/runtime/kernel/capsules/src/dma/hil.rs similarity index 86% rename from platforms/emulator/runtime/kernel/drivers/dma/src/hil.rs rename to runtime/kernel/capsules/src/dma/hil.rs index 5758aea4a..88563a339 100644 --- a/platforms/emulator/runtime/kernel/drivers/dma/src/hil.rs +++ b/runtime/kernel/capsules/src/dma/hil.rs @@ -4,7 +4,7 @@ use kernel::ErrorCode; /// This trait provides the interfaces for managing DMA transfers. -pub trait DMA { +pub trait Dma { /// Configure the DMA transfer with 64-bit source and destination addresses. /// /// # Arguments: @@ -33,13 +33,13 @@ pub trait DMA { ) -> Result<(), ErrorCode>; /// Poll the DMA status for transfer progress or completion. - fn poll_status(&self) -> Result; + fn poll_status(&self) -> Result; /// Push data into the WR FIFO for AHB -> AXI WR transfers. /// /// # Arguments: /// - `data`: Slice of data to be written (as bytes). - fn write_fifo(&self, data: &[u8]) -> Result<(), DMAError>; + fn write_fifo(&self, data: &[u8]) -> Result<(), DmaError>; /// Pop data from the RD FIFO for AXI RD -> AHB transfers. /// @@ -48,10 +48,10 @@ pub trait DMA { /// /// Returns: /// - `Ok(bytes_read)` indicating the number of bytes read. - fn read_fifo(&self, buffer: &mut [u8]) -> Result; + fn read_fifo(&self, buffer: &mut [u8]) -> Result; /// Set a client for receiving DMA transfer events asynchronously. - fn set_client(&self, client: &'static dyn DMAClient); + fn set_client(&self, client: &'static dyn DmaClient); } /// DMA Route configuration for Read/Write routes. @@ -63,7 +63,7 @@ pub enum DmaRoute { /// Represents the current status of the DMA transfer. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum DMAStatus { +pub enum DmaStatus { TxnDone, // Transaction complete RdFifoNotEmpty, // Read FIFO has data RdFifoFull, // Read FIFO is full @@ -73,7 +73,7 @@ pub enum DMAStatus { /// Represents possible DMA errors. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum DMAError { +pub enum DmaError { CommandError, // General command error AxiReadError, // AXI Read error AxiWriteError, // AXI Write error @@ -85,10 +85,10 @@ pub enum DMAError { } /// A client trait for handling asynchronous DMA transfer events. -pub trait DMAClient { +pub trait DmaClient { /// Called when a DMA transfer completes successfully. - fn transfer_complete(&self, status: DMAStatus); + fn transfer_complete(&self, status: DmaStatus); /// Called when a DMA transfer encounters an error. - fn transfer_error(&self, error: DMAError); + fn transfer_error(&self, error: DmaError); } diff --git a/runtime/kernel/capsules/src/dma/mod.rs b/runtime/kernel/capsules/src/dma/mod.rs new file mode 100644 index 000000000..e000e7d3a --- /dev/null +++ b/runtime/kernel/capsules/src/dma/mod.rs @@ -0,0 +1,3 @@ +// Licensed under the Apache-2.0 license + +pub mod hil; diff --git a/runtime/kernel/capsules/src/lib.rs b/runtime/kernel/capsules/src/lib.rs index 9936ec12d..07111083d 100644 --- a/runtime/kernel/capsules/src/lib.rs +++ b/runtime/kernel/capsules/src/lib.rs @@ -5,6 +5,7 @@ pub mod test; +pub mod dma; pub mod doe; pub mod flash_partition; pub mod mailbox; diff --git a/runtime/kernel/capsules/src/mailbox.rs b/runtime/kernel/capsules/src/mailbox.rs index a983144bf..57f4325df 100644 --- a/runtime/kernel/capsules/src/mailbox.rs +++ b/runtime/kernel/capsules/src/mailbox.rs @@ -3,6 +3,7 @@ //! This provides the mailbox capsule that calls the underlying mailbox driver to //! communicate with Caliptra. +use crate::dma::hil::{Dma, DmaRoute, DmaStatus}; use caliptra_api::CaliptraApiError; use core::cell::Cell; use kernel::grant::{AllowRoCount, AllowRwCount, Grant, UpcallCount}; @@ -59,6 +60,12 @@ pub struct Mailbox<'a, A: Alarm<'a>> { current_app: OptionalCell, resp_min_size: Cell, resp_size: Cell, + /// AXI address of the staging SRAM + staging_sram_axi_addr: Option, + current_request_offset: Cell, + current_cmd: Cell, + // DMA peripheral for data transfers + dma_driver: &'static dyn Dma, } impl<'a, A: Alarm<'a>> Mailbox<'a, A> { @@ -71,6 +78,8 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { AllowRwCount<{ rw_allow::COUNT }>, >, driver: &'static mut CaliptraSoC, + staging_sram_axi_addr: Option, + dma_driver: &'static dyn Dma, ) -> Mailbox<'a, A> { Mailbox { alarm, @@ -79,6 +88,10 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { current_app: OptionalCell::empty(), resp_min_size: Cell::new(0), resp_size: Cell::new(0), + staging_sram_axi_addr, + current_request_offset: Cell::new(0), + current_cmd: Cell::new(0), + dma_driver, } } @@ -90,6 +103,7 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { if self.current_app.is_some() { return Err(ErrorCode::BUSY); } + self.current_cmd.set(command); self.apps.enter(processid, |_app, kernel_data| { // copy the request so we can write async kernel_data @@ -115,6 +129,73 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { })? } + fn copy_app_buffer_to_staging_sram( + &self, + app_buffer: &ReadableProcessSlice, + offset: usize, + ) -> Result<(), ErrorCode> { + const CHUNK_SIZE: usize = 256; + const MAX_DMA_POLL_TRIES: usize = 10000; + let buffer_len = app_buffer.len(); + let mut bytes_written = 0; + + // Process in CHUNK_SIZE byte chunks + while bytes_written < buffer_len { + let chunk_len = core::cmp::min(CHUNK_SIZE, buffer_len - bytes_written); + let mut chunk_buf = [0u8; CHUNK_SIZE]; + + if let Some(chunk) = app_buffer.get(bytes_written..bytes_written + chunk_len) { + chunk.copy_to_slice(&mut chunk_buf[..chunk_len]); + + // Configure and execute DMA transfer for this chunk + let src_addr = chunk_buf.as_ptr() as u64; + let dest_addr = + self.staging_sram_axi_addr.unwrap() + (offset + bytes_written) as u64; + self.dma_driver.configure_transfer( + chunk_len, + chunk_len, + Some(src_addr), + Some(dest_addr), + )?; + + // Start the DMA transfer for this chunk + self.dma_driver + .start_transfer(DmaRoute::AxiToAxi, DmaRoute::AxiToAxi, false) + .map_err(|_| ErrorCode::FAIL)?; + + // Poll for completion of this chunk + let mut completed = false; + for _ in 0..MAX_DMA_POLL_TRIES { + match self.dma_driver.poll_status() { + Ok(DmaStatus::TxnDone) => { + completed = true; + break; + } + Ok(_) => continue, + Err(e) => { + debug!("DMA transfer error: {:?}", e); + return Err(ErrorCode::FAIL); + } + } + } + if !completed { + debug!("DMA transfer timed out"); + return Err(ErrorCode::FAIL); + } + + bytes_written += chunk_len; + } else { + debug!( + "Failed to get chunk from app_buffer at offset {}", + bytes_written + ); + return Err(ErrorCode::FAIL); + } + } + + Ok(()) + } + fn start_request( &self, processid: ProcessId, @@ -124,23 +205,39 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { ) -> Result<(), ErrorCode> { self.current_app.set(processid); - // App buffer contains the full payload - match driver.start_mailbox_req( - command, - app_buffer.len(), - app_buffer.chunks(4).map(|chunk| { - let mut dest = [0u8; 4]; - chunk.copy_to_slice(&mut dest); - u32::from_le_bytes(dest) - }), - ) { - Ok(_) => { - self.schedule_alarm(); - Ok(()) + if let Some(staging_axi_addr) = self.staging_sram_axi_addr { + // Copy payload to staging SRAM + self.copy_app_buffer_to_staging_sram(app_buffer, 0)?; + + match driver.execute_ext_mailbox_req(command, app_buffer.len(), staging_axi_addr) { + Ok(_) => { + self.schedule_alarm(); + Ok(()) + } + Err(err) => { + debug!("Error starting mailbox command: {:?}", err); + Err(ErrorCode::FAIL) + } } - Err(err) => { - debug!("Error starting mailbox command: {:?}", err); - Err(ErrorCode::FAIL) + } else { + // Copy payload to mailbox directly + match driver.start_mailbox_req( + command, + app_buffer.len(), + app_buffer.chunks(4).map(|chunk| { + let mut dest = [0u8; 4]; + chunk.copy_to_slice(&mut dest); + u32::from_le_bytes(dest) + }), + ) { + Ok(_) => { + self.schedule_alarm(); + Ok(()) + } + Err(err) => { + debug!("Error starting mailbox command: {:?}", err); + Err(ErrorCode::FAIL) + } } } } @@ -156,13 +253,19 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { return Err(ErrorCode::BUSY); } self.current_app.set(processid); - self.driver - .map(|driver| { - driver - .initiate_request(command, payload_size) - .map_err(|_| ErrorCode::FAIL) - }) - .ok_or(ErrorCode::RESERVE)? + self.current_cmd.set(command); + if self.staging_sram_axi_addr.is_none() { + // If not using staging SRAM, then the mailbox command can be initiated directly. + let _ = self + .driver + .map(|driver| { + driver + .initiate_request(command, payload_size) + .map_err(|_| ErrorCode::FAIL) + }) + .ok_or(ErrorCode::RESERVE)?; + } + Ok(()) } fn send_next_chunk(&self, processid: ProcessId) -> Result<(), ErrorCode> { @@ -180,11 +283,7 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { }) .and_then(|ro_buffer| { ro_buffer - .enter(|app_buffer| { - self.driver - .map(|driver| self.write_chunk(driver, app_buffer)) - .ok_or(ErrorCode::RESERVE)? - }) + .enter(|app_buffer| self.write_chunk(app_buffer)) .map_err(|err| { debug!("Error getting application buffer: {:?}", err); ErrorCode::FAIL @@ -199,23 +298,35 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { })? } - fn write_chunk( - &self, - driver: &mut CaliptraSoC, - app_buffer: &ReadableProcessSlice, - ) -> Result<(), ErrorCode> { - for chunk in app_buffer.chunks(4) { - if chunk.len() == 4 { - let mut buf = [0u8; 4]; - chunk.copy_to_slice(&mut buf); - let data = u32::from_le_bytes(buf); - driver.write_data(data).map_err(|_| ErrorCode::FAIL)?; - } else { - // If the last chunk is not 4 bytes, we can't write it to the mailbox - debug!("Error: Incomplete data chunk in mailbox request"); - return Err(ErrorCode::FAIL); - } + fn write_chunk(&self, app_buffer: &ReadableProcessSlice) -> Result<(), ErrorCode> { + if self.staging_sram_axi_addr.is_none() { + // Copy payload directly to mailbox + let _ = self + .driver + .map(|driver| { + for chunk in app_buffer.chunks(4) { + if chunk.len() == 4 { + let mut buf = [0u8; 4]; + chunk.copy_to_slice(&mut buf); + let data = u32::from_le_bytes(buf); + driver.write_data(data).map_err(|_| ErrorCode::FAIL)?; + } else { + // If the last chunk is not 4 bytes, we can't write it to the mailbox + debug!("Error: Incomplete data chunk in mailbox request"); + return Err(ErrorCode::FAIL); + } + } + Ok(()) + }) + .ok_or(ErrorCode::RESERVE)?; + } else { + // Copy payload to staging SRAM + let offset = self.current_request_offset.get(); + let buffer_len = app_buffer.len(); + self.copy_app_buffer_to_staging_sram(app_buffer, offset)?; + self.current_request_offset.set(offset + buffer_len); } + Ok(()) } @@ -224,15 +335,35 @@ impl<'a, A: Alarm<'a>> Mailbox<'a, A> { if self.current_app.is_none() { return Err(ErrorCode::CANCEL); } - self.driver - .map(|driver| match driver.execute_command() { - Ok(()) => { - self.schedule_alarm(); - Ok(()) - } - Err(_) => Err(ErrorCode::FAIL), - }) - .unwrap_or(Err(ErrorCode::FAIL)) + if let Some(staging_axi_addr) = self.staging_sram_axi_addr { + // If using staging SRAM, execute the command with staging address + self.driver + .map(|driver| { + match driver.execute_ext_mailbox_req( + self.current_cmd.take(), + self.current_request_offset.take(), + staging_axi_addr, + ) { + Ok(()) => { + self.schedule_alarm(); + Ok(()) + } + Err(_) => Err(ErrorCode::FAIL), + } + }) + .unwrap_or(Err(ErrorCode::FAIL))?; + } else { + self.driver + .map(|driver| match driver.execute_command() { + Ok(()) => { + self.schedule_alarm(); + Ok(()) + } + Err(_) => Err(ErrorCode::FAIL), + }) + .unwrap_or(Err(ErrorCode::FAIL))?; + } + Ok(()) } /// Returns number of bytes in response if the response was copied to the app. diff --git a/runtime/kernel/components/src/dma.rs b/runtime/kernel/components/src/dma.rs index 46dfa5109..e79b8a8a3 100644 --- a/runtime/kernel/components/src/dma.rs +++ b/runtime/kernel/components/src/dma.rs @@ -2,21 +2,21 @@ // Component for DMA driver. +use capsules_runtime::dma::hil::Dma as DmaHal; use core::mem::MaybeUninit; -use dma_driver::hil::DMA; use kernel::capabilities; use kernel::component::Component; use kernel::create_capability; pub struct DmaComponent { - driver: &'static dyn dma_driver::hil::DMA, + driver: &'static dyn DmaHal, board_kernel: &'static kernel::Kernel, driver_num: usize, } impl DmaComponent { pub fn new( - driver: &'static dyn DMA, + driver: &'static dyn DmaHal, board_kernel: &'static kernel::Kernel, driver_num: usize, ) -> Self { diff --git a/runtime/kernel/components/src/mailbox.rs b/runtime/kernel/components/src/mailbox.rs index 80ddc2fee..5497cda75 100644 --- a/runtime/kernel/components/src/mailbox.rs +++ b/runtime/kernel/components/src/mailbox.rs @@ -3,6 +3,7 @@ // Component for mailbox capsule. use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; +use capsules_runtime::dma::hil::Dma as DmaHal; use capsules_runtime::mailbox::Mailbox; use core::mem::MaybeUninit; use kernel::capabilities; @@ -13,14 +14,14 @@ use romtime::CaliptraSoC; #[macro_export] macro_rules! mailbox_component_static { - ($A:ty, $b:expr, $c:expr, $d:expr) => {{ + ($A:ty, $b:expr, $c:expr, $d:expr, $e:expr) => {{ use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm; let alarm = kernel::static_buf!(VirtualMuxAlarm<'static, $A>); let caliptra_soc = kernel::static_buf!(CaliptraSoC); let mbox = kernel::static_buf!( capsules_runtime::mailbox::Mailbox<'static, VirtualMuxAlarm<'static, $A>> ); - (alarm, mbox, caliptra_soc, $b, $c, $d) + (alarm, mbox, caliptra_soc, $b, $c, $d, $e) }}; } @@ -28,6 +29,7 @@ pub struct MailboxComponent + 'static> { board_kernel: &'static kernel::Kernel, driver_num: usize, mux_alarm: &'static MuxAlarm<'static, A>, + dma: &'static dyn DmaHal, } impl> MailboxComponent { @@ -35,11 +37,13 @@ impl> MailboxComponent { board_kernel: &'static kernel::Kernel, driver_num: usize, mux_alarm: &'static MuxAlarm<'static, A>, + dma: &'static dyn DmaHal, ) -> Self { Self { board_kernel, driver_num, mux_alarm, + dma, } } } @@ -52,6 +56,7 @@ impl> Component for MailboxComponent { Option, Option, Option, + Option, ); type Output = &'static Mailbox<'static, VirtualMuxAlarm<'static, A>>; @@ -59,6 +64,7 @@ impl> Component for MailboxComponent { fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output { let mux_alarm = static_buffer.0.write(VirtualMuxAlarm::new(self.mux_alarm)); mux_alarm.setup(); + let caliptra_soc = static_buffer.2.write(CaliptraSoC::new( static_buffer.3, static_buffer.4, @@ -73,6 +79,8 @@ impl> Component for MailboxComponent { mux_alarm, self.board_kernel.create_grant(self.driver_num, &grant_cap), caliptra_soc, + static_buffer.6, + self.dma, )); mailbox } diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index 1993358ae..42da6706a 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -40,6 +40,8 @@ mod test { }; use zerocopy::IntoBytes; + const TEST_HW_REVISION: &str = "2.1.0"; + #[derive(Default)] pub struct TestParams<'a> { pub feature: Option<&'a str>, @@ -105,6 +107,9 @@ mod test { if let Some(feature) = feature { features.push(feature); } + if TEST_HW_REVISION == "2.1.0" { + features.push("hw-2-1"); + } let feature = feature.map(|f| format!("-{f}")).unwrap_or_default(); let output = target_binary(&format!("runtime{}-{}.bin", feature, platform())); let output_name = format!("{}", output.display()); diff --git a/tests/integration/src/test_firmware_update.rs b/tests/integration/src/test_firmware_update.rs index d79200c52..c03d6b816 100644 --- a/tests/integration/src/test_firmware_update.rs +++ b/tests/integration/src/test_firmware_update.rs @@ -653,12 +653,6 @@ mod test { lock.fetch_add(1, std::sync::atomic::Ordering::Relaxed); } - // TODO(#694): fails with - // 2025-12-06T00:14:42.314Z INFO [pldm_ua::update_sm] Transfer complete success - // [FW Upd] Verifying Caliptra Bundle - // Error copying from mailbox: MailboxCmdFailed(720898) - // test test_firmware_update::test::test_firmware_update ... FAILED - #[ignore] #[test] fn test_firmware_update() { test_firmware_update_common(true);