Scan for PCI devices

This commit is contained in:
Josh Holtrop 2022-04-13 21:54:22 -04:00
parent 12067b8e1a
commit 53e2e52bbe
3 changed files with 70 additions and 0 deletions

View File

@ -24,3 +24,23 @@ ulong read_cr4()
{ {
return __asm!ulong("mov %cr4, %rax", "={rax}"); return __asm!ulong("mov %cr4, %rax", "={rax}");
} }
ushort in16(ushort ioaddr)
{
return __asm!ushort("inw %dx, %ax", "={ax},{dx}", ioaddr);
}
ulong in32(ushort ioaddr)
{
return __asm!ulong("inl %dx, %eax", "={eax},{dx}", ioaddr);
}
void out16(ushort ioaddr, ushort v)
{
__asm("outw %ax, %dx", "{dx},{ax}", ioaddr, v);
}
void out32(ushort ioaddr, ulong v)
{
__asm("outl %eax, %dx", "{dx},{eax}", ioaddr, v);
}

View File

@ -12,6 +12,7 @@ import hulk.kfont;
import hulk.klog; import hulk.klog;
import hulk.hurl; import hulk.hurl;
import hulk.hippo; import hulk.hippo;
import hulk.pci;
extern extern(C) __gshared ubyte _hulk_total_size; extern extern(C) __gshared ubyte _hulk_total_size;
@ -38,6 +39,7 @@ void hulk_start()
klog.writefln("Welcome to HULK, the HOS UltraLight Kernel!"); klog.writefln("Welcome to HULK, the HOS UltraLight Kernel!");
hippo.initialize(&hulk_header); hippo.initialize(&hulk_header);
pci.initialize();
for (;;) for (;;)
{ {

48
src/hulk/pci.d Normal file
View File

@ -0,0 +1,48 @@
module hulk.pci;
import hos.cpu;
import hulk.klog;
struct pci
{
/* IO address for PCI configuration address. */
enum IO_ADDR_CONFIG_ADDRESS = 0xCF8u;
/* IO address for PCI configuration data. */
enum IO_ADDR_CONFIG_DATA = 0xCFCu;
private static ulong read_config_register(ulong bus_id, ulong device_id, ulong register_id)
{
ulong addr = 0x8000_0000u | (bus_id << 16u) | (device_id << 11u) | (register_id << 2u);
out32(IO_ADDR_CONFIG_ADDRESS, addr);
return in32(IO_ADDR_CONFIG_DATA);
}
private static void scan(ulong bus_id, ulong device_id)
{
ulong reg0 = read_config_register(bus_id, device_id, 0u);
if (reg0 != 0xFFFFFFFFu)
{
ulong reg2 = read_config_register(bus_id, device_id, 2u);
klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u",
(reg0 & 0xFFFFu), (reg0 >> 16u),
(reg2 >> 24u) & 0xFFu,
(reg2 >> 16u) & 0xFFu,
(reg2 >> 8u) & 0xFFu,
bus_id, device_id);
}
}
public static void initialize()
{
klog.writefln("Scanning PCI devices...");
for (ulong bus_id = 0u; bus_id < 256u; bus_id++)
{
for (ulong device_id = 0u; device_id < 32u; device_id++)
{
scan(bus_id, device_id);
}
}
klog.writefln("PCI scan complete.");
}
}