Add pci_device_drivers, IDE driver
diff --git a/src/kernel/Jmk b/src/kernel/Jmk
index ddbc343..3759fd6 100644
--- a/src/kernel/Jmk
+++ b/src/kernel/Jmk
@@ -13,6 +13,7 @@
depends(initrd, $(ROOT)/boot/initrd, initrd.img)
depends(ata_pio, dri/ata_pio, ata_pio.a)
depends(pci, dri/pci, pci.a)
+depends(ide, dri/ide, ide.a)
# AHCI not yet implemented
# depends(ahci, dri/ahci, ahci.a)
@@ -49,7 +50,8 @@
task_api.o \
faults.o \
lib(ata_pio) \
- lib(pci)
+ lib(pci) \
+ lib(ide)
type(custom_link)
diff --git a/src/kernel/alloc.h b/src/kernel/alloc.h
deleted file mode 100644
index 81ce15b..0000000
--- a/src/kernel/alloc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include "kint.h"
-
-void *_kmalloc(size_t size, bool align, void **phys);
-void *kmalloc(size_t size);
-void *kmalloc_a(size_t size);
-void *kmalloc_ap(size_t size, void **p);
-
-void *malloc(size_t size);
-void free(void *mem);
-void *realloc(void *mem, size_t size);
-
-void init_allocator();
-
-void test_allocator();
diff --git a/src/kernel/dri/ide/Jmk b/src/kernel/dri/ide/Jmk
new file mode 100644
index 0000000..675af5a
--- /dev/null
+++ b/src/kernel/dri/ide/Jmk
@@ -0,0 +1,17 @@
+init(ide, ide.a)
+
+preset(freestanding)
+preset(optimize)
+preset(debug)
+preset(32)
+preset(warn)
+
+archetype(c)
+
+CFLAGS += -I$(ROOT)/include/kernel
+
+OBJECTS = ide.o
+
+type(static_lib)
+
+finish
diff --git a/src/kernel/dri/ide/ide.c b/src/kernel/dri/ide/ide.c
new file mode 100644
index 0000000..c5a5241
--- /dev/null
+++ b/src/kernel/dri/ide/ide.c
@@ -0,0 +1,42 @@
+#include <dri/ide/ide.h>
+#include <task.h>
+#include <alloc.h>
+
+struct ide_thread_data
+{
+ struct pci_device dev;
+ uchar bus, slot, func;
+};
+
+bool ide_supports(struct pci_device *dev)
+{
+ return dev->class == 1 && dev->subclass == 1;
+}
+
+void ide_thread(struct ide_thread_data *data)
+{
+ kprintf("IDE driver thread starting: device=0x%x\n", data->dev.device_id);
+}
+
+void ide_init(struct pci_device dev, uchar bus, uchar slot, uchar func)
+{
+ struct ide_thread_data *data = malloc(sizeof(struct ide_thread_data));
+ data->dev = dev;
+ data->bus = bus;
+ data->slot = slot;
+ data->func = func;
+
+ spawn_thread(ide_thread, data);
+}
+
+void ide_register()
+{
+ struct pci_device_driver dri =
+ {
+ .supports = ide_supports,
+ .init = ide_init,
+ .generic_name = "IDE Controller",
+ };
+
+ pci_register_device_driver(dri);
+}
diff --git a/src/kernel/dri/pci/pci.c b/src/kernel/dri/pci/pci.c
index a5416b6..6d35edc 100644
--- a/src/kernel/dri/pci/pci.c
+++ b/src/kernel/dri/pci/pci.c
@@ -2,40 +2,51 @@
#include <dri/pci/vendors.h>
#include <io.h>
#include <log.h>
+#include <alloc.h>
+
+static uint num_drivers, size_drivers;
+static struct pci_device_driver *drivers;
uint pci_config_readd(uchar bus, uchar slot, uchar func, uchar offset)
{
- uint address = (bus << 16) | (slot << 11) | (func << 8) | (offset << 2) | 0x80000000;
+ uint address =
+ (bus << 16) | (slot << 11) | (func << 8) | (offset << 2) | 0x80000000;
outl(PCI_CONFIG_ADDRESS, address);
return inl(PCI_CONFIG_DATA);
}
-struct pci_vendor *pci_check_vendor(uchar bus, uchar slot, uchar func, ushort *v, ushort *d)
+struct pci_device pci_check_device(uchar bus, uchar slot, uchar func)
{
uint vendor_device = pci_config_readd(bus, slot, func, 0);
ushort vendor = vendor_device & 0xffff;
- if (v)
- *v = vendor;
+ struct pci_device device;
+ device.valid = false;
if (vendor != 0xffff)
{
- if (d)
- *d = vendor_device >> 16;
+ device.valid = true;
- return pci_vendor_by_id(vendor);
+ device.device_id = vendor_device >> 16;
+ device.vendor = pci_vendor_by_id(vendor);
+
+ // 3rd dword
+ uint class_subclass = pci_config_readd(bus, slot, func, 2);
+ device.class = class_subclass >> 24;
+ device.subclass = (class_subclass >> 16) & 0xff;
+ device.prog_if = (class_subclass >> 8) & 0xff;
}
- return NULL;
+
+ return device;
}
struct pci_vendor *pci_vendor_by_id(ushort id)
{
// Find vendor using binary search
- uint start = 0,
- max = pci_num_vendors;
+ uint start = 0, max = pci_num_vendors;
while (true)
{
@@ -63,15 +74,73 @@
{
for (int func = 0; func < 8; func++)
{
- ushort vendor, device;
+ struct pci_device dev = pci_check_device(bus, slot, func);
- struct pci_vendor *v = pci_check_vendor(bus, slot, func, &vendor, &device);
-
- if (v)
+ if (dev.valid)
{
- kprintf("%d %d %d --- v:0x%x d:0x%x --- %s\n", bus, slot, func, vendor, device, v->name);
+ kprintf("%d %d %d --- d:0x%x --- %d:%d:%d --- %s\n", bus,
+ slot, func, dev.device_id, dev.class, dev.subclass,
+ dev.prog_if, dev.vendor->name);
}
}
}
}
}
+
+void pci_register_device_driver(struct pci_device_driver driver)
+{
+ if (num_drivers == size_drivers)
+ {
+ size_drivers += 8;
+ drivers = realloc(drivers, sizeof(struct pci_device_driver) * size_drivers);
+ }
+
+ driver.loaded = 0;
+ drivers[num_drivers++] = driver;
+}
+
+void pci_init()
+{
+ num_drivers = 0;
+ size_drivers = 4;
+ drivers = malloc(sizeof(struct pci_device_driver) * size_drivers);
+}
+
+void pci_load()
+{
+ for (int bus = 0; bus < 0xff; bus++)
+ {
+ for (int slot = 0; slot < 32; slot++)
+ {
+ for (int func = 0; func < 8; func++)
+ {
+ struct pci_device dev = pci_check_device(bus, slot, func);
+
+ // Do any drivers support this?
+
+ for (int i = 0; i < num_drivers; i++)
+ {
+ if (drivers[i].supports(&dev))
+ {
+ drivers[i].loaded++;
+ drivers[i].dev = dev;
+ drivers[i].init(dev, bus, slot, func);
+ }
+ }
+ }
+ }
+ }
+}
+
+void pci_print_drivers()
+{
+ kprintf("Enumerating PCI device drivers:\n");
+ for (int i = 0; i < num_drivers; i++)
+ {
+ for (int j = 0; j < drivers[i].loaded; j++)
+ {
+ struct pci_device_driver d = drivers[i];
+ kprintf("Driver: %s, vendor: %s\n", d.generic_name, d.dev.vendor->name);
+ }
+ }
+}
diff --git a/src/kernel/main.c b/src/kernel/main.c
index bc40ff8..b973b41 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -12,6 +12,7 @@
#include "vga.h"
#include <dri/ata_pio/ata_pio.h>
#include <dri/pci/pci.h>
+#include <dri/ide/ide.h>
void greet()
{
@@ -80,6 +81,13 @@
init_tasks();
kprintf("\ndone initializing tasks\n");
+ pci_init();
+
+ // Register PCI drivers
+ ide_register();
+
+ pci_load();
+
#ifdef TEST_THREADS
spawn_thread(other_thread, NULL);
@@ -92,6 +100,7 @@
#ifdef TEST_PCI
pci_print_devices();
+ pci_print_drivers();
#endif
while (true)
diff --git a/src/kernel/task.h b/src/kernel/task.h
deleted file mode 100644
index 487c143..0000000
--- a/src/kernel/task.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include "kint.h"
-#include "registers.h"
-
-#define INIT_TASKS_INTERRUPT 0x81
-
-extern bool tasks_initialized;
-
-struct process
-{
- bool exists;
- int id; // kernel uses pid 0, which cannot exit
- int ring;
- int uid;
- char name[32];
- uint page_directory_p;
- // most recent (bottom) stack used by a task, next
- // stack should be under this one.
- // NOTE: must be PAGE ALIGNED
- uint last_stack_pos;
-};
-
-struct task
-{
- int id;
- struct process *proc;
- uint stack_top_p; // stack frame PHYSICAL address
- uint esp, ebp, eip;
-};
-
-struct ll_task_i
-{
- struct ll_task_i *next, *prev;
- struct task task;
-};
-
-// extern struct process processes[1024];
-// extern struct ll_task_i *first_task, *current_task;
-
-// Note: interrupts must be enabled BEFORE this for it to work.
-void init_tasks();
-struct process *get_process(uint pid);
-
-int get_process_id();
-int get_task_id();
-
-// For compatibility I guess
-#define getpid get_process_id
-
-void spawn_thread(void (*function)(void *), void *data);
-void kill_this_thread();
-extern void switch_task();
-void switch_to_task(struct task *task);
-void _sys_init_tasks_h(struct registers *regs);