diff --git a/kernel/src/arch/x86_64/driver/mod.rs b/kernel/src/arch/x86_64/driver/mod.rs index f8382dab..9e5f46a0 100644 --- a/kernel/src/arch/x86_64/driver/mod.rs +++ b/kernel/src/arch/x86_64/driver/mod.rs @@ -1,4 +1,5 @@ use once::*; +use crate::arch::interrupt::{consts, enable_irq}; pub mod vga; pub mod serial; @@ -19,4 +20,14 @@ pub fn init() { serial::init(); keyboard::init(); + + // Enable PCI Interrupts + enable_irq(consts::PIRQA); + enable_irq(consts::PIRQB); + enable_irq(consts::PIRQC); + enable_irq(consts::PIRQD); + enable_irq(consts::PIRQE); + enable_irq(consts::PIRQF); + enable_irq(consts::PIRQG); + enable_irq(consts::PIRQH); } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/interrupt/consts.rs b/kernel/src/arch/x86_64/interrupt/consts.rs index 4ab7494e..d9b7f7ee 100644 --- a/kernel/src/arch/x86_64/interrupt/consts.rs +++ b/kernel/src/arch/x86_64/interrupt/consts.rs @@ -34,3 +34,14 @@ pub const COM1: u8 = 4; pub const IDE: u8 = 14; pub const Error: u8 = 19; pub const Spurious: u8 = 31; + +// PCI Interrupts +// See https://gist.github.com/mcastelino/4acda7c2407f1c51e68f3f994d8ffc98 +pub const PIRQA: u8 = 16; +pub const PIRQB: u8 = 17; +pub const PIRQC: u8 = 18; +pub const PIRQD: u8 = 19; +pub const PIRQE: u8 = 20; +pub const PIRQF: u8 = 21; +pub const PIRQG: u8 = 22; +pub const PIRQH: u8 = 23; diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index 8761d348..c214e16c 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -168,15 +168,19 @@ impl PciTag { let mf = self.read(PCI_HEADER, 1); let cl = self.read(PCI_CLASS, 1); let scl = self.read(PCI_SUBCLASS, 1); + let line = self.read(PCI_INTERRUPT_LINE, 1); + let pin = self.read(PCI_INTERRUPT_PIN, 1); info!( - "{}: {}: {}: {:#X} {:#X} ({} {})", + "{}: {}: {}: {:#X} {:#X} ({} {}) at {}:{}", self.bus(), self.dev(), self.func(), v, d, cl, - scl + scl, + line, + pin ); return Some((v, d, mf & 0x80 != 0)); @@ -189,6 +193,7 @@ impl PciTag { self.write(PCI_COMMAND, orig | 0x40f); // find MSI cap + let mut msi_found = false; let mut cap_ptr = self.read(PCI_CAP_PTR, 1); while cap_ptr > 0 { let cap_id = self.read(cap_ptr, 1); @@ -202,19 +207,36 @@ impl PciTag { // enable MSI interrupt let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4); self.write(cap_ptr + PCI_MSI_CTRL_CAP, orig_ctrl | 0x10000); + info!("MSI control {:#b}, enabling MSI interrupts", orig_ctrl >> 16); + msi_found = true; break; } - info!("cap id {} at {:#X}", self.read(cap_ptr, 1), cap_ptr); + info!("PCI device has cap id {} at {:#X}", self.read(cap_ptr, 1), cap_ptr); cap_ptr = self.read(cap_ptr + 1, 1); } + + if !msi_found { + // Use PCI legacy interrupt instead + // IO Space | MEM Space | Bus Mastering | Special Cycles + self.write(PCI_COMMAND, orig | 0xf); + let line = self.read(PCI_INTERRUPT_LINE, 1); + let pin = self.read(PCI_INTERRUPT_PIN, 1); + info!("MSI not found, using PCI interrupt line {} pin {}", line, pin); + } } } pub fn init_driver(vid: u32, did: u32, tag: PciTag) { if vid == 0x8086 { - if did == 0x100e || did == 0x10d3 { + if did == 0x100e || did == 0x100f || did == 0x10d3 || did == 0x15b8 { + // 0x100e // 82540EM Gigabit Ethernet Controller + // 0x100f + // 82545EM Gigabit Ethernet Controller (Copper) + // 0x10d3 // 82574L Gigabit Network Connection + // 0x15b8 + // Ethernet Connection (2) I219-V if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } { unsafe { tag.enable(); @@ -227,7 +249,7 @@ pub fn init_driver(vid: u32, did: u32, tag: PciTag) { unsafe { tag.enable(); } - ixgbe::ixgbe_init(addr, len); + //ixgbe::ixgbe_init(addr, len); } } }