Skip to content

Commit 0d2f9f4

Browse files
committed
SiFive Test device
1 parent 2f94aa0 commit 0d2f9f4

File tree

5 files changed

+52
-25
lines changed

5 files changed

+52
-25
lines changed

rustsbi-qemu/src/execute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub fn execute_supervisor(supervisor_mepc: usize, hart_id: usize, a1: usize, hsm
9797
},
9898
GeneratorState::Complete(()) => {
9999
use rustsbi::Reset;
100-
crate::test_device::Reset.system_reset(
100+
crate::test_device::SiFiveTest.system_reset(
101101
rustsbi::reset::RESET_TYPE_SHUTDOWN,
102102
rustsbi::reset::RESET_REASON_NO_REASON,
103103
);

rustsbi-qemu/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fn panic(info: &PanicInfo) -> ! {
4242
println!("[rustsbi-panic] hart {} {}", hart_id, info);
4343
println!("[rustsbi-panic] system shutdown scheduled due to RustSBI panic");
4444
use rustsbi::Reset;
45-
test_device::Reset.system_reset(
45+
test_device::SiFiveTest.system_reset(
4646
rustsbi::reset::RESET_TYPE_SHUTDOWN,
4747
rustsbi::reset::RESET_REASON_SYSTEM_FAILURE,
4848
);
@@ -119,7 +119,7 @@ fn init_clint() {
119119

120120
fn init_test_device() {
121121
use rustsbi::init_reset;
122-
init_reset(test_device::Reset);
122+
init_reset(test_device::SiFiveTest);
123123
}
124124

125125
// 委托中断;把S的中断全部委托给S层

rustsbi-qemu/src/test_device.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
1-
pub struct Reset;
1+
// SiFive Test virtual device
2+
//
3+
// This is a test finisher memory mapped device used to exit simulation
4+
//
5+
// Ref: https://github.com/qemu/qemu/blob/master/hw/misc/sifive_test.c
6+
use rustsbi::{Reset, SbiRet, reset::{
7+
RESET_TYPE_SHUTDOWN, RESET_TYPE_COLD_REBOOT, RESET_TYPE_WARM_REBOOT,
8+
RESET_REASON_NO_REASON, RESET_REASON_SYSTEM_FAILURE
9+
}};
210

11+
// Zero sized structure for a static write-only device
12+
pub struct SiFiveTest;
13+
14+
// Write these values to perform test device operations
315
const TEST_FAIL: u32 = 0x3333;
416
const TEST_PASS: u32 = 0x5555;
517
const TEST_RESET: u32 = 0x7777;
618

7-
impl rustsbi::Reset for Reset {
8-
fn system_reset(&self, reset_type: usize, reset_reason: usize) -> rustsbi::SbiRet {
9-
// todo: only exit after all harts finished
10-
// loop {}
19+
// On most QEMU host platforms, exit code for a general error is 1
20+
const QEMU_ERR_EXIT_CODE: u32 = 1;
21+
22+
impl Reset for SiFiveTest {
23+
fn system_reset(&self, reset_type: usize, reset_reason: usize) -> SbiRet {
1124
const VIRT_TEST: *mut u32 = 0x10_0000 as *mut u32;
12-
// Fail = 0x3333,
13-
// Pass = 0x5555,
14-
// Reset = 0x7777,
15-
let mut value = match reset_type {
16-
rustsbi::reset::RESET_TYPE_SHUTDOWN => TEST_PASS,
17-
rustsbi::reset::RESET_TYPE_COLD_REBOOT => TEST_RESET,
18-
rustsbi::reset::RESET_TYPE_WARM_REBOOT => TEST_RESET,
19-
_ => TEST_FAIL,
20-
};
21-
if reset_reason == rustsbi::reset::RESET_REASON_SYSTEM_FAILURE {
22-
value = TEST_FAIL;
25+
let value = match reset_type {
26+
RESET_TYPE_SHUTDOWN => match reset_reason {
27+
RESET_REASON_NO_REASON => TEST_PASS,
28+
RESET_REASON_SYSTEM_FAILURE => TEST_FAIL | (QEMU_ERR_EXIT_CODE << 16),
29+
// pass unknown reason from [2, 0xFFFF] to qemu return value output
30+
// reason if reason <= 0xFFFF => TEST_FAIL | (((reason & 0xFFFF) as u32) << 16),
31+
_ => return SbiRet::invalid_param(),
32+
},
33+
RESET_TYPE_COLD_REBOOT => TEST_RESET,
34+
RESET_TYPE_WARM_REBOOT => TEST_RESET,
35+
_ => return SbiRet::invalid_param(),
2336
};
2437
unsafe {
2538
core::ptr::write_volatile(VIRT_TEST, value);

test-kernel/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ use core::panic::PanicInfo;
153153
fn panic(info: &PanicInfo) -> ! {
154154
println!("!! Test-kernel: {}", info);
155155
println!("!! Test-kernel: SBI test FAILED due to panic");
156-
sbi::shutdown()
156+
sbi::reset(sbi::RESET_TYPE_SHUTDOWN, sbi::RESET_REASON_SYSTEM_FAILURE);
157+
loop {}
157158
}
158159

159160
const BOOT_STACK_SIZE: usize = 4096 * 4 * 8;

test-kernel/src/sbi.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,24 @@ pub fn get_mimpid() -> usize {
8686
sbi_call_0(EXTENSION_BASE, FUNCTION_BASE_GET_MIMPID).value
8787
}
8888

89+
const FUNCTION_SYSTEM_RESET: usize = 0x0;
90+
91+
pub const RESET_TYPE_SHUTDOWN: usize = 0x0000_0000;
92+
pub const RESET_TYPE_COLD_REBOOT: usize = 0x0000_0001;
93+
pub const RESET_TYPE_WARM_REBOOT: usize = 0x0000_0002;
94+
pub const RESET_REASON_NO_REASON: usize = 0x0000_0000;
95+
pub const RESET_REASON_SYSTEM_FAILURE: usize = 0x0000_0001;
96+
97+
#[inline]
98+
pub fn reset(reset_type: usize, reset_reason: usize) -> SbiRet {
99+
sbi_call_2(EXTENSION_SRST, FUNCTION_SYSTEM_RESET, reset_type, reset_reason)
100+
}
101+
102+
pub fn shutdown() -> ! {
103+
sbi_call_2(EXTENSION_SRST, FUNCTION_SYSTEM_RESET, RESET_TYPE_SHUTDOWN, RESET_REASON_NO_REASON);
104+
unreachable!()
105+
}
106+
89107
#[inline(always)]
90108
fn sbi_call_legacy(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
91109
let ret;
@@ -126,11 +144,6 @@ pub fn console_getchar() -> usize {
126144
sbi_call_legacy(SBI_CONSOLE_GETCHAR, 0, 0, 0)
127145
}
128146

129-
pub fn shutdown() -> ! {
130-
sbi_call_legacy(SBI_SHUTDOWN, 0, 0, 0);
131-
unreachable!()
132-
}
133-
134147
pub fn set_timer(time: usize) {
135148
sbi_call_legacy(SBI_SET_TIMER, time, 0, 0);
136149
}

0 commit comments

Comments
 (0)