Add ATA PIO IRQ handler, documentation
Still WIP, doesn't look like IRQ handler works yet.
diff --git a/include/kernel/dri/ata_pio/ata_pio.h b/include/kernel/dri/ata_pio/ata_pio.h
index c509f52..667ed3b 100644
--- a/include/kernel/dri/ata_pio/ata_pio.h
+++ b/include/kernel/dri/ata_pio/ata_pio.h
@@ -29,6 +29,7 @@
ATA_PORT_LBA_LOW,
ATA_PORT_LBA_MID,
ATA_PORT_LBA_HIGH,
+ ATA_PORT_STATUS = ATA_PORT_CMD,
};
// Commands
@@ -36,12 +37,15 @@
{
ATA_CMD_READ = 0x20,
ATA_CMD_WRITE = 0x30,
+ ATA_CMD_IDENTIFY = 0xec,
};
void ata_pio_wait_bsy();
void ata_pio_wait_drq();
void ata_pio_read_sectors(void *buffer, uint lba, uchar num_sectors);
-void ata_pio_write_sectors(uint lba, uchar num_sectors, void *buffer);
+void ata_pio_write_sectors(uint lba, uchar num_sectors, ushort *buffer);
uint ata_pio_get_error();
void test_ata_pio();
+
+void init_ata_pio();
\ No newline at end of file
diff --git a/include/kernel/io.h b/include/kernel/io.h
index 718bb20..be82998 100644
--- a/include/kernel/io.h
+++ b/include/kernel/io.h
@@ -3,34 +3,95 @@
#include "kint.h"
#include "registers.h"
+/**
+ * IO port for keyboard commands.
+ */
#define KBD_CMD_PORT 0x64
+
+/**
+ * IO port for keyboard data
+ */
#define KBD_DATA_PORT 0x60
-struct kbd_scan_code_info
-{
- bool pressed;
- bool escape;
- char key;
-};
-
-extern struct kbd_scan_code_info scan_code_table[0xff];
-
+/**
+ * Write a byte to a port
+ */
void outb(ushort port, uchar val);
+
+/**
+ * Write a double word to a port.
+ */
void outl(ushort port, uint val);
+
+/**
+ * Read a byte from a port.
+ */
uchar inb(ushort port);
+
+/**
+ * Read a word from a port.
+ */
ushort inw(ushort port);
+
+/**
+ * Write a word to a port.
+ */
+void outw(ushort port, ushort val);
+
+/**
+ * Just waste some time.
+ */
+void nop();
+
+/**
+ * Read a double word from a port
+ */
uint inl(ushort port);
-/* Random string.h stuff, TODO: move to own header */
+/**
+ * Set n bytes of s to c.
+ */
void *memset(void *s, int c, size_t n);
+
+/**
+ * Copy n bytes from src to dest.
+ */
void *memcpy(void *dest, const void *src, size_t n);
+
+/**
+ * Copy null terminated string src to dest.
+ */
void strcpy(char *dest, char *src);
+
+/**
+ * Compare two strings. This might not work like the libc function, so be
+ * careful.
+ * @returns 0 if equal, non-0 otherwise.
+ */
int strcmp(char *a, char *b);
+/**
+ * @returns the length of null-terminated string a.
+ */
uint strlen(char *a);
bool isdigit(char c);
+/**
+ * Ignores trailing non-digit characters.
+ * @returns 0 if string is not a valid decimal integer
+ */
uint parse_int(char *string);
+/**
+ * Read a scan code from the keyboard
+ */
uchar kbd_scan_code();
+
+/**
+ * Keyboard IRQ handler
+ */
void kbd_handle_input(struct registers *registers);
+
+/**
+ * Set up keyboard driver.
+ */
void init_kbd();
diff --git a/include/kernel/pic.h b/include/kernel/pic.h
new file mode 100644
index 0000000..de11f3f
--- /dev/null
+++ b/include/kernel/pic.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "kint.h"
+#include "registers.h"
+
+#define PIC1 0x20
+#define PIC2 0xa0
+#define PIC1_COMMAND PIC1
+#define PIC1_DATA (PIC1 + 1)
+#define PIC2_COMMAND PIC2
+#define PIC2_DATA (PIC2 + 1)
+
+#define PIC_EOI 0x20 // End of input
+
+#define IRQ_TO_INT(irq) ((irq) + 32)
+
+void pic_send_eoi(uchar interrupt);
+void add_interrupt_handler(uchar interrupt, void (*handler)(struct registers *));
+
+void pic_remap();
diff --git a/include/kernel/registers.h b/include/kernel/registers.h
index 687bd0e..8abe32f 100644
--- a/include/kernel/registers.h
+++ b/include/kernel/registers.h
@@ -2,6 +2,9 @@
#include "kint.h"
+/**
+ * Represents the full execution state before an interrupt.
+ */
struct registers
{
uint ds;
diff --git a/include/kernel/task.h b/include/kernel/task.h
index 87b412b..b0d0f97 100644
--- a/include/kernel/task.h
+++ b/include/kernel/task.h
@@ -7,6 +7,9 @@
extern bool tasks_initialized;
+/**
+ * A process. For now there is only one, the kernel.
+ */
struct process
{
bool exists;
@@ -20,12 +23,15 @@
// NOTE: must be PAGE ALIGNED
uint last_stack_pos;
};
-
+/**
+ * The smallest schedulable unit, a thread of a process.
+ */
struct task
{
int id;
struct process *proc;
- uint stack_top_p; // stack frame PHYSICAL address
+ /// Physical address of the top of the stack.
+ uint stack_top_p;
uint esp, ebp, eip;
};
@@ -53,7 +59,23 @@
#define TASK_FUNCTION(f) ((task_function_t)(f))
void spawn_thread(task_function_t function, void *data);
+
+/**
+ * Halt the current thread.
+ */
void kill_this_thread();
+
+/**
+ * Force a task switch. Only call in a safe environment (ISR).
+ */
extern void switch_task();
+
+/**
+ * Switch to a specific task. Only call in a safe environment (ISR).
+ */
void switch_to_task(struct task *task);
+
+/**
+ * Internal. Do not call.
+ */
void _sys_init_tasks_h(struct registers *regs);
diff --git a/include/kernel/vfs.h b/include/kernel/vfs.h
index 1da0d6e..40a8e87 100644
--- a/include/kernel/vfs.h
+++ b/include/kernel/vfs.h
@@ -6,18 +6,27 @@
struct fs_node
{
- char name[128]; /* file name */
- uint inode; /* identifier */
- uint flags; /* type of node */
- uint mask; /* permissions */
- uint gid; /* group id */
- uint uid; /* user id */
- size_t size; /* size in bytes */
- uint dri_res; /* reserved for driver */
+ /** file name */
+ char name[128];
+ /** identifier */
+ uint inode;
+ /** type of node */
+ uint flags;
+ /** permissions */
+ uint mask;
+ /** group id */
+ uint gid;
+ /** user id */
+ uint uid;
+ /** size in bytes */
+ size_t size;
+ /** reserved for driver */
+ uint dri_res;
struct fs_vtable *vtable;
- struct fs_node *mount; /* used for mounts */
+ /** used for mounts */
+ struct fs_node *mount;
};
struct fs_dirent
@@ -26,13 +35,13 @@
uint inode;
};
-typedef uint (* fs_read_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
-typedef uint (* fs_write_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
-typedef void (* fs_open_t)(struct fs_node *node);
-typedef void (* fs_close_t)(struct fs_node *node);
+typedef uint (*fs_read_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+typedef uint (*fs_write_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+typedef void (*fs_open_t)(struct fs_node *node);
+typedef void (*fs_close_t)(struct fs_node *node);
-typedef bool (* fs_readdir_t)(struct fs_node *node, uint index, struct fs_dirent *dirent);
-typedef struct fs_node *(* fs_finddir_t)(struct fs_node *node, char *name);
+typedef bool (*fs_readdir_t)(struct fs_node *node, uint index, struct fs_dirent *dirent);
+typedef struct fs_node *(*fs_finddir_t)(struct fs_node *node, char *name);
struct fs_vtable
{
@@ -52,8 +61,8 @@
FS_BLOCKDEVICE,
FS_PIPE,
FS_SYMLINK,
-
- FS_MOUNT = 8, /* Can be or'd with others */
+
+ FS_MOUNT = 8, /* Can be or'd with others */
};
extern struct fs_node root, dev, initrd;