forked from AbleOS/ableos
50 lines
1.4 KiB
Plaintext
50 lines
1.4 KiB
Plaintext
|
.{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))
|
||
|
}
|