Lines
100 %
Functions
use esp_sync::NonReentrantMutex;
use crate::{peripherals::RNG, soc::clocks};
// TODO: find a better place for these
#[inline]
#[cfg(all(soc_cpu_has_csr_pc, soc_cpu_csr_prv_mode_is_set))]
fn tee_enabled() -> bool {
false
}
fn current_cpu_cycles() -> usize {
cfg_select! {
xtensa => xtensa_lx::timer::get_cycle_count() as usize,
soc_cpu_has_csr_pc => {
const PRV_M: usize = 3;
macro_rules! read_csr_fn {
($fnname:ident, $csr:expr) => {
fn $fnname() -> usize {
let r: usize;
unsafe {
core::arch::asm!(concat!("csrrs {0}, ", $csr, ", x0"), out(reg) r);
return r;
read_csr_fn!(read_pccr_machine, "0x7e2");
read_csr_fn!(read_pccr_user, "0x802");
fn read_prv_mode() -> usize {
#[cfg(soc_cpu_csr_prv_mode_is_set)]
if tee_enabled() {
read_csr_fn!(read_prv_m, property!("soc.cpu_csr_prv_mode", str));
return read_prv_m();
PRV_M
if read_prv_mode() == PRV_M {
read_pccr_machine()
} else {
read_pccr_user()
_ => riscv::register::mcycle::read(),
static LAST_READ: NonReentrantMutex<usize> = NonReentrantMutex::new(0);
fn read_one(wait_cycles: usize) -> u32 {
loop {
let random = LAST_READ.with(|last_wait_start| {
let now: usize = current_cpu_cycles();
if now.wrapping_sub(*last_wait_start) >= wait_cycles {
*last_wait_start = now;
any(esp32c5, esp32c61) => Some(RNG::regs().rng_data_sync().read().bits()),
rng_is_lp_sys => Some(RNG::regs().rng_data().read().bits()),
esp32s31 => Some(RNG::regs().crc_sync_data().read().bits()),
_ => Some(RNG::regs().data().read().bits()),
None
});
if let Some(random) = random {
return random;
pub(super) fn fill_ptr_range(data: *mut u8, len: usize) {
let cpu_to_apb_freq_ratio = clocks::cpu_clk_frequency() / clocks::apb_clk_frequency();
let wait_cycles = cpu_to_apb_freq_ratio as usize * property!("rng.apb_cycle_wait_num");
let mut remaining = len;
let mut dst = data;
while remaining > 0 {
let random_bytes = read_one(wait_cycles).to_le_bytes();
let bytes_to_copy = random_bytes.len().min(remaining);
dst.copy_from_nonoverlapping(random_bytes.as_ptr(), bytes_to_copy);
dst = dst.add(bytes_to_copy);
remaining -= bytes_to_copy;