Using sbi-rt instead of asm && update rustsbi-qemu to latest

rustsbi-qemu version: a4f0bbe44d9f2f1069a9e5becd09f291e542852c
This commit is contained in:
Yifan Wu 2023-03-28 00:03:29 +08:00
parent 3305a9e147
commit 5f68141543
5 changed files with 22 additions and 118 deletions

Binary file not shown.

View File

@ -14,6 +14,8 @@ bitflags = "1.2.1"
xmas-elf = "0.7.0" xmas-elf = "0.7.0"
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" } virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" }
easy-fs = { path = "../easy-fs" } easy-fs = { path = "../easy-fs" }
log = "0.4"
sbi-rt = { version = "0.0.2", features = ["legacy"] }
[profile.release] [profile.release]
debug = true debug = true

View File

@ -7,83 +7,3 @@ pub const MMIO: &[(usize, usize)] = &[
]; ];
pub type BlockDeviceImpl = crate::drivers::block::VirtIOBlock; pub type BlockDeviceImpl = crate::drivers::block::VirtIOBlock;
//ref:: https://github.com/andre-richter/qemu-exit
use core::arch::asm;
const EXIT_SUCCESS: u32 = 0x5555; // Equals `exit(0)`. qemu successful exit
const EXIT_FAILURE_FLAG: u32 = 0x3333;
const EXIT_FAILURE: u32 = exit_code_encode(1); // Equals `exit(1)`. qemu failed exit
const EXIT_RESET: u32 = 0x7777; // qemu reset
pub trait QEMUExit {
/// Exit with specified return code.
///
/// Note: For `X86`, code is binary-OR'ed with `0x1` inside QEMU.
fn exit(&self, code: u32) -> !;
/// Exit QEMU using `EXIT_SUCCESS`, aka `0`, if possible.
///
/// Note: Not possible for `X86`.
fn exit_success(&self) -> !;
/// Exit QEMU using `EXIT_FAILURE`, aka `1`.
fn exit_failure(&self) -> !;
}
/// RISCV64 configuration
pub struct RISCV64 {
/// Address of the sifive_test mapped device.
addr: u64,
}
/// Encode the exit code using EXIT_FAILURE_FLAG.
const fn exit_code_encode(code: u32) -> u32 {
(code << 16) | EXIT_FAILURE_FLAG
}
impl RISCV64 {
/// Create an instance.
pub const fn new(addr: u64) -> Self {
RISCV64 { addr }
}
}
impl QEMUExit for RISCV64 {
/// Exit qemu with specified exit code.
fn exit(&self, code: u32) -> ! {
// If code is not a special value, we need to encode it with EXIT_FAILURE_FLAG.
let code_new = match code {
EXIT_SUCCESS | EXIT_FAILURE | EXIT_RESET => code,
_ => exit_code_encode(code),
};
unsafe {
asm!(
"sw {0}, 0({1})",
in(reg)code_new, in(reg)self.addr
);
// For the case that the QEMU exit attempt did not work, transition into an infinite
// loop. Calling `panic!()` here is unfeasible, since there is a good chance
// this function here is the last expression in the `panic!()` handler
// itself. This prevents a possible infinite loop.
loop {
asm!("wfi", options(nomem, nostack));
}
}
}
fn exit_success(&self) -> ! {
self.exit(EXIT_SUCCESS);
}
fn exit_failure(&self) -> ! {
self.exit(EXIT_FAILURE);
}
}
const VIRT_TEST: u64 = 0x100000;
pub const QEMU_EXIT_HANDLE: RISCV64 = RISCV64::new(VIRT_TEST);

View File

@ -14,5 +14,5 @@ fn panic(info: &PanicInfo) -> ! {
} else { } else {
println!("[kernel] Panicked: {}", info.message().unwrap()); println!("[kernel] Panicked: {}", info.message().unwrap());
} }
shutdown() shutdown(true)
} }

View File

@ -1,48 +1,30 @@
//! SBI call wrappers //! SBI call wrappers
#![allow(unused)] #![allow(unused)]
use core::arch::asm;
const SBI_SET_TIMER: usize = 0;
const SBI_CONSOLE_PUTCHAR: usize = 1;
const SBI_CONSOLE_GETCHAR: usize = 2;
const SBI_CLEAR_IPI: usize = 3;
const SBI_SEND_IPI: usize = 4;
const SBI_REMOTE_FENCE_I: usize = 5;
const SBI_REMOTE_SFENCE_VMA: usize = 6;
const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
const SBI_SHUTDOWN: usize = 8;
/// general sbi call
#[inline(always)]
fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
let mut ret;
unsafe {
asm!(
"li x16, 0",
"ecall",
inlateout("x10") arg0 => ret,
in("x11") arg1,
in("x12") arg2,
in("x17") which,
);
}
ret
}
/// use sbi call to set timer
pub fn set_timer(timer: usize) {
sbi_call(SBI_SET_TIMER, timer, 0, 0);
}
/// use sbi call to putchar in console (qemu uart handler) /// use sbi call to putchar in console (qemu uart handler)
pub fn console_putchar(c: usize) { pub fn console_putchar(c: usize) {
sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0); #[allow(deprecated)]
sbi_rt::legacy::console_putchar(c);
} }
/// use sbi call to getchar from console (qemu uart handler) /// use sbi call to getchar from console (qemu uart handler)
pub fn console_getchar() -> usize { pub fn console_getchar() -> usize {
sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) #[allow(deprecated)]
sbi_rt::legacy::console_getchar()
} }
/// use sbi call to set timer
pub fn set_timer(timer: usize) {
sbi_rt::set_timer(timer as _);
}
/// use sbi call to shutdown the kernel /// use sbi call to shutdown the kernel
pub fn shutdown() -> ! { pub fn shutdown(failure: bool) -> ! {
sbi_call(SBI_SHUTDOWN, 0, 0, 0); use sbi_rt::{system_reset, NoReason, Shutdown, SystemFailure};
panic!("It should shutdown!"); if !failure {
system_reset(Shutdown, NoReason);
} else {
system_reset(Shutdown, SystemFailure);
}
unreachable!()
} }