#![cfg_attr(feature = "std", allow(dead_code, unreachable_code))]
use crate::{map::reg::scb, reg::prelude::*};
use drone_core::token::Token;
pub unsafe trait ThrsInitToken: Token {
type ThrTokens: Token;
}
#[allow(missing_docs)]
pub struct ThrInitExtended {
pub scb_ccr_bfhfnmign: scb::ccr::Bfhfnmign<Srt>,
pub scb_ccr_div_0_trp: scb::ccr::Div0Trp<Srt>,
pub scb_ccr_unalign_trp: scb::ccr::UnalignTrp<Srt>,
pub scb_ccr_usersetmpend: scb::ccr::Usersetmpend<Srt>,
}
#[allow(clippy::needless_pass_by_value)]
#[inline]
pub fn init_extended<T: ThrsInitToken>(_token: T) -> (T::ThrTokens, ThrInitExtended) {
let scb_ccr = unsafe { scb::Ccr::<Srt>::take() };
scb_ccr.store(|r| r.set_stkalign().set_nonbasethrdena());
let scb::Ccr {
stkalign,
bfhfnmign: scb_ccr_bfhfnmign,
div_0_trp: scb_ccr_div_0_trp,
unalign_trp: scb_ccr_unalign_trp,
usersetmpend: scb_ccr_usersetmpend,
nonbasethrdena,
} = scb_ccr;
#[cfg(feature = "memory-protection-unit")]
unsafe {
mpu::reset();
}
drop(stkalign);
drop(nonbasethrdena);
(unsafe { T::ThrTokens::take() }, ThrInitExtended {
scb_ccr_bfhfnmign,
scb_ccr_div_0_trp,
scb_ccr_unalign_trp,
scb_ccr_usersetmpend,
})
}
#[allow(clippy::needless_pass_by_value)]
#[inline]
pub fn init<T: ThrsInitToken>(token: T) -> T::ThrTokens {
let (thr, _) = init_extended(token);
thr
}
#[cfg(feature = "memory-protection-unit")]
mod mpu {
use crate::{map::reg::mpu, reg::prelude::*};
use drone_core::token::Token;
static MPU_RESET_TABLE: [u32; 16] = [
rbar_reset(0),
0,
rbar_reset(1),
0,
rbar_reset(2),
0,
rbar_reset(3),
0,
rbar_reset(4),
0,
rbar_reset(5),
0,
rbar_reset(6),
0,
rbar_reset(7),
0,
];
pub(super) unsafe fn reset() {
#[cfg(feature = "std")]
return unimplemented!();
let mpu_type = unsafe { mpu::Type::<Srt>::take() };
let mpu_ctrl = unsafe { mpu::Ctrl::<Srt>::take() };
if mpu_type.load().dregion() == 0 {
return;
}
mpu_ctrl.reset();
#[cfg(not(feature = "std"))]
unsafe {
asm!(
"ldmia r0!, {{r2, r3, r4, r5, r8, r9, r10, r11}}",
"stmia r1, {{r2, r3, r4, r5, r8, r9, r10, r11}}",
"ldmia r0!, {{r2, r3, r4, r5, r8, r9, r10, r11}}",
"stmia r1, {{r2, r3, r4, r5, r8, r9, r10, r11}}",
inout("r0") MPU_RESET_TABLE.as_ptr() => _,
in("r1") mpu::Rbar::<Srt>::ADDRESS,
out("r2") _,
out("r3") _,
out("r4") _,
out("r5") _,
out("r8") _,
out("r9") _,
out("r10") _,
out("r11") _,
options(preserves_flags),
);
}
}
#[allow(clippy::cast_lossless)]
const fn rbar_reset(region: u8) -> u32 {
1 << 4 | region as u32 & 0b1111
}
}