diff --git a/Cargo.toml b/Cargo.toml index bda48be..80babe5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ bitflags = "0.7.0" x86_64 = "0.1.2" once = "0.3.3" linked_list_allocator = "0.5.0" +redox_syscall = "0.1.37" [build-dependencies] cc = "1.0" diff --git a/src/arch/x86_64/driver/mod.rs b/src/arch/x86_64/driver/mod.rs index 881ad79..c02bc76 100644 --- a/src/arch/x86_64/driver/mod.rs +++ b/src/arch/x86_64/driver/mod.rs @@ -2,4 +2,5 @@ pub mod vga; pub mod acpi; pub mod apic; pub mod mp; -pub mod serial; \ No newline at end of file +pub mod serial; +pub mod pic; \ No newline at end of file diff --git a/src/arch/x86_64/driver/pic.rs b/src/arch/x86_64/driver/pic.rs new file mode 100644 index 0000000..3e9c295 --- /dev/null +++ b/src/arch/x86_64/driver/pic.rs @@ -0,0 +1,64 @@ +use syscall::io::*; + +pub static mut MASTER: Pic = Pic::new(0x20); +pub static mut SLAVE: Pic = Pic::new(0xA0); + +pub unsafe fn init() { + // Start initialization + MASTER.cmd.write(0x11); + SLAVE.cmd.write(0x11); + + // Set offsets + MASTER.data.write(0x20); + SLAVE.data.write(0x28); + + // Set up cascade + MASTER.data.write(4); + SLAVE.data.write(2); + + // Set up interrupt mode (1 is 8086/88 mode, 2 is auto EOI) + MASTER.data.write(1); + SLAVE.data.write(1); + + // Unmask interrupts + MASTER.data.write(0); + SLAVE.data.write(0); + + // Ack remaining interrupts + MASTER.ack(); + SLAVE.ack(); +} + +pub struct Pic { + cmd: Pio, + data: Pio, +} + +impl Pic { + pub const fn new(port: u16) -> Pic { + Pic { + cmd: Pio::new(port), + data: Pio::new(port + 1), + } + } + + pub fn ack(&mut self) { + self.cmd.write(0x20); + } + + pub fn mask_set(&mut self, irq: u8) { + assert!(irq < 8); + + let mut mask = self.data.read(); + mask |= 1 << irq; + self.data.write(mask); + } + + pub fn mask_clear(&mut self, irq: u8) { + assert!(irq < 8); + + let mut mask = self.data.read(); + mask &= !(1 << irq); + self.data.write(mask); + } +} diff --git a/src/lib.rs b/src/lib.rs index fa95282..78d1cbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ extern crate linked_list_allocator; #[macro_use] extern crate lazy_static; extern crate bit_field; +extern crate syscall; #[macro_use] // print! mod io; @@ -78,7 +79,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) { memory_controller.map_page_identity(acpi.lapic_addr as usize); // LAPIC arch::driver::apic::init(acpi.lapic_addr); - io::init(); + unsafe{ arch::driver::pic::init(); } test_end!(); }