forked from M-Labs/artiq
firmware: More explicit panic message if stack guard is tripped
This should give even only mildly technical users a chance to figure out what's going on, which empirically is not the case for a plain Exception(LoadFault) without further context.
This commit is contained in:
parent
6c47aac760
commit
950b9ac4d6
|
@ -471,6 +471,8 @@ unsafe fn attribute_writeback(typeinfo: *const ()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mut STACK_GUARD_BASE: usize = 0x0;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe fn main() {
|
pub unsafe fn main() {
|
||||||
eh_artiq::reset_exception_buffer(KERNELCPU_PAYLOAD_ADDRESS);
|
eh_artiq::reset_exception_buffer(KERNELCPU_PAYLOAD_ADDRESS);
|
||||||
|
@ -502,6 +504,7 @@ pub unsafe fn main() {
|
||||||
ptr::write_bytes(__bss_start as *mut u8, 0, (_end - __bss_start) as usize);
|
ptr::write_bytes(__bss_start as *mut u8, 0, (_end - __bss_start) as usize);
|
||||||
|
|
||||||
board_misoc::pmp::init_stack_guard(_sstack_guard as usize);
|
board_misoc::pmp::init_stack_guard(_sstack_guard as usize);
|
||||||
|
STACK_GUARD_BASE = _sstack_guard as usize;
|
||||||
board_misoc::cache::flush_cpu_dcache();
|
board_misoc::cache::flush_cpu_dcache();
|
||||||
board_misoc::cache::flush_cpu_icache();
|
board_misoc::cache::flush_cpu_icache();
|
||||||
|
|
||||||
|
@ -531,10 +534,20 @@ pub unsafe fn main() {
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[unwind(allowed)]
|
#[unwind(allowed)]
|
||||||
pub extern fn exception(_regs: *const u32) {
|
pub unsafe extern fn exception(_regs: *const u32) {
|
||||||
let pc = mepc::read();
|
let pc = mepc::read();
|
||||||
let cause = mcause::read().cause();
|
let cause = mcause::read().cause();
|
||||||
let mtval = mtval::read();
|
let mtval = mtval::read();
|
||||||
|
if let mcause::Trap::Exception(mcause::Exception::LoadFault)
|
||||||
|
| mcause::Trap::Exception(mcause::Exception::StoreFault) = cause
|
||||||
|
{
|
||||||
|
if mtval >= STACK_GUARD_BASE
|
||||||
|
&& mtval < (STACK_GUARD_BASE + board_misoc::pmp::STACK_GUARD_SIZE)
|
||||||
|
{
|
||||||
|
panic!("{:?} at PC {:#08x} in stack guard page ({:#08x}); stack overflow in user kernel code?",
|
||||||
|
cause, u32::try_from(pc).unwrap(), mtval);
|
||||||
|
}
|
||||||
|
}
|
||||||
panic!("{:?} at PC {:#08x}, trap value {:#08x}", cause, u32::try_from(pc).unwrap(), mtval);
|
panic!("{:?} at PC {:#08x}, trap value {:#08x}", cause, u32::try_from(pc).unwrap(), mtval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ const PMP_W : usize = 0b00000010;
|
||||||
const PMP_R : usize = 0b00000001;
|
const PMP_R : usize = 0b00000001;
|
||||||
const PMP_OFF : usize = 0b00000000;
|
const PMP_OFF : usize = 0b00000000;
|
||||||
|
|
||||||
|
pub const STACK_GUARD_SIZE: usize = 0x1000;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn init_stack_guard(guard_base: usize) {
|
pub unsafe fn init_stack_guard(guard_base: usize) {
|
||||||
pmpaddr2::write((guard_base >> 2) | ((0x1000 - 1) >> 3));
|
pmpaddr2::write((guard_base >> 2) | ((0x1000 - 1) >> 3));
|
||||||
|
|
Loading…
Reference in New Issue