]> Chaos Git - misc/eidos.git/commitdiff
More-ish refactoring
authorJon Feldman <chaos.kagami@gmail.com>
Tue, 21 Feb 2017 02:04:50 +0000 (21:04 -0500)
committerJon Feldman <chaos.kagami@gmail.com>
Tue, 21 Feb 2017 02:04:50 +0000 (21:04 -0500)
Makefile
common/kernel_main.c
i686/idt.c
i686/include/idt.h [new file with mode: 0644]
i686/timer.c
i686/utils.c
module/biosvga/module.c
module/console.c

index daedf78c7436702e2341d8047057e2366099253c..246db951e4c0c52827eaca369f4ee3c8109f10a2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 # The only one that needs changing is the assembler
 # rule, as we use nasm instead of GNU as.
 
-CONF=-DCONF_EARLY_KPRINTF=1
+CONF=-DCONF_TIMER_FREQ=1000
 
 TGT=i686
 
index b64842e7e950f2a88924442af967b82064f47c74..f8214ec9d408905e1cb71ec78d62bbde082d551d 100644 (file)
@@ -10,13 +10,13 @@ int kernel_main(struct multiboot *mboot_ptr)
 
     printf("1%c%% %s %X\n", 'c', "whoop", 0xDEADBEEF);
 
-    console_deinit();
-
     while(1) {
         uint64_t ticks = clock();
         printf("%X%X\r", ((uint32_t*)&ticks)[1], ((uint32_t*)&ticks)[0]);
         asm("hlt");
     }
 
+    console_deinit();
+
     return 0xDEADBEEF;
 }
index e61f569f815b571bef7f26d736083e1a641fd5e8..0ab044b0c7706e9a17fe9ce406532299974c1e43 100644 (file)
@@ -1,93 +1,15 @@
 #include <stdint.h>
 #include <stddef.h>
 
-#include <stdc/string.h>
-
-// A struct describing an interrupt gate.
-struct idt_entry_struct
-{
-   uint16_t base_lo;             // The lower 16 bits of the address to jump to when this interrupt fires.
-   uint16_t sel;                 // Kernel segment selector.
-   uint8_t  always0;             // This must always be zero.
-   uint8_t  flags;               // More flags. See documentation.
-   uint16_t base_hi;             // The upper 16 bits of the address to jump to.
-} __attribute__((packed));
-typedef struct idt_entry_struct idt_entry_t;
-
-// A struct describing a pointer to an array of interrupt handlers.
-// This is in a format suitable for giving to 'lidt'.
-struct idt_ptr_struct
-{
-   uint16_t limit;
-   uint32_t base;                // The address of the first element in our idt_entry_t array.
-} __attribute__((packed));
-typedef struct idt_ptr_struct idt_ptr_t;
-
-idt_entry_t idt_entries[256];
-idt_ptr_t   idt_ptr;
-
-void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
-{
-   idt_entries[num].base_lo = base & 0xFFFF;
-   idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
+#include <idt.h>
 
-   idt_entries[num].sel     = sel;
-   idt_entries[num].always0 = 0;
-   // We must uncomment the OR below when we get to using user-mode.
-   // It sets the interrupt gate's privilege level to 3.
-   idt_entries[num].flags   = flags /* | 0x60 */;
-}
-
-struct interrupt_frame
-{
-   uint32_t ds;                  // Data segment selector
-   uint32_t edi, esi, ebp, reserve, ebx, edx, ecx, eax; // Pushed by pusha.
-   uint32_t int_no, err_code;    // Interrupt number and error code (if applicable)
-   uint32_t eip, cs, eflags, esp, ss; // Pushed by the processor automatically.
-};
-
-void isr_handler(struct interrupt_frame* esp) {
-}
-
-int      ticks_lock = 0;
-uint64_t ticks      = 0;
-
-uint64_t clock() {
-    return ticks;
-}
-
-char table[255] = {
-    0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
-    '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
-    'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h',
-    'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v',
-    'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', ' ',
-};
-
-uint32_t timer_lock;
-
-void irq_handler(struct interrupt_frame* esp) {
-    char c_kb = 0;
-
-    if (esp->int_no >= 7) {
-         outb(0xA0, 0x20);
-    }
+#include <stdc/string.h>
 
-    outb(0x20, 0x20);
+#define ISR_CALL(N) \
+    idt_set_gate( N , (uint32_t) isr_##N , 0x08, 0x8E )
 
-    switch(esp->int_no) {
-        case 0:
-            ++ticks;
-            break;
-        case 1:
-            c_kb = inb(0x60);
-            putc(table[c_kb]);
-            break;
-        default:
-            break;
-    }
-}
+#define IRQ_CALL(N) \
+    idt_set_gate( 32 + N , (uint32_t) irq_##N , 0x08, 0x8E )
 
 extern void isr_0();
 extern void isr_1();
@@ -139,19 +61,45 @@ extern void irq_13();
 extern void irq_14();
 extern void irq_15();
 
-#define ISR_CALL(N) \
-    idt_set_gate( N , (uint32_t) isr_##N , 0x08, 0x8E )
+idt_entry_t idt_entries[256];
+idt_ptr_t   idt_ptr;
+int_handle  interrupts[256];
 
-#define IRQ_CALL(N) \
-    idt_set_gate( 32 + N , (uint32_t) irq_##N , 0x08, 0x8E )
+void register_int_handler(int index, int_handle hdl) {
+    interrupts[index] = hdl;
+}
 
-void init_idt()
+void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
 {
-    idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
-    idt_ptr.base  = (uint32_t)&idt_entries;
+   idt_entries[num].base_lo = base & 0xFFFF;
+   idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
 
-    memset(&idt_entries, 0, sizeof(idt_entry_t)*256);
+   idt_entries[num].sel     = sel;
+   idt_entries[num].always0 = 0;
+   // We must uncomment the OR below when we get to using user-mode.
+   // It sets the interrupt gate's privilege level to 3.
+   idt_entries[num].flags   = flags | 0x60;
+}
 
+void isr_handler(struct interrupt_frame* esp) {
+    if (interrupts[esp->int_no])
+        (interrupts[esp->int_no])(esp);
+}
+
+void irq_handler(struct interrupt_frame* esp) {
+    char c_kb = 0;
+
+    if (esp->int_no >= 7) {
+         outb(0xA0, 0x20);
+    }
+
+    outb(0x20, 0x20);
+
+    if (interrupts[esp->int_no + 32])
+        interrupts[esp->int_no + 32](esp);
+}
+
+void init_isr() {
     ISR_CALL(0);
     ISR_CALL(1);
     ISR_CALL(2);
@@ -184,7 +132,10 @@ void init_idt()
     ISR_CALL(29);
     ISR_CALL(30);
     ISR_CALL(31);
+}
 
+void init_irq()
+{
     outb(0x20, 0x11);
     outb(0xA0, 0x11);
 
@@ -216,6 +167,17 @@ void init_idt()
     IRQ_CALL(13);
     IRQ_CALL(14);
     IRQ_CALL(15);
+}
+
+void init_idt()
+{
+    idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
+    idt_ptr.base  = (uint32_t)&idt_entries;
+
+    memset(&idt_entries, 0, sizeof(idt_entry_t)*256);
+
+    init_isr();
+    init_irq();
 
     idt_flush((uint32_t)&idt_ptr);
 
diff --git a/i686/include/idt.h b/i686/include/idt.h
new file mode 100644 (file)
index 0000000..1d1da16
--- /dev/null
@@ -0,0 +1,31 @@
+// A struct describing an interrupt gate.
+struct idt_entry_struct
+{
+   uint16_t base_lo;             // The lower 16 bits of the address to jump to when this interrupt fires.
+   uint16_t sel;                 // Kernel segment selector.
+   uint8_t  always0;             // This must always be zero.
+   uint8_t  flags;               // More flags. See documentation.
+   uint16_t base_hi;             // The upper 16 bits of the address to jump to.
+} __attribute__((packed));
+typedef struct idt_entry_struct idt_entry_t;
+
+// A struct describing a pointer to an array of interrupt handlers.
+// This is in a format suitable for giving to 'lidt'.
+struct idt_ptr_struct
+{
+   uint16_t limit;
+   uint32_t base;                // The address of the first element in our idt_entry_t array.
+} __attribute__((packed));
+typedef struct idt_ptr_struct idt_ptr_t;
+
+struct interrupt_frame
+{
+   uint32_t ds;                  // Data segment selector
+   uint32_t edi, esi, ebp, reserve, ebx, edx, ecx, eax; // Pushed by pusha.
+   uint32_t int_no, err_code;    // Interrupt number and error code (if applicable)
+   uint32_t eip, cs, eflags, esp, ss; // Pushed by the processor automatically.
+};
+
+typedef void (*int_handle)(struct interrupt_frame*);
+
+void register_int_handler(int, int_handle);
index 8532e2842a8f38762cde1209ecd85cbe73025787..2755c0481db993fa941494f71f6ea325b021d804 100644 (file)
@@ -1,6 +1,8 @@
 #include <stdint.h>
 #include <stddef.h>
 
+#include <idt.h>
+
 #include <stdc/string.h>
 
 int set_pitdiv(int freq) {
@@ -15,3 +17,18 @@ int set_pitdiv(int freq) {
     outb(0x40, l);
     outb(0x40, h);
 }
+
+uint64_t ticks = 0;
+
+uint64_t clock() {
+    return ticks;
+}
+
+void clock_inc(struct interrupt_frame* frame) {
+    ++ticks;
+}
+
+void i686_pic_init() {
+    register_int_handler(32, clock_inc);
+    set_pitdiv(CONF_TIMER_FREQ);
+}
index b2c833cd7c9cd03502b3febdbb056d85068b683c..38ce5c36de16034ac9d46fcd346fb8d825871995 100644 (file)
@@ -52,5 +52,6 @@ int set_pitdiv(int freq);
 void i686_init() {
     init_gdt();
     init_idt();
-    set_pitdiv(1000);
+
+    i686_pic_init();
 }
index 4f29b0076bc4397bbe7103282f708a52840a28f0..a9f48664b5731eef79e90b50bccbde15d135a7c6 100644 (file)
@@ -62,10 +62,10 @@ struct output biosvga_module = {
 
 void biosvga_init() {
     x = y = 0;
-    console_reg(&biosvga_module);
+    console_reg_write(&biosvga_module);
 }
 
 void biosvga_deinit() {
-    console_unreg(&biosvga_module);
+    console_unreg_write(&biosvga_module);
     // Stub.
 }
index 22bfe6bb7e8da8548dc3c938b565cfeeb2f5373a..9faf2c40d18b6b9de325f08ea2f9395c1ea8b230 100644 (file)
@@ -7,18 +7,29 @@ actually printing to; in the future, adding a new backend for framebuffer render
 #include <module.h>
 #include <module_console.h>
 
-struct output *active;
+struct output *out_active;
+struct input *in_active;
 
 void put_handler(char c) {
-    active->out(c);
+    out_active->out(c);
 }
 
-void console_reg(struct output* out) {
-    active = out;
+void console_reg_write(struct output* out) {
+    out_active = out;
 }
 
-void console_unreg(struct output* out) {
-    active = out;
+void console_unreg_write(struct output* out) {
+    if (out_active == out)
+        out_active = NULL;
+}
+
+void console_reg_read(struct input* out) {
+    in_active = out;
+}
+
+void console_unreg_read(struct input* out) {
+    if (in_active == out)
+        in_active = NULL;
 }
 
 void console_init() {