Skip to content

Commit 4875880

Browse files
committed
feat(test-kernel): 测试 hsm 所有功能
1 parent 351a23f commit 4875880

File tree

3 files changed

+60
-29
lines changed

3 files changed

+60
-29
lines changed

rustsbi-qemu/src/execute/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
clint, hart_id,
3-
qemu_hsm::{QemuHsm, SUSPEND_RETENTIVE},
3+
qemu_hsm::{QemuHsm, SUSPEND_NON_RETENTIVE},
44
Supervisor,
55
};
66

@@ -64,7 +64,7 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) {
6464
if ctx.a(7) == EID_HSM && ans.error == 0 {
6565
match ctx.a(6) {
6666
FID_HART_STOP => return,
67-
FID_HART_SUSPEND if ctx.a(0) == SUSPEND_RETENTIVE => return,
67+
FID_HART_SUSPEND if ctx.a(0) == SUSPEND_NON_RETENTIVE => return,
6868
_ => {}
6969
}
7070
}

sbi-rt/Cargo.toml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
[package]
22
name = "sbi-rt"
33
version = "0.1.0"
4-
authors = ["luojia65 <me@luojia.cc>"]
4+
authors = ["YdrMaster <ydrml@hotmail.com>"]
55
edition = "2021"
66
publish = false
7-
8-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
9-
10-
[dependencies]

test-kernel/src/test.rs

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -78,31 +78,46 @@ pub(crate) fn trap_delegate(hartid: usize) {
7878
);
7979
}
8080

81-
/// 操作一个静态的原子变量。
82-
/// 现在除启动核外,所有核都处于 STOPPED 状态,
83-
/// 主核在 [`sbi::hart_start`] 之前给原子变量 +1。
84-
/// 核启动后,会自动给原子变量 -1。
85-
/// 所有核成功启动则原子变量值归零。
86-
/// 所有核一起等待原子变量归零,然后副核调用 [`sbi::hart_stop`] 关闭。
87-
/// 主核等待所有副核关闭,然后退出。
81+
/// 所有副核:启动 -> 不可恢复休眠 -> 唤醒 -> 可恢复休眠 -> 唤醒 -> 关闭。
8882
pub(crate) fn start_stop_harts(hartid: usize, smp: usize) {
83+
const SUSPENDED: sbi::SbiRet = sbi::SbiRet {
84+
error: sbi::RET_SUCCESS,
85+
value: sbi::HART_STATE_SUSPENDED,
86+
};
87+
const STOPPED: sbi::SbiRet = sbi::SbiRet {
88+
error: sbi::RET_SUCCESS,
89+
value: sbi::HART_STATE_STOPPED,
90+
};
91+
8992
use spin::{Barrier, Once};
90-
static BARRIER: Once<Barrier> = Once::new();
93+
static STARTED: Once<Barrier> = Once::new();
94+
static RESUMED: Once<Barrier> = Once::new();
9195

9296
#[naked]
93-
unsafe extern "C" fn test_start_entry(hartid: usize) -> ! {
97+
unsafe extern "C" fn test_entry(hartid: usize, main: usize) -> ! {
9498
core::arch:: asm!(
9599
"csrw sie, zero", // 关中断
96100
"call {select_stack}", // 设置启动栈
97-
"j {main}", // 进入 rust
101+
"jr a1", // 进入 rust
98102
select_stack = sym crate::select_stack,
99-
main = sym secondary_rust_main,
100103
options(noreturn)
101104
)
102105
}
103106

104-
extern "C" fn secondary_rust_main(hart_id: usize) -> ! {
105-
BARRIER.wait().wait();
107+
extern "C" fn start_rust_main(hart_id: usize) -> ! {
108+
STARTED.wait().wait();
109+
let ret = sbi::hart_suspend(
110+
sbi::HART_SUSPEND_TYPE_NON_RETENTIVE,
111+
test_entry as _,
112+
resume_rust_main as _,
113+
);
114+
unreachable!("suspend [{hart_id}] but {ret:?}");
115+
}
116+
117+
extern "C" fn resume_rust_main(hart_id: usize) -> ! {
118+
RESUMED.wait().wait();
119+
let ret = sbi::hart_suspend(sbi::HART_SUSPEND_TYPE_RETENTIVE, 0, 0);
120+
assert_eq!(sbi::RET_SUCCESS, ret.error);
106121
let ret = sbi::hart_stop();
107122
unreachable!("stop [{hart_id}] but {ret:?}");
108123
}
@@ -113,11 +128,12 @@ pub(crate) fn start_stop_harts(hartid: usize, smp: usize) {
113128
);
114129

115130
// 启动副核
116-
let barrier = BARRIER.call_once(|| Barrier::new(smp));
131+
let started = STARTED.call_once(|| Barrier::new(smp));
132+
let resumed = RESUMED.call_once(|| Barrier::new(smp));
117133
for id in 0..smp {
118134
if id != hartid {
119135
println!("[test-kernel] Hart{id} is booting...");
120-
let ret = sbi::hart_start(id, test_start_entry as usize, 0);
136+
let ret = sbi::hart_start(id, test_entry as _, start_rust_main as _);
121137
if ret.error != sbi::RET_SUCCESS {
122138
panic!("[test-kernel] Start hart{id} failed: {ret:?}");
123139
}
@@ -126,19 +142,38 @@ pub(crate) fn start_stop_harts(hartid: usize, smp: usize) {
126142
}
127143
}
128144
// 等待副核启动完成
129-
barrier.wait();
145+
started.wait();
130146
print!("[test-kernel] All harts boot successfully!\n");
131-
// 等待副核关闭
147+
// 等待副核休眠(不可恢复)
148+
for id in 0..smp {
149+
if id != hartid {
150+
while sbi::hart_get_status(id) != SUSPENDED {
151+
core::hint::spin_loop();
152+
}
153+
println!("[test-kernel] Hart{id} suspended.");
154+
} else {
155+
println!("[test-kernel] Hart{id} is the primary hart.");
156+
}
157+
}
158+
// 全部唤醒
159+
sbi::send_ipi(0, -1isize as usize);
160+
// 等待副核恢复完成
161+
resumed.wait();
162+
print!("[test-kernel] All harts resume successfully!\n");
132163
for id in 0..smp {
133-
const STOPPED: sbi::SbiRet = sbi::SbiRet {
134-
error: sbi::RET_SUCCESS,
135-
value: sbi::HART_STATE_STOPPED,
136-
};
137164
if id != hartid {
165+
// 等待副核休眠
166+
while sbi::hart_get_status(id) != SUSPENDED {
167+
core::hint::spin_loop();
168+
}
169+
print!("[test-kernel] Hart{id} suspended, ");
170+
// 单独唤醒
171+
sbi::send_ipi(1usize << id, 0);
172+
// 等待副核关闭
138173
while sbi::hart_get_status(id) != STOPPED {
139174
core::hint::spin_loop();
140175
}
141-
println!("[test-kernel] Hart{id} stopped.");
176+
println!("then stopped.");
142177
} else {
143178
println!("[test-kernel] Hart{id} is the primary hart.");
144179
}

0 commit comments

Comments
 (0)