mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
Add support for PCI legacy interrupts
This commit is contained in:
parent
28ce8ba81c
commit
b7f47235f8
@ -1,4 +1,5 @@
|
|||||||
use once::*;
|
use once::*;
|
||||||
|
use crate::arch::interrupt::{consts, enable_irq};
|
||||||
|
|
||||||
pub mod vga;
|
pub mod vga;
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
@ -19,4 +20,14 @@ pub fn init() {
|
|||||||
|
|
||||||
serial::init();
|
serial::init();
|
||||||
keyboard::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);
|
||||||
}
|
}
|
@ -34,3 +34,14 @@ pub const COM1: u8 = 4;
|
|||||||
pub const IDE: u8 = 14;
|
pub const IDE: u8 = 14;
|
||||||
pub const Error: u8 = 19;
|
pub const Error: u8 = 19;
|
||||||
pub const Spurious: u8 = 31;
|
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;
|
||||||
|
@ -168,15 +168,19 @@ impl PciTag {
|
|||||||
let mf = self.read(PCI_HEADER, 1);
|
let mf = self.read(PCI_HEADER, 1);
|
||||||
let cl = self.read(PCI_CLASS, 1);
|
let cl = self.read(PCI_CLASS, 1);
|
||||||
let scl = self.read(PCI_SUBCLASS, 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!(
|
info!(
|
||||||
"{}: {}: {}: {:#X} {:#X} ({} {})",
|
"{}: {}: {}: {:#X} {:#X} ({} {}) at {}:{}",
|
||||||
self.bus(),
|
self.bus(),
|
||||||
self.dev(),
|
self.dev(),
|
||||||
self.func(),
|
self.func(),
|
||||||
v,
|
v,
|
||||||
d,
|
d,
|
||||||
cl,
|
cl,
|
||||||
scl
|
scl,
|
||||||
|
line,
|
||||||
|
pin
|
||||||
);
|
);
|
||||||
|
|
||||||
return Some((v, d, mf & 0x80 != 0));
|
return Some((v, d, mf & 0x80 != 0));
|
||||||
@ -189,6 +193,7 @@ impl PciTag {
|
|||||||
self.write(PCI_COMMAND, orig | 0x40f);
|
self.write(PCI_COMMAND, orig | 0x40f);
|
||||||
|
|
||||||
// find MSI cap
|
// find MSI cap
|
||||||
|
let mut msi_found = false;
|
||||||
let mut cap_ptr = self.read(PCI_CAP_PTR, 1);
|
let mut cap_ptr = self.read(PCI_CAP_PTR, 1);
|
||||||
while cap_ptr > 0 {
|
while cap_ptr > 0 {
|
||||||
let cap_id = self.read(cap_ptr, 1);
|
let cap_id = self.read(cap_ptr, 1);
|
||||||
@ -202,19 +207,36 @@ impl PciTag {
|
|||||||
// enable MSI interrupt
|
// enable MSI interrupt
|
||||||
let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4);
|
let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4);
|
||||||
self.write(cap_ptr + PCI_MSI_CTRL_CAP, orig_ctrl | 0x10000);
|
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;
|
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);
|
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) {
|
pub fn init_driver(vid: u32, did: u32, tag: PciTag) {
|
||||||
if vid == 0x8086 {
|
if vid == 0x8086 {
|
||||||
if did == 0x100e || did == 0x10d3 {
|
if did == 0x100e || did == 0x100f || did == 0x10d3 || did == 0x15b8 {
|
||||||
|
// 0x100e
|
||||||
// 82540EM Gigabit Ethernet Controller
|
// 82540EM Gigabit Ethernet Controller
|
||||||
|
// 0x100f
|
||||||
|
// 82545EM Gigabit Ethernet Controller (Copper)
|
||||||
|
// 0x10d3
|
||||||
// 82574L Gigabit Network Connection
|
// 82574L Gigabit Network Connection
|
||||||
|
// 0x15b8
|
||||||
|
// Ethernet Connection (2) I219-V
|
||||||
if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } {
|
if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } {
|
||||||
unsafe {
|
unsafe {
|
||||||
tag.enable();
|
tag.enable();
|
||||||
@ -227,7 +249,7 @@ pub fn init_driver(vid: u32, did: u32, tag: PciTag) {
|
|||||||
unsafe {
|
unsafe {
|
||||||
tag.enable();
|
tag.enable();
|
||||||
}
|
}
|
||||||
ixgbe::ixgbe_init(addr, len);
|
//ixgbe::ixgbe_init(addr, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user