Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Axi bus behind the DMA engine #1878

Merged
merged 11 commits into from
Jan 23, 2025
Next Next commit
hw-model: Revert to proper names
There was confusion on how that the dma engine operated on a axi bus
that replaced the apb bus. This is not true. AXI is a completely
separate bus and the DMA widget is a bridge to it.

Signed-off-by: Arthur Heymans <[email protected]>
ArthurHeymans authored and mhatrevi committed Jan 22, 2025
commit fb359844c911b2030ed8d88c3148cc14bcc09b2c
4 changes: 2 additions & 2 deletions hw-model/c-binding/examples/api/caliptra_api.c
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ int caliptra_init_fuses(struct caliptra_model *model, struct caliptra_fuses *fus
caliptra_fuse_array_write(model, GENERIC_AND_FUSE_REG_FUSE_IDEVID_MANUF_HSM_ID_0, fuses->idevid_manuf_hsm_id, CALIPTRA_ARRAY_SIZE(fuses->idevid_manuf_hsm_id));

// Write to Caliptra Fuse Done
caliptra_model_axi_write_u32(model, EXTERNAL_PERIPH_BASE + CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_FUSE_WR_DONE, 1);
caliptra_model_apb_write_u32(model, EXTERNAL_PERIPH_BASE + CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_FUSE_WR_DONE, 1);

// It shouldn`t be longer ready for fuses
if (caliptra_model_ready_for_fuses(model))
@@ -48,7 +48,7 @@ int caliptra_bootfsm_go(struct caliptra_model *model)
}

// Write BOOTFSM_GO Register
caliptra_model_axi_write_u32(model, EXTERNAL_PERIPH_BASE + CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_BOOTFSM_GO, 1);
caliptra_model_apb_write_u32(model, EXTERNAL_PERIPH_BASE + CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_BOOTFSM_GO, 1);

return 0;
}
2 changes: 1 addition & 1 deletion hw-model/c-binding/examples/api/caliptra_fuses.h
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ extern "C" {

static inline void caliptra_fuse_write(caliptra_model *model, uint32_t offset, uint32_t data)
{
caliptra_model_axi_write_u32(model, EXTERNAL_PERIPH_BASE + (offset + CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_BASE_ADDR), data);
caliptra_model_apb_write_u32(model, EXTERNAL_PERIPH_BASE + (offset + CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_BASE_ADDR), data);
}

static inline void caliptra_fuse_array_write(caliptra_model *model, uint32_t offset, uint32_t *data, size_t size)
4 changes: 2 additions & 2 deletions hw-model/c-binding/examples/api/caliptra_mbox.h
Original file line number Diff line number Diff line change
@@ -13,13 +13,13 @@ extern "C" {

static inline void caliptra_mbox_write(caliptra_model *model, uint32_t offset, uint32_t data)
{
caliptra_model_axi_write_u32(model, EXTERNAL_PERIPH_BASE + (offset + CALIPTRA_TOP_REG_MBOX_CSR_BASE_ADDR), data);
caliptra_model_apb_write_u32(model, EXTERNAL_PERIPH_BASE + (offset + CALIPTRA_TOP_REG_MBOX_CSR_BASE_ADDR), data);
}

static inline uint32_t caliptra_mbox_read(caliptra_model *model, uint32_t offset)
{
uint32_t data;
caliptra_model_axi_read_u32(model, EXTERNAL_PERIPH_BASE + (offset + CALIPTRA_TOP_REG_MBOX_CSR_BASE_ADDR), &data);
caliptra_model_apb_read_u32(model, EXTERNAL_PERIPH_BASE + (offset + CALIPTRA_TOP_REG_MBOX_CSR_BASE_ADDR), &data);
return data;
}

8 changes: 4 additions & 4 deletions hw-model/c-binding/src/caliptra_model.rs
Original file line number Diff line number Diff line change
@@ -72,15 +72,15 @@ pub unsafe extern "C" fn caliptra_model_destroy(model: *mut caliptra_model) {

/// # Safety
#[no_mangle]
pub unsafe extern "C" fn caliptra_model_axi_read_u32(
pub unsafe extern "C" fn caliptra_model_apb_read_u32(
model: *mut caliptra_model,
addr: c_uint,
data: *mut c_uint,
) -> c_int {
// Parameter check
assert!(!model.is_null() || !data.is_null());
*data = (*{ model as *mut DefaultHwModel })
.axi_bus()
.apb_bus()
.read(RvSize::Word, addr)
.unwrap();

@@ -89,15 +89,15 @@ pub unsafe extern "C" fn caliptra_model_axi_read_u32(

/// # Safety
#[no_mangle]
pub unsafe extern "C" fn caliptra_model_axi_write_u32(
pub unsafe extern "C" fn caliptra_model_apb_write_u32(
model: *mut caliptra_model,
addr: c_uint,
data: c_uint,
) -> c_int {
// Parameter check
assert!(!model.is_null());
(*{ model as *mut DefaultHwModel })
.axi_bus()
.apb_bus()
.write(RvSize::Word, addr, data)
.unwrap();

14 changes: 7 additions & 7 deletions hw-model/src/lib.rs
Original file line number Diff line number Diff line change
@@ -634,11 +634,11 @@ pub trait HwModel: SocManager {
self.soc_ifc().cptra_bootfsm_go().write(|w| w.go(true));
}

/// The AXI bus from the SoC to Caliptra
/// The APB bus from the SoC to Caliptra
///
/// WARNING: Reading or writing to this bus may involve the Caliptra
/// microcontroller executing a few instructions
fn axi_bus(&mut self) -> Self::TBus<'_>;
fn apb_bus(&mut self) -> Self::TBus<'_>;

/// Step execution ahead one clock cycle.
fn step(&mut self);
@@ -667,7 +667,7 @@ pub trait HwModel: SocManager {

/// Returns true if the microcontroller has signalled that it is ready for
/// firmware to be written to the mailbox. For RTL implementations, this
/// should come via a caliptra_top wire rather than an AXI register.
/// should come via a caliptra_top wire rather than an APB register.
fn ready_for_fw(&self) -> bool;

/// Initializes the fuse values and locks them in until the next reset. This
@@ -1153,21 +1153,21 @@ mod tests {
.write(|w| w.lock(true));

assert_eq!(
model.axi_bus().read(RvSize::Word, MBOX_ADDR_LOCK).unwrap(),
model.apb_bus().read(RvSize::Word, MBOX_ADDR_LOCK).unwrap(),
0
);

assert_eq!(
model.axi_bus().read(RvSize::Word, MBOX_ADDR_LOCK).unwrap(),
model.apb_bus().read(RvSize::Word, MBOX_ADDR_LOCK).unwrap(),
1
);

model
.axi_bus()
.apb_bus()
.write(RvSize::Word, MBOX_ADDR_CMD, 4242)
.unwrap();
assert_eq!(
model.axi_bus().read(RvSize::Word, MBOX_ADDR_CMD).unwrap(),
model.apb_bus().read(RvSize::Word, MBOX_ADDR_CMD).unwrap(),
4242
);
}
14 changes: 7 additions & 7 deletions hw-model/src/model_emulated.rs
Original file line number Diff line number Diff line change
@@ -30,11 +30,11 @@ use crate::TrngMode;
use caliptra_emu_bus::{Bus, BusMmio};

use caliptra_api::soc_mgr::SocManager;
pub struct EmulatedAxiBus<'a> {
pub struct EmulatedApbBus<'a> {
model: &'a mut ModelEmulated,
}

impl<'a> Bus for EmulatedAxiBus<'a> {
impl<'a> Bus for EmulatedApbBus<'a> {
fn read(&mut self, size: RvSize, addr: RvAddr) -> Result<RvData, caliptra_emu_bus::BusError> {
let result = self.model.soc_to_caliptra_bus.read(size, addr);
self.model.cpu.bus.log_read("SoC", size, addr, result);
@@ -109,14 +109,14 @@ fn hash_slice(slice: &[u8]) -> u64 {
}

impl SocManager for ModelEmulated {
type TMmio<'a> = BusMmio<EmulatedAxiBus<'a>>;
type TMmio<'a> = BusMmio<EmulatedApbBus<'a>>;

fn delay(&mut self) {
self.step();
}

fn mmio_mut(&mut self) -> Self::TMmio<'_> {
BusMmio::new(self.axi_bus())
BusMmio::new(self.apb_bus())
}

const SOC_IFC_ADDR: u32 = 0x3003_0000;
@@ -128,7 +128,7 @@ impl SocManager for ModelEmulated {
}

impl HwModel for ModelEmulated {
type TBus<'a> = EmulatedAxiBus<'a>;
type TBus<'a> = EmulatedApbBus<'a>;

fn new_unbooted(params: InitParams) -> Result<Self, Box<dyn Error>>
where
@@ -228,8 +228,8 @@ impl HwModel for ModelEmulated {
fn ready_for_fw(&self) -> bool {
self.ready_for_fw.get()
}
fn axi_bus(&mut self) -> Self::TBus<'_> {
EmulatedAxiBus { model: self }
fn apb_bus(&mut self) -> Self::TBus<'_> {
EmulatedApbBus { model: self }
}

fn step(&mut self) {
4 changes: 2 additions & 2 deletions hw-model/src/model_fpga_realtime.rs
Original file line number Diff line number Diff line change
@@ -334,7 +334,7 @@ impl SocManager for ModelFpgaRealtime {
type TMmio<'a> = BusMmio<FpgaRealtimeBus<'a>>;

fn mmio_mut(&mut self) -> Self::TMmio<'_> {
BusMmio::new(self.axi_bus())
BusMmio::new(self.apb_bus())
}

fn delay(&mut self) {
@@ -344,7 +344,7 @@ impl SocManager for ModelFpgaRealtime {
impl HwModel for ModelFpgaRealtime {
type TBus<'a> = FpgaRealtimeBus<'a>;

fn axi_bus(&mut self) -> Self::TBus<'_> {
fn apb_bus(&mut self) -> Self::TBus<'_> {
FpgaRealtimeBus {
mmio: self.mmio,
phantom: Default::default(),
18 changes: 9 additions & 9 deletions hw-model/src/model_verilated.rs
Original file line number Diff line number Diff line change
@@ -22,15 +22,15 @@ const DEFAULT_AXI_PAUSER: u32 = 0x1;
// How many clock cycles before emitting a TRNG nibble
const TRNG_DELAY: u32 = 4;

pub struct VerilatedAxiBus<'a> {
pub struct VerilatedApbBus<'a> {
model: &'a mut ModelVerilated,
}
impl<'a> Bus for VerilatedAxiBus<'a> {
impl<'a> Bus for VerilatedApbBus<'a> {
fn read(&mut self, size: RvSize, addr: RvAddr) -> Result<RvData, caliptra_emu_bus::BusError> {
if addr & 0x3 != 0 {
return Err(caliptra_emu_bus::BusError::LoadAddrMisaligned);
}
let result = Ok(self.model.v.axi_read_u32(self.model.soc_axi_pauser, addr));
let result = Ok(self.model.v.apb_read_u32(self.model.soc_axi_pauser, addr));
self.model
.log
.borrow_mut()
@@ -53,7 +53,7 @@ impl<'a> Bus for VerilatedAxiBus<'a> {
}
self.model
.v
.axi_write_u32(self.model.soc_axi_pauser, addr, val);
.apb_write_u32(self.model.soc_axi_pauser, addr, val);
self.model
.log
.borrow_mut()
@@ -113,10 +113,10 @@ fn ahb_txn_size(ty: AhbTxnType) -> RvSize {
}
}
impl SocManager for ModelVerilated {
type TMmio<'a> = BusMmio<VerilatedAxiBus<'a>>;
type TMmio<'a> = BusMmio<VerilatedApbBus<'a>>;

fn mmio_mut(&mut self) -> Self::TMmio<'_> {
BusMmio::new(self.axi_bus())
BusMmio::new(self.apb_bus())
}

fn delay(&mut self) {
@@ -132,7 +132,7 @@ impl SocManager for ModelVerilated {
}

impl HwModel for ModelVerilated {
type TBus<'a> = VerilatedAxiBus<'a>;
type TBus<'a> = VerilatedApbBus<'a>;

fn new_unbooted(params: crate::InitParams) -> Result<Self, Box<dyn std::error::Error>>
where
@@ -271,8 +271,8 @@ impl HwModel for ModelVerilated {
self.trng_mode
}

fn axi_bus(&mut self) -> Self::TBus<'_> {
VerilatedAxiBus { model: self }
fn apb_bus(&mut self) -> Self::TBus<'_> {
VerilatedApbBus { model: self }
}

fn step(&mut self) {
4 changes: 2 additions & 2 deletions libcaliptra/examples/hwmodel/interface.c
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ int caliptra_write_u32(uint32_t address, uint32_t data)
{
struct caliptra_model *m = hwmod_get_or_init();

int result = caliptra_model_axi_write_u32(m, address, (int)data);
int result = caliptra_model_apb_write_u32(m, address, (int)data);

caliptra_model_step(m);

@@ -90,7 +90,7 @@ int caliptra_write_u32(uint32_t address, uint32_t data)
*/
int caliptra_read_u32(uint32_t address, uint32_t *data)
{
return caliptra_model_axi_read_u32(hwmod_get_or_init(), address, (uint*)data);
return caliptra_model_apb_read_u32(hwmod_get_or_init(), address, (uint*)data);
}

/**
4 changes: 2 additions & 2 deletions test/dpe_verification/transport.go
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ var CALIPTRA_C_MODEL *C.struct_caliptra_model

//export caliptra_write_u32
func caliptra_write_u32(address C.uint32_t, data C.uint32_t) C.int {
result := C.caliptra_model_axi_write_u32(CALIPTRA_C_MODEL, address, data)
result := C.caliptra_model_apb_write_u32(CALIPTRA_C_MODEL, address, data)

C.caliptra_model_step(CALIPTRA_C_MODEL)

@@ -77,7 +77,7 @@ func caliptra_write_u32(address C.uint32_t, data C.uint32_t) C.int {

//export caliptra_read_u32
func caliptra_read_u32(address C.uint32_t, data *C.uint32_t) C.int {
return C.caliptra_model_axi_read_u32(CALIPTRA_C_MODEL, address, data)
return C.caliptra_model_apb_read_u32(CALIPTRA_C_MODEL, address, data)
}

//export caliptra_wait
18 changes: 9 additions & 9 deletions test/tests/fips_test_suite/security_parameters.rs
Original file line number Diff line number Diff line change
@@ -27,11 +27,11 @@ fn prove_jtag_inaccessible<T: HwModel>(_hw: &mut T) {
fn attempt_csp_fuse_read<T: HwModel>(hw: &mut T) {
let uds_ptr = hw.soc_ifc().fuse_uds_seed().at(0).ptr;
let uds_read_val =
unsafe { caliptra_hw_model::BusMmio::new(hw.axi_bus()).read_volatile(uds_ptr) };
unsafe { caliptra_hw_model::BusMmio::new(hw.apb_bus()).read_volatile(uds_ptr) };

let field_entropy_ptr = hw.soc_ifc().fuse_field_entropy().at(0).ptr;
let field_entropy_read_val =
unsafe { caliptra_hw_model::BusMmio::new(hw.axi_bus()).read_volatile(field_entropy_ptr) };
unsafe { caliptra_hw_model::BusMmio::new(hw.apb_bus()).read_volatile(field_entropy_ptr) };

// TODO: Add exception for SW emulator (does not model locked registers at the MMIO level)
assert_eq!(uds_read_val, INACCESSIBLE_READ_VALUE);
@@ -45,7 +45,7 @@ fn attempt_psp_fuse_modify<T: HwModel>(hw: &mut T) {
// Try to write a new value
let owner_pk_hash_ptr = hw.soc_ifc().fuse_key_manifest_pk_hash().at(0).ptr;
unsafe {
caliptra_hw_model::BusMmio::new(hw.axi_bus()).write_volatile(owner_pk_hash_ptr, 0xaaaaaaaa)
caliptra_hw_model::BusMmio::new(hw.apb_bus()).write_volatile(owner_pk_hash_ptr, 0xaaaaaaaa)
};

let owner_pk_hash_read_val = hw.soc_ifc().fuse_key_manifest_pk_hash().at(0).read();
@@ -62,17 +62,17 @@ fn attempt_keyvault_access<T: HwModel>(hw: &mut T) {
// This is not visible to the SoC, but shared modules (mailbox, SHA engine, etc.) use a 1:1
// address mapping between the SoC and Caliptra
let kv_key_ctrl_val =
unsafe { caliptra_hw_model::BusMmio::new(hw.axi_bus()).read_volatile(kv_key_ctrl_ptr) };
unsafe { caliptra_hw_model::BusMmio::new(hw.apb_bus()).read_volatile(kv_key_ctrl_ptr) };
assert_eq!(kv_key_ctrl_val, INACCESSIBLE_READ_VALUE);

// Attempt to write
unsafe {
caliptra_hw_model::BusMmio::new(hw.axi_bus()).write_volatile(kv_key_ctrl_ptr, 0xffffffff)
caliptra_hw_model::BusMmio::new(hw.apb_bus()).write_volatile(kv_key_ctrl_ptr, 0xffffffff)
};

// Read again
let kv_key_ctrl_val =
unsafe { caliptra_hw_model::BusMmio::new(hw.axi_bus()).read_volatile(kv_key_ctrl_ptr) };
unsafe { caliptra_hw_model::BusMmio::new(hw.apb_bus()).read_volatile(kv_key_ctrl_ptr) };
assert_eq!(kv_key_ctrl_val, INACCESSIBLE_READ_VALUE);
}

@@ -83,14 +83,14 @@ fn attempt_caliptra_dccm_access<T: HwModel>(hw: &mut T) {
// Attempt to read DCCM module from the SoC side
// This is not visible to the SoC, but shared modules (mailbox, SHA engine, etc.) use a 1:1
// address mapping between the SoC and Caliptra
let dccm_val = unsafe { caliptra_hw_model::BusMmio::new(hw.axi_bus()).read_volatile(dccm_ptr) };
let dccm_val = unsafe { caliptra_hw_model::BusMmio::new(hw.apb_bus()).read_volatile(dccm_ptr) };
assert_eq!(dccm_val, INACCESSIBLE_READ_VALUE);

// Attempt to write
unsafe { caliptra_hw_model::BusMmio::new(hw.axi_bus()).write_volatile(dccm_ptr, 0xffffffff) };
unsafe { caliptra_hw_model::BusMmio::new(hw.apb_bus()).write_volatile(dccm_ptr, 0xffffffff) };

// Read again
let dccm_val = unsafe { caliptra_hw_model::BusMmio::new(hw.axi_bus()).read_volatile(dccm_ptr) };
let dccm_val = unsafe { caliptra_hw_model::BusMmio::new(hw.apb_bus()).read_volatile(dccm_ptr) };
assert_eq!(dccm_val, INACCESSIBLE_READ_VALUE);
}