Skip to content

Commit d8807e6

Browse files
committed
kernel: Move rand driver to platform module.
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
1 parent b334e5b commit d8807e6

File tree

9 files changed

+123
-80
lines changed

9 files changed

+123
-80
lines changed

kernel/src/arch/riscv/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ pub mod exception;
77
pub mod irq;
88
pub mod mem;
99
pub mod process;
10-
pub mod rand;
1110
pub mod syscall;
1211

1312
pub use process::Thread;
@@ -49,7 +48,6 @@ pub fn init() {
4948
sie::set_ssoft();
5049
sie::set_sext();
5150
}
52-
rand::init();
5351
}
5452

5553
/// Put the core to sleep until an interrupt hits. Returns `true`

kernel/src/arch/riscv/rand.rs

Lines changed: 0 additions & 69 deletions
This file was deleted.

kernel/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ pub unsafe extern "C" fn init(arg_offset: *const u32, init_offset: *const u32, r
6969
println!("KMAIN (clean boot): Supervisor mode started...");
7070

7171
// rand::init() already clears the initial pipe, but pump the TRNG a little more out of no other reason than sheer paranoia
72-
arch::rand::get_u32();
73-
arch::rand::get_u32();
72+
platform::rand::get_u32();
73+
platform::rand::get_u32();
7474
}
7575

7676
/// Loop through the SystemServices list to determine the next PID to be run.

kernel/src/platform/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#[cfg(any(feature="precursor", feature="renode"))]
55
pub mod precursor;
66

7+
pub mod rand;
8+
79
/// Platform specific initialization.
810
#[cfg(not(any(unix, windows)))]
911
pub fn init() {

kernel/src/platform/precursor/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
#[cfg(any(feature = "debug-print", feature = "print-panics"))]
55
pub mod uart;
6+
pub mod rand;
67

78
/// Precursor specific initialization.
89
pub fn init() {
10+
self::rand::init();
911
#[cfg(any(feature = "debug-print", feature = "print-panics"))]
1012
self::uart::init();
1113
}

kernel/src/platform/precursor/rand.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// SPDX-FileCopyrightText: 2020 Sean Cross <[email protected]>
2+
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <[email protected]>
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
use crate::mem::MemoryManager;
6+
use utralib::generated::*;
7+
use xous_kernel::{MemoryFlags, MemoryType, PID};
8+
9+
/// The manually chosen virtual address has to be in the top 4MiB as it is the
10+
/// only page shared among all processes.
11+
///
12+
/// See https://github.com/betrusted-io/xous-core/blob/master/docs/memory.md
13+
pub const TRNG_KERNEL_ADDR: usize = 0xffce_0000;
14+
pub static mut TRNG_KERNEL: Option<TrngKernel> = None;
15+
16+
pub struct TrngKernel {
17+
pub trng_kernel_csr: CSR<u32>,
18+
}
19+
20+
impl TrngKernel {
21+
pub fn new(addr: usize) -> TrngKernel {
22+
TrngKernel {
23+
trng_kernel_csr: CSR::new(addr as *mut u32),
24+
}
25+
}
26+
27+
pub fn init(&mut self) {
28+
if false { // raw random path - left in for debugging urandom, can strip out later
29+
while self.trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
30+
// discard the first entry, as it is always 0x0000_0000
31+
// this is because the read register is a pipeline stage behind the FIFO
32+
// once the pipeline has been filled, there is no need to prime it again.
33+
self.trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA);
34+
} else { // urandom path (recommended)
35+
// simulations show this isn't strictly necessary, but I prefer to have it
36+
// just in case a subtle bug in the reset logic leaves something deterministic
37+
// in the connecting logic: the simulation coverage stops at the edge of the TRNG block.
38+
for _ in 0..4 {
39+
// wait until the urandom port is initialized
40+
while self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
41+
// pull a dummy piece of data
42+
self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM);
43+
}
44+
}
45+
}
46+
47+
pub fn get_u32(&mut self) -> u32 {
48+
if false { // raw random path
49+
while self.trng_kernel_csr.rf(utra::trng_kernel::STATUS_AVAIL) == 0 {}
50+
self.trng_kernel_csr.rf(utra::trng_kernel::DATA_DATA)
51+
} else { // urandom path (recommended)
52+
while self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_VALID_URANDOM_VALID) == 0 {}
53+
self.trng_kernel_csr.rf(utra::trng_kernel::URANDOM_URANDOM)
54+
}
55+
}
56+
}
57+
58+
/// Initialize TRNG driver.
59+
///
60+
/// Needed so that the kernel can allocate names.
61+
pub fn init() {
62+
// Map the TRNG so that we can allocate names
63+
// hardware guarantees that:
64+
// - TRNG will automatically power on
65+
// - Both TRNGs are enabled, with conservative defaults
66+
// - Kernel FIFO will fill with TRNGs such that at least the next 512 calls to get_u32() will succeed without delay
67+
// - The kernel will start a TRNG server
68+
// - All further security decisions and policies are 100% delegated to this new server.
69+
MemoryManager::with_mut(|memory_manager| {
70+
memory_manager
71+
.map_range(
72+
utra::trng_kernel::HW_TRNG_KERNEL_BASE as *mut u8,
73+
(TRNG_KERNEL_ADDR & !4095) as *mut u8,
74+
4096,
75+
PID::new(1).unwrap(),
76+
MemoryFlags::R | MemoryFlags::W,
77+
MemoryType::Default,
78+
)
79+
.expect("unable to map TRNG_KERNEL")
80+
});
81+
82+
let mut trng_kernel = TrngKernel::new(TRNG_KERNEL_ADDR);
83+
trng_kernel.init();
84+
85+
unsafe {
86+
TRNG_KERNEL = Some(trng_kernel);
87+
}
88+
}
89+
90+
/// Retrieve random `u32`.
91+
pub fn get_u32() -> u32 {
92+
unsafe {
93+
TRNG_KERNEL
94+
.as_mut()
95+
.expect("TRNG_KERNEL driver not initialized")
96+
.get_u32()
97+
}
98+
}

kernel/src/platform/precursor/uart.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ pub fn init() {
8585
.expect("unable to map serial port")
8686
});
8787

88-
unsafe {
89-
let mut uart = Uart::new(UART_ADDR, process_characters);
90-
uart.init();
88+
let mut uart = Uart::new(UART_ADDR, process_characters);
89+
uart.init();
9190

91+
unsafe {
9292
UART = Some(uart);
9393
crate::debug::shell::init(UART.as_mut().unwrap());
9494

kernel/src/platform/rand.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <[email protected]>
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
pub fn get_u32() -> u32 {
5+
// hosted rand code is coupled with arch code.
6+
#[cfg(any(windows, unix))]
7+
let rand = crate::arch::rand::get_u32();
8+
#[cfg(any(feature="precursor", feature="renode"))]
9+
let rand = crate::platform::precursor::rand::get_u32();
10+
rand
11+
}

kernel/src/services.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::arch;
55
use crate::arch::mem::MemoryMapping;
66
pub use crate::arch::process::Process as ArchProcess;
77
pub use crate::arch::process::Thread;
8+
use crate::platform;
89
use xous_kernel::arch::ProcessStartup;
910
use xous_kernel::MemoryRange;
1011

@@ -1742,10 +1743,10 @@ impl SystemServices {
17421743
/// any processes.
17431744
pub fn create_server_id(&mut self) -> Result<SID, xous_kernel::Error> {
17441745
let sid = SID::from_u32(
1745-
arch::rand::get_u32(),
1746-
arch::rand::get_u32(),
1747-
arch::rand::get_u32(),
1748-
arch::rand::get_u32(),
1746+
platform::rand::get_u32(),
1747+
platform::rand::get_u32(),
1748+
platform::rand::get_u32(),
1749+
platform::rand::get_u32(),
17491750
);
17501751
Ok(sid)
17511752
}

0 commit comments

Comments
 (0)