Skip to content

Commit

Permalink
Merge pull request #586 from betrusted-io/biobdma-timing
Browse files Browse the repository at this point in the history
Biobdma timing
  • Loading branch information
bunnie authored Sep 26, 2024
2 parents a40aa11 + ab41cbc commit 66c3656
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 6 deletions.
3 changes: 3 additions & 0 deletions libs/xous-bio-bdma/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ hosted = []
renode = []
# may be activated in conjunction with "cramium-soc", "rp2040" targets when not running Xous
baremetal = []
std = []
arty = []
bio-mul = []

tests = []
default = ["tests", "cramium-soc"]
81 changes: 81 additions & 0 deletions libs/xous-bio-bdma/src/bio_tests/arith.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,84 @@ bio_code!(stack_test2_code, STACK_TEST2_START, STACK_TEST2_END,
"add sp, sp, 8",
"ret"
);

#[cfg(feature = "bio-mul")]
/// Safety: Only safe if the target BIO has the multiply extension
pub unsafe fn mac_test() -> usize {
print!("MAC test\r");
// clear prior test config state
let mut test_cfg = CSR::new(utra::csrtest::HW_CSRTEST_BASE as *mut u32);
test_cfg.wo(utra::csrtest::WTEST, 0);

let mut bio_ss = BioSharedState::new();
// stop all the machines, so that code can be loaded
bio_ss.bio.wo(utra::bio_bdma::SFR_CTRL, 0x0);
bio_ss.load_code(mac_code(), 0, BioCore::Core0);

// These actually "don't matter" because there are no synchronization instructions in the code
// Everything runs at "full tilt"
bio_ss.bio.wo(utra::bio_bdma::SFR_QDIV0, 0x0);
bio_ss.bio.wo(utra::bio_bdma::SFR_CTRL, 0x111);

// a test vector
let a: [i32; 7] = [1, -1, 3047, 0, 12, -92101, 12432];
let b = 7;
let check = mac(&a, b);

// pass values to fifo; fifo is 8-deep, so this should fit without checking depth
bio_ss.bio.wo(utra::bio_bdma::SFR_TXF0, a.len() as u32);
bio_ss.bio.wo(utra::bio_bdma::SFR_TXF0, b as u32);
for v in a.iter() {
bio_ss.bio.wo(utra::bio_bdma::SFR_TXF0, *v as u32);
}
// wait for the computation to return
while bio_ss.bio.rf(utra::bio_bdma::SFR_FLEVEL_PCLK_REGFIFO_LEVEL1) == 0 {}
let result = bio_ss.bio.r(utra::bio_bdma::SFR_RXF1) as i32;
print!("Got {}\r", result);
if result != check {
print!("Computed {}, should be {}\r", result, check);
print!("===MAC test FAIL===\r");
0
} else {
print!("===MAC test PASS===\r");
1
}
}

/// the recursive function implemented below
#[cfg(feature = "bio-mul")]
fn mac(a: &[i32], b: i32) -> i32 {
let mut r: i32 = 0;
for &v in a.iter() {
r += v * b;
}
r
}

#[rustfmt::skip]
#[cfg(feature = "bio-mul")]
bio_code!(mac_code, MAC_START, MAC_END,
// first arg into x16 is the number of elements to MAC
// second arg is the coefficient
// remaining args are the vector
// compute mac = a0 * b + a1 * b + a2 * b ...
// return value is in x17
"20:",
"mv a0, x16", // number of elements
"mv a1, x16", // coefficient
"mv a2, x0", // initialize return value
"jal ra, 30f",
"mv x17, a2", // return the value
"j 20b", // go back for more
"30:",
"bne x0, a0, 31f", // test if end
"ret",
"31:",
"addi a0, a0, -1", // decrement arg counter
"mv t1, x16", // fetch vector value: note, we can't multiply directly from a FIFO because while the multi-cycle multiply runs, the FIFO keeps draining
// "mul t0, a1, t1", // multiply
// mul x5, x11, x6, same as above. hand-assembled because Rust refuses to emit `mul` instructions for global_asm!
".word 0x026582b3",
"add a2, t0, a2", // accumulate
"j 30b" // loop
);
27 changes: 23 additions & 4 deletions libs/xous-bio-bdma/src/bio_tests/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,19 @@ pub fn dma_filter_off() {

pub fn filter_test() -> usize {
print!("==Filter test==\r");
// clear any prior test config state
let mut test_cfg = CSR::new(utra::csrtest::HW_CSRTEST_BASE as *mut u32);
test_cfg.wo(utra::csrtest::WTEST, 0);

let mut passing = true;
use utralib::generated::HW_SRAM_MEM as RAM_BASE;
use utralib::generated::HW_SRAM_MEM_LEN as RAM_SIZE;

let mut bio_ss = BioSharedState::new();
bio_ss.bio.wo(utra::bio_bdma::SFR_CTRL, 0x0);
// reset all the fifos
bio_ss.bio.wo(utra::bio_bdma::SFR_FIFO_CLR, 0xF);

// enable the filters
bio_ss.bio.rmwf(utra::bio_bdma::SFR_CONFIG_DISABLE_FILTER_MEM, 0);
bio_ss.bio.rmwf(utra::bio_bdma::SFR_CONFIG_DISABLE_FILTER_PERI, 0);
Expand Down Expand Up @@ -85,6 +93,14 @@ pub fn filter_test() -> usize {
// *** increments 3 ret values total
// - access to the BIO_BDMA registers: try to disable the filters.
print!("attempt to violate peri filter\r");
if bio_ss.bio.rf(utra::bio_bdma::SFR_CONFIG_DISABLE_FILTER_MEM) != 0 {
passing = false;
print!("peri range filter pre-condition fail A\r");
}
if bio_ss.bio.rf(utra::bio_bdma::SFR_CONFIG_DISABLE_FILTER_PERI) != 0 {
passing = false;
print!("peri range filter pre-condition fail B\r");
}
cache_flush();
let naughty_dma_ptr: &mut [u32] = unsafe {
core::slice::from_raw_parts_mut(
Expand All @@ -102,11 +118,11 @@ pub fn filter_test() -> usize {
// check that the values did not change
if bio_ss.bio.rf(utra::bio_bdma::SFR_CONFIG_DISABLE_FILTER_MEM) != 0 {
passing = false;
print!("peri range filter FAIL\r");
print!("peri range filter FAIL A\r");
}
if bio_ss.bio.rf(utra::bio_bdma::SFR_CONFIG_DISABLE_FILTER_PERI) != 0 {
passing = false;
print!("peri range filter FAIL\r");
print!("peri range filter FAIL B\r");
}
// attempt to read the config word
bio_ss.bio.wo(
Expand All @@ -117,9 +133,12 @@ pub fn filter_test() -> usize {
bio_ss.bio.wo(utra::bio_bdma::SFR_TXF0, 4); // initiate a single transfer
while bio_ss.bio.r(utra::bio_bdma::SFR_EVENT_STATUS) & 0x1 == 0 {}
cache_flush();
if target[0] != 0x0 {
let tval = target[0];
if tval == 0x1000_0408 {
passing = false;
print!("peri range read filter FAIL\r")
print!("peri range read filter FAIL target[0]->{:x} got a correct value of 0x10000408\r", tval);
} else {
print!("CFGINFO returned {:x}, != 0x10000408\r", tval);
}
print!("peri violation test done\r");

Expand Down
5 changes: 3 additions & 2 deletions libs/xous-bio-bdma/src/bio_tests/units.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,8 +1032,9 @@ pub fn aclk_tests() -> usize {
print!("{}: {} cycles\r", i, r);
}
assert!(results[1] - results[0] == 3);
assert!(results[2] - results[1] == 3);
assert!(results[3] - results[2] == 6);
// variability is due to option for REGISTER_MEM or not
assert!((results[2] - results[1] == 3) || (results[2] - results[1] == 4));
assert!((results[3] - results[2] == 6) || (results[3] - results[2] == 7));
assert!(results[4] - results[3] == 3);

assert!(results[6] - results[5] == 10); // related to the clock divider
Expand Down

0 comments on commit 66c3656

Please sign in to comment.