#pragma once #include namespace PCI { enum Field : u32 { VendorID = 0x00, DeviceID = 0x02, Command = 0x04, Status = 0x06, RevisionID = 0x08, ProgIF = 0x09, Subclass = 0x0a, Class = 0x0b, HeaderType = 0x0e, SecondaryBus = 0x19 }; struct Device { struct ID { u16 vendor; u16 device; }; struct Type { u8 klass; u8 subclass; u8 prog_if; }; struct Address { u32 bus; u32 slot; u32 function; }; ID id; Type type; Address address; }; typedef void (*Callback)(const Device&); struct Match { i16 klass { -1 }; i16 subclass { -1 }; i16 prog_if { -1 }; }; constexpr u16 INVALID_ID = 0xFFFF; // Architecture-dependent. u8 read8(const Device::Address& address, u32 field); u16 read16(const Device::Address& address, u32 field); u32 read32(const Device::Address& address, u32 field); void write8(const Device::Address& address, u32 field, u8 value); void write16(const Device::Address& address, u32 field, u16 value); void write32(const Device::Address& address, u32 field, u32 value); Device::ID read_id(const Device::Address& address); Device::Type read_type(const Device::Address& address); void scan(Callback callback, Match match); }