Skip to content

Commit cbbb8a7

Browse files
committed
todo: 再补充部分系统重置逻辑
Signed-off-by: YdrMaster <ydrml@hotmail.com>
1 parent 86e16dd commit cbbb8a7

File tree

4 files changed

+110
-52
lines changed

4 files changed

+110
-52
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rustsbi-qemu/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ readme = "README.md"
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10-
rustsbi = { git = "https://github.com/YdrMaster/rustsbi.git", rev = "2aeecdf" }
10+
rustsbi = { git = "https://github.com/YdrMaster/rustsbi.git", rev = "bd3c092" }
1111
riscv = "0.8"
1212
spin = "0.9"
1313
r0 = "1"

rustsbi-qemu/src/execute.rs

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
use crate::{clint, hart_id, qemu_hsm::QemuHsm, Supervisor};
22
use riscv::register::{mstatus, mtval, scause, sepc, stval, stvec};
33

4-
pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
4+
#[repr(usize)]
5+
pub(crate) enum Operation {
6+
Stop = 0,
7+
SystemReset = usize::MAX,
8+
}
9+
10+
pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) -> Operation {
511
use core::arch::asm;
612
use riscv::register::{medeleg, mie};
713

@@ -50,30 +56,9 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
5056
}
5157
}
5258
T::Exception(E::SupervisorEnvCall) => {
53-
use rustsbi::spec::{binary::*, hsm::*, srst::*};
54-
let param = [ctx.a(0), ctx.a(1), ctx.a(2), ctx.a(3), ctx.a(4), ctx.a(5)];
55-
let ans = rustsbi::ecall(ctx.a(7), ctx.a(6), param);
56-
if ans.error == RET_SUCCESS {
57-
match ctx.a(7) {
58-
EID_HSM => match ctx.a(6) {
59-
HART_STOP => return,
60-
HART_SUSPEND
61-
if ctx.a(0) == HART_SUSPEND_TYPE_NON_RETENTIVE as usize =>
62-
{
63-
return
64-
}
65-
_ => {}
66-
},
67-
EID_SRST => match ctx.a(0) as u32 {
68-
RESET_TYPE_COLD_REBOOT | RESET_TYPE_WARM_REBOOT => todo!(),
69-
_ => {}
70-
},
71-
_ => {}
72-
}
59+
if let Some(op) = ctx.handle_ecall() {
60+
return op;
7361
}
74-
*ctx.a_mut(0) = ans.error;
75-
*ctx.a_mut(1) = ans.value;
76-
ctx.mepc = ctx.mepc.wrapping_add(4);
7762
}
7863
T::Exception(E::IllegalInstruction) => {
7964
use riscv::register::scause::{Exception as E, Trap as T};
@@ -149,7 +134,61 @@ impl Context {
149134
self.x_mut(n + 10)
150135
}
151136

152-
pub(super) fn do_transfer_trap(&mut self, cause: scause::Trap) {
137+
fn handle_ecall(&mut self) -> Option<Operation> {
138+
use rustsbi::spec::{binary::*, hsm::*, srst::*};
139+
let extension = self.a(7);
140+
let function = self.a(6);
141+
let ans = rustsbi::ecall(
142+
extension,
143+
function,
144+
[
145+
self.a(0),
146+
self.a(1),
147+
self.a(2),
148+
self.a(3),
149+
self.a(4),
150+
self.a(5),
151+
],
152+
);
153+
// 判断导致退出执行流程的调用
154+
if ans.error == RET_SUCCESS {
155+
match extension {
156+
// 核状态
157+
EID_HSM => match function {
158+
HART_STOP => return Some(Operation::Stop),
159+
HART_SUSPEND
160+
if matches!(
161+
u32::try_from(self.a(0)),
162+
Ok(HART_SUSPEND_TYPE_NON_RETENTIVE)
163+
) =>
164+
{
165+
return Some(Operation::Stop);
166+
}
167+
_ => {}
168+
},
169+
// 系统重置
170+
EID_SRST => match function {
171+
SYSTEM_RESET
172+
if matches!(
173+
u32::try_from(self.a(0)),
174+
Ok(RESET_TYPE_COLD_REBOOT) | Ok(RESET_TYPE_WARM_REBOOT)
175+
) =>
176+
{
177+
return Some(Operation::SystemReset)
178+
}
179+
_ => {}
180+
},
181+
182+
_ => {}
183+
}
184+
}
185+
*self.a_mut(0) = ans.error;
186+
*self.a_mut(1) = ans.value;
187+
self.mepc = self.mepc.wrapping_add(4);
188+
None
189+
}
190+
191+
fn do_transfer_trap(&mut self, cause: scause::Trap) {
153192
unsafe {
154193
// 向 S 转发陷入
155194
mstatus::set_mpp(mstatus::MPP::Supervisor);

rustsbi-qemu/src/main.rs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
#![no_main]
44
#![deny(warnings)]
55

6-
#[macro_use] // for print
7-
extern crate rustsbi;
8-
96
mod clint;
107
mod device_tree;
118
mod execute;
@@ -14,6 +11,15 @@ mod ns16550a;
1411
mod qemu_hsm;
1512
mod qemu_test;
1613

14+
#[macro_use] // for print
15+
extern crate rustsbi;
16+
17+
use constants::*;
18+
use core::sync::atomic::{AtomicBool, Ordering::AcqRel};
19+
use device_tree::BoardInfo;
20+
use execute::Operation;
21+
use spin::Once;
22+
1723
mod constants {
1824
/// 特权软件入口。
1925
pub(crate) const SUPERVISOR_ENTRY: usize = 0x8020_0000;
@@ -25,8 +31,6 @@ mod constants {
2531
pub(crate) const LEN_STACK_SBI: usize = LEN_STACK_PER_HART * NUM_HART_MAX;
2632
}
2733

28-
use constants::*;
29-
3034
/// 特权软件信息。
3135
struct Supervisor {
3236
start_addr: usize,
@@ -60,24 +64,27 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
6064
#[naked]
6165
#[link_section = ".text.entry"]
6266
#[export_name = "_start"]
63-
unsafe extern "C" fn entry(hartid: usize, opaque: usize) -> ! {
67+
unsafe extern "C" fn entry() -> ! {
6468
#[link_section = ".bss.uninit"]
6569
static mut SBI_STACK: [u8; LEN_STACK_SBI] = [0; LEN_STACK_SBI];
6670

67-
core::arch::asm!("
68-
csrw mie, zero
69-
csrr a0, mhartid
70-
la sp, {stack}
71+
core::arch::asm!(
72+
// 关中断
73+
" csrw mie, zero",
74+
// 设置栈
75+
" la sp, {stack}
7176
li t0, {per_hart_stack_size}
72-
addi t1, a0, 1
77+
csrr t1, mhartid
78+
addi t1, t1, 1
7379
1: add sp, sp, t0
7480
addi t1, t1, -1
75-
bnez t1, 1b
76-
call {rust_main}
77-
call {finalize}
81+
bnez t1, 1b",
82+
" call {rust_main}",
83+
// 清理,然后重启或等待
84+
" call {finalize}
85+
bnez a0, _start
7886
1: wfi
79-
j 1b
80-
",
87+
j 1b",
8188
per_hart_stack_size = const LEN_STACK_PER_HART,
8289
stack = sym SBI_STACK,
8390
rust_main = sym rust_main,
@@ -104,14 +111,10 @@ extern "C" fn early_trap() -> ! {
104111
}
105112
}
106113

107-
use core::sync::atomic::{AtomicBool, Ordering::AcqRel};
108-
use device_tree::BoardInfo;
109-
use spin::Once;
110-
111114
static HSM: Once<qemu_hsm::QemuHsm> = Once::new();
112115

113116
/// rust 入口。
114-
extern "C" fn rust_main(_hartid: usize, opaque: usize) {
117+
extern "C" fn rust_main(_hartid: usize, opaque: usize) -> Operation {
115118
unsafe { set_mtvec(early_trap as _) };
116119

117120
#[link_section = ".bss.uninit"] // 以免清零
@@ -168,22 +171,38 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
168171

169172
let hsm = HSM.wait();
170173
if let Some(supervisor) = hsm.take_supervisor() {
174+
use execute::*;
171175
// 设置并打印 pmp
172176
set_pmp(BOARD_INFO.wait());
173177
if !CSR_PRINT.swap(true, AcqRel) {
174178
hart_csr_utils::print_pmps();
175179
}
176-
execute::execute_supervisor(hsm, supervisor);
180+
execute_supervisor(hsm, supervisor)
181+
} else {
182+
Operation::Stop
177183
}
178184
}
179185

180186
/// 准备好不可恢复休眠或关闭
181187
///
182188
/// 在隔离的环境(汇编)调用,以确保 main 中使用的堆资源完全释放。
183189
/// (只是作为示例,因为这个版本完全不使用堆)
184-
extern "C" fn finalize() {
185-
HSM.wait().finallize_before_stop();
186-
unsafe { riscv::interrupt::enable() };
190+
unsafe extern "C" fn finalize(op: Operation) -> ! {
191+
match op {
192+
Operation::Stop => {
193+
HSM.wait().finallize_before_stop();
194+
riscv::interrupt::enable();
195+
// 从中断响应直接回 entry
196+
loop {
197+
riscv::asm::wfi();
198+
}
199+
}
200+
Operation::SystemReset => {
201+
// TODO 等待其他核关闭
202+
// 直接回 entry
203+
entry()
204+
}
205+
}
187206
}
188207

189208
/// 清零 bss 段。

0 commit comments

Comments
 (0)