Add working exception recovery
This commit is contained in:
parent
b7d2fdf0b2
commit
a9d25b74e9
|
@ -43,6 +43,7 @@
|
|||
// nested exceptions, for example, to allow a higher priority interrupt
|
||||
// to interrupt the handling of a lower priority source, then software needs
|
||||
// to explicitly re-enable interrupts
|
||||
use crate::{arch::endless_sleep, println};
|
||||
use cortex_a::{barrier, regs};
|
||||
use register::cpu::RegisterReadWrite;
|
||||
|
||||
|
@ -77,12 +78,10 @@ pub struct ExceptionContext {
|
|||
/// The default exception, invoked for every exception type unless the handler
|
||||
/// is overwritten.
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn default_exception_handler() {
|
||||
// println!("Unexpected exception. Halting CPU.");
|
||||
unsafe extern "C" fn default_exception_handler() -> ! {
|
||||
println!("Unexpected exception. Halting CPU.");
|
||||
|
||||
loop {
|
||||
cortex_a::asm::wfe()
|
||||
}
|
||||
endless_sleep()
|
||||
}
|
||||
|
||||
// To implement an exception handler, overwrite it by defining the respective
|
||||
|
@ -107,15 +106,15 @@ unsafe extern "C" fn default_exception_handler() {
|
|||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
|
||||
// println!("[!] A synchronous exception happened.");
|
||||
// println!(" ELR_EL1: {:#010X}", e.elr_el1);
|
||||
// println!(
|
||||
// " Incrementing ELR_EL1 by 4 now to continue with the first \
|
||||
// instruction after the exception!"
|
||||
// );
|
||||
println!("[!] A synchronous exception happened.");
|
||||
println!(" ELR_EL1: {:#010X}", e.elr_el1);
|
||||
println!(
|
||||
" Incrementing ELR_EL1 by 4 now to continue with the first \
|
||||
instruction after the exception!"
|
||||
);
|
||||
|
||||
e.elr_el1 += 4;
|
||||
|
||||
// println!(" ELR_EL1 modified: {:#010X}", e.elr_el1);
|
||||
// println!(" Returning from exception...\n");
|
||||
println!(" ELR_EL1 modified: {:#010X}", e.elr_el1);
|
||||
println!(" Returning from exception...\n");
|
||||
}
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -80,24 +80,35 @@ fn kmain() -> ! {
|
|||
|
||||
println!("\n[0] UART is live!");
|
||||
|
||||
println!("Hello, world!");
|
||||
|
||||
extern "C" {
|
||||
static __exception_vectors_start: u64;
|
||||
}
|
||||
|
||||
//==============================================
|
||||
// Since formatted output doesn't work, lets do some other preparatory steps:
|
||||
// 1. Initialize MMU
|
||||
// 2. Set up exception handlers
|
||||
// Obviously, things should keep working after that...
|
||||
//==============================================
|
||||
|
||||
unsafe {
|
||||
let exception_vectors_start: u64 = &__exception_vectors_start as *const _ as u64;
|
||||
|
||||
arch::traps::set_vbar_el1_checked(exception_vectors_start);
|
||||
println!("Exception traps set up");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
mmu::init();
|
||||
}
|
||||
println!("MMU initialised");
|
||||
|
||||
if let Some(mut display) = VC::init_fb(Size2d { x: 800, y: 600 }) {
|
||||
println!("Display created");
|
||||
|
||||
display.clear(Color::black()); // Takes A LOONG time, check caching opts?
|
||||
println!("Display cleared");
|
||||
|
||||
if let Some(mut display) = VC::init_fb(Size2d { x: 800, y: 600 } /*, &mut uart*/) {
|
||||
display.clear(Color::black());
|
||||
display.rect(10, 10, 250, 250, Color::rgb(32, 96, 64));
|
||||
display.draw_text(50, 50, "Hello there!", Color::rgb(128, 192, 255));
|
||||
|
||||
|
@ -112,21 +123,27 @@ fn kmain() -> ! {
|
|||
// display.draw_text(50, 150, s.unwrap(), Color::white());
|
||||
// }
|
||||
|
||||
//==============================================
|
||||
// Since formatted output doesn't work, lets do some other preparatory steps:
|
||||
// 1. Initialize MMU
|
||||
// 2. Set up exception handlers
|
||||
// Obviously, things should keep working after that...
|
||||
//==============================================
|
||||
|
||||
display.draw_text(150, 50, "RED", Color::red());
|
||||
display.draw_text(160, 60, "GREEN", Color::green());
|
||||
display.draw_text(170, 70, "BLUE", Color::blue());
|
||||
}
|
||||
|
||||
// unsafe {
|
||||
// mmu::init();
|
||||
// }
|
||||
// Cause an exception by accessing a virtual address for which no
|
||||
// address translations have been set up.
|
||||
//
|
||||
// This line of code accesses the address 3 GiB, but page tables are
|
||||
// only set up for the range [0..1] GiB.
|
||||
let big_addr: u64 = 3 * 1024 * 1024 * 1024;
|
||||
unsafe { core::ptr::read_volatile(big_addr as *mut u64) };
|
||||
|
||||
println!("[i] Whoa! We recovered from an exception.");
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Start a command prompt
|
||||
//------------------------------------------------------------
|
||||
CONSOLE.lock(|c| {
|
||||
c.command_prompt();
|
||||
});
|
||||
|
||||
// writeln!(uart, "Bye, going to sleep now");
|
||||
// qemu_aarch64_exit()
|
||||
|
|
Loading…
Reference in New Issue