mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
make TRNG testing variants easier to configure
This commit is contained in:
parent
9f9575fdd8
commit
ec2a87e306
7 changed files with 232 additions and 342 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
|
@ -1457,19 +1457,6 @@ dependencies = [
|
|||
"xous-names",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trng-tester"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"heapless",
|
||||
"log",
|
||||
"log-server",
|
||||
"ticktimer-server",
|
||||
"typenum",
|
||||
"utralib",
|
||||
"xous",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ default-members = [
|
|||
"services/shellchat",
|
||||
"services/llio",
|
||||
"services/rtc",
|
||||
"services/trng-tester",
|
||||
"services/cb-test-srv",
|
||||
"services/cb-test-c1",
|
||||
"services/cb-test-c2",
|
||||
|
|
@ -55,7 +54,6 @@ members = [
|
|||
"services/content-plugin-api",
|
||||
"services/llio",
|
||||
"services/rtc",
|
||||
"services/trng-tester",
|
||||
"services/cb-test-srv",
|
||||
"services/cb-test-c1",
|
||||
"services/cb-test-c2",
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
[package]
|
||||
name = "trng-tester"
|
||||
version = "0.1.0"
|
||||
authors = ["bunnie <bunnie@kosagi.com>"]
|
||||
edition = "2018"
|
||||
description = "TRNG tester"
|
||||
|
||||
[dependencies]
|
||||
xous = { path = "../../xous-rs" }
|
||||
heapless = "0.5"
|
||||
log-server = { path = "../log-server" }
|
||||
ticktimer-server = { path = "../ticktimer-server" }
|
||||
log = "0.4"
|
||||
typenum = "1.12"
|
||||
|
||||
[target.'cfg(not(any(windows,unix)))'.dependencies]
|
||||
utralib = { path = "../../utralib"}
|
||||
|
||||
[target.'cfg(any(windows,unix))'.dependencies]
|
||||
|
||||
[features]
|
||||
debugprint = []
|
||||
default = [] # "debugprint"
|
||||
#default = ["debugprint"]
|
||||
|
|
@ -1,265 +0,0 @@
|
|||
#![cfg_attr(target_os = "none", no_std)]
|
||||
#![cfg_attr(target_os = "none", no_main)]
|
||||
|
||||
use log::info;
|
||||
|
||||
pub enum WhichMessible {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
pub const TRNG_BUFF_LEN: usize = 512*1024;
|
||||
|
||||
#[cfg(target_os = "none")]
|
||||
mod implementation {
|
||||
use utralib::generated::*;
|
||||
use xous::MemoryRange;
|
||||
use crate::WhichMessible;
|
||||
|
||||
pub struct Trng {
|
||||
server_csr: utralib::CSR<u32>,
|
||||
messible_csr: utralib::CSR<u32>,
|
||||
messible2_csr: utralib::CSR<u32>,
|
||||
buffer_a: MemoryRange,
|
||||
buffer_b: MemoryRange,
|
||||
}
|
||||
|
||||
fn handle_irq(_irq_no: usize, arg: *mut usize) {
|
||||
let trng = unsafe { &mut *(arg as *mut Trng) };
|
||||
// just clear the pending request, as this is used as a "wait" until request function
|
||||
trng.server_csr.wo(utra::trng_server::EV_PENDING, trng.server_csr.r(utra::trng_server::EV_PENDING));
|
||||
}
|
||||
|
||||
impl Trng {
|
||||
pub fn new() -> Trng {
|
||||
let server_csr = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(utra::trng_server::HW_TRNG_SERVER_BASE),
|
||||
None,
|
||||
4096,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map TRNG Server CSR range");
|
||||
|
||||
let buff_a = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(0x4020_0000), // fix this at a known physical address
|
||||
None,
|
||||
crate::TRNG_BUFF_LEN,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map TRNG comms buffer A");
|
||||
|
||||
let buff_b = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(0x4030_0000), // fix this at a known physical address
|
||||
None,
|
||||
crate::TRNG_BUFF_LEN,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map TRNG comms buffer B");
|
||||
|
||||
let messible = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(utra::messible::HW_MESSIBLE_BASE),
|
||||
None,
|
||||
4096,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map messible");
|
||||
|
||||
let messible2 = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(utra::messible2::HW_MESSIBLE2_BASE),
|
||||
None,
|
||||
4096,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map messible");
|
||||
|
||||
let mut trng = Trng {
|
||||
server_csr: CSR::new(server_csr.as_mut_ptr() as *mut u32),
|
||||
buffer_a: buff_a,
|
||||
buffer_b: buff_b,
|
||||
messible_csr: CSR::new(messible.as_mut_ptr() as *mut u32),
|
||||
messible2_csr: CSR::new(messible2.as_mut_ptr() as *mut u32),
|
||||
};
|
||||
|
||||
xous::claim_interrupt(
|
||||
utra::trng_server::TRNG_SERVER_IRQ,
|
||||
handle_irq,
|
||||
(&mut trng) as *mut Trng as *mut usize,
|
||||
)
|
||||
.expect("couldn't claim irq");
|
||||
|
||||
trng
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
///// configure power settings and which generator to use
|
||||
self.server_csr.wo(utra::trng_server::CONTROL,
|
||||
self.server_csr.ms(utra::trng_server::CONTROL_ENABLE, 1)
|
||||
| self.server_csr.ms(utra::trng_server::CONTROL_POWERSAVE, 0)
|
||||
// | self.server_csr.ms(utra::trng_server::CONTROL_AV_DIS, 1) // disable the AV generator to characterize the RO
|
||||
// | self.server_csr.ms(utra::trng_server::CONTROL_RO_DIS, 1) // disable the RO to characterize only the AV
|
||||
);
|
||||
|
||||
///// configure avalanche
|
||||
// delay in microseconds for avalanche poweron after powersave
|
||||
// self.server_csr.rmwf(utra::trng_server::AV_CONFIG_POWERDELAY, 50_000);
|
||||
self.server_csr.wo(utra::trng_server::AV_CONFIG,
|
||||
self.server_csr.ms(utra::trng_server::AV_CONFIG_POWERDELAY, 50_000)
|
||||
| self.server_csr.ms(utra::trng_server::AV_CONFIG_SAMPLES, 32)
|
||||
);
|
||||
|
||||
///// configure ring oscillator
|
||||
self.server_csr.wo(utra::trng_server::RO_CONFIG,
|
||||
self.server_csr.ms(utra::trng_server::RO_CONFIG_DELAY, 4)
|
||||
| self.server_csr.ms(utra::trng_server::RO_CONFIG_DWELL, 100)
|
||||
| self.server_csr.ms(utra::trng_server::RO_CONFIG_GANG, 1)
|
||||
| self.server_csr.ms(utra::trng_server::RO_CONFIG_FUZZ, 1)
|
||||
| self.server_csr.ms(utra::trng_server::RO_CONFIG_OVERSAMPLING, 3)
|
||||
)
|
||||
|
||||
/* historical note -- for modular noise variants -- do not remove
|
||||
self.xadc_csr.rmwf(utra::trng::MODNOISE_CTL_PERIOD, 495); // to set just the period
|
||||
|
||||
self.xadc_csr.wo(utra::trng::MODNOISE_CTL, // to set also the deadtime
|
||||
self.xadc_csr.ms(utra::trng::MODNOISE_CTL_ENA, 1)
|
||||
| self.xadc_csr.ms(utra::trng::MODNOISE_CTL_PERIOD, 64)
|
||||
| self.xadc_csr.ms(utra::trng::MODNOISE_CTL_DEADTIME, 5)
|
||||
);*/
|
||||
}
|
||||
|
||||
pub fn messible_send(&mut self, which: WhichMessible, value: u8) {
|
||||
match which {
|
||||
WhichMessible::One => self.messible_csr.wfo(utra::messible::IN_IN, value as u32),
|
||||
WhichMessible::Two => self.messible2_csr.wfo(utra::messible2::IN_IN, value as u32),
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn messible_get(&mut self, which: WhichMessible) -> u8 {
|
||||
match which {
|
||||
WhichMessible::One => self.messible_csr.rf(utra::messible::OUT_OUT) as u8,
|
||||
WhichMessible::Two => self.messible2_csr.rf(utra::messible2::OUT_OUT) as u8,
|
||||
}
|
||||
}
|
||||
pub fn messible_wait_get(&mut self, which: WhichMessible) -> u8 {
|
||||
match which {
|
||||
WhichMessible::One => {
|
||||
while self.messible_csr.rf(utra::messible::STATUS_HAVE) == 0 {
|
||||
xous::yield_slice();
|
||||
}
|
||||
self.messible_csr.rf(utra::messible::OUT_OUT) as u8
|
||||
},
|
||||
WhichMessible::Two => {
|
||||
while self.messible2_csr.rf(utra::messible2::STATUS_HAVE) == 0 {
|
||||
xous::yield_slice();
|
||||
}
|
||||
self.messible2_csr.rf(utra::messible2::OUT_OUT) as u8
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_buff_a(&self) -> *mut u32 {
|
||||
self.buffer_a.as_mut_ptr() as *mut u32
|
||||
}
|
||||
pub fn get_buff_b(&self) -> *mut u32 {
|
||||
self.buffer_b.as_mut_ptr() as *mut u32
|
||||
}
|
||||
|
||||
pub fn get_data_eager(&self) -> u32 {
|
||||
while self.server_csr.rf(utra::trng_server::STATUS_AVAIL) == 0 {
|
||||
xous::yield_slice();
|
||||
}
|
||||
self.server_csr.rf(utra::trng_server::DATA_DATA)
|
||||
}
|
||||
pub fn wait_full(&self) {
|
||||
while self.server_csr.rf(utra::trng_server::STATUS_FULL) == 0 {
|
||||
xous::yield_slice();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a stub to try to avoid breaking hosted mode for as long as possible.
|
||||
#[cfg(not(target_os = "none"))]
|
||||
mod implementation {
|
||||
pub struct Trng {
|
||||
}
|
||||
|
||||
impl Trng {
|
||||
pub fn new() -> Trng {
|
||||
Trng {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn messible_send(&mut self, which: WhichMessible, value: u32) {
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wdt_thread() {
|
||||
let ticktimer = ticktimer_server::Ticktimer::new().expect("Couldn't connect to Ticktimer");
|
||||
|
||||
loop {
|
||||
ticktimer.sleep_ms(100).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[xous::xous_main]
|
||||
fn xmain() -> ! {
|
||||
use crate::implementation::Trng;
|
||||
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
info!("my PID is {}", xous::process::id());
|
||||
|
||||
let ticktimer = ticktimer_server::Ticktimer::new().expect("Couldn't connect to Ticktimer");
|
||||
|
||||
xous::create_thread_0(wdt_thread).expect("couldn't create waking thread");
|
||||
|
||||
// Create a new com object
|
||||
let mut trng = Trng::new();
|
||||
trng.init();
|
||||
// just create buffers out of pointers. Definitely. Unsafe.
|
||||
let buff_a = trng.get_buff_a() as *mut u32;
|
||||
let buff_b = trng.get_buff_b() as *mut u32;
|
||||
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
// buff_a[i] = trng.get_data_eager();
|
||||
unsafe { buff_a.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
// buff_b[i] = trng.get_data_eager();
|
||||
unsafe { buff_b.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
info!("TRNG: starting service");
|
||||
let mut phase = 1;
|
||||
trng.messible_send(WhichMessible::One, phase); // indicate buffer A is ready to go
|
||||
|
||||
loop {
|
||||
if false {
|
||||
// to test the powerdown feature
|
||||
trng.wait_full();
|
||||
ticktimer.sleep_ms(5000).expect("couldn't sleep");
|
||||
}
|
||||
|
||||
// to test the full loop
|
||||
trng.messible_wait_get(WhichMessible::Two);
|
||||
phase += 1;
|
||||
if phase % 2 == 1 {
|
||||
info!("TRNG: filling A");
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
//buff_a[i] = trng.get_data_eager();
|
||||
unsafe { buff_a.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
trng.messible_send(WhichMessible::One, phase);
|
||||
} else {
|
||||
info!("TRNG: filling B");
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
//buff_b[i] = trng.get_data_eager();
|
||||
unsafe { buff_b.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
trng.messible_send(WhichMessible::One, phase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,4 +21,6 @@ utralib = { path = "../../utralib"}
|
|||
|
||||
[features]
|
||||
debugprint = []
|
||||
avalanchetest = []
|
||||
ringosctest = []
|
||||
default = [] # "debugprint"
|
||||
|
|
|
|||
|
|
@ -34,12 +34,38 @@ mod implementation {
|
|||
};
|
||||
|
||||
///// configure power settings and which generator to use
|
||||
trng.csr.wo(utra::trng_server::CONTROL,
|
||||
trng.csr.ms(utra::trng_server::CONTROL_ENABLE, 1)
|
||||
| trng.csr.ms(utra::trng_server::CONTROL_POWERSAVE, 1)
|
||||
// | self.server_csr.ms(utra::trng_server::CONTROL_AV_DIS, 1) // disable the AV generator to characterize the RO
|
||||
// | self.server_csr.ms(utra::trng_server::CONTROL_RO_DIS, 1) // disable the RO to characterize only the AV
|
||||
);
|
||||
if !(cfg!(feature = "avalanchetest") || cfg!(feature = "ringosctest")) {
|
||||
trng.csr.wo(utra::trng_server::CONTROL,
|
||||
trng.csr.ms(utra::trng_server::CONTROL_ENABLE, 1)
|
||||
| trng.csr.ms(utra::trng_server::CONTROL_POWERSAVE, 1)
|
||||
// | self.server_csr.ms(utra::trng_server::CONTROL_AV_DIS, 1) // disable the AV generator to characterize the RO
|
||||
// | self.server_csr.ms(utra::trng_server::CONTROL_RO_DIS, 1) // disable the RO to characterize only the AV
|
||||
);
|
||||
log::trace!("TRNG configured for normal operation (av+ro): 0x{:08x}", trng.csr.r(utra::trng_server::CONTROL));
|
||||
} else if cfg!(feature = "avalanchetest") && ! cfg!(feature = "ringosctest") {
|
||||
// avalanche test only
|
||||
trng.csr.wo(utra::trng_server::CONTROL,
|
||||
trng.csr.ms(utra::trng_server::CONTROL_ENABLE, 1)
|
||||
| trng.csr.ms(utra::trng_server::CONTROL_POWERSAVE, 1) // question: do we want power save on or off for testing?? let's leave it on for now, it will make the test run slower but maybe more accurate to our usual use case
|
||||
| trng.csr.ms(utra::trng_server::CONTROL_RO_DIS, 1) // disable the RO to characterize only the AV
|
||||
);
|
||||
log::info!("TRNG configured for avalanche testing: 0x{:08x}", trng.csr.r(utra::trng_server::CONTROL));
|
||||
} else if ! cfg!(feature = "avalanchetest") && cfg!(feature = "ringosctest") {
|
||||
// ring osc test only
|
||||
trng.csr.wo(utra::trng_server::CONTROL,
|
||||
trng.csr.ms(utra::trng_server::CONTROL_ENABLE, 1)
|
||||
| trng.csr.ms(utra::trng_server::CONTROL_POWERSAVE, 1)
|
||||
| trng.csr.ms(utra::trng_server::CONTROL_AV_DIS, 1) // disable the AV generator to characterize the RO
|
||||
);
|
||||
log::info!("TRNG configured for ring oscillator testing: 0x{:08x}", trng.csr.r(utra::trng_server::CONTROL));
|
||||
} else {
|
||||
// both on
|
||||
trng.csr.wo(utra::trng_server::CONTROL,
|
||||
trng.csr.ms(utra::trng_server::CONTROL_ENABLE, 1)
|
||||
| trng.csr.ms(utra::trng_server::CONTROL_POWERSAVE, 1)
|
||||
);
|
||||
log::info!("TRNG configured for both avalanche and ring oscillator testing: 0x{:08x}", trng.csr.r(utra::trng_server::CONTROL));
|
||||
}
|
||||
|
||||
/*** TRNG tuning parameters: these were configured and tested in a long run against Dieharder
|
||||
There is a rate of TRNG generation vs. quality trade-off. The tuning below is toward quality of
|
||||
|
|
@ -65,6 +91,11 @@ mod implementation {
|
|||
|
||||
trng
|
||||
}
|
||||
// for the test procedure
|
||||
#[cfg(any(feature = "avalanchetest", feature="ringosctest"))]
|
||||
pub fn get_trng_csr(&self) -> *mut u32 {
|
||||
self.csr.base
|
||||
}
|
||||
|
||||
pub fn get_data_eager(&self) -> u32 {
|
||||
while self.csr.rf(utra::trng_server::STATUS_AVAIL) == 0 {
|
||||
|
|
@ -145,6 +176,166 @@ mod implementation {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "avalanchetest", feature="ringosctest"))]
|
||||
pub const TRNG_BUFF_LEN: usize = 512*1024;
|
||||
#[cfg(any(feature = "avalanchetest", feature="ringosctest"))]
|
||||
pub enum WhichMessible {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
#[cfg(any(feature = "avalanchetest", feature="ringosctest"))]
|
||||
struct Tester {
|
||||
server_csr: utralib::CSR<u32>,
|
||||
messible_csr: utralib::CSR<u32>,
|
||||
messible2_csr: utralib::CSR<u32>,
|
||||
buffer_a: xous::MemoryRange,
|
||||
buffer_b: xous::MemoryRange,
|
||||
ticktimer: ticktimer_server::Ticktimer,
|
||||
}
|
||||
#[cfg(any(feature = "avalanchetest", feature="ringosctest"))]
|
||||
impl Tester {
|
||||
pub fn new(server_csr: *mut u32) -> Tester {
|
||||
use utralib::generated::*;
|
||||
let buff_a = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(0x4020_0000), // fix this at a known physical address
|
||||
None,
|
||||
crate::TRNG_BUFF_LEN,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map TRNG comms buffer A");
|
||||
|
||||
let buff_b = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(0x4030_0000), // fix this at a known physical address
|
||||
None,
|
||||
crate::TRNG_BUFF_LEN,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map TRNG comms buffer B");
|
||||
|
||||
let messible = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(utra::messible::HW_MESSIBLE_BASE),
|
||||
None,
|
||||
4096,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map messible");
|
||||
|
||||
let messible2 = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(utra::messible2::HW_MESSIBLE2_BASE),
|
||||
None,
|
||||
4096,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map messible");
|
||||
|
||||
Tester {
|
||||
server_csr: CSR::new(server_csr),
|
||||
buffer_a: buff_a,
|
||||
buffer_b: buff_b,
|
||||
messible_csr: CSR::new(messible.as_mut_ptr() as *mut u32),
|
||||
messible2_csr: CSR::new(messible2.as_mut_ptr() as *mut u32),
|
||||
ticktimer: ticktimer_server::Ticktimer::new().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn messible_send(&mut self, which: WhichMessible, value: u8) {
|
||||
use utralib::generated::*;
|
||||
match which {
|
||||
WhichMessible::One => self.messible_csr.wfo(utra::messible::IN_IN, value as u32),
|
||||
WhichMessible::Two => self.messible2_csr.wfo(utra::messible2::IN_IN, value as u32),
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn messible_get(&mut self, which: WhichMessible) -> u8 {
|
||||
use utralib::generated::*;
|
||||
match which {
|
||||
WhichMessible::One => self.messible_csr.rf(utra::messible::OUT_OUT) as u8,
|
||||
WhichMessible::Two => self.messible2_csr.rf(utra::messible2::OUT_OUT) as u8,
|
||||
}
|
||||
}
|
||||
pub fn messible_wait_get(&mut self, which: WhichMessible) -> u8 {
|
||||
use utralib::generated::*;
|
||||
match which {
|
||||
WhichMessible::One => {
|
||||
while self.messible_csr.rf(utra::messible::STATUS_HAVE) == 0 {
|
||||
//xous::yield_slice();
|
||||
self.ticktimer.sleep_ms(50).unwrap();
|
||||
}
|
||||
self.messible_csr.rf(utra::messible::OUT_OUT) as u8
|
||||
},
|
||||
WhichMessible::Two => {
|
||||
while self.messible2_csr.rf(utra::messible2::STATUS_HAVE) == 0 {
|
||||
//xous::yield_slice();
|
||||
self.ticktimer.sleep_ms(50).unwrap();
|
||||
}
|
||||
self.messible2_csr.rf(utra::messible2::OUT_OUT) as u8
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_buff_a(&self) -> *mut u32 {
|
||||
self.buffer_a.as_mut_ptr() as *mut u32
|
||||
}
|
||||
pub fn get_buff_b(&self) -> *mut u32 {
|
||||
self.buffer_b.as_mut_ptr() as *mut u32
|
||||
}
|
||||
|
||||
pub fn get_data_eager(&self) -> u32 {
|
||||
use utralib::generated::*;
|
||||
while self.server_csr.rf(utra::trng_server::STATUS_AVAIL) == 0 {
|
||||
xous::yield_slice();
|
||||
}
|
||||
self.server_csr.rf(utra::trng_server::DATA_DATA)
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn wait_full(&self) {
|
||||
use utralib::generated::*;
|
||||
while self.server_csr.rf(utra::trng_server::STATUS_FULL) == 0 {
|
||||
xous::yield_slice();
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(any(feature = "avalanchetest", feature="ringosctest"))]
|
||||
fn tester_thread(csr: usize) {
|
||||
let mut trng = Tester::new(csr as *mut u32);
|
||||
|
||||
// just create buffers out of pointers. Definitely. Unsafe.
|
||||
let buff_a = trng.get_buff_a() as *mut u32;
|
||||
let buff_b = trng.get_buff_b() as *mut u32;
|
||||
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
// buff_a[i] = trng.get_data_eager();
|
||||
unsafe { buff_a.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
// buff_b[i] = trng.get_data_eager();
|
||||
unsafe { buff_b.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
log::info!("TRNG_TESTER: starting service");
|
||||
let mut phase = 1;
|
||||
trng.messible_send(WhichMessible::One, phase); // indicate buffer A is ready to go
|
||||
|
||||
loop {
|
||||
trng.messible_wait_get(WhichMessible::Two);
|
||||
phase += 1;
|
||||
if phase % 2 == 1 {
|
||||
log::info!("TRNG_TESTER: filling A");
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
//buff_a[i] = trng.get_data_eager();
|
||||
unsafe { buff_a.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
trng.messible_send(WhichMessible::One, phase);
|
||||
} else {
|
||||
log::info!("TRNG_TESTER: filling B");
|
||||
for i in 0..TRNG_BUFF_LEN / 4 {
|
||||
//buff_b[i] = trng.get_data_eager();
|
||||
unsafe { buff_b.add(i).write_volatile(trng.get_data_eager()) };
|
||||
}
|
||||
trng.messible_send(WhichMessible::One, phase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[xous::xous_main]
|
||||
fn xmain() -> ! {
|
||||
use crate::implementation::Trng;
|
||||
|
|
@ -163,6 +354,10 @@ fn xmain() -> ! {
|
|||
#[cfg(not(target_os = "none"))]
|
||||
let mut trng = Trng::new();
|
||||
|
||||
if cfg!(feature = "avalanchetest") || cfg!(feature = "ringosctest") {
|
||||
xous::create_thread_1(tester_thread, trng.get_trng_csr() as usize).expect("couldn't create test thread");
|
||||
}
|
||||
|
||||
// pump the TRNG hardware to clear the first number out, sometimes it is 0 due to clock-sync issues on the fifo
|
||||
trng.get_trng(2);
|
||||
log::trace!("ready to accept requests");
|
||||
|
|
|
|||
|
|
@ -90,22 +90,6 @@ fn try_main() -> Result<(), DynError> {
|
|||
"cb-test-c1",
|
||||
"cb-test-c2",
|
||||
];
|
||||
let trng_pkgs = [
|
||||
//"gam",
|
||||
//"shellchat",
|
||||
//"ime-frontend",
|
||||
//"ime-plugin-shell",
|
||||
"graphics-server",
|
||||
"ticktimer-server",
|
||||
"log-server",
|
||||
"com",
|
||||
"xous-names",
|
||||
"keyboard",
|
||||
"llio",
|
||||
"rtc",
|
||||
|
||||
"trng-tester",
|
||||
];
|
||||
let task = env::args().nth(1);
|
||||
match task.as_deref() {
|
||||
Some("renode-image") => renode_image(false, &hw_pkgs)?,
|
||||
|
|
@ -115,12 +99,17 @@ fn try_main() -> Result<(), DynError> {
|
|||
)?,
|
||||
Some("renode-image-debug") => renode_image(true, &hw_pkgs)?,
|
||||
Some("run") => run(false, &hw_pkgs)?,
|
||||
Some("hw-image") => build_hw_image(false, env::args().nth(2), &hw_pkgs)?,
|
||||
Some("benchmark") => build_hw_image(false, env::args().nth(2), &benchmark_pkgs)?,
|
||||
Some("fcc-agent") => build_hw_image(false, env::args().nth(2), &fcc_pkgs)?,
|
||||
Some("minimal") => build_hw_image(false, env::args().nth(2), &minimal_pkgs)?,
|
||||
Some("cbtest") => build_hw_image(false, env::args().nth(2), &cbtest_pkgs)?,
|
||||
Some("trng-test") => build_hw_image(false, env::args().nth(2), &trng_pkgs)?,
|
||||
Some("hw-image") => build_hw_image(false, env::args().nth(2), &hw_pkgs, None)?,
|
||||
Some("benchmark") => build_hw_image(false, env::args().nth(2), &benchmark_pkgs, None)?,
|
||||
Some("fcc-agent") => build_hw_image(false, env::args().nth(2), &fcc_pkgs, None)?,
|
||||
Some("minimal") => build_hw_image(false, env::args().nth(2), &minimal_pkgs, None)?,
|
||||
Some("cbtest") => build_hw_image(false, env::args().nth(2), &cbtest_pkgs, None)?,
|
||||
Some("trng-test") => build_hw_image(false, env::args().nth(2), &hw_pkgs,
|
||||
Some(&["--features", "ringosctest", "--features", "avalanchetest"]))?,
|
||||
Some("ro-test") => build_hw_image(false, env::args().nth(2), &hw_pkgs,
|
||||
Some(&["--features", "ringosctest"]))?,
|
||||
Some("av-test") => build_hw_image(false, env::args().nth(2), &hw_pkgs,
|
||||
Some(&["--features", "avalanchetest"]))?,
|
||||
Some("debug") => run(true, &hw_pkgs)?,
|
||||
_ => print_help(),
|
||||
}
|
||||
|
|
@ -140,12 +129,14 @@ benchmark [soc.svd] builds a benchmarking image for real hardware
|
|||
fcc-agent [soc.svd] builds a version suitable for FCC testing
|
||||
minimal [soc.svd] builds a minimal image for API testing
|
||||
cbtest builds an image for callback testing
|
||||
trng-test [soc.svd] builds an image for TRNG testing
|
||||
trng-test [soc.svd] builds an image for TRNG testing (both avalanche and ring oscillator on)
|
||||
ro-test [soc.svd] builds an image for ring oscillator only TRNG testing
|
||||
av-test [soc.svd] builds an image for avalanche generater only TRNG testing
|
||||
"
|
||||
)
|
||||
}
|
||||
|
||||
fn build_hw_image(debug: bool, svd: Option<String>, packages: &[&str]) -> Result<(), DynError> {
|
||||
fn build_hw_image(debug: bool, svd: Option<String>, packages: &[&str], extra_args: Option<&[&str]>) -> Result<(), DynError> {
|
||||
let svd_file = match svd {
|
||||
Some(s) => s,
|
||||
None => return Err("svd file not specified".into()),
|
||||
|
|
@ -163,13 +154,13 @@ fn build_hw_image(debug: bool, svd: Option<String>, packages: &[&str]) -> Result
|
|||
|
||||
let kernel = build_kernel(debug)?;
|
||||
let mut init = vec![];
|
||||
let base_path = build(packages, debug, Some(TARGET), None)?;
|
||||
let base_path = build(packages, debug, Some(TARGET), None, extra_args)?;
|
||||
for pkg in packages {
|
||||
let mut pkg_path = base_path.clone();
|
||||
pkg_path.push(pkg);
|
||||
init.push(pkg_path);
|
||||
}
|
||||
let mut loader = build(&["loader"], debug, Some(TARGET), Some("loader".into()))?;
|
||||
let mut loader = build(&["loader"], debug, Some(TARGET), Some("loader".into()), None)?;
|
||||
loader.push(PathBuf::from("loader"));
|
||||
|
||||
let output_bundle = create_image(&kernel, &init, debug, MemorySpec::SvdFile(svd_file))?;
|
||||
|
|
@ -192,8 +183,7 @@ fn build_hw_image(debug: bool, svd: Option<String>, packages: &[&str]) -> Result
|
|||
"--",
|
||||
loader.as_os_str().to_str().unwrap(),
|
||||
loader_bin.as_os_str().to_str().unwrap(),
|
||||
])
|
||||
.status()?;
|
||||
]).status()?;
|
||||
if !status.success() {
|
||||
return Err("cargo build failed".into());
|
||||
}
|
||||
|
|
@ -221,13 +211,13 @@ fn renode_image(debug: bool, packages: &[&str]) -> Result<(), DynError> {
|
|||
std::env::set_var("XOUS_SVD_FILE", path.canonicalize().unwrap());
|
||||
let kernel = build_kernel(debug)?;
|
||||
let mut init = vec![];
|
||||
let base_path = build(packages, debug, Some(TARGET), None)?;
|
||||
let base_path = build(packages, debug, Some(TARGET), None, None)?;
|
||||
for pkg in packages {
|
||||
let mut pkg_path = base_path.clone();
|
||||
pkg_path.push(pkg);
|
||||
init.push(pkg_path);
|
||||
}
|
||||
build(&["loader"], debug, Some(TARGET), Some("loader".into()))?;
|
||||
build(&["loader"], debug, Some(TARGET), Some("loader".into()), None)?;
|
||||
|
||||
create_image(
|
||||
&kernel,
|
||||
|
|
@ -242,7 +232,7 @@ fn renode_image(debug: bool, packages: &[&str]) -> Result<(), DynError> {
|
|||
fn run(debug: bool, init: &[&str]) -> Result<(), DynError> {
|
||||
let stream = if debug { "debug" } else { "release" };
|
||||
|
||||
build(&init, debug, None, None)?;
|
||||
build(&init, debug, None, None, None)?;
|
||||
|
||||
// Build and run the kernel
|
||||
let mut args = vec!["run"];
|
||||
|
|
@ -283,7 +273,7 @@ fn run(debug: bool, init: &[&str]) -> Result<(), DynError> {
|
|||
}
|
||||
|
||||
fn build_kernel(debug: bool) -> Result<PathBuf, DynError> {
|
||||
let mut path = build(&["kernel"], debug, Some(TARGET), Some("kernel".into()))?;
|
||||
let mut path = build(&["kernel"], debug, Some(TARGET), Some("kernel".into()), None)?;
|
||||
path.push("kernel");
|
||||
Ok(path)
|
||||
}
|
||||
|
|
@ -293,6 +283,7 @@ fn build(
|
|||
debug: bool,
|
||||
target: Option<&str>,
|
||||
directory: Option<PathBuf>,
|
||||
extra_args: Option<&[&str]>,
|
||||
) -> Result<PathBuf, DynError> {
|
||||
let stream = if debug { "debug" } else { "release" };
|
||||
let mut args = vec!["build"];
|
||||
|
|
@ -314,6 +305,12 @@ fn build(
|
|||
args.push("--release");
|
||||
}
|
||||
|
||||
if let Some(extra) = extra_args {
|
||||
for &a in extra {
|
||||
args.push(a);
|
||||
}
|
||||
}
|
||||
|
||||
let mut dir = project_root();
|
||||
if let Some(subdir) = &directory {
|
||||
dir.push(subdir);
|
||||
|
|
|
|||
Loading…
Reference in a new issue