Merge pull request #618 from betrusted-io/cram-dev

WIP cram dev branch
This commit is contained in:
bunnie 2025-04-29 03:27:18 +08:00 committed by GitHub
commit 4e95f7d7f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1029 additions and 534 deletions

View file

@ -39,7 +39,8 @@ board-baosec = [
"utralib/cramium-soc",
"ux-api/board-baosec",
] # USB form factor token
loader-baosec = ["camera-ov2640", "display-sh1107", "axp2101", "ux-api"]
loader-baosec = ["camera-ov2640", "display-sh1107", "axp2101", "ux-api/loader-baosec"]
test-baosec = ["ux-api/loader-baosec", "camera-ov2640"]
hosted-baosec = [] # emulated hardware on x86 platform
board-baosor = [
"camera-ov2640",

View file

@ -112,8 +112,8 @@ pub fn setup_memory_pins(iox: &dyn IoSetup) -> SpimChannel {
Some(IoxFunction::AF1),
None,
None,
Some(IoxEnable::Enable),
Some(IoxDriveStrength::Drive4mA),
Some(IoxEnable::Disable),
Some(IoxDriveStrength::Drive12mA),
);
// SPIM_SD[0-3]_A[1]
for i in 7..11 {
@ -124,8 +124,8 @@ pub fn setup_memory_pins(iox: &dyn IoSetup) -> SpimChannel {
Some(IoxFunction::AF1),
None,
None,
Some(IoxEnable::Enable),
Some(IoxDriveStrength::Drive2mA),
Some(IoxEnable::Disable),
Some(IoxDriveStrength::Drive8mA),
);
}
// SPIM_CSN0_A[1]
@ -136,8 +136,8 @@ pub fn setup_memory_pins(iox: &dyn IoSetup) -> SpimChannel {
Some(IoxFunction::AF1),
None,
None,
Some(IoxEnable::Enable),
Some(IoxDriveStrength::Drive2mA),
Some(IoxEnable::Disable),
Some(IoxDriveStrength::Drive8mA),
);
// SPIM_CSN1_A[1]
iox.setup_pin(
@ -147,8 +147,8 @@ pub fn setup_memory_pins(iox: &dyn IoSetup) -> SpimChannel {
Some(IoxFunction::AF1),
None,
None,
Some(IoxEnable::Enable),
Some(IoxDriveStrength::Drive2mA),
Some(IoxEnable::Disable),
Some(IoxDriveStrength::Drive8mA),
);
SpimChannel::Channel1
}

View file

@ -1,6 +1,6 @@
#[cfg(any(feature = "board-baosec", feature = "loader-baosec"))]
#[cfg(any(feature = "board-baosec", feature = "loader-baosec", feature = "test-baosec"))]
pub mod baosec;
#[cfg(any(feature = "board-baosec", feature = "loader-baosec"))]
#[cfg(any(feature = "board-baosec", feature = "loader-baosec", feature = "test-baosec"))]
pub use baosec::*;
#[cfg(any(feature = "board-baosor", feature = "loader-baosor"))]
pub mod baosor;

View file

@ -4,6 +4,7 @@ pub mod payload;
pub use payload::*;
pub mod action;
pub use action::*;
pub mod slider;
pub use slider::*;
pub mod modal;

View file

@ -1,6 +1,7 @@
use core::mem::size_of;
use utra::bio_bdma::SFR_CFGINFO;
use utralib::utra::bio_bdma::SFR_CONFIG_CLOCKING_MODE;
use crate::*;
@ -84,7 +85,7 @@ pub fn filter_test() -> usize {
bio_ss.bio.wo(utra::bio_bdma::SFR_FILTER_BOUNDS_2, (0x6000_0000 - HW_IOX_BASE as u32) >> 12);
// with the filters so set, test some transactions that "should" pass
if dma_basic(false) != 4 {
if dma_basic(false, 0) != 4 {
passing = false;
print!("DMA Filter: allowed transactions are incorrectly blocked");
};
@ -195,11 +196,11 @@ pub fn filter_test() -> usize {
///
/// The `concurrent` flag causes the CPU to do concurrent traffic during the test to
/// exercise contention on AXI bus.
pub fn dma_basic(concurrent: bool) -> usize {
pub fn dma_basic(concurrent: bool, clkmode: u8) -> usize {
const TEST_LEN: usize = 64;
let mut passing = 0;
if !concurrent {
print!("DMA basic\r");
print!("DMA basic2w\r");
} else {
print!("DMA cpu+dma concurrent\r");
}
@ -210,7 +211,13 @@ pub fn dma_basic(concurrent: bool) -> usize {
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(dma_basic_code(), 0, BioCore::Core0);
bio_ss.load_code(dma_basic_code(), 0, BioCore::Core3);
// setup clocking mode option
bio_ss.bio.rmwf(SFR_CONFIG_CLOCKING_MODE, clkmode as u32);
// setup clocking mode option
bio_ss.bio.rmwf(SFR_CONFIG_CLOCKING_MODE, clkmode as u32);
// These actually "don't matter" because there are no synchronization instructions in the code
// Everything runs at "full tilt"
@ -219,7 +226,7 @@ pub fn dma_basic(concurrent: bool) -> usize {
bio_ss.bio.wo(utra::bio_bdma::SFR_QDIV2, 0x1_0000);
bio_ss.bio.wo(utra::bio_bdma::SFR_QDIV3, 0x1_0000);
// start the machine
bio_ss.bio.wo(utra::bio_bdma::SFR_CTRL, 0x111);
bio_ss.bio.wo(utra::bio_bdma::SFR_CTRL, 0x888);
let mut main_mem_src: [u32; TEST_LEN] = [0u32; TEST_LEN];
let mut main_mem_dst: [u32; TEST_LEN] = [0u32; TEST_LEN];
@ -231,19 +238,19 @@ pub fn dma_basic(concurrent: bool) -> usize {
unsafe { core::slice::from_raw_parts_mut((utralib::HW_IFRAM1_MEM + 10000) as *mut u32, TEST_LEN) };
ifram_src.fill(0);
ifram_dst.fill(0);
passing += basic_u32(&mut bio_ss, &mut main_mem_src, &mut main_mem_dst, 0, "Main->main", concurrent);
passing += basic_u32(&mut bio_ss, &mut main_mem_src, &mut main_mem_dst, 0, "m->m", concurrent);
main_mem_src.fill(0);
main_mem_dst.fill(0);
passing += basic_u32(&mut bio_ss, ifram_src, &mut main_mem_dst, 0x40, "ifram0->main", concurrent);
passing += basic_u32(&mut bio_ss, ifram_src, &mut main_mem_dst, 0x40, "i0->m", concurrent);
ifram_src.fill(0);
main_mem_dst.fill(0);
passing += basic_u32(&mut bio_ss, &mut main_mem_src, ifram_dst, 0x80, "Main->ifram1", concurrent);
passing += basic_u32(&mut bio_ss, &mut main_mem_src, ifram_dst, 0x80, "m->i1", concurrent);
main_mem_src.fill(0);
ifram_dst.fill(0);
passing += basic_u32(&mut bio_ss, ifram_src, ifram_dst, 0xC0, "ifram0->ifram1", concurrent);
passing += basic_u32(&mut bio_ss, ifram_src, ifram_dst, 0xC0, "i0->i1", concurrent);
if !concurrent {
print!("DMA basic done.\r");
@ -277,13 +284,32 @@ fn basic_u32(
bio_ss.bio.wo(utra::bio_bdma::SFR_TXF0, (src.len() * size_of::<u32>()) as u32); // bytes to move
while bio_ss.bio.r(utra::bio_bdma::SFR_EVENT_STATUS) & 0x1 == 0 {}
cache_flush();
let mut errs = 0;
for (i, &d) in src.iter().enumerate() {
let rbk = unsafe { dst.as_ptr().add(i).read_volatile() };
if rbk != d {
print!("{} DMA err @{}, {:x} rbk: {:x}\r", name, i, d, rbk);
if errs < 4 {
unsafe {
print!(
"{} @{:x}/{:x}, {:x} rb:{:x}\r",
name,
src.as_ptr().add(i) as usize,
dst.as_ptr().add(i) as usize,
d,
rbk
);
}
} else {
print!("x");
}
errs += 1;
pass = 0;
}
}
if errs > 0 {
print!("\r");
// errs = 0;
}
} else {
// this flushes any read data from the cache, so that the CPU copy is forced to fetch
// the data from memory
@ -318,12 +344,16 @@ bio_code!(dma_basic_code, DMA_BASIC_START, DMA_BASIC_END,
"li x29, 0x1", // clear event done flag - just before the last parameter arrives
"mv a1, x16", // wait for # of bytes to move
"sw x0, 0(a2)", // make sure write pipeline is in a good state
"sw x0, 0(a2)", // make sure write pipeline is in a good state
"add a4, a1, a3", // a4 <- end condition based on source address increment
"30:",
"lw t0, 0(a3)", // blocks until load responds
"sw t0, 0(a2)", // blocks until store completes
"addi a3, a3, 4", // 3 cycles
"sw t0, 0(a2)", // blocks until store completes
"addi a2, a2, 4", // 3 cycles
"bne a3, a4, 30b", // 5 cycles
"li x28, 0x1", // flip event done flag
@ -539,7 +569,7 @@ bio_code!(dma_u16_code, DMA_U16_START, DMA_U16_END,
/// Multi-core DMA copy. More performant, but uses two cores for address generation in
/// parallel with the copy master.
pub fn dma_multicore() -> usize {
pub fn dma_multicore(clkmode: u8) -> usize {
let mut passing = 0;
print!("DMA fast\r");
// clear prior test config state
@ -551,6 +581,9 @@ pub fn dma_multicore() -> usize {
// reset all the fifos
bio_ss.bio.wo(utra::bio_bdma::SFR_FIFO_CLR, 0xF);
// setup clocking mode option
bio_ss.bio.rmwf(SFR_CONFIG_CLOCKING_MODE, clkmode as u32);
// stop all the machines, so that code can be loaded
bio_ss.bio.wo(utra::bio_bdma::SFR_CTRL, 0x0);
bio_ss.load_code(dma_mc_copy_code(), 0, BioCore::Core2);
@ -640,7 +673,7 @@ bio_code!(dma_mc_dst_addr_code, DMA_MC_DST_ADDR_START, DMA_MC_DST_ADDR_END,
);
/// Attempt to fire off all four engines at once, simultaneously, for maximum bus contention
pub fn dma_coincident() -> usize {
pub fn dma_coincident(clkmode: u8) -> usize {
let mut passing = 0;
print!("DMA coincident\r");
// clear prior test config state
@ -651,6 +684,9 @@ pub fn dma_coincident() -> usize {
// reset all the fifos
bio_ss.bio.wo(utra::bio_bdma::SFR_FIFO_CLR, 0xF);
// setup clocking mode option
bio_ss.bio.rmwf(SFR_CONFIG_CLOCKING_MODE, clkmode as u32);
// stop all the machines, so that code can be loaded
bio_ss.bio.wo(utra::bio_bdma::SFR_CTRL, 0x0);
bio_ss.load_code(dma_coincident_code(), 0, BioCore::Core0);
@ -677,14 +713,14 @@ pub fn dma_coincident() -> usize {
ifram_src.fill(0);
ifram_dst.fill(0);
passing += coincident_u32(&mut bio_ss, &mut main_mem_src, &mut main_mem_dst, 0x200, "DMA coincident");
print!("m->m\r");
passing += coincident_u32(&mut bio_ss, &mut main_mem_src, &mut main_mem_dst, 0x200, "m->m");
print!("m->m coincident\r");
// try other memory banks
passing += coincident_u32(&mut bio_ss, ifram_src, &mut main_mem_dst, 0x300, "ifram0->main");
passing += coincident_u32(&mut bio_ss, ifram_src, &mut main_mem_dst, 0x300, "i0->m");
print!("0->m\r");
passing += coincident_u32(&mut bio_ss, &mut main_mem_src, ifram_dst, 0x400, "main->ifram1");
passing += coincident_u32(&mut bio_ss, &mut main_mem_src, ifram_dst, 0x400, "m->i1");
print!("m->1\r");
passing += coincident_u32(&mut bio_ss, ifram_src, ifram_dst, 0x500, "ifram0->ifram1");
passing += coincident_u32(&mut bio_ss, ifram_src, ifram_dst, 0x500, "i0->i1");
print!("0->1\r");
print!("DMA coincident done.\r");
@ -712,13 +748,22 @@ fn coincident_u32(
while bio_ss.bio.r(utra::bio_bdma::SFR_EVENT_STATUS) & 0xF_0000 != 0xF_0000 {} // one bit per core is set on completion of bits 8:12
cache_flush();
let mut pass = 1;
let mut errs = 0;
for (i, &d) in src.iter().enumerate() {
let rbk = unsafe { dst.as_ptr().add(i).read_volatile() };
if rbk != d {
print!("{} err @{}, {:x} rbk: {:x}\r", name, i, d, rbk);
if errs < 4 {
print!("{} err @{}, {:x} rbk: {:x}\r", name, i, d, rbk);
} else {
print!(".");
}
errs += 1;
pass = 0;
}
}
if errs >= 4 {
print!("\r");
}
pass
}
@ -816,7 +861,7 @@ pub fn dmareq_test() -> usize {
bio_ss.bio.wo(utra::bio_bdma::SFR_TXF1, bit as u32);
print!("starting search \r");
for i in 1..15 {
print!("search iter {} \r", i);
print!("{}\r", i);
// send the bit pattern into the event-set via core 0
bio_ss.bio.wo(utra::bio_bdma::SFR_TXF0, i);

View file

@ -88,7 +88,9 @@ pub fn spi_test() -> usize {
print!("dbg pc 2: {:x}\r", bio_ss.bio.r(utra::bio_bdma::SFR_DBG2));
print!("dbg pc 3: {:x}\r", bio_ss.bio.r(utra::bio_bdma::SFR_DBG3));
for (index, &val) in retvals.iter().enumerate() {
print!("SPI rbk {:x}\r", val);
if index < 4 {
print!("SPI rbk {:x}\r", val);
}
// the XOR to 0xAAAA is just a mask we threw in to test immediate loads
assert!(val == ((0xAA00 | index as u32) ^ 0xAAAA));
}

View file

@ -318,13 +318,13 @@ pub fn host_fifo_tests() -> usize {
//
// finally, we're pegged at 15, because, backpressure caused us to miss the rest of
// the entries, and we are stuck at the final written value of the output test
print!("rbk: {:x}\r", rbk);
print!("r {:x}\r", rbk);
if i <= 9 {
assert!(rbk == (0xF1F0_0000 + i));
} else {
assert!(rbk == (0xF1F0_0000 + 15));
}
print!("backpressure {:x}\r", rbk);
print!("bp {:x}\r", rbk);
}
fn get_gpio_via_core(bio_ss: &mut BioSharedState) -> u32 {
@ -390,7 +390,9 @@ pub fn host_fifo_tests() -> usize {
// fifo2 should have the entire log of all values in it. make sure that's the case
for i in 0..7 {
let f2_val = bio_ss.bio.r(utra::bio_bdma::SFR_RXF2);
print!("f2_val {:x}\r", f2_val);
if i > 5 {
print!("f2_val {:x}\r", f2_val);
}
assert!(f2_val == 0xf1f0_1000 + i);
}
let stop_check = bio_ss.bio.r(utra::bio_bdma::SFR_RXF2);
@ -590,7 +592,7 @@ pub fn fifo_level_tests() -> usize {
// reset all the fifos
bio_ss.bio.wo(utra::bio_bdma::SFR_FIFO_CLR, 0xF);
for test_level in 0..FIFO_MAX {
print!("test_level {:x} bank {:x}\r", test_level, bank);
// print!("test_level {:x} bank {:x}\r", test_level, bank);
// test eq at level
bio_ss.bio.wfo(level, test_level);
bio_ss.bio.rmwf(SFR_ETYPE_FIFO_EVENT_EQ_MASK, mask);
@ -886,7 +888,7 @@ pub fn fifo_alias_tests() -> usize {
// reset all the fifos
bio_ss.bio.wo(utra::bio_bdma::SFR_FIFO_CLR, 0xF);
for test_level in 0..FIFO_MAX {
print!("test_level {:x} bank {:x}\r", test_level, bank);
// print!("test_level {:x} bank {:x}\r", test_level, bank);
// test eq at level
bio_ss.bio.wfo(level, test_level);
bio_ss.bio.rmwf(SFR_ETYPE_FIFO_EVENT_EQ_MASK, mask);
@ -1106,7 +1108,7 @@ pub fn event_aliases() -> usize {
let mut passing = 1;
for (i, config) in event_test_configs.iter_mut().enumerate() {
print!(" Checking bank {}...\r", i);
print!(" bnk{}\r", i);
for _ in 0..3 {
// clear all events
bio_ss.bio.wfo(utra::bio_bdma::SFR_EVENT_CLR_SFR_EVENT_CLR, 0xFFFF_FF);

View file

@ -3,7 +3,7 @@
<device schemaVersion="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd" >
<vendor>litex</vendor>
<name>SOC</name>
<description><![CDATA[Litex SoC 2025-01-11 17:47:31]]></description>
<description><![CDATA[Litex SoC 2025-02-08 05:05:20]]></description>
<addressUnitBits>8</addressUnitBits>
<width>32</width>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff