reading pci id is always 0x1111
Posted: Mon Apr 12, 2021 12:06 pm
Hello there,
I am attempting to enumerate the pci configuration space (on qemu, if that matters, I haven't had a chance to try on real hardware), but the ID always comes out as 0x1111, and the vendor always comes out as 0.
my pci code looks like this
and I'm calling it like this (please excuse my debug code)
a snippet of the output
the issue could be from the fact that I'm using ffi to call from rust, but I sort of doubt it. I'm pretty bad at math so I could possibly be doing shifting wrong or something, or it could be a deeper issue.
thank you,
skylar alexandra bleed
I am attempting to enumerate the pci configuration space (on qemu, if that matters, I haven't had a chance to try on real hardware), but the ID always comes out as 0x1111, and the vendor always comes out as 0.
my pci code looks like this
Code: Select all
#define PCI_ADDR 0x0CF8
#define PCI_DATA 0x0CFC
// port is the byte offset from 0x00
unsigned char pci_read_byte(const int bus, const int dev, const int func, const int port) {
const int shift = ((port & 3) * 8);
const unsigned int val = 0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (port & 0xFC);
outl(PCI_ADDR, val);
return (inl(PCI_DATA) >> shift) & 0xFF;
}
// port is the byte offset from 0x00
unsigned short pci_read_word(const int bus, const int dev, const int func, const int port) {
if ((port & 3) <= 2) {
const int shift = ((port & 3) * 8);
const unsigned int val = 0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (port & 0xFC);
outl(PCI_ADDR, val);
return (inl(PCI_DATA) >> shift) & 0xFFFF;
} else
return (pci_read_byte(bus, dev, func, port + 1) << 8) | pci_read_byte(bus, dev, func, port);
}
// port is the byte offset from 0x00
unsigned int pci_read_dword(const int bus, const int dev, const int func, const int port) {
if ((port & 3) == 0) {
const unsigned int val = 0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (port & 0xFC);
outl(PCI_ADDR, val);
return inl(PCI_DATA);
} else
return (pci_read_word(bus, dev, func, port + 2) << 16) | pci_read_word(bus, dev, func, port);
}
Code: Select all
/// max pci buses to enumerate
pub const PCI_MAX_BUS: i32 = 256;
/// max number of devices to enumerate in a bus
pub const PCI_MAX_DEV: i32 = 32;
/// max number of functions to enumerate in a device
pub const PCI_MAX_FUNC: i32 = 8;
pub unsafe fn probe() {
let mut found = false;
let mut nonzero = false;
// enumerate pci buses
for bus in 0..PCI_MAX_BUS {
for dev in 0..PCI_MAX_DEV {
for func in 0..PCI_MAX_FUNC {
// read the first 16 bytes of the function
// if it is not 0xFFFF, then it's a valid function
let id = pci::pci_read_dword(bus, dev, func, 0x00);
// vendor is bits 31:16
let vendor = (id & 0xFFFF0000) << 15;
dbgln!(
"[{}][{}][{}] -> id: {i:b} ({i:x}), vendor: {v:b} ({v:x})",
bus,
dev,
func,
i = id,
v = vendor
);
if vendor != 0xFFFF {
// 0x09 is CC - Class Code
// see 2.1.5 of the intel serial ata spec
let class_code = pci::pci_read_dword(bus, dev, func, 0x09);
// base class code, bits 23:16
let bcc = (class_code & 0x0000FF00) << 15;
// sub class code, bits 15:08
let scc = (class_code & 0x00FF0000) << 7;
dbgln!("[{}][{}][{}] -> class code: {:b}, base class code: {:b}, sub class code: {:b}", bus, dev, func, class_code, bcc, scc);
if bcc == 0x01 && scc == 0x06 {
found = true;
}
if bcc != 0 || scc != 0 {
nonzero = true;
}
}
}
}
}
dbgln!(
"found a suitable drive: {}\nany values nonzero? : {}",
found,
nonzero
);
}
Code: Select all
[1][12][0] -> class code: 10001000000000000000000010001, base class code: 0, sub class code: 0
[1][12][1] -> id: 1000100010001 (1111), vendor: 0 (0)
[1][12][1] -> class code: 10001000000000000000000010001, base class code: 0, sub class code: 0
[1][12][2] -> id: 1000100010001 (1111), vendor: 0 (0)
[1][12][2] -> class code: 10001000000000000000000010001, base class code: 0, sub class code: 0
[1][12][3] -> id: 1000100010001 (1111), vendor: 0 (0)
[1][12][3] -> class code: 10001000000000000000000010001, base class code: 0, sub class code: 0
[1][12][4] -> id: 1000100010001 (1111), vendor: 0 (0)
[1][12][4] -> class code: 10001000000000000000000010001, base class code: 0, sub class code: 0
thank you,
skylar alexandra bleed