/* * This is the main file of the Driver core, it finds the devices attached to * the system and also triggers any initialisation required for them. */ #include #include #include "drivers.h" #include "pci.h" #include "../vfs/vfs.h" #include "../screen.h" /* Structure for a Device */ typedef struct Device { uint16_t vendor, device; char *name; void (*init)(uint8_t, uint8_t, uint8_t); } Device; Device devices[] = { /* Intel system devices */ {0x8086, 0x1237, "Intel i440FX Chipset", NULL}, {0x8086, 0x7000, "Intel PIIX3 PCI-to-ISA Bridge (Triton II)", NULL}, {0x8086, 0x7010, "Intel PIIX3 IDE Interface (Triton II)", ide_init}, {0x8086, 0x7020, "Intel PIIX3 USB (Natoma/Triton II)", NULL}, {0x8086, 0x7113, "Intel PIIX4/4E/4M Power Management Controller", NULL}, /* Network devices */ {0x10ec, 0x8139, "Realtek RTL8139 10/100 NIC", rtl8139_init}, {0x8086, 0x100e, "Intel Pro 1000/MT NIC", NULL}, /* Virtual devices */ {0x1b36, 0x000d, "QEMU XHCI Host Adapter", xhci_init}, /* VGA devices */ {0x1234, 0x1111, "QEMU/Bochs VBE Framebuffer", bga_init}, }; Driver *drivers = NULL; /* Register a driver */ void register_driver(Driver *driver) { Driver *prev; search: if (!driver->major) /* Zero not allowed */ driver->major = 1; /* Maintain an ordered (by major) list of drivers */ if (!drivers) { drivers = driver; return; } if (drivers->major > driver->major) { driver->next = drivers; drivers = driver; return; } for (prev = drivers; prev->next; prev = prev->next) { /* If major is taken, find next available slot */ if (prev->major == driver->major) { driver->major++; if (!driver->major) /* Overflow */ goto search; } if (prev->major < driver->major && prev->next->major > driver->major) break; } driver->next = prev->next; prev->next = driver; } /* Initialise devices */ void init_drivers(void) { uint16_t bus, slot, func; uint16_t vendor, device; uint8_t class, subclass; uint32_t dev; kprintf("Enumerating PCI devices"); for (bus = 0; bus < 256; bus++) for (slot = 0; slot < 32; slot++) for (func = 0; func < 8; func++) if ((vendor = pci_read_word(bus, slot, func, 0)) != 0xFFFF) { device = pci_read_word(bus, slot, func, 2); for (dev = 0; dev < sizeof(devices)/sizeof(devices[0]); dev++) { if (devices[dev].vendor == vendor && devices[dev].device == device) { kprintf(" PCI(%d,%d,%d) \"%s\"", bus, slot, func, devices[dev].name); if (devices[dev].init) devices[dev].init(bus, slot, func); break; } } if (devices[dev].vendor != vendor || devices[dev].device != device) { class = pci_read_byte(bus, slot, func, 11); subclass = pci_read_byte(bus, slot, func, 10); kprintf(" PCI(%d,%d,%d) = %#.4x:%#.4x (%#.2x, %#.2x)", bus, slot, func, vendor, device, class, subclass); } } }