Skip to content

Commit

Permalink
Fix driver/dma: Operate on 64bit addresses (#1861)
Browse files Browse the repository at this point in the history
This fixes the driver side to operate on 64bit AXI addresses.
  • Loading branch information
ArthurHeymans authored Dec 19, 2024
1 parent 5f88202 commit 1186ca8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 33 deletions.
60 changes: 34 additions & 26 deletions drivers/src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,26 @@ use zerocopy::AsBytes;
pub enum DmaReadTarget {
Mbox,
AhbFifo,
AxiWr(usize),
AxiWr(AxiAddr),
}

#[derive(Debug, Clone, Copy)]
pub struct AxiAddr {
pub lo: u32,
pub hi: u32,
}

impl From<u64> for AxiAddr {
fn from(addr: u64) -> Self {
Self {
lo: addr as u32,
hi: (addr >> 32) as u32,
}
}
}

pub struct DmaReadTransaction {
pub read_addr: usize,
pub read_addr: AxiAddr,
pub fixed_addr: bool,
pub length: u32,
pub target: DmaReadTarget,
Expand All @@ -35,11 +50,11 @@ pub struct DmaReadTransaction {
pub enum DmaWriteOrigin {
Mbox,
AhbFifo,
AxiRd(usize),
AxiRd(AxiAddr),
}

pub struct DmaWriteTransaction {
pub write_addr: usize,
pub write_addr: AxiAddr,
pub fixed_addr: bool,
pub length: u32,
pub origin: DmaWriteOrigin,
Expand Down Expand Up @@ -78,16 +93,13 @@ impl Dma {
fn setup_dma_read(&mut self, read_transaction: DmaReadTransaction) {
let dma = self.dma.regs_mut();

let read_addr: usize = read_transaction.read_addr;
#[cfg(target_pointer_width = "64")]
dma.src_addr_h().write(|_| (read_addr >> 32) as u32);
dma.src_addr_l().write(|_| (read_addr & 0xffff_ffff) as u32);
let read_addr = read_transaction.read_addr;
dma.src_addr_l().write(|_| read_addr.lo);
dma.src_addr_h().write(|_| read_addr.hi);

if let DmaReadTarget::AxiWr(target_addr) = read_transaction.target {
#[cfg(target_pointer_width = "64")]
dma.dst_addr_h().write(|_| (target_addr >> 32) as u32);
dma.dst_addr_l()
.write(|_| (target_addr & 0xffff_ffff) as u32);
dma.dst_addr_l().write(|_| target_addr.lo);
dma.dst_addr_h().write(|_| target_addr.hi);
}

dma.ctrl().modify(|c| {
Expand All @@ -110,16 +122,12 @@ impl Dma {
let dma = self.dma.regs_mut();

let write_addr = write_transaction.write_addr;
#[cfg(target_pointer_width = "64")]
dma.dst_addr_h().write(|_| (write_addr >> 32) as u32);
dma.dst_addr_l()
.write(|_| (write_addr & 0xffff_ffff) as u32);
dma.dst_addr_l().write(|_| write_addr.lo);
dma.dst_addr_h().write(|_| write_addr.hi);

if let DmaWriteOrigin::AxiRd(origin_addr) = write_transaction.origin {
#[cfg(target_pointer_width = "64")]
dma.dst_addr_h().write(|_| (origin_addr >> 32) as u32);
dma.dst_addr_l()
.write(|_| (origin_addr & 0xffff_ffff) as u32);
dma.dst_addr_l().write(|_| origin_addr.lo);
dma.dst_addr_h().write(|_| origin_addr.hi);
}

dma.ctrl().modify(|c| {
Expand Down Expand Up @@ -193,18 +201,18 @@ impl Dma {

let status0 = dma.status0().read();
if status0.busy() {
return Err(CaliptraError::DRIVER_DMA_TRANSACTION_ALREADY_BUSY);
Err(CaliptraError::DRIVER_DMA_TRANSACTION_ALREADY_BUSY)?;
}

if status0.error() {
return Err(CaliptraError::DRIVER_DMA_TRANSACTION_ERROR);
Err(CaliptraError::DRIVER_DMA_TRANSACTION_ERROR)?;
}

dma.ctrl().modify(|c| c.go(true));

while dma.status0().read().busy() {
if dma.status0().read().error() {
return Err(CaliptraError::DRIVER_DMA_TRANSACTION_ERROR);
Err(CaliptraError::DRIVER_DMA_TRANSACTION_ERROR)?;
}
}

Expand All @@ -220,7 +228,7 @@ impl Dma {
/// # Returns
///
/// * `CaliptraResult<u32>` - Read value or error code
pub fn read_dword(&mut self, read_addr: usize) -> CaliptraResult<u32> {
pub fn read_dword(&mut self, read_addr: AxiAddr) -> CaliptraResult<u32> {
let mut read_val: u32 = 0;

self.flush();
Expand Down Expand Up @@ -248,7 +256,7 @@ impl Dma {
/// # Returns
///
/// * `CaliptraResult<()>` - Success or error code
pub fn write_dword(&mut self, write_addr: usize, write_val: u32) -> CaliptraResult<()> {
pub fn write_dword(&mut self, write_addr: AxiAddr, write_val: u32) -> CaliptraResult<()> {
self.flush();

let write_transaction = DmaWriteTransaction {
Expand Down Expand Up @@ -279,7 +287,7 @@ impl Dma {
/// * `CaliptraResult<()>` - Success or error code
pub fn transfer_payload_to_mbox(
&mut self,
read_addr: usize,
read_addr: AxiAddr,
payload_len_bytes: u32,
fixed_addr: bool,
block_size: u32,
Expand Down
4 changes: 3 additions & 1 deletion drivers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ pub use bounded_address::{BoundedAddr, MemBounds, RomAddr};
pub use caliptra_error::{CaliptraError, CaliptraResult};
pub use csrng::{Csrng, HealthFailCounts as CsrngHealthFailCounts, Seed as CsrngSeed};
pub use data_vault::{ColdResetEntries, DataVault, WarmResetEntries};
pub use dma::{Dma, DmaReadTarget, DmaReadTransaction, DmaWriteOrigin, DmaWriteTransaction};
pub use dma::{
AxiAddr, Dma, DmaReadTarget, DmaReadTransaction, DmaWriteOrigin, DmaWriteTransaction,
};
pub use doe::DeobfuscationEngine;
pub use ecc384::{
Ecc384, Ecc384PrivKeyIn, Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Result, Ecc384Scalar,
Expand Down
17 changes: 11 additions & 6 deletions drivers/test-fw/src/bin/dma_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Abstract:
#![no_std]
#![no_main]

use caliptra_drivers::{memory_layout, Dma, Mailbox};
use caliptra_drivers::{memory_layout, AxiAddr, Dma, Mailbox};
use caliptra_registers::{axi_dma::AxiDmaReg, ecc::EccReg, mbox::MboxCsr};
use caliptra_test_harness::test_suite;
use core::slice;
Expand All @@ -27,7 +27,7 @@ fn test_dma_read_from_periph() {
let ecc_regs = unsafe { EccReg::new() };
let ecc_name = ecc_regs.regs().name().ptr();

let dword = dma.read_dword(ecc_name as usize).unwrap();
let dword = dma.read_dword(AxiAddr::from(ecc_name as u64)).unwrap();
assert_eq!(dword.to_ne_bytes(), [0x70, 0x63, 0x65, 0x73]); // secp
}

Expand All @@ -40,8 +40,8 @@ fn test_dma_write_to_periph() {

let data: u32 = 0xdead_beef;

dma.write_dword(ecc_iv as usize, data).unwrap();
let dword = dma.read_dword(ecc_iv as usize).unwrap();
dma.write_dword(AxiAddr::from(ecc_iv as u64), data).unwrap();
let dword = dma.read_dword(AxiAddr::from(ecc_iv as u64)).unwrap();
assert_eq!(dword, data);
}

Expand All @@ -59,8 +59,13 @@ fn test_read_rri_to_mailbox() {
let mut txn = mbox_driver.try_start_send_txn().unwrap();
txn.send_request(0xdead_beef, b"").unwrap();

dma.transfer_payload_to_mbox(rri_regs, test_image.len() as u32, true, block_size)
.unwrap();
dma.transfer_payload_to_mbox(
AxiAddr::from(rri_regs as u64),
test_image.len() as u32,
true,
block_size,
)
.unwrap();

let mbox_fifo = unsafe {
slice::from_raw_parts(
Expand Down

0 comments on commit 1186ca8

Please sign in to comment.