mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
kernel: Move rand driver to platform module.
Signed-off-by: Jean-Pierre De Jesus DIAZ <me@jeandudey.tech>
This commit is contained in:
parent
b334e5bc31
commit
d8807e6cea
9 changed files with 123 additions and 80 deletions
|
|
@ -7,7 +7,6 @@ pub mod exception;
|
|||
pub mod irq;
|
||||
pub mod mem;
|
||||
pub mod process;
|
||||
pub mod rand;
|
||||
pub mod syscall;
|
||||
|
||||
pub use process::Thread;
|
||||
|
|
@ -49,7 +48,6 @@ pub fn init() {
|
|||
sie::set_ssoft();
|
||||
sie::set_sext();
|
||||
}
|
||||
rand::init();
|
||||
}
|
||||
|
||||
/// Put the core to sleep until an interrupt hits. Returns `true`
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2020 Sean Cross <sean@xobs.io>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::mem::MemoryManager;
|
||||
use utralib::generated::*;
|
||||
use xous_kernel::{MemoryFlags, MemoryType, PID};
|
||||
|
||||
pub const TRNG_KERNEL: Trng = Trng {
|
||||
// the HW device mapping is done in xous-rs/src/lib.rs/init()
|
||||
// the manually chosen virtual address has to be in the top 4MiB as it is the only page shared among all processes
|
||||
base: 0xffce_0000 as *mut usize, // see https://github.com/betrusted-io/xous-core/blob/master/docs/memory.md
|
||||
};
|
||||
|
||||
pub struct Trng {
|
||||
pub base: *mut usize,
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
// Map the TRNG so that we can allocate names
|
||||
// hardware guarantees that:
|
||||
// - TRNG will automatically power on
|
||||
// - Both TRNGs are enabled, with conservative defaults
|
||||
// - Kernel FIFO will fill with TRNGs such that at least the next 512 calls to get_u32() will succeed without delay
|
||||
// - The kernel will start a TRNG server
|
||||
// - All further security decisions and policies are 100% delegated to this new server.
|
||||
MemoryManager::with_mut(|memory_manager| {
|
||||
memory_manager
|
||||
.map_range(
|
||||
utra::trng_kernel::HW_TRNG_KERNEL_BASE as *mut u8,
|
||||
((TRNG_KERNEL.base as u32) & !4095) as *mut u8,
|
||||
4096,
|
||||
PID::new(1).unwrap(),
|
||||
MemoryFlags::R | MemoryFlags::W,
|
||||
MemoryType::Default,
|
||||
)
|
||||
.expect("unable to map TRNG")
|
||||
});
|
||||
|
||||
let trng_kernel_csr = CSR::new(TRNG_KERNEL.base as *mut u32);
|
||||
if false { // raw random path - left in for debugging urandom, can strip out later
|
||||
while trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
|
||||
// discard the first entry, as it is always 0x0000_0000
|
||||
// this is because the read register is a pipeline stage behind the FIFO
|
||||
// once the pipeline has been filled, there is no need to prime it again.
|
||||
trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA);
|
||||
} else { // urandom path (recommended)
|
||||
// simulations show this isn't strictly necessary, but I prefer to have it
|
||||
// just in case a subtle bug in the reset logic leaves something deterministic
|
||||
// in the connecting logic: the simulation coverage stops at the edge of the TRNG block.
|
||||
for _ in 0..4 {
|
||||
// wait until the urandom port is initialized
|
||||
while trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
|
||||
// pull a dummy piece of data
|
||||
trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn get_u32() -> u32 {
|
||||
let trng_kernel_csr = CSR::new(TRNG_KERNEL.base as *mut u32);
|
||||
if false { // raw random path
|
||||
while trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
|
||||
trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA)
|
||||
} else { // urandom path (recommended)
|
||||
while trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
|
||||
trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM)
|
||||
}
|
||||
}
|
||||
|
|
@ -69,8 +69,8 @@ pub unsafe extern "C" fn init(arg_offset: *const u32, init_offset: *const u32, r
|
|||
println!("KMAIN (clean boot): Supervisor mode started...");
|
||||
|
||||
// rand::init() already clears the initial pipe, but pump the TRNG a little more out of no other reason than sheer paranoia
|
||||
arch::rand::get_u32();
|
||||
arch::rand::get_u32();
|
||||
platform::rand::get_u32();
|
||||
platform::rand::get_u32();
|
||||
}
|
||||
|
||||
/// Loop through the SystemServices list to determine the next PID to be run.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#[cfg(any(feature="precursor", feature="renode"))]
|
||||
pub mod precursor;
|
||||
|
||||
pub mod rand;
|
||||
|
||||
/// Platform specific initialization.
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
pub fn init() {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
|
||||
#[cfg(any(feature = "debug-print", feature = "print-panics"))]
|
||||
pub mod uart;
|
||||
pub mod rand;
|
||||
|
||||
/// Precursor specific initialization.
|
||||
pub fn init() {
|
||||
self::rand::init();
|
||||
#[cfg(any(feature = "debug-print", feature = "print-panics"))]
|
||||
self::uart::init();
|
||||
}
|
||||
98
kernel/src/platform/precursor/rand.rs
Normal file
98
kernel/src/platform/precursor/rand.rs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// SPDX-FileCopyrightText: 2020 Sean Cross <sean@xobs.io>
|
||||
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <hello@foundationdevices.com>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::mem::MemoryManager;
|
||||
use utralib::generated::*;
|
||||
use xous_kernel::{MemoryFlags, MemoryType, PID};
|
||||
|
||||
/// The manually chosen virtual address has to be in the top 4MiB as it is the
|
||||
/// only page shared among all processes.
|
||||
///
|
||||
/// See https://github.com/betrusted-io/xous-core/blob/master/docs/memory.md
|
||||
pub const TRNG_KERNEL_ADDR: usize = 0xffce_0000;
|
||||
pub static mut TRNG_KERNEL: Option<TrngKernel> = None;
|
||||
|
||||
pub struct TrngKernel {
|
||||
pub trng_kernel_csr: CSR<u32>,
|
||||
}
|
||||
|
||||
impl TrngKernel {
|
||||
pub fn new(addr: usize) -> TrngKernel {
|
||||
TrngKernel {
|
||||
trng_kernel_csr: CSR::new(addr as *mut u32),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
if false { // raw random path - left in for debugging urandom, can strip out later
|
||||
while self.trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
|
||||
// discard the first entry, as it is always 0x0000_0000
|
||||
// this is because the read register is a pipeline stage behind the FIFO
|
||||
// once the pipeline has been filled, there is no need to prime it again.
|
||||
self.trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA);
|
||||
} else { // urandom path (recommended)
|
||||
// simulations show this isn't strictly necessary, but I prefer to have it
|
||||
// just in case a subtle bug in the reset logic leaves something deterministic
|
||||
// in the connecting logic: the simulation coverage stops at the edge of the TRNG block.
|
||||
for _ in 0..4 {
|
||||
// wait until the urandom port is initialized
|
||||
while self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
|
||||
// pull a dummy piece of data
|
||||
self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_u32(&mut self) -> u32 {
|
||||
if false { // raw random path
|
||||
while self.trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
|
||||
self.trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA)
|
||||
} else { // urandom path (recommended)
|
||||
while self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
|
||||
self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize TRNG driver.
|
||||
///
|
||||
/// Needed so that the kernel can allocate names.
|
||||
pub fn init() {
|
||||
// Map the TRNG so that we can allocate names
|
||||
// hardware guarantees that:
|
||||
// - TRNG will automatically power on
|
||||
// - Both TRNGs are enabled, with conservative defaults
|
||||
// - Kernel FIFO will fill with TRNGs such that at least the next 512 calls to get_u32() will succeed without delay
|
||||
// - The kernel will start a TRNG server
|
||||
// - All further security decisions and policies are 100% delegated to this new server.
|
||||
MemoryManager::with_mut(|memory_manager| {
|
||||
memory_manager
|
||||
.map_range(
|
||||
utra::trng_kernel::HW_TRNG_KERNEL_BASE as *mut u8,
|
||||
(TRNG_KERNEL_ADDR & !4095) as *mut u8,
|
||||
4096,
|
||||
PID::new(1).unwrap(),
|
||||
MemoryFlags::R | MemoryFlags::W,
|
||||
MemoryType::Default,
|
||||
)
|
||||
.expect("unable to map TRNG_KERNEL")
|
||||
});
|
||||
|
||||
let mut trng_kernel = TrngKernel::new(TRNG_KERNEL_ADDR);
|
||||
trng_kernel.init();
|
||||
|
||||
unsafe {
|
||||
TRNG_KERNEL = Some(trng_kernel);
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve random `u32`.
|
||||
pub fn get_u32() -> u32 {
|
||||
unsafe {
|
||||
TRNG_KERNEL
|
||||
.as_mut()
|
||||
.expect("TRNG_KERNEL driver not initialized")
|
||||
.get_u32()
|
||||
}
|
||||
}
|
||||
|
|
@ -85,10 +85,10 @@ pub fn init() {
|
|||
.expect("unable to map serial port")
|
||||
});
|
||||
|
||||
unsafe {
|
||||
let mut uart = Uart::new(UART_ADDR, process_characters);
|
||||
uart.init();
|
||||
let mut uart = Uart::new(UART_ADDR, process_characters);
|
||||
uart.init();
|
||||
|
||||
unsafe {
|
||||
UART = Some(uart);
|
||||
crate::debug::shell::init(UART.as_mut().unwrap());
|
||||
|
||||
|
|
|
|||
11
kernel/src/platform/rand.rs
Normal file
11
kernel/src/platform/rand.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <hello@foundationdevices.com>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub fn get_u32() -> u32 {
|
||||
// hosted rand code is coupled with arch code.
|
||||
#[cfg(any(windows, unix))]
|
||||
let rand = crate::arch::rand::get_u32();
|
||||
#[cfg(any(feature="precursor", feature="renode"))]
|
||||
let rand = crate::platform::precursor::rand::get_u32();
|
||||
rand
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ use crate::arch;
|
|||
use crate::arch::mem::MemoryMapping;
|
||||
pub use crate::arch::process::Process as ArchProcess;
|
||||
pub use crate::arch::process::Thread;
|
||||
use crate::platform;
|
||||
use xous_kernel::arch::ProcessStartup;
|
||||
use xous_kernel::MemoryRange;
|
||||
|
||||
|
|
@ -1742,10 +1743,10 @@ impl SystemServices {
|
|||
/// any processes.
|
||||
pub fn create_server_id(&mut self) -> Result<SID, xous_kernel::Error> {
|
||||
let sid = SID::from_u32(
|
||||
arch::rand::get_u32(),
|
||||
arch::rand::get_u32(),
|
||||
arch::rand::get_u32(),
|
||||
arch::rand::get_u32(),
|
||||
platform::rand::get_u32(),
|
||||
platform::rand::get_u32(),
|
||||
platform::rand::get_u32(),
|
||||
platform::rand::get_u32(),
|
||||
);
|
||||
Ok(sid)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue