BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / blob / d41a53cbc7d055b1c00cf0a339dbed6925f4f02c / drivers / drivers.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months 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);
		}
	}
}