Skip to content

Commit 25d45c2

Browse files
committed
feat: 初始化陷入栈
Signed-off-by: YdrMaster <[email protected]>
1 parent fc79b31 commit 25d45c2

File tree

3 files changed

+79
-6
lines changed

3 files changed

+79
-6
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rustsbi-qemu/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ uart_16550 = "0.2"
2626
rcore-console = "0.0.0"
2727
dtb-walker = "=0.2.0-alpha.3"
2828
qemu-exit = "3.0"
29+
30+
fast-trap = { git = "https://github.com/YdrMaster/fast-trap", features = [
31+
"riscv-m",
32+
] }

rustsbi-qemu/src/main.rs

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,21 @@ extern crate rcore_console;
2525
use constants::*;
2626
use core::{
2727
convert::Infallible,
28-
mem::MaybeUninit,
28+
mem::{forget, MaybeUninit},
29+
ptr::NonNull,
2930
sync::atomic::{AtomicBool, Ordering::AcqRel},
3031
};
3132
use device_tree::BoardInfo;
3233
use execute::Operation;
34+
use fast_trap::{reuse_stack_for_trap, FastContext, FastResult, FreeTrapStack, TrapStackBlock};
3335
use rustsbi::RustSBI;
3436
use spin::{Mutex, Once};
3537
use uart_16550::MmioSerialPort;
3638

39+
/// 栈空间。
40+
#[link_section = ".bss.uninit"]
41+
static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
42+
3743
/// 入口。
3844
///
3945
/// 1. 关中断
@@ -47,9 +53,6 @@ use uart_16550::MmioSerialPort;
4753
#[no_mangle]
4854
#[link_section = ".text.entry"]
4955
unsafe extern "C" fn _start() -> ! {
50-
#[link_section = ".bss.uninit"]
51-
static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
52-
5356
core::arch::asm!(
5457
// 关中断
5558
" csrw mie, zero",
@@ -60,15 +63,19 @@ unsafe extern "C" fn _start() -> ! {
6063
addi t1, t1, 1
6164
1: add sp, sp, t0
6265
addi t1, t1, -1
63-
bnez t1, 1b",
66+
bnez t1, 1b
67+
call {move_stack}
68+
",
6469
" call {rust_main}",
6570
// 清理,然后重启或等待
6671
" call {finalize}
6772
bnez a0, _start
6873
1: wfi
69-
j 1b",
74+
j 1b
75+
",
7076
per_hart_stack_size = const LEN_STACK_PER_HART,
7177
stack = sym ROOT_STACK,
78+
move_stack = sym reuse_stack_for_trap,
7279
rust_main = sym rust_main,
7380
finalize = sym finalize,
7481
options(noreturn)
@@ -134,6 +141,8 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
134141
);
135142
}
136143

144+
unsafe { ROOT_STACK[hart_id()].load_as_stack() };
145+
137146
let hsm = HSM.wait();
138147
if let Some(supervisor) = hsm.take_supervisor() {
139148
// 设置并打印 pmp
@@ -205,6 +214,19 @@ fn set_pmp(board_info: &BoardInfo) {
205214
}
206215
}
207216

217+
extern "C" fn fast_handler(
218+
mut _ctx: FastContext,
219+
_a1: usize,
220+
_a2: usize,
221+
_a3: usize,
222+
_a4: usize,
223+
_a5: usize,
224+
_a6: usize,
225+
_a7: usize,
226+
) -> FastResult {
227+
todo!()
228+
}
229+
208230
#[panic_handler]
209231
fn panic(info: &core::panic::PanicInfo) -> ! {
210232
use rustsbi::{
@@ -225,6 +247,44 @@ struct Stack([u8; LEN_STACK_PER_HART]);
225247
impl Stack {
226248
/// 零初始化以避免加载。
227249
const ZERO: Self = Self([0; LEN_STACK_PER_HART]);
250+
251+
fn load_as_stack(&'static mut self) {
252+
let bottom = self.0.as_mut_ptr().cast();
253+
forget(
254+
FreeTrapStack::new(
255+
StackRef(self),
256+
unsafe { NonNull::new_unchecked(bottom) },
257+
fast_handler,
258+
)
259+
.unwrap()
260+
.load(),
261+
);
262+
}
263+
}
264+
265+
#[repr(transparent)]
266+
struct StackRef(&'static mut Stack);
267+
268+
impl AsRef<[u8]> for StackRef {
269+
#[inline]
270+
fn as_ref(&self) -> &[u8] {
271+
&self.0 .0
272+
}
273+
}
274+
275+
impl AsMut<[u8]> for StackRef {
276+
#[inline]
277+
fn as_mut(&mut self) -> &mut [u8] {
278+
&mut self.0 .0
279+
}
280+
}
281+
282+
impl TrapStackBlock for StackRef {}
283+
284+
impl Drop for StackRef {
285+
fn drop(&mut self) {
286+
panic!("Root stack cannot be dropped")
287+
}
228288
}
229289

230290
/// 特权软件信息。

0 commit comments

Comments
 (0)