Skip to content

Commit

Permalink
Merge branch 'main' into usb-irq
Browse files Browse the repository at this point in the history
  • Loading branch information
bunnie authored Jan 1, 2025
2 parents 7375dc0 + 89ebd5d commit 6d3c501
Show file tree
Hide file tree
Showing 20 changed files with 18,458 additions and 17,019 deletions.
4 changes: 2 additions & 2 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(ci)', 'cfg(baremetal)'] }

[features]
cramium-soc = ["utralib/cramium-soc", "cramium-hal", "rand_chacha", "raw-trng"]
verilator-only = ["cramium-hal/verilator-only"]
cramium-fpga = ["utralib/cramium-fpga"]
verilator-only = []
cramium-fpga = ["utralib/cramium-fpga", "rand_chacha"]
board-baosec = ["cramium-hal/board-baosec"]
board-baosor = ["cramium-hal/board-baosor"]
board-dabao = ["cramium-hal/board-dabao"]
Expand Down
3 changes: 3 additions & 0 deletions kernel/src/debug/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// SPDX-FileCopyrightText: 2023 Foundation Devices, Inc. <[email protected]>
// SPDX-License-Identifier: Apache-2.0

// allow all functions to go unused in case debug is disabled with a feature flag
#![allow(dead_code)]

use core::fmt;

use crate::{
Expand Down
6 changes: 6 additions & 0 deletions kernel/src/platform/cramium/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
// SPDX-FileCopyrightText: 2024 bunnie <[email protected]>
// SPDX-License-Identifier: Apache-2.0

#[cfg(feature = "cramium-soc")]
pub mod rand;
#[cfg(feature = "cramium-fpga")]
pub mod rand_fake;
#[cfg(feature = "cramium-fpga")]
pub use rand_fake as rand;

#[cfg(any(feature = "debug-print", feature = "print-panics"))]
pub mod uart;

Expand Down
63 changes: 63 additions & 0 deletions kernel/src/platform/cramium/rand_fake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-FileCopyrightText: 2020 Sean Cross <[email protected]>
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <[email protected]>
// SPDX-FileCopyrightText: 2024 bunnie <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use core::convert::TryInto;
use core::sync::atomic::{AtomicU32, Ordering};

use rand_chacha::ChaCha8Rng;
use rand_chacha::rand_core::RngCore;
use rand_chacha::rand_core::SeedableRng;

// This is the sum total of state used for simulations
static LOCAL_RNG_STATE: [AtomicU32; 8] = [
AtomicU32::new(0),
AtomicU32::new(0),
AtomicU32::new(0),
AtomicU32::new(0),
AtomicU32::new(0),
AtomicU32::new(0),
AtomicU32::new(0),
AtomicU32::new(1),
];

pub fn init() {}

/// This a fully deterministic PRNG that relies on Chacha8 for state evolution.
pub fn get_u32() -> u32 {
// Local storage for the seed.
let mut seed = [0u8; 32];

// Pull our true seed data from the static AtomicU32 variables. We have to do this because
// we're the kernel: any machine persistent state is by definition, global mutable state.
//
// Mix in more data from the TRNG while recovering the state from the kernel holding area.
for (s, state) in seed.chunks_mut(4).zip(LOCAL_RNG_STATE.iter()) {
let incoming = get_raw_u32() ^ state.load(Ordering::SeqCst);
for (s_byte, &incoming_byte) in s.iter_mut().zip(incoming.to_le_bytes().iter()) {
*s_byte ^= incoming_byte;
}
}
let mut cstrng = ChaCha8Rng::from_seed(seed);
// Mix up the internal state with output from the CSPRNG. We do this because the TRNG bits
// could be biased, and by running the CSPRNG forward based on the new seed, we have a chance to
// diffuse any true entropy over all bits in the seed pool.
for s in seed.chunks_mut(8) {
for (s_byte, chacha_byte) in s.iter_mut().zip(cstrng.next_u64().to_le_bytes()) {
*s_byte ^= chacha_byte;
}
}
// Now extract one value from the CSPRNG: this is the number we reveal to the outside world.
// It should not, in theory, be possible to deduce the seed from this value.
let ret_val = cstrng.next_u32();

// Save the mixed state into the kernel holding area
for (s, state) in seed.chunks(4).zip(LOCAL_RNG_STATE.iter()) {
state.store(u32::from_le_bytes(s.try_into().unwrap()), Ordering::SeqCst);
}
ret_val
}

/// There is no TRNG in simulation, just return a constant and rely on the chacha8 whitener
pub fn get_raw_u32() -> u32 { 0 }
108 changes: 16 additions & 92 deletions kernel/src/platform/cramium/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]

#[cfg(feature = "cramium-soc")]
use utralib::generated::*;
#[cfg(feature = "cramium-soc")]
use xous_kernel::{MemoryFlags, MemoryType};

#[cfg(feature = "cramium-fpga")]
use crate::{
PID,
debug::shell::process_characters,
io::{SerialRead, SerialWrite},
mem::MemoryManager,
};
use crate::io::{SerialRead, SerialWrite};
#[cfg(feature = "cramium-soc")]
use crate::{
PID,
Expand All @@ -27,117 +24,44 @@ use crate::{
/// UART virtual address.
///
/// See https://github.com/betrusted-io/xous-core/blob/master/docs/memory.md
#[cfg(feature = "cramium-soc")]
pub const UART_ADDR: usize = 0xffcf_0000;
#[cfg(feature = "cramium-soc")]
pub const IRQ0_ADDR: usize = UART_ADDR + 0x1000;

/// UART instance.
///
/// Initialized by [`init`].
#[cfg(feature = "cramium-soc")]
pub static mut UART: Option<Uart> = None;

/// UART peripheral driver.
/// All dummy stubs for cramium-fpga because we want the console to have the DUART
#[cfg(feature = "cramium-fpga")]
pub struct Uart {
uart_csr: CSR<u32>,
irq_csr: CSR<u32>,
callback: fn(&mut Self),
}
pub fn init() {}

#[cfg(feature = "cramium-fpga")]
impl Uart {
pub fn new(addr: usize, irq_addr: usize, callback: fn(&mut Self)) -> Uart {
Uart { uart_csr: CSR::new(addr as *mut u32), irq_csr: CSR::new(irq_addr as *mut u32), callback }
}
pub struct Uart {}

pub fn init(&mut self) {
self.uart_csr.rmwf(utra::uart::EV_ENABLE_RX, 1);
self.irq_csr.rmwf(utra::irqarray0::EV_ENABLE_SOURCE0, 1);
}
#[cfg(feature = "cramium-fpga")]
#[allow(dead_code)]
impl Uart {
pub fn new(_addr: usize, _irq_addr: usize, _callback: fn(&mut Self)) -> Uart { Uart {} }

pub fn irq(_irq_number: usize, arg: *mut usize) {
let uart = unsafe { &mut *(arg as *mut Uart) };
(uart.callback)(uart);
// uart.acknowledge_irq();
}
pub fn init(&mut self) {}
}

#[cfg(feature = "cramium-fpga")]
impl SerialWrite for Uart {
fn putc(&mut self, c: u8) {
// Wait until TXFULL is `0`
while self.uart_csr.r(utra::uart::TXFULL) != 0 {}
self.uart_csr.wfo(utra::uart::RXTX_RXTX, c as u32);
}
fn putc(&mut self, _c: u8) {}
}

#[cfg(feature = "cramium-fpga")]
impl SerialRead for Uart {
fn getc(&mut self) -> Option<u8> {
// If EV_PENDING_RX is 1, return the pending character.
// Otherwise, return None.
match self.uart_csr.rf(utra::uart::EV_PENDING_RX) {
0 => None,
_ => {
let ret = Some(self.uart_csr.r(utra::uart::RXTX) as u8);
self.uart_csr.wfo(utra::uart::EV_PENDING_RX, 1);
self.irq_csr.wfo(utra::irqarray0::EV_PENDING_SOURCE0, 1);
ret
}
}
}
}

/// Initialize UART driver and debug shell.
#[cfg(feature = "cramium-fpga")]
pub fn init() {
// Map the UART peripheral.
MemoryManager::with_mut(|memory_manager| {
memory_manager
.map_range(
utra::uart::HW_UART_BASE as *mut u8,
(UART_ADDR & !4095) as *mut u8,
4096,
PID::new(1).unwrap(),
MemoryFlags::R | MemoryFlags::W,
MemoryType::Default,
)
.expect("unable to map serial port")
});
// Map the IRQ0 handler
MemoryManager::with_mut(|memory_manager| {
memory_manager
.map_range(
utra::irqarray0::HW_IRQARRAY0_BASE as *mut u8,
(IRQ0_ADDR & !4095) as *mut u8,
4096,
PID::new(1).unwrap(),
MemoryFlags::R | MemoryFlags::W,
MemoryType::Default,
)
.expect("unable to map serial port")
});

let mut uart = Uart::new(UART_ADDR, IRQ0_ADDR, process_characters);
uart.init();

unsafe {
UART = Some(uart);
crate::debug::shell::init((&mut *(&raw mut UART)).as_mut().unwrap());

// Claim UART interrupt.
println!("Claiming IRQ {} via syscall...", utra::uart::UART_IRQ);
xous_kernel::claim_interrupt(
utra::uart::UART_IRQ,
Uart::irq,
((&mut *(&raw mut UART)).as_mut().unwrap() as *mut Uart) as *mut usize,
)
.expect("Couldn't claim debug interrupt");
}
fn getc(&mut self) -> Option<u8> { None }
}

#[cfg(feature = "cramium-soc")]
pub fn init() {
// there is no kernel UART yet...just a placeholder function
// Map the UART peripheral.
MemoryManager::with_mut(|memory_manager| {
memory_manager
Expand Down
2 changes: 1 addition & 1 deletion loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ board-baosec = [
]
board-baosor = ["cramium-hal/board-baosor"]
board-dabao = ["cramium-hal/board-dabao"]
cramium-fpga = ["utralib/cramium-fpga", "debug-print", "cramium-hal"]
cramium-fpga = ["utralib/cramium-fpga", "debug-print"]
atsama5d27 = ["utralib/atsama5d27", "armv7", "dep:atsama5d27"]

# precursor flags
Expand Down
5 changes: 3 additions & 2 deletions loader/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ fn boot_sequence(args: KernelArguments, _signature: u32, fs_prehash: [u8; 64], _
println!("No suspend marker found, doing a cold boot!");
#[cfg(feature = "simulation-only")]
println!("Configured for simulation. Skipping RAM clear!");
#[cfg(not(feature = "cramium-soc"))] // cramium-soc target clears RAM with assembly routine on boot
#[cfg(not(any(feature = "cramium-soc", feature = "cramium-fpga")))]
// cramium target clears RAM with assembly routine on boot
clear_ram(&mut cfg);
phase_1(&mut cfg);
phase_2(&mut cfg, &fs_prehash);
Expand Down Expand Up @@ -287,7 +288,7 @@ fn boot_sequence(args: KernelArguments, _signature: u32, fs_prehash: [u8; 64], _

#[cfg(not(feature = "atsama5d27"))]
{
#[cfg(not(feature = "cramium-soc"))]
#[cfg(not(any(feature = "cramium-soc", feature = "cramium-fpga")))]
{
// uart mux only exists on the FPGA variant
use utralib::generated::*;
Expand Down
2 changes: 2 additions & 0 deletions loader/src/platform/cramium/cramium.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use cramium_hal::axp2101::Axp2101;
#[cfg(not(feature = "verilator-only"))]
use cramium_hal::iox::{Iox, IoxDir, IoxEnable, IoxFunction, IoxPort};
#[cfg(feature = "cramium-soc")]
use cramium_hal::udma;
#[cfg(any(feature = "board-baosec", feature = "board-baosor"))]
use cramium_hal::udma::PeriphId;
Expand Down Expand Up @@ -1556,6 +1557,7 @@ fn fsfreq_to_hz(fs_freq: u32) -> u32 { (fs_freq * (48_000_000 / 32)) / 1_000_000
fn fsfreq_to_hz_32(fs_freq: u32) -> u32 { (fs_freq * (32_000_000 / 32)) / 1_000_000 }

#[allow(dead_code)]
#[cfg(feature = "cramium-soc")]
/// Used mainly for debug breaks. Not used in every configuration.
pub fn getc() -> char {
let uart_buf_addr = loader::UART_IFRAM_ADDR;
Expand Down
9 changes: 4 additions & 5 deletions services/cram-mbox1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ num-derive = { version = "0.4.2", default-features = false }
num-traits = { version = "0.2.14", default-features = false }

[features]
"cramium" = []
"cramium-soc" = []
"cramium-fpga" = []
"cramium" = ["utralib/cramium-fpga"]
"hwsim" = []
"ext" = [] # must match setting in cram-mbox2
default = ["cramium", "ext"]
# ext specifies to use the APB client, instead of the loopback local
"ext" = [] # must match setting in cram-mbox2
default = ["cramium"]
Loading

0 comments on commit 6d3c501

Please sign in to comment.