parent
05310dcd7d
commit
197bebb1d2
@ -1 +1,3 @@
|
||||
pub mod virtio_mmio;
|
||||
pub mod virtio_mmio;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod pci;
|
@ -0,0 +1,98 @@
|
||||
use x86_64::instructions::port::Port;
|
||||
use crate::logging::*;
|
||||
|
||||
const VENDOR: u32 = 0x00;
|
||||
const DEVICE: u32 = 0x02;
|
||||
const STATUS: u32 = 0x06;
|
||||
const SUBCLASS: u32 = 0x0a;
|
||||
const CLASS: u32 = 0x0b;
|
||||
const HEADER: u32 = 0x0e;
|
||||
|
||||
const PCI_ADDR_PORT: u16 = 0xcf8;
|
||||
const PCI_DATA_PORT: u16 = 0xcfc;
|
||||
|
||||
struct PciTag(u32);
|
||||
|
||||
impl PciTag {
|
||||
pub fn new(bus: u32, dev: u32, func: u32) -> PciTag {
|
||||
PciTag(bus << 16 | dev << 11 | func << 8)
|
||||
}
|
||||
|
||||
pub fn bus(&self) -> u32 {
|
||||
(self.0 >> 16) & 0xFF
|
||||
}
|
||||
|
||||
pub fn dev(&self) -> u32 {
|
||||
(self.0 >> 11) & 0x1F
|
||||
}
|
||||
|
||||
pub fn func(&self) -> u32 {
|
||||
(self.0 >> 8) & 0x7
|
||||
}
|
||||
|
||||
// biscuit/src/pci/pci.go
|
||||
pub unsafe fn read(&self, reg: u32, width: u32) -> u32 {
|
||||
// spans in one reg
|
||||
assert_eq!(reg / 4, (reg + width - 1) / 4);
|
||||
|
||||
let enable = 1 << 31;
|
||||
let rsh = reg % 4;
|
||||
let r = reg - rsh;
|
||||
let t = enable | self.0 | r;
|
||||
|
||||
let mut pci_addr: Port<u32> = Port::new(PCI_ADDR_PORT);
|
||||
let mut pci_data: Port<u32> = Port::new(PCI_DATA_PORT);
|
||||
|
||||
pci_addr.write(t);
|
||||
let d = pci_data.read();
|
||||
pci_addr.write(0);
|
||||
|
||||
let ret = d >> (rsh * 8);
|
||||
let m = (1 << (8 * width)) - 1;
|
||||
return ret & m;
|
||||
}
|
||||
|
||||
pub unsafe fn write(&self, reg: u32, val: u32) {
|
||||
assert_eq!(reg & 3, 0);
|
||||
|
||||
let enable = 1 << 31;
|
||||
let t = enable | self.0 | reg;
|
||||
|
||||
let mut pci_addr: Port<u32> = Port::new(PCI_ADDR_PORT);
|
||||
let mut pci_data: Port<u32> = Port::new(PCI_DATA_PORT);
|
||||
|
||||
pci_addr.write(t);
|
||||
pci_data.write(val);
|
||||
pci_addr.write(0);
|
||||
}
|
||||
|
||||
pub fn describe(&self) -> bool {
|
||||
unsafe {
|
||||
let v = self.read(VENDOR, 2);
|
||||
if v == 0xffff {
|
||||
return false;
|
||||
}
|
||||
let d = self.read(DEVICE, 2);
|
||||
let mf = self.read(HEADER, 1);
|
||||
let cl = self.read(CLASS, 1);
|
||||
let scl = self.read(SUBCLASS, 1);
|
||||
info!("{}: {}: {}: {:#X} {:#X} ({} {})", self.bus(), self.dev(), self.func(), v, d, cl, scl);
|
||||
return mf & 0x80 != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
for bus in 0..256 {
|
||||
for dev in 0..32 {
|
||||
let tag = PciTag::new(bus, dev, 0);
|
||||
if tag.describe() {
|
||||
for func in 1..8 {
|
||||
let tag = PciTag::new(bus, dev, func);
|
||||
tag.describe();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
info!("Init pci");
|
||||
}
|
Loading…
Reference in new issue