aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTianhao Wang <wth@riseup.net>2024-02-01 15:10:11 +0100
committerTianhao Wang <shrik3@mailbox.org>2024-06-11 15:13:37 +0200
commitc01e440d014253fd4cae9f642c949720a54baf4b (patch)
tree68d9fc26ccf2f124702b2c2a000892c344f203fe
parent753955dbb4e6c77b9c56c659fe766a867c575023 (diff)
basic interrupt/PIC support
-rw-r--r--src/arch/x86_64/interrupt/mod.rs23
-rw-r--r--src/arch/x86_64/interrupt/pic_8259.rs46
-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.rs4
-rw-r--r--src/arch/x86_64/pic.rs1
-rw-r--r--src/arch/x86_64/plugbox.rs1
-rw-r--r--src/lib.rs7
-rw-r--r--src/machine/interrupt.rs2
-rw-r--r--src/machine/mod.rs4
-rw-r--r--src/machine/plugbox.rs0
-rw-r--r--startup.s4
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 @@
-
diff --git a/src/lib.rs b/src/lib.rs
index 5de826c..80d0146 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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
diff --git a/startup.s b/startup.s
index 4d4df62..fb73dcb 100644
--- a/startup.s
+++ b/startup.s
@@ -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