Code:
uint8_t PCI::read_byte(uint8_t bus,uint8_t slot,uint8_t func,uint8_t offset) {
write_addr(bus,slot,func,offset);
using namespace io;
return (uint8_t)((Ports::read_long(0xCFC) >> ((offset & 3) * 8)) & 0xFF);
using namespace hardware;
}
void PCI::write_addr(uint8_t bus,uint8_t slot,uint8_t fn,uint8_t offset) {
using namespace io;
uint32_t addr = (uint32_t)((uint32_t)0x80000000 | (uint32_t)bus << 16 | (uint32_t)slot << 11 | (uint32_t)fn << 8 | (uint32_t)offset);
Ports::write_long(0xCF8,addr);
using namespace hardware;
}
...
void Ports::write_long(uint16_t port,uint16_t value) {
asm volatile ("outw %w0,%w1" :: "a"(value),"d"(port));
}
uint16_t Ports::read_long(uint16_t port) {
uint16_t value;
asm volatile ("inw %w1,%w0" : "=a"(value) : "d"(port));
return value;
}
You are confusing 32 bit longs / dwords with 16 bit words all over the place.
Your Ports::write_long() function is called with a 32 bit value, but only takes 16 bit values.
Similarly, your Ports::read_long() function is used to read 32 bit values, but only returns 16 bit values.
One of the many problems that are caused by this that PCI::write_addr() isn't actually able to send the enable bit to the address port, which means that PCI::read_whatever() doesn't actually read anything at all, not even the wrong address.