Skip to content

Commit d41ce40

Browse files
committed
temp: 增加一些启动逻辑
Signed-off-by: YdrMaster <[email protected]>
1 parent b8637e1 commit d41ce40

File tree

2 files changed

+98
-15
lines changed

2 files changed

+98
-15
lines changed

rustsbi-qemu/src/hsm_cell.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use core::{
2+
cell::UnsafeCell,
3+
hint::spin_loop,
4+
sync::atomic::{AtomicUsize, Ordering},
5+
};
6+
use rustsbi::spec::hsm as spec;
7+
8+
pub struct HsmCell<T> {
9+
state: AtomicUsize,
10+
value: UnsafeCell<Option<T>>,
11+
}
12+
13+
unsafe impl<T: Send> Sync for HsmCell<T> {}
14+
unsafe impl<T: Send> Send for HsmCell<T> {}
15+
16+
const HART_STATE_START_PENDING_EXT: usize = usize::MAX;
17+
18+
#[allow(unused)]
19+
impl<T> HsmCell<T> {
20+
#[inline]
21+
pub fn put(&self, t: T) -> bool {
22+
if self
23+
.state
24+
.compare_exchange(
25+
spec::HART_STATE_STOPPED,
26+
HART_STATE_START_PENDING_EXT,
27+
Ordering::Acquire,
28+
Ordering::Relaxed,
29+
)
30+
.is_ok()
31+
{
32+
unsafe { *self.value.get() = Some(t) };
33+
self.state
34+
.store(spec::HART_STATE_START_PENDING, Ordering::Release);
35+
true
36+
} else {
37+
false
38+
}
39+
}
40+
41+
#[inline]
42+
pub fn take(&self) -> Result<T, usize> {
43+
loop {
44+
match self.state.compare_exchange(
45+
spec::HART_STATE_START_PENDING,
46+
spec::HART_START,
47+
Ordering::AcqRel,
48+
Ordering::Relaxed,
49+
) {
50+
Ok(_) => break Ok(unsafe { (*self.value.get()).take().unwrap() }),
51+
Err(HART_STATE_START_PENDING_EXT) => spin_loop(),
52+
Err(s) => break Err(s),
53+
}
54+
}
55+
}
56+
57+
#[inline]
58+
pub fn sbi_get_status(&self) -> usize {
59+
match self.state.load(Ordering::Acquire) {
60+
HART_STATE_START_PENDING_EXT => spec::HART_STATE_START_PENDING,
61+
normal => normal,
62+
}
63+
}
64+
}

rustsbi-qemu/src/main.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod clint;
77
mod device_tree;
88
mod execute;
99
mod hart_csr_utils;
10+
mod hsm_cell;
1011
mod qemu_hsm;
1112
mod qemu_test;
1213

@@ -24,16 +25,18 @@ extern crate rcore_console;
2425

2526
use constants::*;
2627
use core::{
28+
arch::asm,
2729
convert::Infallible,
2830
mem::{forget, size_of, MaybeUninit},
2931
ptr::NonNull,
30-
sync::atomic::{AtomicBool, AtomicUsize, Ordering::AcqRel},
32+
sync::atomic::{AtomicBool, Ordering},
3133
};
3234
use device_tree::BoardInfo;
3335
use execute::Operation;
3436
use fast_trap::{
3537
reuse_stack_for_trap, FastContext, FastResult, FlowContext, FreeTrapStack, TrapStackBlock,
3638
};
39+
use hsm_cell::HsmCell;
3740
use riscv::register::*;
3841
use rustsbi::RustSBI;
3942
use spin::{Mutex, Once};
@@ -56,7 +59,7 @@ static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
5659
#[no_mangle]
5760
#[link_section = ".text.entry"]
5861
unsafe extern "C" fn _start() -> ! {
59-
core::arch::asm!(
62+
asm!(
6063
// 关中断
6164
" csrw mie, zero",
6265
// 设置栈
@@ -85,6 +88,11 @@ unsafe extern "C" fn _start() -> ! {
8588
)
8689
}
8790

91+
#[naked]
92+
unsafe extern "C" fn _stop() -> ! {
93+
asm!("wfi", options(noreturn))
94+
}
95+
8896
static HSM: Once<qemu_hsm::QemuHsm> = Once::new();
8997

9098
type FixedRustSBI<'a> = RustSBI<
@@ -100,10 +108,9 @@ type FixedRustSBI<'a> = RustSBI<
100108
extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
101109
static GENESIS: AtomicBool = AtomicBool::new(true);
102110
static BOARD_INFO: Once<BoardInfo> = Once::new();
103-
static CSR_PRINT: AtomicBool = AtomicBool::new(false);
104111

105112
// 全局初始化过程
106-
if GENESIS.swap(false, AcqRel) {
113+
if GENESIS.swap(false, Ordering::AcqRel) {
107114
extern "C" {
108115
static mut sbss: u64;
109116
static mut ebss: u64;
@@ -142,17 +149,17 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
142149
dtb = board_info.dtb,
143150
firmware = _start as usize,
144151
);
152+
// 设置并打印 pmp
153+
set_pmp(board_info);
154+
hart_csr_utils::print_pmps();
155+
} else {
156+
set_pmp(BOARD_INFO.wait());
145157
}
146158

147159
unsafe { ROOT_STACK[hart_id()].load_as_stack() };
148160

149161
let hsm = HSM.wait();
150162
if let Some(supervisor) = hsm.take_supervisor() {
151-
// 设置并打印 pmp
152-
set_pmp(BOARD_INFO.wait());
153-
if !CSR_PRINT.swap(true, AcqRel) {
154-
hart_csr_utils::print_pmps();
155-
}
156163
// 初始化 SBI 服务
157164
let sbi = rustsbi::Builder::new_machine()
158165
.with_ipi(&clint::Clint)
@@ -234,7 +241,19 @@ extern "C" fn fast_handler(
234241
match cause.cause() {
235242
T::Exception(E::Unknown) => match cause.bits() {
236243
cause::BOOT => {
237-
// TODO 检查状态,设置启动参数
244+
let hart_id = hart_id();
245+
let hart_ctx = unsafe { ROOT_STACK[hart_id].hart_context() };
246+
match hart_ctx.hsm.take() {
247+
Ok(supervisor) => {
248+
hart_ctx.trap.a[0] = hart_id;
249+
hart_ctx.trap.a[1] = supervisor.opaque;
250+
hart_ctx.trap.pc = supervisor.start_addr;
251+
}
252+
// TODO 检查状态,设置启动参数
253+
Err(_state) => {
254+
hart_ctx.trap.pc = _stop as usize;
255+
}
256+
}
238257
ctx.call(2)
239258
}
240259
_ => todo!(),
@@ -275,7 +294,7 @@ impl Stack {
275294
}
276295

277296
fn load_as_stack(&'static mut self) {
278-
let ptr = unsafe { NonNull::new_unchecked(&mut self.hart_context().flow) };
297+
let ptr = unsafe { NonNull::new_unchecked(&mut self.hart_context().trap) };
279298
forget(
280299
FreeTrapStack::new(StackRef(self), ptr, fast_handler)
281300
.unwrap()
@@ -309,12 +328,12 @@ impl Drop for StackRef {
309328
}
310329
}
311330

331+
/// 硬件线程上下文。
312332
#[repr(C)]
313333
struct HartContext {
314-
flow: FlowContext,
315-
state: AtomicUsize,
316-
start_address: usize,
317-
opaque: usize,
334+
/// 陷入上下文。
335+
trap: FlowContext,
336+
hsm: HsmCell<Supervisor>,
318337
}
319338

320339
/// 特权软件信息。

0 commit comments

Comments
 (0)