Skip to content

Commit ded7188

Browse files
committed
refactor: 封装 trap_stack 以探索复用的可能性
Signed-off-by: YdrMaster <[email protected]>
1 parent 97395c9 commit ded7188

File tree

4 files changed

+174
-159
lines changed

4 files changed

+174
-159
lines changed

rustsbi-qemu/src/main.rs

Lines changed: 47 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod device_tree;
88
mod hart_csr_utils;
99
mod qemu_test;
1010
mod riscv_spec;
11+
mod trap_stack;
1112
mod trap_vec;
1213

1314
mod constants {
@@ -26,24 +27,18 @@ use constants::*;
2627
use core::{
2728
arch::asm,
2829
convert::Infallible,
29-
mem::{forget, size_of, MaybeUninit},
30-
ptr::NonNull,
30+
mem::MaybeUninit,
3131
sync::atomic::{AtomicBool, Ordering},
3232
};
3333
use device_tree::BoardInfo;
34-
use fast_trap::{FastContext, FastResult, FlowContext, FreeTrapStack, TrapStackBlock};
35-
use hsm_cell::HsmCell;
34+
use fast_trap::{FastContext, FastResult};
3635
use riscv_spec::*;
3736
use rustsbi::RustSBI;
3837
use sbi_spec::binary::SbiRet;
3938
use spin::{Mutex, Once};
40-
use trap_vec::{load_trap_vec, trap_vec};
39+
use trap_stack::{local_hsm, local_remote_hsm, remote_hsm};
4140
use uart_16550::MmioSerialPort;
4241

43-
/// 栈空间。
44-
#[link_section = ".bss.uninit"]
45-
static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
46-
4742
/// 入口。
4843
///
4944
/// # Safety
@@ -54,22 +49,13 @@ static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
5449
#[link_section = ".text.entry"]
5550
unsafe extern "C" fn _start() -> ! {
5651
asm!(
57-
" la sp, {stack}
58-
li t0, {per_hart_stack_size}
59-
csrr t1, mhartid
60-
addi t1, t1, 1
61-
1: add sp, sp, t0
62-
addi t1, t1, -1
63-
bnez t1, 1b
64-
call {move_stack}
52+
" call {locate_stack}
6553
call {rust_main}
6654
j {trap}
6755
",
68-
per_hart_stack_size = const LEN_STACK_PER_HART,
69-
stack = sym ROOT_STACK,
70-
move_stack = sym fast_trap::reuse_stack_for_trap,
71-
rust_main = sym rust_main,
72-
trap = sym trap_vec,
56+
locate_stack = sym trap_stack::locate,
57+
rust_main = sym rust_main,
58+
trap = sym trap_vec::trap_vec,
7359
options(noreturn)
7460
)
7561
}
@@ -139,24 +125,18 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
139125
set_pmp(board_info);
140126
hart_csr_utils::print_pmps();
141127
// 设置陷入栈
142-
unsafe { ROOT_STACK[hart_id()].load_as_stack() };
128+
trap_stack::load();
143129
// 设置内核入口
144-
unsafe {
145-
ROOT_STACK[hart_id()]
146-
.hart_context()
147-
.hsm
148-
.remote()
149-
.start(Supervisor {
150-
start_addr: SUPERVISOR_ENTRY,
151-
opaque,
152-
});
153-
}
130+
local_remote_hsm().start(Supervisor {
131+
start_addr: SUPERVISOR_ENTRY,
132+
opaque,
133+
});
154134
DONE.store(false, Ordering::SeqCst);
155135
} else {
156136
// 设置 pmp
157137
set_pmp(BOARD_INFO.wait());
158138
// 设置陷入栈
159-
unsafe { ROOT_STACK[hart_id()].load_as_stack() };
139+
trap_stack::load();
160140
while DONE.load(Ordering::SeqCst) {
161141
core::hint::spin_loop();
162142
}
@@ -227,30 +207,25 @@ extern "C" fn fast_handler(
227207
|| cause.cause() == T::Interrupt(I::MachineSoft)
228208
{
229209
let hart_id = hart_id();
230-
let hart_ctx = unsafe { ROOT_STACK[hart_id].hart_context() };
231-
match unsafe { hart_ctx.hsm.local() }.start() {
210+
match local_hsm().start() {
232211
Ok(supervisor) => {
233-
unsafe {
234-
let mut status = mstatus::read();
235-
status &= !mstatus::MPP;
236-
status |= mstatus::MPIE | mstatus::MPP_SUPERVISOR;
237-
mstatus::write(status);
238-
mie::write(mie::MSIE | mie::MTIE | mie::MEIE);
239-
load_trap_vec(true);
240-
}
212+
mstatus::update(|bits| {
213+
*bits &= !mstatus::MPP;
214+
*bits |= mstatus::MPIE | mstatus::MPP_SUPERVISOR;
215+
});
216+
mie::write(mie::MSIE | mie::MTIE | mie::MEIE);
217+
trap_vec::load(true);
241218
ctx.regs().a[0] = hart_id;
242219
ctx.regs().a[1] = supervisor.opaque;
243220
ctx.regs().pc = supervisor.start_addr;
244221
}
245222
Err(_state) => {
246-
unsafe {
247-
let mut status = mstatus::read();
248-
status &= !mstatus::MPP;
249-
status |= mstatus::MPIE | mstatus::MPP_MACHINE;
250-
mstatus::write(status);
251-
mie::write(mie::MSIE);
252-
load_trap_vec(false);
253-
};
223+
mstatus::update(|bits| {
224+
*bits &= !mstatus::MPP;
225+
*bits |= mstatus::MPIE | mstatus::MPP_MACHINE;
226+
});
227+
mie::write(mie::MSIE);
228+
trap_vec::load(false);
254229
ctx.regs().pc = _stop as usize;
255230
}
256231
}
@@ -268,22 +243,18 @@ extern "C" fn fast_handler(
268243
if ret.is_ok() && a7 == hsm::EID_HSM {
269244
// 关闭
270245
if a6 == hsm::HART_STOP {
271-
unsafe {
272-
load_trap_vec(false);
273-
mie::write(mie::MSIE);
274-
ROOT_STACK[hart_id()].hart_context().hsm.local().stop();
275-
ctx.regs().pc = _stop as usize;
276-
}
246+
local_hsm().stop();
247+
mie::write(mie::MSIE);
248+
trap_vec::load(false);
249+
ctx.regs().pc = _stop as _;
277250
return ctx.call(0);
278251
}
279252
// 不可恢复挂起
280253
if a6 == hsm::HART_SUSPEND
281254
&& ctx.a0() == hsm::HART_SUSPEND_TYPE_NON_RETENTIVE as usize
282255
{
283-
unsafe {
284-
load_trap_vec(false);
285-
ctx.regs().pc = _stop as usize;
286-
}
256+
trap_vec::load(false);
257+
ctx.regs().pc = _stop as _;
287258
return ctx.call(0);
288259
}
289260
}
@@ -325,69 +296,6 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
325296
unreachable!()
326297
}
327298

328-
/// 类型化栈。
329-
///
330-
/// 每个硬件线程拥有一个满足这样条件的内存块。
331-
/// 这个内存块的底部放着硬件线程状态 [`HartContext`],顶部用于陷入处理,中间是这个硬件线程的栈空间。
332-
/// 不需要 M 态线程,每个硬件线程只有这一个栈。
333-
#[repr(C, align(128))]
334-
struct Stack([u8; LEN_STACK_PER_HART]);
335-
336-
impl Stack {
337-
/// 零初始化以避免加载。
338-
const ZERO: Self = Self([0; LEN_STACK_PER_HART]);
339-
340-
/// 从栈上取出硬件线程状态。
341-
#[inline]
342-
fn hart_context(&mut self) -> &mut HartContext {
343-
unsafe { &mut *self.0.as_mut_ptr().cast() }
344-
}
345-
346-
fn load_as_stack(&'static mut self) {
347-
let hart = self.hart_context();
348-
hart.hsm = HsmCell::new();
349-
let ptr = unsafe { NonNull::new_unchecked(&mut hart.trap) };
350-
forget(
351-
FreeTrapStack::new(StackRef(self), ptr, fast_handler)
352-
.unwrap()
353-
.load(),
354-
);
355-
}
356-
}
357-
358-
#[repr(transparent)]
359-
struct StackRef(&'static mut Stack);
360-
361-
impl AsRef<[u8]> for StackRef {
362-
#[inline]
363-
fn as_ref(&self) -> &[u8] {
364-
&self.0 .0[size_of::<HartContext>()..]
365-
}
366-
}
367-
368-
impl AsMut<[u8]> for StackRef {
369-
#[inline]
370-
fn as_mut(&mut self) -> &mut [u8] {
371-
&mut self.0 .0[size_of::<HartContext>()..]
372-
}
373-
}
374-
375-
impl TrapStackBlock for StackRef {}
376-
377-
impl Drop for StackRef {
378-
fn drop(&mut self) {
379-
panic!("Root stack cannot be dropped")
380-
}
381-
}
382-
383-
/// 硬件线程上下文。
384-
#[repr(C)]
385-
struct HartContext {
386-
/// 陷入上下文。
387-
trap: FlowContext,
388-
hsm: HsmCell<Supervisor>,
389-
}
390-
391299
/// 特权软件信息。
392300
#[derive(Debug)]
393301
struct Supervisor {
@@ -429,9 +337,9 @@ struct Hsm;
429337

430338
impl rustsbi::Hsm for Hsm {
431339
fn hart_start(&self, hartid: usize, start_addr: usize, opaque: usize) -> SbiRet {
432-
match unsafe { ROOT_STACK.get_mut(hartid).map(|s| s.hart_context()) } {
433-
Some(hart) => {
434-
if hart.hsm.remote().start(Supervisor { start_addr, opaque }) {
340+
match remote_hsm(hartid) {
341+
Some(remote) => {
342+
if remote.start(Supervisor { start_addr, opaque }) {
435343
clint::msip::send(hartid);
436344
SbiRet::success(0)
437345
} else {
@@ -444,40 +352,30 @@ impl rustsbi::Hsm for Hsm {
444352

445353
#[inline]
446354
fn hart_stop(&self) -> SbiRet {
447-
unsafe {
448-
ROOT_STACK[hart_id()]
449-
.hart_context()
450-
.hsm
451-
.local()
452-
.stop_pending()
453-
};
355+
local_hsm().stop_pending();
454356
SbiRet::success(0)
455357
}
456358

457359
#[inline]
458360
fn hart_get_status(&self, hartid: usize) -> SbiRet {
459-
match unsafe { ROOT_STACK.get_mut(hartid).map(|s| s.hart_context()) } {
460-
Some(hart) => SbiRet::success(hart.hsm.remote().sbi_get_status()),
361+
match remote_hsm(hartid) {
362+
Some(remote) => SbiRet::success(remote.sbi_get_status()),
461363
None => SbiRet::invalid_param(),
462364
}
463365
}
464366

465367
fn hart_suspend(&self, suspend_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
466368
use sbi_spec::hsm as spec;
467369
match suspend_type {
468-
spec::HART_SUSPEND_TYPE_NON_RETENTIVE => unsafe {
469-
ROOT_STACK[hart_id()]
470-
.hart_context()
471-
.hsm
472-
.local()
473-
.suspend_non_retentive(Supervisor {
474-
start_addr: resume_addr,
475-
opaque,
476-
});
370+
spec::HART_SUSPEND_TYPE_NON_RETENTIVE => {
371+
local_hsm().suspend_non_retentive(Supervisor {
372+
start_addr: resume_addr,
373+
opaque,
374+
});
477375
SbiRet::success(0)
478-
},
376+
}
479377
spec::HART_SUSPEND_TYPE_RETENTIVE => unsafe {
480-
ROOT_STACK[hart_id()].hart_context().hsm.local().suspend();
378+
local_hsm().suspend();
481379
asm!(
482380
" la {0}, 1f
483381
csrrw {0}, mtvec, {0}
@@ -493,7 +391,7 @@ impl rustsbi::Hsm for Hsm {
493391
out(reg) _,
494392
mie = const mstatus::MIE,
495393
);
496-
ROOT_STACK[hart_id()].hart_context().hsm.local().resume();
394+
local_hsm().resume();
497395
SbiRet::success(0)
498396
},
499397
_ => SbiRet::not_supported(),

rustsbi-qemu/src/riscv_spec.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,10 @@ pub mod mstatus {
4848
pub const MPP_SUPERVISOR: usize = 1 << 11;
4949
pub const MPP_USER: usize = 0 << 11;
5050

51-
#[inline(always)]
52-
pub fn read() -> usize {
53-
let bits: usize;
51+
pub fn update(f: impl FnOnce(&mut usize)) {
52+
let mut bits: usize;
5453
unsafe { asm!("csrr {}, mstatus", out(reg) bits, options(nomem)) };
55-
bits
56-
}
57-
58-
#[inline(always)]
59-
pub fn write(bits: usize) {
54+
f(&mut bits);
6055
unsafe { asm!("csrw mstatus, {}", in(reg) bits, options(nomem)) };
6156
}
6257
}

0 commit comments

Comments
 (0)