1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- use core::mem::forget;
- use fast_trap::FreeTrapStack;
- use crate::hsm::HartContext;
- use crate::trap::fast_handler;
- use crate::hart_id;
- const LEN_STACK_PER_HART: usize = 16 * 1024;
- pub const NUM_HART_MAX: usize = 8;
- #[link_section = ".bss.uninit"]
- pub(crate) static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
- #[naked]
- pub(crate) unsafe extern "C" fn locate() {
- core::arch::asm!(
- " la sp, {stack}
- li t0, {per_hart_stack_size}
- csrr t1, mhartid
- addi t1, t1, 1
- 1: add sp, sp, t0
- addi t1, t1, -1
- bnez t1, 1b
- call t1, {move_stack}
- ret
- ",
- per_hart_stack_size = const LEN_STACK_PER_HART,
- stack = sym ROOT_STACK,
- move_stack = sym fast_trap::reuse_stack_for_trap,
- options(noreturn),
- )
- }
- pub(crate) fn prepare_for_trap() {
- unsafe { ROOT_STACK.get_unchecked_mut(hart_id()).load_as_stack() };
- }
- #[repr(C, align(128))]
- pub(crate) struct Stack([u8; LEN_STACK_PER_HART]);
- impl Stack {
-
- const ZERO: Self = Self([0; LEN_STACK_PER_HART]);
-
- #[inline]
- pub fn hart_context(&mut self) -> &mut HartContext {
- unsafe { &mut *self.0.as_mut_ptr().cast() }
- }
- fn load_as_stack(&'static mut self) {
- let hart = self.hart_context();
- let context_ptr = hart.context_ptr();
- hart.init();
- let range = self.0.as_ptr_range();
- forget(
- FreeTrapStack::new(
- range.start as usize..range.end as usize,
- |_| {},
- context_ptr,
- fast_handler,
- )
- .unwrap()
- .load(),
- );
- }
- }
|