diff --git a/src/arch/aarch64/traps.rs b/src/arch/aarch64/traps.rs index 7ffcf24..d82c0ec 100644 --- a/src/arch/aarch64/traps.rs +++ b/src/arch/aarch64/traps.rs @@ -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"); } diff --git a/src/main.rs b/src/main.rs index b8f2237..76b7fbb 100644 --- a/src/main.rs +++ b/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()