update rustsbi-qemu.bin :: PMP set RW for [base: 0x10_0000, len: 0x2000], and os kernel supports VIRT_TEST based qemu exit

This commit is contained in:
Yu Chen 2022-05-15 17:00:29 +08:00
parent 09299aabb0
commit 017dbcbd79
4 changed files with 108 additions and 17 deletions

Binary file not shown.

View File

@ -1,6 +1,7 @@
//! The panic handler //! The panic handler
use crate::sbi::shutdown; //use crate::sbi::shutdown;
use crate::qemu_exit::{QEMUExit,QEMU_EXIT_HANDLE};
use core::panic::PanicInfo; use core::panic::PanicInfo;
#[panic_handler] #[panic_handler]
@ -15,5 +16,7 @@ fn panic(info: &PanicInfo) -> ! {
} else { } else {
println!("[kernel] Panicked: {}", info.message().unwrap()); println!("[kernel] Panicked: {}", info.message().unwrap());
} }
shutdown() //shutdown()
// QEMU_EXIT_HANDLE.exit(13)
QEMU_EXIT_HANDLE.exit_success()
} }

View File

@ -18,7 +18,9 @@ use core::arch::global_asm;
#[macro_use] #[macro_use]
mod console; mod console;
mod lang_items; mod lang_items;
mod qemu_exit;
mod sbi; mod sbi;
use crate::qemu_exit::{QEMUExit, QEMU_EXIT_HANDLE};
global_asm!(include_str!("entry.asm")); global_asm!(include_str!("entry.asm"));
@ -56,5 +58,8 @@ pub fn rust_main() -> ! {
boot_stack as usize, boot_stack_top as usize boot_stack as usize, boot_stack_top as usize
); );
println!(".bss [{:#x}, {:#x})", sbss as usize, ebss as usize); println!(".bss [{:#x}, {:#x})", sbss as usize, ebss as usize);
panic!("Shutdown machine!");
QEMU_EXIT_HANDLE.exit_success(); //need successful qemu exit
//QEMU_EXIT_HANDLE.exit_failure(); //need failed qemu exit
//panic!("Shutdown machine!");
} }

83
os/src/qemu_exit.rs Normal file
View File

@ -0,0 +1,83 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2020-2022 Esteban Blanc <estblcsk@gmail.com>
//! RISCV64.
use core::arch::asm;
const EXIT_SUCCESS: u32 = 0x5555; // Equals `exit(0)`.
const EXIT_FAILURE_FLAG: u32 = 0x3333;
const EXIT_FAILURE: u32 = exit_code_encode(1); // Equals `exit(1)`.
const EXIT_RESET: u32 = 0x7777;
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);
}
}
pub const QEMU_EXIT_HANDLE: RISCV64 = RISCV64::new(0x100000);