Skip to content

Commit 14ad46f

Browse files
committed
refactor: 使用 qemu-exit 实现关机
temp: 实现系统重启操作的一部分,exectute 还没接住 Signed-off-by: YdrMaster <ydrml@hotmail.com>
1 parent c2843d3 commit 14ad46f

File tree

8 files changed

+101
-96
lines changed

8 files changed

+101
-96
lines changed

Cargo.lock

Lines changed: 18 additions & 2 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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ 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 = "118ca4c" }
10+
rustsbi = { git = "https://github.com/YdrMaster/rustsbi.git", rev = "0bcbd5b" }
1111
riscv = "0.8"
1212
spin = "0.9"
1313
r0 = "1"
1414
uart_16550 = "0.2"
1515
dtb-walker = "0.1.1"
16+
qemu-exit = "3.0"

rustsbi-qemu/src/execute.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use crate::{
2-
clint, hart_id,
3-
qemu_hsm::{QemuHsm, SUSPEND_NON_RETENTIVE},
4-
Supervisor,
5-
};
1+
use crate::{clint, hart_id, qemu_hsm::QemuHsm, Supervisor};
62
use riscv::register::{mstatus, mtval, scause, sepc, stval, stvec};
73

84
pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
@@ -33,7 +29,6 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
3329

3430
hsm.record_current_start_finished();
3531
loop {
36-
use crate::qemu_hsm::{EID_HSM, FID_HART_STOP, FID_HART_SUSPEND};
3732
use riscv::register::{
3833
mcause::{self, Exception as E, Interrupt as I, Trap as T},
3934
mip,
@@ -55,12 +50,24 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
5550
}
5651
}
5752
T::Exception(E::SupervisorEnvCall) => {
53+
use rustsbi::spec::{binary::*, hsm::*, srst::*};
5854
let param = [ctx.a(0), ctx.a(1), ctx.a(2), ctx.a(3), ctx.a(4), ctx.a(5)];
5955
let ans = rustsbi::ecall(ctx.a(7), ctx.a(6), param);
60-
if ctx.a(7) == EID_HSM && ans.error == 0 {
61-
match ctx.a(6) {
62-
FID_HART_STOP => return,
63-
FID_HART_SUSPEND if ctx.a(0) == SUSPEND_NON_RETENTIVE => return,
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+
},
6471
_ => {}
6572
}
6673
}

rustsbi-qemu/src/main.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod execute;
1212
mod hart_csr_utils;
1313
mod ns16550a;
1414
mod qemu_hsm;
15-
mod test_device;
15+
mod qemu_test;
1616

1717
mod constants {
1818
/// 特权软件入口。
@@ -36,15 +36,16 @@ struct Supervisor {
3636
#[cfg_attr(not(test), panic_handler)]
3737
fn panic(info: &core::panic::PanicInfo) -> ! {
3838
use rustsbi::{
39-
reset::{RESET_REASON_SYSTEM_FAILURE, RESET_TYPE_SHUTDOWN},
39+
spec::srst::{RESET_REASON_NO_REASON, RESET_TYPE_SHUTDOWN},
4040
Reset,
4141
};
42-
4342
// 输出的信息大概是“[rustsbi-panic] hart 0 panicked at ...”
4443
println!("[rustsbi-panic] hart {} {info}", hart_id());
4544
println!("[rustsbi-panic] system shutdown scheduled due to RustSBI panic");
46-
test_device::get().system_reset(RESET_TYPE_SHUTDOWN, RESET_REASON_SYSTEM_FAILURE);
47-
loop {}
45+
qemu_test::get().system_reset(RESET_TYPE_SHUTDOWN, RESET_REASON_NO_REASON);
46+
loop {
47+
core::hint::spin_loop();
48+
}
4849
}
4950

5051
/// 入口。
@@ -132,12 +133,12 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
132133
);
133134

134135
clint::init(board_info.clint.start);
135-
test_device::init(board_info.test.start);
136+
qemu_test::init(board_info.test.start);
136137
let hsm = HSM.call_once(|| qemu_hsm::QemuHsm::new(clint::get(), NUM_HART_MAX, opaque));
137138
// 初始化 SBI 服务
138139
rustsbi::init_ipi(clint::get());
139140
rustsbi::init_timer(clint::get());
140-
rustsbi::init_reset(test_device::get());
141+
rustsbi::init_reset(qemu_test::get());
141142
rustsbi::init_hsm(hsm);
142143
// 打印启动信息
143144
print!(

rustsbi-qemu/src/qemu_hsm.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,16 @@
22
33
use crate::{clint::Clint, entry, hart_id, set_mtvec, Supervisor, NUM_HART_MAX, SUPERVISOR_ENTRY};
44
use core::{mem::MaybeUninit, sync::atomic::AtomicU8};
5-
use rustsbi::SbiRet;
5+
use rustsbi::{spec::hsm as spec, SbiRet};
66
use spin::Mutex;
77

8-
pub(crate) const SUSPEND_RETENTIVE: usize = 0x00000000;
9-
pub(crate) const SUSPEND_NON_RETENTIVE: usize = 0x80000000;
10-
pub(crate) const EID_HSM: usize = 0x48534D;
11-
pub(crate) const FID_HART_STOP: usize = 1;
12-
pub(crate) const FID_HART_SUSPEND: usize = 3;
13-
14-
const STARTED: u8 = 0;
15-
const STOPPED: u8 = 1;
16-
const START_PENDING: u8 = 2;
17-
const STOP_PENDING: u8 = 3;
18-
const SUSPEND: u8 = 4;
19-
const SUSPEND_PENDING: u8 = 5;
20-
const RESUME_PENDING: u8 = 6;
8+
const STARTED: u8 = spec::HART_STATE_STARTED as _;
9+
const STOPPED: u8 = spec::HART_STATE_STOPPED as _;
10+
const START_PENDING: u8 = spec::HART_STATE_START_PENDING as _;
11+
const STOP_PENDING: u8 = spec::HART_STATE_STOP_PENDING as _;
12+
const SUSPENDED: u8 = spec::HART_STATE_SUSPENDED as _;
13+
const SUSPEND_PENDING: u8 = spec::HART_STATE_SUSPEND_PENDING as _;
14+
const RESUME_PENDING: u8 = spec::HART_STATE_RESUME_PENDING as _;
2115

2216
pub(crate) struct QemuHsm {
2317
clint: &'static Clint,
@@ -76,7 +70,7 @@ impl QemuHsm {
7670
return supervisor;
7771
}
7872
}
79-
SUSPEND => {
73+
SUSPENDED => {
8074
if supervisor.is_none() {
8175
// 在挂起状态但未设置特权态入口,无法恢复
8276
panic!("cannot resume without supervisor!")
@@ -108,7 +102,7 @@ impl QemuHsm {
108102
use core::sync::atomic::Ordering::Acquire;
109103
self.state
110104
.get(hart_id)
111-
.map_or(false, |s| matches!(s.load(Acquire), STARTED | SUSPEND))
105+
.map_or(false, |s| matches!(s.load(Acquire), STARTED | SUSPENDED))
112106
}
113107

114108
/// 为硬件线程准备休眠或关闭。
@@ -130,7 +124,7 @@ impl QemuHsm {
130124
SUSPEND_PENDING => {
131125
// 休眠也可以通过外部中断唤醒
132126
unsafe { mie::set_mext() };
133-
SUSPEND
127+
SUSPENDED
134128
}
135129
s => panic!("wrong state {s:?}!"),
136130
};
@@ -170,7 +164,8 @@ impl QemuHsm {
170164
let mtvec = mtvec::read().address();
171165

172166
// 转移状态
173-
if let Err(unexpected) = state.compare_exchange(SUSPEND_PENDING, SUSPEND, AcqRel, Acquire) {
167+
if let Err(unexpected) = state.compare_exchange(SUSPEND_PENDING, SUSPENDED, AcqRel, Acquire)
168+
{
174169
panic!("failed to suspend by wrong state: {unexpected:?}")
175170
}
176171
// 调整中断,休眠
@@ -187,7 +182,7 @@ impl QemuHsm {
187182
set_mtvec(mtvec);
188183
}
189184
// 恢复状态
190-
if let Err(unexpected) = state.compare_exchange(SUSPEND, STARTED, AcqRel, Acquire) {
185+
if let Err(unexpected) = state.compare_exchange(SUSPENDED, STARTED, AcqRel, Acquire) {
191186
panic!("failed to resume by wrong state: {unexpected:?}")
192187
}
193188
}
@@ -258,12 +253,12 @@ impl rustsbi::Hsm for QemuHsm {
258253
fn hart_suspend(&self, suspend_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
259254
use core::sync::atomic::Ordering::{AcqRel, Acquire};
260255
match self.state[hart_id()].compare_exchange(STARTED, SUSPEND_PENDING, AcqRel, Acquire) {
261-
Ok(_) => match suspend_type as usize {
262-
SUSPEND_RETENTIVE => {
256+
Ok(_) => match suspend_type {
257+
spec::HART_SUSPEND_TYPE_RETENTIVE => {
263258
self.retentive_suspend();
264259
SbiRet::ok(0)
265260
}
266-
SUSPEND_NON_RETENTIVE => {
261+
spec::HART_SUSPEND_TYPE_NON_RETENTIVE => {
267262
*self.supervisor[hart_id()].lock() = Some(Supervisor {
268263
start_addr: resume_addr,
269264
opaque,

rustsbi-qemu/src/qemu_test.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use qemu_exit::{QEMUExit, RISCV64};
2+
use rustsbi::{
3+
spec::srst::{
4+
RESET_REASON_NO_REASON, RESET_REASON_SYSTEM_FAILURE, RESET_TYPE_COLD_REBOOT,
5+
RESET_TYPE_SHUTDOWN, RESET_TYPE_WARM_REBOOT,
6+
},
7+
Reset, SbiRet,
8+
};
9+
use spin::Once;
10+
11+
pub(crate) struct QemuTest(RISCV64);
12+
13+
static TEST: Once<QemuTest> = Once::new();
14+
15+
pub(crate) fn init(base: usize) {
16+
TEST.call_once(|| QemuTest(RISCV64::new(base as _)));
17+
}
18+
19+
pub(crate) fn get() -> &'static QemuTest {
20+
TEST.wait()
21+
}
22+
23+
impl Reset for QemuTest {
24+
fn system_reset(&self, reset_type: u32, reset_reason: u32) -> SbiRet {
25+
match reset_type {
26+
RESET_TYPE_SHUTDOWN => match reset_reason {
27+
RESET_REASON_NO_REASON => self.0.exit_success(),
28+
RESET_REASON_SYSTEM_FAILURE => self.0.exit_failure(),
29+
value => match u32::try_from(value) {
30+
Ok(code) => self.0.exit(code),
31+
Err(_) => SbiRet::invalid_param(),
32+
},
33+
},
34+
RESET_TYPE_COLD_REBOOT | RESET_TYPE_WARM_REBOOT => SbiRet::ok(0),
35+
_ => SbiRet::invalid_param(),
36+
}
37+
}
38+
}

rustsbi-qemu/src/test_device.rs

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

test-kernel/Cargo.toml

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

1010
[dependencies]
11-
sbi-rt = { git = "https://github.com/rustsbi/sbi-rt.git", rev = "6047ed5" }
11+
sbi-rt = { git = "https://github.com/rustsbi/sbi-rt.git", rev = "72b607c" }
1212
riscv = "0.8"
1313
spin = "0.9"
1414
r0 = "1"

0 commit comments

Comments
 (0)