Orion
Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)diff --git a/drivers/drivers.c b/drivers/drivers.c new file mode 100644 index 0000000..5ae8c4b --- /dev/null +++ b/drivers/drivers.c @@ -0,0 +1,102 @@ +/* + * 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 <stdint.h> +#include <stddef.h> +#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}, + + /* 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; + 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) { + kprintf(" PCI(%d,%d,%d) = %#x:%#x", + bus, slot, func, vendor, device); + } + } +}