diff --git a/Cargo.lock b/Cargo.lock index f26bdc627..0001f9523 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 9601f5562..52f78c759 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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", diff --git a/services/trng-tester/Cargo.toml b/services/trng-tester/Cargo.toml deleted file mode 100644 index e01bff50b..000000000 --- a/services/trng-tester/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "trng-tester" -version = "0.1.0" -authors = ["bunnie "] -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"] diff --git a/services/trng-tester/src/main.rs b/services/trng-tester/src/main.rs deleted file mode 100644 index d06815dac..000000000 --- a/services/trng-tester/src/main.rs +++ /dev/null @@ -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, - messible_csr: utralib::CSR, - messible2_csr: utralib::CSR, - 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); - } - } -} diff --git a/services/trng/Cargo.toml b/services/trng/Cargo.toml index a16aa8f69..a53baf0a5 100644 --- a/services/trng/Cargo.toml +++ b/services/trng/Cargo.toml @@ -21,4 +21,6 @@ utralib = { path = "../../utralib"} [features] debugprint = [] +avalanchetest = [] +ringosctest = [] default = [] # "debugprint" diff --git a/services/trng/src/main.rs b/services/trng/src/main.rs index 92672b9f3..efb51d295 100644 --- a/services/trng/src/main.rs +++ b/services/trng/src/main.rs @@ -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, + messible_csr: utralib::CSR, + messible2_csr: utralib::CSR, + 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"); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index f134fce8a..3098c3e5d 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -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, packages: &[&str]) -> Result<(), DynError> { +fn build_hw_image(debug: bool, svd: Option, 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, 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, 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 { - 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, + extra_args: Option<&[&str]>, ) -> Result { 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);