stn := @use("../../stn/src/lib.hb"); .{string, memory, buffer} := stn PCIAddress := struct { bus: u8, device: u8, function: u8, } PCI_ID := struct { vendor: u16, device: u16, } get_ids := fn(bus: u8, device: u8, function: u8): PCI_ID { res := config_read32(bus, device, function, 0) dev_id := res >> 16 dev_id &= 0xFFFF vnd_id := res & 0xFFFF return PCI_ID.(dev_id, vnd_id) } PciDeviceInfo := struct { header_type: u8, device: u8, bus: u8, device_id: PCI_ID, class: u16, rev_id: u8, } calculate_address := fn(bus: u8, device: u8, function: u8, offset: u8): int { address := bus << 16 address |= device << 11 address |= function << 8 address |= offset & 0xFC address |= 0x80000000 return address } get_header_type := fn(bus: u8, device: u8, function: u8): u8 { res := config_read32(bus, device, function, 0xC) ret := res >> 16 ret &= 0xFF return ret } check_device := fn(bus: u8, device: u8): PciDeviceInfo { pci_id := get_ids(bus, device, 0) if pci_id.vendor == 0xFFFF { stn.log.warn(":|\0") } else { stn.log.info(":)\0") } address := calculate_address(bus, device, 0, 0x8) reg2 := config_read32(bus, device, 0, 0x8) class := reg2 >> 16 & 0xFFFF header_type := get_header_type(bus, device, 0) rev_id := reg2 & 0xFF return PciDeviceInfo.(header_type, device, bus, pci_id, class, rev_id) } find_device := fn(vendor_id: int, device_id: int, pci_address: PCIAddress): PCI_ID { pci_id := get_ids(0, 2, 0) return pci_id } scan_bus := fn(): void { } config_read32 := fn(bus: u32, device: u32, func: u32, offset: u32): u32 { // construct address param offset_and := offset & 0xFC address := bus << 16 address |= device << 11 address |= func << 8 address |= offset_and address |= 0x80000000 // write address memory.outl(0xCF8, address) // read data return memory.inl(0xCFC) }