Add pci_device_drivers, IDE driver
diff --git a/include/kernel/alloc.h b/include/kernel/alloc.h
new file mode 100644
index 0000000..81ce15b
--- /dev/null
+++ b/include/kernel/alloc.h
@@ -0,0 +1,16 @@
+#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/include/kernel/dri/ide/ide.h b/include/kernel/dri/ide/ide.h
new file mode 100644
index 0000000..0283999
--- /dev/null
+++ b/include/kernel/dri/ide/ide.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <dri/pci/pci.h>
+
+void ide_register();
diff --git a/include/kernel/dri/pci/pci.h b/include/kernel/dri/pci/pci.h
index 5791674..b4c21f1 100644
--- a/include/kernel/dri/pci/pci.h
+++ b/include/kernel/dri/pci/pci.h
@@ -17,7 +17,23 @@
 	bool valid;
 };
 
+struct pci_device_driver
+{
+	bool (* supports)(struct pci_device *dev);
+	void (* init)(struct pci_device dev, uchar bus, uchar slot, uchar func);
+	char *generic_name;
+	uint loaded; // reserved
+	struct pci_device dev; // reserved
+};
+
+// Call this first
+void pci_init();
+// Call this after registering drivers to load them
+void pci_load();
+
 // offset is in dwords
 uint pci_config_readd(uchar bus, uchar slot, uchar func, uchar offset);
 struct pci_device pci_check_device(uchar bus, uchar slot, uchar func);
 void pci_print_devices();
+void pci_register_device_driver(struct pci_device_driver driver);
+void pci_print_drivers();
diff --git a/include/kernel/task.h b/include/kernel/task.h
new file mode 100644
index 0000000..487c143
--- /dev/null
+++ b/include/kernel/task.h
@@ -0,0 +1,55 @@
+#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);