Skip to content

Commit bfe7b0a

Browse files
committed
refactor: hsm cell 拆分 crate
temp: 增加启动逻辑 Signed-off-by: YdrMaster <[email protected]>
1 parent d41ce40 commit bfe7b0a

File tree

7 files changed

+156
-71
lines changed

7 files changed

+156
-71
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[workspace]
2-
members = ["rustsbi-qemu", "test-kernel", "bench-kernel", "xtask"]
2+
members = ["rustsbi-qemu", "hsm-cell", "test-kernel", "bench-kernel", "xtask"]
33
default-members = ["xtask"]

hsm-cell/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "hsm-cell"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
sbi-spec = "0.0.4"

hsm-cell/src/lib.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//! 硬件线程状态和受状态保护的线程间共享数据。
2+
3+
#![no_std]
4+
#![deny(warnings, missing_docs)]
5+
6+
use core::{
7+
cell::UnsafeCell,
8+
hint::spin_loop,
9+
sync::atomic::{AtomicUsize, Ordering},
10+
};
11+
use sbi_spec::hsm::*;
12+
13+
/// 硬件线程状态和受状态保护的线程间共享数据。
14+
pub struct HsmCell<T> {
15+
status: AtomicUsize,
16+
val: UnsafeCell<Option<T>>,
17+
}
18+
19+
/// 当前硬件线程的共享对象。
20+
pub struct LocalHsmCell<'a, T>(&'a HsmCell<T>);
21+
22+
/// 任意硬件线程的共享对象。
23+
pub struct RemoteHsmCell<'a, T>(&'a HsmCell<T>);
24+
25+
unsafe impl<T: Send> Sync for HsmCell<T> {}
26+
unsafe impl<T: Send> Send for HsmCell<T> {}
27+
28+
const HART_STATE_START_PENDING_EXT: usize = usize::MAX;
29+
30+
impl<T> HsmCell<T> {
31+
/// 从当前硬件线程的状态中获取线程间共享对象。
32+
///
33+
/// # Safety
34+
///
35+
/// 用户需要确保对象属于当前硬件线程。
36+
#[inline]
37+
pub unsafe fn local(&self) -> LocalHsmCell<'_, T> {
38+
LocalHsmCell(self)
39+
}
40+
41+
/// 取出共享对象。
42+
#[inline]
43+
pub fn remote(&self) -> RemoteHsmCell<'_, T> {
44+
RemoteHsmCell(self)
45+
}
46+
}
47+
48+
impl<T> LocalHsmCell<'_, T> {
49+
/// 从启动挂起状态的硬件线程取出共享数据,并将其状态设置为启动,如果成功返回取出的数据,否则返回当前状态。
50+
#[inline]
51+
pub fn start(&self) -> Result<T, usize> {
52+
loop {
53+
match self.0.status.compare_exchange(
54+
HART_STATE_START_PENDING,
55+
HART_STATE_STARTED,
56+
Ordering::AcqRel,
57+
Ordering::Relaxed,
58+
) {
59+
Ok(_) => break Ok(unsafe { (*self.0.val.get()).take().unwrap() }),
60+
Err(HART_STATE_START_PENDING_EXT) => spin_loop(),
61+
Err(s) => break Err(s),
62+
}
63+
}
64+
}
65+
}
66+
67+
impl<T> RemoteHsmCell<'_, T> {
68+
/// 向关闭状态的硬件线程传入共享数据,并将其状态设置为启动挂起,返回是否放入成功。
69+
#[inline]
70+
pub fn start(self, t: T) -> bool {
71+
if self
72+
.0
73+
.status
74+
.compare_exchange(
75+
HART_STATE_STOPPED,
76+
HART_STATE_START_PENDING_EXT,
77+
Ordering::Acquire,
78+
Ordering::Relaxed,
79+
)
80+
.is_ok()
81+
{
82+
unsafe { *self.0.val.get() = Some(t) };
83+
self.0
84+
.status
85+
.store(HART_STATE_START_PENDING, Ordering::Release);
86+
true
87+
} else {
88+
false
89+
}
90+
}
91+
92+
/// 取出当前状态。
93+
#[inline]
94+
pub fn sbi_get_status(&self) -> usize {
95+
match self.0.status.load(Ordering::Acquire) {
96+
HART_STATE_START_PENDING_EXT => HART_STATE_START_PENDING,
97+
normal => normal,
98+
}
99+
}
100+
}

rustsbi-qemu/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ rcore-console = "0.0.0"
2727
dtb-walker = "=0.2.0-alpha.3"
2828
qemu-exit = "3.0"
2929

30+
hsm-cell = { path = "../hsm-cell" }
3031
fast-trap = { git = "https://github.com/YdrMaster/fast-trap", features = [
3132
"riscv-m",
3233
] }

rustsbi-qemu/src/hsm_cell.rs

Lines changed: 0 additions & 64 deletions
This file was deleted.

rustsbi-qemu/src/main.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ mod clint;
77
mod device_tree;
88
mod execute;
99
mod hart_csr_utils;
10-
mod hsm_cell;
1110
mod qemu_hsm;
1211
mod qemu_test;
1312

@@ -34,7 +33,8 @@ use core::{
3433
use device_tree::BoardInfo;
3534
use execute::Operation;
3635
use fast_trap::{
37-
reuse_stack_for_trap, FastContext, FastResult, FlowContext, FreeTrapStack, TrapStackBlock,
36+
load_direct_trap_entry, reuse_stack_for_trap, FastContext, FastResult, FlowContext,
37+
FreeTrapStack, TrapStackBlock,
3838
};
3939
use hsm_cell::HsmCell;
4040
use riscv::register::*;
@@ -152,11 +152,38 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
152152
// 设置并打印 pmp
153153
set_pmp(board_info);
154154
hart_csr_utils::print_pmps();
155+
// 设置陷入栈
156+
unsafe { ROOT_STACK[hart_id()].load_as_stack() };
157+
// 设置内核入口
158+
unsafe {
159+
ROOT_STACK[hart_id()]
160+
.hart_context()
161+
.hsm
162+
.remote()
163+
.start(Supervisor {
164+
start_addr: SUPERVISOR_ENTRY,
165+
opaque,
166+
});
167+
}
155168
} else {
169+
// 设置 pmp
156170
set_pmp(BOARD_INFO.wait());
171+
// 设置陷入栈
172+
unsafe { ROOT_STACK[hart_id()].load_as_stack() };
173+
}
174+
// 准备启动调度
175+
unsafe {
176+
asm!("csrw mcause, {}", in(reg) cause::BOOT);
177+
asm!("csrw mideleg, {}", in(reg) !0);
178+
asm!("csrw medeleg, {}", in(reg) !0);
179+
asm!("csrw mcounteren, {}", in(reg) !0);
180+
medeleg::clear_supervisor_env_call();
181+
medeleg::clear_machine_env_call();
182+
mie::set_mext();
183+
mie::set_msoft();
184+
mie::set_mtimer();
185+
load_direct_trap_entry();
157186
}
158-
159-
unsafe { ROOT_STACK[hart_id()].load_as_stack() };
160187

161188
let hsm = HSM.wait();
162189
if let Some(supervisor) = hsm.take_supervisor() {
@@ -243,8 +270,12 @@ extern "C" fn fast_handler(
243270
cause::BOOT => {
244271
let hart_id = hart_id();
245272
let hart_ctx = unsafe { ROOT_STACK[hart_id].hart_context() };
246-
match hart_ctx.hsm.take() {
273+
match unsafe { hart_ctx.hsm.local() }.start() {
247274
Ok(supervisor) => {
275+
unsafe {
276+
mstatus::set_mpie();
277+
mstatus::set_mpp(mstatus::MPP::Supervisor);
278+
}
248279
hart_ctx.trap.a[0] = hart_id;
249280
hart_ctx.trap.a[1] = supervisor.opaque;
250281
hart_ctx.trap.pc = supervisor.start_addr;
@@ -256,7 +287,7 @@ extern "C" fn fast_handler(
256287
}
257288
ctx.call(2)
258289
}
259-
_ => todo!(),
290+
_ => unreachable!(),
260291
},
261292
T::Exception(_) | T::Interrupt(_) => todo!(),
262293
}

0 commit comments

Comments
 (0)