Orion
Barry Importing existing Orion kernel d41a53c (3 years, 1 month ago)
/*
* 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);
}
}
}