From 0e22ba24be386dcda0a26af5bd827461ceba78a1 Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Sat, 11 Feb 2017 20:54:14 -0700
Subject: [PATCH] Initialize PIC in Rust

---
 arch/x86_64/src/device/mod.rs |  2 ++
 arch/x86_64/src/device/pic.rs | 48 +++++++++++++++++++++++++++++++++++
 arch/x86_64/src/start.rs      |  4 ---
 3 files changed, 50 insertions(+), 4 deletions(-)
 create mode 100644 arch/x86_64/src/device/pic.rs

diff --git a/arch/x86_64/src/device/mod.rs b/arch/x86_64/src/device/mod.rs
index d4d56e66..522b2b48 100644
--- a/arch/x86_64/src/device/mod.rs
+++ b/arch/x86_64/src/device/mod.rs
@@ -2,10 +2,12 @@ use paging::ActivePageTable;
 
 pub mod cpu;
 pub mod local_apic;
+pub mod pic;
 pub mod rtc;
 pub mod serial;
 
 pub unsafe fn init(active_table: &mut ActivePageTable){
+    pic::init();
     local_apic::init(active_table);
     rtc::init();
     serial::init();
diff --git a/arch/x86_64/src/device/pic.rs b/arch/x86_64/src/device/pic.rs
new file mode 100644
index 00000000..f5b63698
--- /dev/null
+++ b/arch/x86_64/src/device/pic.rs
@@ -0,0 +1,48 @@
+use syscall::io::{Io, Pio};
+
+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 manual, 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<u8>,
+    data: Pio<u8>,
+}
+
+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);
+    }
+}
diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs
index 72772ea1..44880095 100644
--- a/arch/x86_64/src/start.rs
+++ b/arch/x86_64/src/start.rs
@@ -120,10 +120,6 @@ pub unsafe extern fn kstart() -> ! {
         // Read ACPI tables, starts APs
         acpi::init(&mut active_table);
 
-        // Clear pending IRQs
-        // TODO: Remove this and ack all IRQs without listeners
-        interrupt::irq::acknowledge(8);
-
         BSP_READY.store(true, Ordering::SeqCst);
     }
 
-- 
GitLab