Skip to content

Commit 5fd115b

Browse files
committed
feat(test-kernel): 测试关闭核
1 parent 4f7c6a8 commit 5fd115b

File tree

3 files changed

+86
-67
lines changed

3 files changed

+86
-67
lines changed

sbi-rt/src/binary.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/// > SBI functions must return a pair of values in a0 and a1,
66
/// > with a0 returning an error code.
77
/// > This is analogous to returning the C structure `SbiRet`.
8+
#[derive(PartialEq, Eq)]
89
#[repr(C)]
910
pub struct SbiRet {
1011
/// Error number

test-kernel/src/main.rs

Lines changed: 4 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
#![no_std]
66
#![no_main]
77

8-
use core::{
9-
arch::asm,
10-
sync::atomic::{AtomicUsize, Ordering},
11-
};
8+
use core::arch::asm;
129
use riscv::register::{
1310
scause::Trap,
1411
sepc,
@@ -64,30 +61,10 @@ unsafe extern "C" fn _start(hartid: usize, device_tree_paddr: usize) -> ! {
6461
)
6562
}
6663

67-
/// 副核入口。此前副核被 SBI 阻塞。
68-
///
69-
/// # Safety
70-
///
71-
/// 裸函数。
72-
#[naked]
73-
unsafe extern "C" fn secondary_hart_start(hartid: usize) -> ! {
74-
asm!(
75-
"csrw sie, zero", // 关中断
76-
"call {select_stack}", // 设置启动栈
77-
"j {main}", // 进入 rust
78-
select_stack = sym select_stack,
79-
main = sym secondary_rust_main,
80-
options(noreturn)
81-
)
82-
}
83-
8464
/// 为每个核记录一个预期的陷入原因,实现陷入代理测试。
8565
/// 总是可以安全地使用,因为这是(硬件)线程独立变量。
8666
static mut EXPECTED: [Option<Trap>; 8] = [None; 8];
8767

88-
/// 每个核的启动函数里 +1
89-
static STARTED: AtomicUsize = AtomicUsize::new(0);
90-
9168
extern "C" fn primary_rust_main(hartid: usize, dtb_pa: usize) -> ! {
9269
zero_bss();
9370

@@ -112,41 +89,10 @@ extern "C" fn primary_rust_main(hartid: usize, dtb_pa: usize) -> ! {
11289
unsafe { stvec::write(start_trap as usize, TrapMode::Direct) };
11390
test::trap_delegate(hartid);
11491

115-
println!();
116-
STARTED.fetch_add(1, Ordering::SeqCst);
117-
let pc: usize;
118-
unsafe { asm!("auipc {}, 0", out(reg) pc) };
119-
println!("pc = {pc:#x}");
120-
// 启动副核
121-
for id in 0..smp {
122-
if id != hartid {
123-
println!("hart{id} is booting...");
124-
let ret = sbi::hart_start(id, secondary_hart_start as usize, 0);
125-
if ret.error != sbi::SBI_SUCCESS {
126-
panic!("start hart{id} failed: {ret:?}");
127-
}
128-
} else {
129-
println!("hart{id} is the primary hart.");
130-
}
131-
}
132-
while STARTED.load(Ordering::SeqCst) < smp {
133-
for id in 0..smp {
134-
print!("{:?}", sbi::hart_get_status(id));
135-
}
136-
println!("({}/{smp})", STARTED.load(Ordering::SeqCst));
137-
for _ in 0..0x8000_0000usize {
138-
core::hint::spin_loop();
139-
}
140-
}
141-
println!("All harts boot successfully!");
142-
shutdown()
143-
}
92+
test::start_stop_harts(hartid, smp);
14493

145-
extern "C" fn secondary_rust_main(_hart_id: usize) -> ! {
146-
STARTED.fetch_add(1, Ordering::SeqCst);
147-
loop {
148-
core::hint::spin_loop();
149-
}
94+
sbi::system_reset(sbi::RESET_TYPE_SHUTDOWN, sbi::RESET_REASON_NO_REASON);
95+
unreachable!()
15096
}
15197

15298
extern "C" fn rust_trap_exception(trap_frame: &mut TrapFrame) {
@@ -310,11 +256,3 @@ fn zero_bss() {
310256
}
311257
unsafe { r0::zero_bss(&mut sbss, &mut ebss) };
312258
}
313-
314-
fn shutdown() -> ! {
315-
use sbi::{system_reset, RESET_REASON_NO_REASON, RESET_TYPE_SHUTDOWN};
316-
system_reset(RESET_TYPE_SHUTDOWN, RESET_REASON_NO_REASON);
317-
loop {
318-
core::hint::spin_loop();
319-
}
320-
}

test-kernel/src/test.rs

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
pub(crate) fn base_extension() {
1+
use core::sync::atomic::{AtomicUsize, Ordering};
2+
3+
pub(crate) fn base_extension() {
24
println!(
35
"
46
[test-kernel] Testing base extension"
@@ -77,3 +79,81 @@ pub(crate) fn trap_delegate(hartid: usize) {
7779
[test-kernel] Illegal exception delegate success"
7880
);
7981
}
82+
83+
/// 操作一个静态的原子变量。
84+
/// 现在除启动核外,所有核都处于 STOPPED 状态,
85+
/// 主核在 [`sbi::hart_start`] 之前给原子变量 +1。
86+
/// 核启动后,会自动给原子变量 -1。
87+
/// 所有核成功启动则原子变量值归零。
88+
/// 所有核一起等待原子变量归零,然后副核调用 [`sbi::hart_stop`] 关闭。
89+
/// 主核等待所有副核关闭,然后退出。
90+
pub(crate) fn start_stop_harts(hartid: usize, smp: usize) {
91+
static STARTED: AtomicUsize = AtomicUsize::new(0);
92+
93+
#[naked]
94+
unsafe extern "C" fn test_start_entry(hartid: usize) -> ! {
95+
core::arch:: asm!(
96+
"csrw sie, zero", // 关中断
97+
"call {select_stack}", // 设置启动栈
98+
"j {main}", // 进入 rust
99+
select_stack = sym crate::select_stack,
100+
main = sym secondary_rust_main,
101+
options(noreturn)
102+
)
103+
}
104+
105+
extern "C" fn secondary_rust_main(_hart_id: usize) -> ! {
106+
STARTED.fetch_sub(1, Ordering::AcqRel);
107+
while STARTED.load(Ordering::Acquire) != 0 {
108+
delay(0x8000_0000usize);
109+
}
110+
sbi::hart_stop();
111+
unreachable!()
112+
}
113+
114+
println!(
115+
"
116+
[test-kernel] Testing start harts"
117+
);
118+
119+
// 启动副核
120+
for id in 0..smp {
121+
if id != hartid {
122+
println!("[test-kernel] Hart{id} is booting...");
123+
STARTED.fetch_add(1, Ordering::AcqRel);
124+
let ret = sbi::hart_start(id, test_start_entry as usize, 0);
125+
if ret.error != sbi::SBI_SUCCESS {
126+
panic!("[test-kernel] Start hart{id} failed: {ret:?}");
127+
}
128+
} else {
129+
println!("[test-kernel] Hart{id} is the primary hart.");
130+
}
131+
}
132+
// 等待副核启动完成
133+
while STARTED.load(Ordering::Acquire) != 0 {
134+
for id in 0..smp {
135+
print!("{:?}", sbi::hart_get_status(id));
136+
}
137+
println!("({}/{smp})", STARTED.load(Ordering::SeqCst));
138+
delay(0x8000_0000usize);
139+
}
140+
println!("[test-kernel] All harts boot successfully!");
141+
// 等待副核关闭
142+
for id in 0..smp {
143+
const STOPPED: sbi::SbiRet = sbi::SbiRet { error: 0, value: 1 };
144+
if id != hartid {
145+
while sbi::hart_get_status(id) != STOPPED {
146+
delay(0x8000_0000usize);
147+
}
148+
println!("[test-kernel] Hart{id} stopped.");
149+
}
150+
}
151+
println!("[test-kernel] All harts stop successfully!");
152+
}
153+
154+
#[inline(always)]
155+
fn delay(cycle: usize) {
156+
for _ in 0..cycle {
157+
core::hint::spin_loop();
158+
}
159+
}

0 commit comments

Comments
 (0)