From d2fb4a68cad4913d8dffd3ed805bc8601aaaa81a Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 1 Nov 2022 10:55:54 +0100 Subject: [PATCH] Kernel: Add basic interrupt handling --- moon/Cargo.lock | 37 ++++++++++++++++++++++++++++++ moon/Cargo.toml | 3 ++- moon/src/arch/interrupts.rs | 2 ++ moon/src/arch/mod.rs | 1 + moon/src/arch/x86_64/interrupts.rs | 34 +++++++++++++++++++++++++++ moon/src/arch/x86_64/mod.rs | 3 ++- moon/src/main.rs | 14 +++++++++++ 7 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 moon/src/arch/interrupts.rs create mode 100644 moon/src/arch/x86_64/interrupts.rs diff --git a/moon/Cargo.lock b/moon/Cargo.lock index 16f90767..fe521804 100644 --- a/moon/Cargo.lock +++ b/moon/Cargo.lock @@ -8,6 +8,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "lock_api" version = "0.4.9" @@ -23,8 +35,15 @@ name = "moon" version = "0.1.0" dependencies = [ "spin", + "x86_64", ] +[[package]] +name = "rustversion" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" + [[package]] name = "scopeguard" version = "1.1.0" @@ -39,3 +58,21 @@ checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" dependencies = [ "lock_api", ] + +[[package]] +name = "volatile" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c" + +[[package]] +name = "x86_64" +version = "0.14.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "100555a863c0092238c2e0e814c1096c1e5cf066a309c696a87e907b5f8c5d69" +dependencies = [ + "bit_field", + "bitflags", + "rustversion", + "volatile", +] diff --git a/moon/Cargo.toml b/moon/Cargo.toml index 03d9ebd1..e315cd20 100644 --- a/moon/Cargo.toml +++ b/moon/Cargo.toml @@ -16,4 +16,5 @@ strip = "debuginfo" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -spin = "0.9.4" \ No newline at end of file +spin = "0.9.4" +x86_64 = "0.14.10" \ No newline at end of file diff --git a/moon/src/arch/interrupts.rs b/moon/src/arch/interrupts.rs new file mode 100644 index 00000000..76e9934a --- /dev/null +++ b/moon/src/arch/interrupts.rs @@ -0,0 +1,2 @@ +#![cfg(target_arch = "x86_64")] +pub use super::x86_64::interrupts::*; \ No newline at end of file diff --git a/moon/src/arch/mod.rs b/moon/src/arch/mod.rs index bc24dc5f..394efc3e 100644 --- a/moon/src/arch/mod.rs +++ b/moon/src/arch/mod.rs @@ -1,5 +1,6 @@ pub mod cpu; pub mod io; +pub mod interrupts; #[cfg(target_arch = "x86_64")] mod x86_64; \ No newline at end of file diff --git a/moon/src/arch/x86_64/interrupts.rs b/moon/src/arch/x86_64/interrupts.rs new file mode 100644 index 00000000..50ab88b1 --- /dev/null +++ b/moon/src/arch/x86_64/interrupts.rs @@ -0,0 +1,34 @@ +use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}; +use crate::try_println; +use core::arch::asm; + +static mut IDT: InterruptDescriptorTable = InterruptDescriptorTable::new(); + +extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) +{ + try_println!("Breakpoint!\n{:#?}", stack_frame); +} + +extern "x86-interrupt" fn page_fault_handler(stack_frame: InterruptStackFrame, faulting_address: PageFaultErrorCode) +{ + try_println!("Page fault at {:#?}\n{:#?}", faulting_address, stack_frame); +} + +pub fn load() +{ + unsafe { + IDT.breakpoint.set_handler_fn(breakpoint_handler); + IDT.page_fault.set_handler_fn(page_fault_handler); + IDT.load(); + } +} + +pub fn enable() +{ + unsafe { asm!("sti"); } +} + +pub fn disable() +{ + unsafe { asm!("cli"); } +} \ No newline at end of file diff --git a/moon/src/arch/x86_64/mod.rs b/moon/src/arch/x86_64/mod.rs index 1d6586c5..be3cffa5 100644 --- a/moon/src/arch/x86_64/mod.rs +++ b/moon/src/arch/x86_64/mod.rs @@ -1,3 +1,4 @@ #![cfg(target_arch = "x86_64")] pub mod cpu; -pub mod io; \ No newline at end of file +pub mod io; +pub mod interrupts; \ No newline at end of file diff --git a/moon/src/main.rs b/moon/src/main.rs index d2a845fe..b51f7744 100644 --- a/moon/src/main.rs +++ b/moon/src/main.rs @@ -2,6 +2,7 @@ #![no_main] #![feature(core_intrinsics)] +#![feature(abi_x86_interrupt)] mod video; mod bootboot; @@ -12,18 +13,31 @@ mod arch; mod log; use arch::cpu; +use arch::interrupts; + +use x86_64::instructions::interrupts::int3; use video::Color; #[no_mangle] pub extern "C" fn _start() -> ! { + interrupts::disable(); + init::halt_other_cores(); init::check_magic(); + interrupts::load(); + video::clear(Color::White); println!("Hello, world!"); + + interrupts::enable(); + + int3(); + + println!("Still here!"); cpu::halt();