diff options
| author | Tianhao Wang <wth@riseup.net> | 2024-02-01 15:10:11 +0100 |
|---|---|---|
| committer | Tianhao Wang <shrik3@mailbox.org> | 2024-06-11 15:13:37 +0200 |
| commit | c01e440d014253fd4cae9f642c949720a54baf4b (patch) | |
| tree | 68d9fc26ccf2f124702b2c2a000892c344f203fe | |
| parent | 753955dbb4e6c77b9c56c659fe766a867c575023 (diff) | |
basic interrupt/PIC support
| -rw-r--r-- | src/arch/x86_64/interrupt/mod.rs | 23 | ||||
| -rw-r--r-- | src/arch/x86_64/interrupt/pic_8259.rs | 46 | ||||
| -rw-r--r-- | src/arch/x86_64/interrupt/pit.rs (renamed from src/arch/x86_64/pit.rs) | 0 | ||||
| -rw-r--r-- | src/arch/x86_64/mod.rs | 4 | ||||
| -rw-r--r-- | src/arch/x86_64/pic.rs | 1 | ||||
| -rw-r--r-- | src/arch/x86_64/plugbox.rs | 1 | ||||
| -rw-r--r-- | src/lib.rs | 7 | ||||
| -rw-r--r-- | src/machine/interrupt.rs | 2 | ||||
| -rw-r--r-- | src/machine/mod.rs | 4 | ||||
| -rw-r--r-- | src/machine/plugbox.rs | 0 | ||||
| -rw-r--r-- | startup.s | 4 |
11 files changed, 85 insertions, 7 deletions
diff --git a/src/arch/x86_64/interrupt/mod.rs b/src/arch/x86_64/interrupt/mod.rs new file mode 100644 index 0000000..3a617e8 --- /dev/null +++ b/src/arch/x86_64/interrupt/mod.rs @@ -0,0 +1,23 @@ +pub mod pic_8259; +pub mod pit; +use crate::io::*; +use core::arch::asm; + +#[no_mangle] +extern "C" fn guardian(slot: u16) { + println!("interrupt received {:x}", slot); +} + +#[inline(always)] +pub fn interrupt_enable() { + unsafe { + asm!("sti"); + } +} + +#[inline(always)] +pub fn interrupt_disable() { + unsafe { + asm!("cli"); + } +} diff --git a/src/arch/x86_64/interrupt/pic_8259.rs b/src/arch/x86_64/interrupt/pic_8259.rs new file mode 100644 index 0000000..43a102c --- /dev/null +++ b/src/arch/x86_64/interrupt/pic_8259.rs @@ -0,0 +1,46 @@ +// For now, the PIC is stateless, i.e. we don'e need a struct for it. +// Perhaps I need a Mutex handle later... +use crate::arch::x86_64::io_port::*; + +const IMR1: u16 = 0x21; +const IMR2: u16 = 0xa1; +const CTRL1: u16 = 0x20; +const CTRL2: u16 = 0xa0; + +pub struct PicDeviceInt; +impl PicDeviceInt { + pub const TIMER: u8 = 0; + pub const KEYBOARD: u8 = 1; +} + +// 8-bit registers IMR1 and IMR2 registers hold interrupt masking bit 0~7 and +// 8~15; if an interrupt is masked(set 1) on the respective bit, it's disabled +pub fn allow(interrupt: u8) { + if interrupt < 8 { + let old = inb(IMR1); + outb(IMR1, old & !(1 << interrupt)); + } else { + let old = inb(IMR2); + outb(IMR2, old & !(1 << (interrupt - 8))); + } +} + +pub fn forbid(interrupt: u8) { + if interrupt < 8 { + let old = inb(IMR1); + outb(IMR1, old | (1 << interrupt)); + } else { + let old = inb(IMR2); + outb(IMR2, old | (1 << (interrupt - 8))); + } +} + +pub fn is_masked(interrupt: u8) -> bool { + if interrupt < 8 { + let val = inb(IMR1); + return val & (interrupt) != 0; + } else { + let val = inb(IMR2); + return val & (interrupt - 8) != 0; + } +} diff --git a/src/arch/x86_64/pit.rs b/src/arch/x86_64/interrupt/pit.rs index 8b13789..8b13789 100644 --- a/src/arch/x86_64/pit.rs +++ b/src/arch/x86_64/interrupt/pit.rs diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index a7f9e89..9429c8f 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -1,6 +1,4 @@ pub mod cpu; +pub mod interrupt; pub mod io_port; pub mod misc; -pub mod pic; -pub mod pit; -pub mod plugbox; diff --git a/src/arch/x86_64/pic.rs b/src/arch/x86_64/pic.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/arch/x86_64/pic.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/arch/x86_64/plugbox.rs b/src/arch/x86_64/plugbox.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/arch/x86_64/plugbox.rs +++ /dev/null @@ -1 +0,0 @@ - @@ -7,6 +7,9 @@ mod io; mod machine; use core::panic::PanicInfo; use machine::cgascr::CGAScreen; +use machine::interrupt; +use arch::x86_64::interrupt::pic_8259; +use arch::x86_64::interrupt::pic_8259::PicDeviceInt; #[cfg(not(test))] #[panic_handler] @@ -25,5 +28,9 @@ pub extern "C" fn _entry() -> ! { println!(" `-.-' \\ )-`( , o o)"); println!(" `- \\`_`\"'-"); println!("it works!"); + + // testing interrupt/PIC + pic_8259::allow(PicDeviceInt::KEYBOARD); + interrupt::interrupt_enable(); loop {} } diff --git a/src/machine/interrupt.rs b/src/machine/interrupt.rs new file mode 100644 index 0000000..1cd3234 --- /dev/null +++ b/src/machine/interrupt.rs @@ -0,0 +1,2 @@ +#[cfg(target_arch = "x86_64")] +pub use crate::arch::x86_64::interrupt::*; diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 70660ce..c6f6fec 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -1,5 +1,9 @@ pub mod cgascr; +pub mod interrupt; mod kbd_defs; pub mod key; pub mod keyctrl; pub mod mem; +pub mod plugbox; + +// TODO: this module *should* be arch independent. diff --git a/src/machine/plugbox.rs b/src/machine/plugbox.rs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/machine/plugbox.rs @@ -60,7 +60,7 @@ pagetable_end: equ 0x200000 ; functions from the C parts of the system [EXTERN _entry] -;[EXTERN guardian] +[EXTERN guardian] ; addresses provided by the compiler [EXTERN ___BSS_START__] @@ -281,7 +281,7 @@ wrapper_body: mov rdi, rax ; call the interrupt handler wrapper here. ; TODO implement it in rust then uncomment the line - ;call guardian + call guardian ; restore volatile registers pop r11 |
