Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions common/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions emulator/periph/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 14 additions & 20 deletions emulator/periph/src/axicdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
29 changes: 29 additions & 0 deletions emulator/periph/src/mcu_mbox0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8> {
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}");
Expand Down Expand Up @@ -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<u32, registers_generated::mbox::bits::MboxLock::Register>
Expand Down
49 changes: 12 additions & 37 deletions emulator/periph/src/root_bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8> = 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 {
Expand All @@ -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<u8> = 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 {
Expand Down Expand Up @@ -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<u8> = data
.chunks(4)
.flat_map(|chunk| {
if chunk.len() == 4 {
chunk.iter().rev().cloned().collect::<Vec<u8>>()
} else {
chunk.to_vec()
}
})
.collect();

if let Some(event_sender) = self.event_sender.as_ref() {
event_sender
.send(Event {
Expand Down
3 changes: 3 additions & 0 deletions platforms/emulator/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
2 changes: 1 addition & 1 deletion platforms/emulator/runtime/kernel/capsules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 8 additions & 10 deletions platforms/emulator/runtime/kernel/capsules/src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -36,15 +37,15 @@ 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<App, UpcallCount<1>, AllowRoCount<0>, AllowRwCount<0>>,
current_app: OptionalCell<ProcessId>,
}

impl<'a> Dma<'a> {
pub fn new(
driver: &'a dyn dma_driver::hil::DMA,
driver: &'a dyn DmaHal,
grant: Grant<App, UpcallCount<1>, AllowRoCount<0>, AllowRwCount<0>>,
) -> Dma<'a> {
Dma {
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down
1 change: 1 addition & 0 deletions platforms/emulator/runtime/kernel/drivers/dma/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading