BarryServer : Git

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

// Related

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);
+		}
+	}
+}