rp: allow for MPU-based stack guards on core 0 as well

using these will require some linker script intervention. setting the
core0 stack needs linker intervention anyway (to provide _stack_start),
having it also provide _stack_end for the guard to use is not that much
of a stretch.
This commit is contained in:
pennae
2023-07-20 16:57:54 +02:00
parent 4d6b3c57b1
commit e9445ec72d
2 changed files with 74 additions and 27 deletions

View File

@ -52,41 +52,20 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
use crate::interrupt::InterruptExt;
use crate::peripherals::CORE1;
use crate::{gpio, interrupt, pac};
use crate::{gpio, install_stack_guard, interrupt, pac};
const PAUSE_TOKEN: u32 = 0xDEADBEEF;
const RESUME_TOKEN: u32 = !0xDEADBEEF;
static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false);
#[inline(always)]
fn install_stack_guard(stack_bottom: *mut usize) {
let core = unsafe { cortex_m::Peripherals::steal() };
// Trap if MPU is already configured
if core.MPU.ctrl.read() != 0 {
fn core1_setup(stack_bottom: *mut usize) {
if let Err(_) = install_stack_guard(stack_bottom) {
// currently only happens if the MPU was already set up, which
// would indicate that the core is already in use from outside
// embassy, somehow. trap if so since we can't deal with that.
cortex_m::asm::udf();
}
// The minimum we can protect is 32 bytes on a 32 byte boundary, so round up which will
// just shorten the valid stack range a tad.
let addr = (stack_bottom as u32 + 31) & !31;
// Mask is 1 bit per 32 bytes of the 256 byte range... clear the bit for the segment we want
let subregion_select = 0xff ^ (1 << ((addr >> 5) & 7));
unsafe {
core.MPU.ctrl.write(5); // enable mpu with background default map
core.MPU.rbar.write((addr & !0xff) | (1 << 4)); // set address and update RNR
core.MPU.rasr.write(
1 // enable region
| (0x7 << 1) // size 2^(7 + 1) = 256
| (subregion_select << 8)
| 0x10000000, // XN = disable instruction fetch; no other bits means no permissions
);
}
}
#[inline(always)]
fn core1_setup(stack_bottom: *mut usize) {
install_stack_guard(stack_bottom);
unsafe {
gpio::init();
}