.{inl, outl} := @use("rel:memory.hb") config_read := fn(bus: u8, device: u8, func: u8, offset: u8): u32 { lbus := @as(u32, bus) ldevice := @as(u32, device) lfunc := @as(u32, func) loffset := @as(u32, offset) address := lbus << 16 | ldevice << 11 | lfunc << 8 | loffset & 0xFC | @as(u32, 0x80000000) outl(0xCF8, address) return inl(0xCFC) } config_write := fn(bus: u8, device: u8, func: u8, offset: u8, value: u32): void { lbus := @as(u32, bus) ldevice := @as(u32, device) lfunc := @as(u32, func) loffset := @as(u32, offset) address := lbus << 16 | ldevice << 11 | lfunc << 8 | loffset & 0xFC | @as(u32, 0x80000000) outl(0xCF8, address) outl(0xCFC, value) } get_header_type := fn(bus: u8, device: u8, func: u8): u8 { return @as(u8, config_read(bus, device, func, 0xC) >> 16 & 0xFF) } Ids := struct {vendor: u16, device: u16} get_ids := fn(bus: u8, device: u8, func: u8): Ids { res := config_read(bus, device, func, 0) return .(@as(u16, res >> 16 & 0xFFFF), @as(u16, res & 0xFFFF)) } PciDeviceInfo := struct {header_type: u8, device: u8, bus: u8, device_id: Ids, full_class: u16, rev_id: u8} check_device := fn(bus: u8, device: u8): PciDeviceInfo { ids := get_ids(bus, device, 0) if ids.vendor == 0xFFFF { return .(0, 0, 0, .(0, 0), 0, 0) } reg2 := config_read(bus, device, 0, 0x8) class := @as(u16, reg2 >> 16 & 0xFFFF) header_type := get_header_type(bus, device, 0) return .(header_type, device, bus, ids, class, @as(u8, reg2 & 0xFF)) }