diff --git a/src/arch/x86_64/driver/apic/ioapic.rs b/src/arch/x86_64/driver/apic/ioapic.rs index f1efdc6..b68f197 100644 --- a/src/arch/x86_64/driver/apic/ioapic.rs +++ b/src/arch/x86_64/driver/apic/ioapic.rs @@ -4,10 +4,22 @@ /// http://www.intel.com/design/chipsets/datashts/29056601.pdf /// See also picirq.c. -use core::ptr::{read_volatile, write_volatile}; +use core::ptr::{Unique}; +use syscall::io::{Io, Mmio}; -pub fn init() { +pub unsafe fn init(ioapic_id: u8) +{ + let ioapic = IOAPIC.as_mut(); + let maxintr = (ioapic.read(REG_VER) >> 16) & 0xFF; + let id = (ioapic.read(REG_ID) >> 24) as u8; + assert!(id == ioapic_id, "ioapicinit: id isn't equal to ioapicid; not a MP"); + // Mark all interrupts edge-triggered, active high, disabled, + // and not routed to any CPUs. + for i in 0 .. maxintr+1 { + ioapic.write(REG_TABLE+2*i, INT_DISABLED | (T_IRQ0 + i)); + ioapic.write(REG_TABLE+2*i+1, 0); + } } const IOAPIC_ADDRESS : u32 = 0xFEC00000; // Default physical address of IO APIC @@ -26,44 +38,28 @@ const INT_LEVEL : u32 = 0x00008000; // Level-triggered (vs edge-) const INT_ACTIVELOW : u32 = 0x00002000; // Active low (vs high) const INT_LOGICAL : u32 = 0x00000800; // Destination is CPU id (vs APIC ID) -// static IOAPIC: *mut IoApic = IOAPIC_ADDRESS as *mut _; +static mut IOAPIC: Unique = unsafe{ Unique::new_unchecked(IOAPIC_ADDRESS as *mut _) }; -const ioapicid: u32 = 0; // TODO fix const T_IRQ0: u32 = 32; // IO APIC MMIO structure: write reg, then read or write data. #[repr(C)] struct IoApic { - reg: u32, - pad: [u32; 3], - data: u32, + reg: Mmio, + pad: [Mmio; 3], + data: Mmio, } impl IoApic { unsafe fn read(&mut self, reg: u32) -> u32 { - write_volatile(&mut self.reg as *mut _, reg); - read_volatile(&self.data as *const _) + self.reg.write(reg); + self.data.read() } unsafe fn write(&mut self, reg: u32, data: u32) { - write_volatile(&mut self.reg as *mut _, reg); - write_volatile(&mut self.data as *mut _, data); - } - unsafe fn init(&mut self) - { - let maxintr = (self.read(REG_VER) >> 16) & 0xFF; - let id = self.read(REG_ID) >> 24; - if id != ioapicid { - println!("ioapicinit: id isn't equal to ioapicid; not a MP"); - } - - // Mark all interrupts edge-triggered, active high, disabled, - // and not routed to any CPUs. - for i in 0 .. maxintr+1 { - self.write(REG_TABLE+2*i, INT_DISABLED | (T_IRQ0 + i)); - self.write(REG_TABLE+2*i+1, 0); - } + self.reg.write(reg); + self.data.write(data); } unsafe fn enable(&mut self, irq: u32, cpunum: u32) { diff --git a/src/arch/x86_64/driver/apic/lapic.rs b/src/arch/x86_64/driver/apic/lapic.rs index 8c2a609..c4537db 100644 --- a/src/arch/x86_64/driver/apic/lapic.rs +++ b/src/arch/x86_64/driver/apic/lapic.rs @@ -3,10 +3,8 @@ extern { fn lapicinit(); // must set `lapic` first } -pub fn init(lapic_addr: *const ()) { +pub unsafe fn init(lapic_addr: *const ()) { debug!("WARNING: lapic::init use C lib"); - unsafe { - lapic = lapic_addr; - lapicinit(); - } + lapic = lapic_addr; + lapicinit(); } \ No newline at end of file diff --git a/src/arch/x86_64/driver/apic/mod.rs b/src/arch/x86_64/driver/apic/mod.rs index d931d6f..fc46842 100644 --- a/src/arch/x86_64/driver/apic/mod.rs +++ b/src/arch/x86_64/driver/apic/mod.rs @@ -1,7 +1,7 @@ mod lapic; mod ioapic; -pub fn init(lapic_addr: *const ()) { +pub unsafe fn init(lapic_addr: *const (), ioapic_id: u8) { self::lapic::init(lapic_addr); - // self::ioapic::init(); + self::ioapic::init(ioapic_id); } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 78d1cbf..452c1a4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,7 +77,8 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) { debug!("{:?}", acpi); memory_controller.map_page_identity(acpi.lapic_addr as usize); // LAPIC - arch::driver::apic::init(acpi.lapic_addr); + memory_controller.map_page_identity(0xFEC00000); // IOAPIC + unsafe{ arch::driver::apic::init(acpi.lapic_addr, acpi.ioapic_id); } unsafe{ arch::driver::pic::init(); }