feat: quit/reset system by using test device provided by Qemu

This commit is contained in:
Paul Pan 2023-12-17 20:18:19 +08:00
parent bc71fa35f5
commit 58b050d2b5
2 changed files with 24 additions and 1 deletions

View File

@ -1,5 +1,6 @@
pub const UART0_BASE: usize = 0x1000_0000; pub const UART0_BASE: usize = 0x1000_0000;
pub const UART0_LSR: usize = 0x1000_0005; pub const UART0_LSR: usize = 0x1000_0005;
pub const TEST_DEVICE: *mut u32 = 0x10_0000 as *mut u32;
pub mod printer; pub mod printer;
pub mod reader; pub mod reader;

View File

@ -1,6 +1,10 @@
use crate::arch::lowlevel::{Hardware, LowLevel};
use log::error; use log::error;
use crate::arch::lowlevel::{Hardware, LowLevel};
#[cfg(feature = "board_virt")]
use super::board::TEST_DEVICE;
impl LowLevel for Hardware { impl LowLevel for Hardware {
#[inline] #[inline]
fn halt() { fn halt() {
@ -12,9 +16,21 @@ impl LowLevel for Hardware {
Self::disable_interrupt(); Self::disable_interrupt();
if failure { if failure {
#[cfg(not(feature = "board_virt"))]
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::SystemFailure); sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::SystemFailure);
#[cfg(feature = "board_virt")]
unsafe {
TEST_DEVICE.write_volatile(0x0042_3333)
}
} else { } else {
#[cfg(not(feature = "board_virt"))]
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason); sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason);
#[cfg(feature = "board_virt")]
unsafe {
TEST_DEVICE.write_volatile(0x0042_5555)
}
} }
loop { loop {
@ -25,12 +41,18 @@ impl LowLevel for Hardware {
#[inline] #[inline]
fn reset(failure: bool) -> ! { fn reset(failure: bool) -> ! {
#[cfg(not(feature = "board_virt"))]
if failure { if failure {
sbi_rt::system_reset(sbi_rt::ColdReboot, sbi_rt::SystemFailure); sbi_rt::system_reset(sbi_rt::ColdReboot, sbi_rt::SystemFailure);
} else { } else {
sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason); sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
} }
#[cfg(feature = "board_virt")]
unsafe {
TEST_DEVICE.write_volatile(0x0042_7777)
}
error!("[riscv/lowlevel] system_reset failed, shutdown instead"); error!("[riscv/lowlevel] system_reset failed, shutdown instead");
Self::shutdown(true); Self::shutdown(true);
} }