]> Chaos Git - misc/eidos.git/commitdiff
Good chunk of refactoring
authorJon Feldman <chaos.kagami@gmail.com>
Tue, 21 Feb 2017 00:42:58 +0000 (19:42 -0500)
committerJon Feldman <chaos.kagami@gmail.com>
Tue, 21 Feb 2017 00:42:58 +0000 (19:42 -0500)
23 files changed:
Makefile
common/kernel_main.c
common/stdc/dumphex.c [new file with mode: 0644]
common/stdc/memcmp.c
common/stdc/memcpy.c
common/stdc/memmove.c
common/stdc/memset.c
common/stdc/printf.c [new file with mode: 0644]
common/stdc/putc.c [new file with mode: 0644]
common/stdc/puts.c [new file with mode: 0644]
common/stdc/strcatlen.c [new file with mode: 0644]
common/stdc/strlen.c
common/stdc/vsprintf.c [new file with mode: 0644]
i686/gdt.c [new file with mode: 0644]
i686/idt.c [new file with mode: 0644]
i686/timer.c [new file with mode: 0644]
i686/utils.c
include/module_console.h
include/stdc/stdio.h [new file with mode: 0644]
include/stdc/string.h
module/biosvga/module.c
module/console.c
module/serial/module.c

index c78b257bf9882e83aa615ba627b73c889cb3fd48..daedf78c7436702e2341d8047057e2366099253c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,9 +8,10 @@ CONF=-DCONF_EARLY_KPRINTF=1
 TGT=i686
 
 SOURCES= \
-    $(TGT)/entry.o \
-    $(TGT)/utils.o \
-    module/biosvga/module.o module/serial/module.o module/console.o \
+    $(TGT)/entry.o $(TGT)/utils.o $(TGT)/gdt.o $(TGT)/idt.o $(TGT)/timer.o \
+    module/biosvga/module.o \
+    module/console.o \
+    common/stdc/putc.o common/stdc/puts.o common/stdc/vsprintf.o common/stdc/printf.o common/stdc/strcatlen.o common/stdc/dumphex.o \
     common/stdc/memmove.o common/stdc/strlen.o common/stdc/memcmp.o common/stdc/memset.o common/stdc/memcpy.o \
     common/kernel_main.o
 
@@ -26,7 +27,7 @@ NM=$(TGTNAM)-nm
 RL=$(TGTNAM)-ranlib
 
 CFLAGS=-ffreestanding -std=gnu11
-CPPFLAGS=-Iinclude -I$(TGT)/include
+CPPFLAGS=-Iinclude -Iinclude/stdc -I$(TGT)/include
 LDFLAGS=-T$(LDSC)
 ASFLAGS=
 LIBS=
index e46e46b4aebe2460560964354145758613781ced..b64842e7e950f2a88924442af967b82064f47c74 100644 (file)
@@ -2,17 +2,19 @@
 #include <module.h>
 #include <module_console.h>
 
+#include <stdio.h>
+
 int kernel_main(struct multiboot *mboot_ptr)
 {
     console_init();
 
-    kprintf("1%c%% %s %X\n", 'c', "whoop", 0xDEADBEEF);
+    printf("1%c%% %s %X\n", 'c', "whoop", 0xDEADBEEF);
 
     console_deinit();
 
     while(1) {
-        uint64_t clock = kclock();
-        kprintf("%X%X\r", ((uint32_t*)&clock)[1], ((uint32_t*)&clock)[0]);
+        uint64_t ticks = clock();
+        printf("%X%X\r", ((uint32_t*)&ticks)[1], ((uint32_t*)&ticks)[0]);
         asm("hlt");
     }
 
diff --git a/common/stdc/dumphex.c b/common/stdc/dumphex.c
new file mode 100644 (file)
index 0000000..8866733
--- /dev/null
@@ -0,0 +1,17 @@
+#include <string.h>
+#include <stdint.h>
+
+int dumphex(char* buf, const char* index, unsigned int num) {
+    uint8_t *num_8 = (uint8_t *)&num;
+    char *obuf = buf;
+    for (int i = 3; i >= 0; i--) {
+        uint8_t high = (num_8[i] >> 4) & 0xf;
+        uint8_t low = num_8[i] & 0xf;
+
+        *buf = (index)[high]; buf++;
+        *buf = (index)[low];  buf++;
+    }
+
+    return buf - obuf;
+}
+
index 576a2424f719095f0ed61bab2d20936b8c8417db..6a0a71a04b6ab052e335923a1ab6def540e9d54c 100644 (file)
@@ -1,13 +1,13 @@
 #include <string.h>
 
 int memcmp(const void* aptr, const void* bptr, size_t size) {
-       const unsigned char* a = (const unsigned char*) aptr;
-       const unsigned char* b = (const unsigned char*) bptr;
-       for (size_t i = 0; i < size; i++) {
-               if (a[i] < b[i])
-                       return -1;
-               else if (b[i] < a[i])
-                       return 1;
-       }
-       return 0;
+    const unsigned char* a = (const unsigned char*) aptr;
+    const unsigned char* b = (const unsigned char*) bptr;
+    for (size_t i = 0; i < size; i++) {
+        if (a[i] < b[i])
+            return -1;
+        else if (b[i] < a[i])
+            return 1;
+    }
+    return 0;
 }
index 18348162c77fa9a0599a796cd2f39a749ff27555..878ff2beacd28db5f15c603686a9f325c2dbe475 100644 (file)
@@ -1,9 +1,9 @@
 #include <string.h>
 
 void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) {
-       unsigned char* dst = (unsigned char*) dstptr;
-       const unsigned char* src = (const unsigned char*) srcptr;
-       for (size_t i = 0; i < size; i++)
-               dst[i] = src[i];
-       return dstptr;
+    unsigned char* dst = (unsigned char*) dstptr;
+    const unsigned char* src = (const unsigned char*) srcptr;
+    for (size_t i = 0; i < size; i++)
+        dst[i] = src[i];
+    return dstptr;
 }
index ceac1e19e9dfc165791d0e82faa0c274c9c49e5e..b5a96f10a0f4b6bda651777674ef64d2c83fd5f5 100644 (file)
@@ -1,14 +1,16 @@
 #include <string.h>
 
 void* memmove(void* dstptr, const void* srcptr, size_t size) {
-       unsigned char* dst = (unsigned char*) dstptr;
-       const unsigned char* src = (const unsigned char*) srcptr;
-       if (dst < src) {
-               for (size_t i = 0; i < size; i++)
-                       dst[i] = src[i];
-       } else {
-               for (size_t i = size; i != 0; i--)
-                       dst[i-1] = src[i-1];
-       }
-       return dstptr;
+    unsigned char* dst = (unsigned char*) dstptr;
+    const unsigned char* src = (const unsigned char*) srcptr;
+
+    if (dst < src) {
+        for (size_t i = 0; i < size; i++)
+            dst[i] = src[i];
+    } else {
+        for (size_t i = size; i != 0; i--)
+            dst[i-1] = src[i-1];
+    }
+
+    return dstptr;
 }
index 449d1e7f2b8323a7bf5eceaf06c2c23465067516..cbcfa6aa34bf28ae5f598f02a179d1dc9c58b553 100644 (file)
@@ -1,8 +1,8 @@
 #include <string.h>
 
 void* memset(void* bufptr, int value, size_t size) {
-       unsigned char* buf = (unsigned char*) bufptr;
-       for (size_t i = 0; i < size; i++)
-               buf[i] = (unsigned char) value;
-       return bufptr;
+    unsigned char* buf = (unsigned char*) bufptr;
+    for (size_t i = 0; i < size; i++)
+        buf[i] = (unsigned char) value;
+    return bufptr;
 }
diff --git a/common/stdc/printf.c b/common/stdc/printf.c
new file mode 100644 (file)
index 0000000..1e8fe63
--- /dev/null
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void printf(const char* fmt, ...) {
+    char buf[4096];
+    va_list ap;
+    va_start(ap, fmt);
+
+    vsprintf(buf, fmt, ap);
+
+    va_end(ap);
+
+    puts(buf);
+}
+
diff --git a/common/stdc/putc.c b/common/stdc/putc.c
new file mode 100644 (file)
index 0000000..c38db8d
--- /dev/null
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+void putc(char c) {
+     put_handler(c);
+}
diff --git a/common/stdc/puts.c b/common/stdc/puts.c
new file mode 100644 (file)
index 0000000..b0e7bd8
--- /dev/null
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+void puts(char* str) {
+    while(*str != 0) {
+        putc(*str);
+        ++str;
+    }
+}
+
diff --git a/common/stdc/strcatlen.c b/common/stdc/strcatlen.c
new file mode 100644 (file)
index 0000000..f2945d7
--- /dev/null
@@ -0,0 +1,11 @@
+#include <string.h>
+
+int strcatlen(char* a, char* b) {
+    char* o = b;
+    while(*b != 0) {
+        *a = *b;
+        a++;
+        b++;
+    }
+    return b - o;
+}
index 8ac0dbe091644db9fef95d61e3fd23bb5723d7b6..5e2cf3327532866d3baebb6e56c55181faab8983 100644 (file)
@@ -1,8 +1,8 @@
 #include <string.h>
 
 size_t strlen(const char* str) {
-       size_t len = 0;
-       while (str[len])
-               len++;
-       return len;
+    size_t len = 0;
+    while (str[len])
+        len++;
+    return len;
 }
diff --git a/common/stdc/vsprintf.c b/common/stdc/vsprintf.c
new file mode 100644 (file)
index 0000000..64cf60a
--- /dev/null
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+void vsprintf(char *buffer, const char* fmt_con, va_list ap) {
+    char* fmt = (char*)fmt_con;
+    char* buf = buffer;
+    while(*fmt != 0) {
+        if (*fmt == '%') {
+            // Format string.
+            ++fmt;
+            switch (*fmt) {
+                case 'c':
+                    *buf = (char)va_arg(ap, int);
+                    buf++;
+                    fmt++;
+                    break;
+                case '%':
+                    *buf = '%';
+                    buf++;
+                    fmt++;
+                    break;
+                case 's':
+                    buf += strcatlen(buf, va_arg(ap, char*));
+                    fmt++;
+                    break;
+                case 'x':
+                    buf += dumphex(buf, "0123456789abcdef", va_arg(ap, unsigned int));
+                    ++fmt;
+                    break;
+                case 'X':
+                    buf += dumphex(buf, "0123456789ABCDEF", va_arg(ap, unsigned int));
+                    ++fmt;
+                    break;
+                case 'd':
+                case 'u':
+                default:
+                    ++fmt;
+                    break;
+            }
+        } else {
+            *buf = *fmt;
+            ++buf;
+            ++fmt;
+        }
+    }
+
+    *buf = 0;
+}
diff --git a/i686/gdt.c b/i686/gdt.c
new file mode 100644 (file)
index 0000000..691860d
--- /dev/null
@@ -0,0 +1,60 @@
+#include <stdint.h>
+#include <stddef.h>
+
+#include <stdc/string.h>
+
+// Lets us access our ASM functions from our C code.
+extern void gdt_flush(uint32_t);
+
+// This structure contains the value of one GDT entry.
+// We use the attribute 'packed' to tell GCC not to change
+// any of the alignment in the structure.
+struct gdt_entry_struct
+{
+   uint16_t limit_low;           // The lower 16 bits of the limit.
+   uint16_t base_low;            // The lower 16 bits of the base.
+   uint8_t  base_middle;         // The next 8 bits of the base.
+   uint8_t  access;              // Access flags, determine what ring this segment can be used in.
+   uint8_t  granularity;
+   uint8_t  base_high;           // The last 8 bits of the base.
+} __attribute__((packed));
+typedef struct gdt_entry_struct gdt_entry_t;
+
+struct gdt_ptr_struct
+{
+   uint16_t limit;               // The upper 16 bits of all selector limits.
+   uint32_t base;                // The address of the first gdt_entry_t struct.
+}
+ __attribute__((packed));
+typedef struct gdt_ptr_struct gdt_ptr_t;
+
+gdt_entry_t gdt_entries[5];
+gdt_ptr_t   gdt_ptr;
+
+// Set the value of one GDT entry.
+void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran)
+{
+   gdt_entries[num].base_low    = (base & 0xFFFF);
+   gdt_entries[num].base_middle = (base >> 16) & 0xFF;
+   gdt_entries[num].base_high   = (base >> 24) & 0xFF;
+
+   gdt_entries[num].limit_low   = (limit & 0xFFFF);
+   gdt_entries[num].granularity = (limit >> 16) & 0x0F;
+
+   gdt_entries[num].granularity |= gran & 0xF0;
+   gdt_entries[num].access      = access;
+}
+
+void init_gdt()
+{
+    gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
+    gdt_ptr.base  = (uint32_t)&gdt_entries;
+
+    gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
+    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
+    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
+    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
+    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
+
+    gdt_flush((uint32_t)&gdt_ptr);
+}
diff --git a/i686/idt.c b/i686/idt.c
new file mode 100644 (file)
index 0000000..e61f569
--- /dev/null
@@ -0,0 +1,223 @@
+#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;
+
+   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);
+    }
+
+    outb(0x20, 0x20);
+
+    switch(esp->int_no) {
+        case 0:
+            ++ticks;
+            break;
+        case 1:
+            c_kb = inb(0x60);
+            putc(table[c_kb]);
+            break;
+        default:
+            break;
+    }
+}
+
+extern void isr_0();
+extern void isr_1();
+extern void isr_2();
+extern void isr_3();
+extern void isr_4();
+extern void isr_5();
+extern void isr_6();
+extern void isr_7();
+extern void isr_8();
+extern void isr_9();
+extern void isr_10();
+extern void isr_11();
+extern void isr_12();
+extern void isr_13();
+extern void isr_14();
+extern void isr_15();
+extern void isr_16();
+extern void isr_17();
+extern void isr_18();
+extern void isr_19();
+extern void isr_20();
+extern void isr_21();
+extern void isr_22();
+extern void isr_23();
+extern void isr_24();
+extern void isr_25();
+extern void isr_26();
+extern void isr_27();
+extern void isr_28();
+extern void isr_29();
+extern void isr_30();
+extern void isr_31();
+
+extern void irq_0();
+extern void irq_1();
+extern void irq_2();
+extern void irq_3();
+extern void irq_4();
+extern void irq_5();
+extern void irq_6();
+extern void irq_7();
+extern void irq_8();
+extern void irq_9();
+extern void irq_10();
+extern void irq_11();
+extern void irq_12();
+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 )
+
+#define IRQ_CALL(N) \
+    idt_set_gate( 32 + N , (uint32_t) irq_##N , 0x08, 0x8E )
+
+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);
+
+    ISR_CALL(0);
+    ISR_CALL(1);
+    ISR_CALL(2);
+    ISR_CALL(3);
+    ISR_CALL(4);
+    ISR_CALL(5);
+    ISR_CALL(6);
+    ISR_CALL(7);
+    ISR_CALL(8);
+    ISR_CALL(9);
+    ISR_CALL(10);
+    ISR_CALL(11);
+    ISR_CALL(12);
+    ISR_CALL(13);
+    ISR_CALL(14);
+    ISR_CALL(15);
+    ISR_CALL(16);
+    ISR_CALL(17);
+    ISR_CALL(18);
+    ISR_CALL(19);
+    ISR_CALL(20);
+    ISR_CALL(21);
+    ISR_CALL(22);
+    ISR_CALL(23);
+    ISR_CALL(24);
+    ISR_CALL(25);
+    ISR_CALL(26);
+    ISR_CALL(27);
+    ISR_CALL(28);
+    ISR_CALL(29);
+    ISR_CALL(30);
+    ISR_CALL(31);
+
+    outb(0x20, 0x11);
+    outb(0xA0, 0x11);
+
+    outb(0x21, 0x20);
+    outb(0xA1, 0x28);
+
+    outb(0x21, 0x04);
+    outb(0xA1, 0x02);
+
+    outb(0x21, 0x01);
+    outb(0xA1, 0x01);
+
+    outb(0x21, 0x0);
+    outb(0xA1, 0x0);
+
+    IRQ_CALL(0);
+    IRQ_CALL(1);
+    IRQ_CALL(2);
+    IRQ_CALL(3);
+    IRQ_CALL(4);
+    IRQ_CALL(5);
+    IRQ_CALL(6);
+    IRQ_CALL(7);
+    IRQ_CALL(8);
+    IRQ_CALL(9);
+    IRQ_CALL(10);
+    IRQ_CALL(11);
+    IRQ_CALL(12);
+    IRQ_CALL(13);
+    IRQ_CALL(14);
+    IRQ_CALL(15);
+
+    idt_flush((uint32_t)&idt_ptr);
+
+    asm volatile ("sti");
+}
diff --git a/i686/timer.c b/i686/timer.c
new file mode 100644 (file)
index 0000000..8532e28
--- /dev/null
@@ -0,0 +1,17 @@
+#include <stdint.h>
+#include <stddef.h>
+
+#include <stdc/string.h>
+
+int set_pitdiv(int freq) {
+    uint32_t div = 1193180 / freq;
+    outb(0x43, 0x36);
+
+    // Divisor has to be sent byte-wise, so split here into upper/lower bytes.
+    uint8_t l = (uint8_t)(div & 0xFF);
+    uint8_t h = (uint8_t)( (div >> 8) & 0xFF );
+
+    // Send the frequency divisor.
+    outb(0x40, l);
+    outb(0x40, h);
+}
index ea4be47bc47e81aeb5887f8ceb7e8e5255efd013..b2c833cd7c9cd03502b3febdbb056d85068b683c 100644 (file)
@@ -45,327 +45,9 @@ uint32_t inl(uint16_t port)
     return ret;
 }
 
-
-// Lets us access our ASM functions from our C code.
-extern void gdt_flush(uint32_t);
-
-// This structure contains the value of one GDT entry.
-// We use the attribute 'packed' to tell GCC not to change
-// any of the alignment in the structure.
-struct gdt_entry_struct
-{
-   uint16_t limit_low;           // The lower 16 bits of the limit.
-   uint16_t base_low;            // The lower 16 bits of the base.
-   uint8_t  base_middle;         // The next 8 bits of the base.
-   uint8_t  access;              // Access flags, determine what ring this segment can be used in.
-   uint8_t  granularity;
-   uint8_t  base_high;           // The last 8 bits of the base.
-} __attribute__((packed));
-typedef struct gdt_entry_struct gdt_entry_t;
-
-struct gdt_ptr_struct
-{
-   uint16_t limit;               // The upper 16 bits of all selector limits.
-   uint32_t base;                // The address of the first gdt_entry_t struct.
-}
- __attribute__((packed));
-typedef struct gdt_ptr_struct gdt_ptr_t;
-
-gdt_entry_t gdt_entries[5];
-gdt_ptr_t   gdt_ptr;
-
-// Set the value of one GDT entry.
-static void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran)
-{
-   gdt_entries[num].base_low    = (base & 0xFFFF);
-   gdt_entries[num].base_middle = (base >> 16) & 0xFF;
-   gdt_entries[num].base_high   = (base >> 24) & 0xFF;
-
-   gdt_entries[num].limit_low   = (limit & 0xFFFF);
-   gdt_entries[num].granularity = (limit >> 16) & 0x0F;
-
-   gdt_entries[num].granularity |= gran & 0xF0;
-   gdt_entries[num].access      = access;
-}
-
-static void init_gdt()
-{
-    gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
-    gdt_ptr.base  = (uint32_t)&gdt_entries;
-
-    gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
-    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
-    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
-    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
-    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
-
-    gdt_flush((uint32_t)&gdt_ptr);
-}
-
-// 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;
-
-static 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;
-
-   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.
-};
-
-char *strs_isr[] = {
-    "divide by zero",
-    "debug exception",
-    "non maskable interrupt",
-    "breakpoint",
-    "into detected overflow",
-    "out of bounds exception",
-    "invalid opcode exception",
-    "no coprocessor exception",
-    "double fault",
-    "coprocessor segment overrun",
-    "bad tss",
-    "segment not present",
-    "stack fault",
-    "general protection fault",
-    "page fault",
-    "unknown interrupt",
-    "coprocessor fault",
-    "alignment check exception",
-    "machine check exception"
-};
-
-void isr_handler(struct interrupt_frame* esp) {
-    kprintf("int %x: ", esp->int_no);
-    if (esp->int_no <= 18) {
-        kprintf("%s\n", strs_isr[esp->int_no]);
-    } else {
-        kprintf("reserved\n");
-    }
-}
-
-uint64_t ticks = 0;
-
-uint64_t kclock() {
-    return ticks;
-}
-
-char *irq_strs[] = {
-    "PIT",
-    "Keyboard",
-    "Cascade",
-    "COM2",
-    "COM1",
-    "LPT1",
-    "CMOS rtc",
-    "Peripheral 1",
-    "Peripheral 2",
-    "Peripheral 3",
-    "PS/2 Mouse",
-    "FPU/Coprocessor",
-    "ATA0",
-    "ATA1",
-};
-
-void irq_handler(struct interrupt_frame* esp) {
-    char c_kb;
-
-    if (esp->int_no >= 7) {
-         outb(0xA0, 0x20);
-    }
-
-    outb(0x20, 0x20);
-
-    switch(esp->int_no) {
-        case 0:
-            ++ticks;
-            break;
-        case 1:
-            c_kb = inb(0x60);
-            kputc(c_kb);
-            break;
-        default:
-            break;
-    }
-}
-
-extern void isr_0();
-extern void isr_1();
-extern void isr_2();
-extern void isr_3();
-extern void isr_4();
-extern void isr_5();
-extern void isr_6();
-extern void isr_7();
-extern void isr_8();
-extern void isr_9();
-extern void isr_10();
-extern void isr_11();
-extern void isr_12();
-extern void isr_13();
-extern void isr_14();
-extern void isr_15();
-extern void isr_16();
-extern void isr_17();
-extern void isr_18();
-extern void isr_19();
-extern void isr_20();
-extern void isr_21();
-extern void isr_22();
-extern void isr_23();
-extern void isr_24();
-extern void isr_25();
-extern void isr_26();
-extern void isr_27();
-extern void isr_28();
-extern void isr_29();
-extern void isr_30();
-extern void isr_31();
-
-extern void irq_0();
-extern void irq_1();
-extern void irq_2();
-extern void irq_3();
-extern void irq_4();
-extern void irq_5();
-extern void irq_6();
-extern void irq_7();
-extern void irq_8();
-extern void irq_9();
-extern void irq_10();
-extern void irq_11();
-extern void irq_12();
-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 )
-
-#define IRQ_CALL(N) \
-    idt_set_gate( 32 + N , (uint32_t) irq_##N , 0x08, 0x8E )
-
-static 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);
-
-    ISR_CALL(0);
-    ISR_CALL(1);
-    ISR_CALL(2);
-    ISR_CALL(3);
-    ISR_CALL(4);
-    ISR_CALL(5);
-    ISR_CALL(6);
-    ISR_CALL(7);
-    ISR_CALL(8);
-    ISR_CALL(9);
-    ISR_CALL(10);
-    ISR_CALL(11);
-    ISR_CALL(12);
-    ISR_CALL(13);
-    ISR_CALL(14);
-    ISR_CALL(15);
-    ISR_CALL(16);
-    ISR_CALL(17);
-    ISR_CALL(18);
-    ISR_CALL(19);
-    ISR_CALL(20);
-    ISR_CALL(21);
-    ISR_CALL(22);
-    ISR_CALL(23);
-    ISR_CALL(24);
-    ISR_CALL(25);
-    ISR_CALL(26);
-    ISR_CALL(27);
-    ISR_CALL(28);
-    ISR_CALL(29);
-    ISR_CALL(30);
-    ISR_CALL(31);
-
-    outb(0x20, 0x11);
-    outb(0xA0, 0x11);
-
-    outb(0x21, 0x20);
-    outb(0xA1, 0x28);
-
-    outb(0x21, 0x04);
-    outb(0xA1, 0x02);
-
-    outb(0x21, 0x01);
-    outb(0xA1, 0x01);
-
-    outb(0x21, 0x0);
-    outb(0xA1, 0x0);
-
-    IRQ_CALL(0);
-    IRQ_CALL(1);
-    IRQ_CALL(2);
-    IRQ_CALL(3);
-    IRQ_CALL(4);
-    IRQ_CALL(5);
-    IRQ_CALL(6);
-    IRQ_CALL(7);
-    IRQ_CALL(8);
-    IRQ_CALL(9);
-    IRQ_CALL(10);
-    IRQ_CALL(11);
-    IRQ_CALL(12);
-    IRQ_CALL(13);
-    IRQ_CALL(14);
-    IRQ_CALL(15);
-
-    idt_flush((uint32_t)&idt_ptr);
-
-    asm volatile ("sti");
-}
-
-int set_pitdiv(int freq) {
-    uint32_t div = 1193180 / freq;
-    outb(0x43, 0x36);
-
-    // Divisor has to be sent byte-wise, so split here into upper/lower bytes.
-    uint8_t l = (uint8_t)(div & 0xFF);
-    uint8_t h = (uint8_t)( (div >> 8) & 0xFF );
-
-    // Send the frequency divisor.
-    outb(0x40, l);
-    outb(0x40, h);
-}
+void init_gdt();
+void init_idt();
+int set_pitdiv(int freq);
 
 void i686_init() {
     init_gdt();
index 02dbf9483a91a0deb51291ca23fc478e2d9a0442..4e0b137dabfd377602aaf68d02e4c28c5174db59 100644 (file)
@@ -1,30 +1,12 @@
 #include <stdarg.h>
 
-typedef void     (*console_put_f)    (char,     char,  char,  uint16_t, uint16_t);
-typedef void     (*console_get_f)    (char*,    char*, char*, uint16_t, uint16_t);
-typedef void     (*console_cursor_f) (uint16_t, uint16_t);
-typedef uint16_t (*console_width_f)  ();
-typedef uint16_t (*console_height_f) ();
-typedef void     (*console_refresh_f)();
-typedef int      (*console_tty_f)    ();
+typedef void     (*module_out_f)    (char);
 
-struct console_module {
-    console_put_f     put;
-    console_get_f     get;
-    console_cursor_f  cursor;
-    console_width_f   width;
-    console_height_f  height;
-    console_refresh_f refresh;
-    console_tty_f     tty;
+struct output {
+    module_out_f     out;
 };
 
-void console_register_module(struct console_module*);
-void console_unregister_module(struct console_module*);
+void console_reg(struct output*);
+void console_unreg(struct output*);
 void console_init();
 void console_deinit();
-
-void kputc(char);
-void kwrite(char*);
-void kvsprintf(char *buffer, const char* fmt_con, va_list ap);
-void kprintf(const char* fmt, ...);
-
diff --git a/include/stdc/stdio.h b/include/stdc/stdio.h
new file mode 100644 (file)
index 0000000..2b5c7d3
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _STRING_H
+#define _STRING_H 1
+
+#include <sys/cdefs.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int    dumphex   (char* buf, const char* index, unsigned int num);
+void   putc      (char c);
+void   puts      (char* str);
+void   vsprintf  (char *buffer, const char* fmt_con, va_list ap);
+void   printf    (const char* fmt_con, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 31a62666e600dd781c47f291b54a2e8d7eb77d19..85fe20b214317a50746c2457e855b95295b78d1d 100644 (file)
@@ -8,11 +8,12 @@
 extern "C" {
 #endif
 
-int memcmp(const void*, const void*, size_t);
-void* memcpy(void* __restrict, const void* __restrict, size_t);
-void* memmove(void*, const void*, size_t);
-void* memset(void*, int, size_t);
-size_t strlen(const char*);
+int    memcmp    (const void*, const void*, size_t);
+void*  memcpy    (void* __restrict, const void* __restrict, size_t);
+void*  memmove   (void*, const void*, size_t);
+void*  memset    (void*, int, size_t);
+size_t strlen    (const char*);
+int    strcatlen (char*, char*);
 
 #ifdef __cplusplus
 }
index afea9262f6c05b729ce3e9a5d083b4b59ad47a51..4f29b0076bc4397bbe7103282f708a52840a28f0 100644 (file)
@@ -1,24 +1,16 @@
 #include <stdint.h>
+#include <string.h>
 #include <module.h>
 #include <module_console.h>
 
-uint16_t *video_mem = (uint16_t*)0xC00B8000;
-
-void biosvga_put(char c, char color_fg, char color_bg, uint16_t x, uint16_t y) {
-    uint8_t attr = (color_bg << 4) | (color_fg & 0xF);
-    uint16_t write = (attr << 8) | c;
+#define WIDTH  80
+#define HEIGHT 25
 
-    video_mem[y * 80 + x] = write;
-}
+int x, y;
 
-void biosvga_get(char* c, char* color_fg, char* color_bg, uint16_t x, uint16_t y) {
-    uint16_t write = video_mem[y * 80 + x];
-    *c = (char)(write & 0xFF);
-    *color_bg = (write << 12) & 0xF;
-    *color_fg = (write << 8)  & 0xF;
-}
+uint16_t *video_mem = (uint16_t*)0xC00B8000;
 
-void biosvga_cursor(uint16_t x, uint16_t y) {
+void cursor(uint16_t x, uint16_t y) {
     uint16_t loc = y * 80 + x;
     outb(0x3D4, 14);
     outb(0x3D5, loc >> 8);
@@ -26,37 +18,54 @@ void biosvga_cursor(uint16_t x, uint16_t y) {
     outb(0x3D5, loc);
 }
 
-uint16_t biosvga_width() {
-    return 80;
-}
+void biosvga_wb(char c) {
+    uint8_t color_bg = 0;
+    uint8_t color_fg = 0xF;
+    uint8_t attr = (color_bg << 4) | (color_fg & 0xF);
+    uint16_t write = (attr << 8) | c;
 
-uint16_t biosvga_height() {
-    return 25;
-}
+    switch(c) {
+        case '\n':
+            y++;
+        case '\r':
+            x = 0;
+            break;
+        case '\b':
+            if (x) --x;
+            break;
+        case '\t':
+            x += 4 - (x % 4);
+            break;
+        case ' ' ... '~':
+            video_mem[y * 80 + x] = write;
+            ++x;
+            break;
+    }
 
-void biosvga_refresh() {
+    if (x >= WIDTH) {
+        x = 0;
+        ++y;
+    }
 
-}
+    if (y >= HEIGHT) {
+        memcpy(video_mem, &video_mem[80], (HEIGHT - 1) * 80 * sizeof(uint16_t));
+        --y;
+        memset(&video_mem[y * 80], 0, 160);
+    }
 
-int biosvga_tty() {
-    return 1;
+    cursor(x, y);
 }
 
-struct console_module biosvga_module = {
-    .put    = biosvga_put,
-    .get    = biosvga_get,
-    .tty    = biosvga_tty,
-    .cursor = biosvga_cursor,
-    .width  = biosvga_width,
-    .height = biosvga_height,
-    .refresh = biosvga_refresh
+struct output biosvga_module = {
+    .out    = biosvga_wb
 };
 
 void biosvga_init() {
-    console_register_module(&biosvga_module);
+    x = y = 0;
+    console_reg(&biosvga_module);
 }
 
 void biosvga_deinit() {
-    console_unregister_module(&biosvga_module);
+    console_unreg(&biosvga_module);
     // Stub.
 }
index 3f997981e00a76ff8fcadae64a4e5772f3ea10bd..22bfe6bb7e8da8548dc3c938b565cfeeb2f5373a 100644 (file)
@@ -7,211 +7,26 @@ actually printing to; in the future, adding a new backend for framebuffer render
 #include <module.h>
 #include <module_console.h>
 
-struct console_module *active;
-struct console_module *reg[2];
-uint16_t x, y, tab_w;
+struct output *active;
 
-void biosvga_init();
-void biosvga_deinit();
-
-void console_mark_active(int idx) {
-    active = reg[idx];
-}
-
-void console_register_module(struct console_module* module) {
-    reg[1] = reg[0];
-    reg[0] = module;
-}
-
-void console_unregister_module(struct console_module* module) {
-    if (reg[0] == module)
-        reg[0] = reg[1];
-    if (reg[1] == module)
-        reg[1] = NULL;
+void put_handler(char c) {
+    active->out(c);
 }
 
-// TODO - Should this be part of the backend? Scrolling is slow.
-void scroll() {
-    if (active->tty() == 0)
-        return;
-
-    if (y >= active->height()) {
-        for(int cy = 1; cy <= active->height(); cy++) {
-            for(int cx = 0; cx <= active->width(); cx++) {
-                char c = 0;
-                uint8_t fg = 0, bg = 0;
-                active->get(&c, &fg, &bg, cx, cy);
-                active->put(c,  0xf,  0,  cx, cy-1);
-            }
-        }
-        --y;
-        for(int cx = 0; cx < active->width(); cx++) {
-            active->put(' ',  0xf,  0,  cx, y);
-        }
-    }
+void console_reg(struct output* out) {
+    active = out;
 }
 
-// TODO - Should this be part of the backend? Scrolling is slow.
-void clear() {
-    if (active->tty() == 0)
-        return;
-
-    x = y = 0;
-    for(int cy = 0; cy < active->height(); cy++) {
-        for(int cx = 0; cx < active->width(); cx++) {
-            active->put(' ',  0xf,  0x0,  cx, cy);
-        }
-    }
-}
-
-void kputc(char c) {
-    switch(c) {
-        case '\t':
-            x += tab_w - (x % tab_w);
-            break;
-        case '\b':
-            --x;
-            break;
-        case '\n':
-            ++y;
-        case '\r':
-            x = 0;
-            break;
-        case ' ' ... '~':
-            active->put(c, 0xf, 0x0, x, y);
-        default:
-            x += 1;
-            break;
-    }
-
-    if (x > active->width()) {
-        x = 0;
-        ++y;
-    }
-
-    scroll();
-    if (active->tty() == 1)
-        active->cursor(x, y);
-}
-
-void kwrite(char* str) {
-    while(*str != 0) {
-        kputc(*str);
-        ++str;
-    }
-}
-
-int strcatlen(char* a, char* b) {
-    char* o = b;
-    while(*b != 0) {
-        *a = *b;
-        a++;
-        b++;
-    }
-    return b - o;
-}
-
-int dumphex(char* buf, const char* index, unsigned int num) {
-    uint8_t *num_8 = (uint8_t *)&num;
-    char *obuf = buf;
-    for (int i = 3; i >= 0; i--) {
-        uint8_t high = (num_8[i] >> 4) & 0xf;
-        uint8_t low = num_8[i] & 0xf;
-
-        *buf = (index)[high]; buf++;
-        *buf = (index)[low];  buf++;
-    }
-
-    return buf - obuf;
-}
-
-void kvsprintf(char *buffer, const char* fmt_con, va_list ap) {
-    char* fmt = (char*)fmt_con;
-    char* buf = buffer;
-    while(*fmt != 0) {
-        if (*fmt == '%') {
-            // Format string.
-            ++fmt;
-            switch (*fmt) {
-                case 'c':
-                    *buf = (char)va_arg(ap, int);
-                    buf++;
-                    fmt++;
-                    break;
-                case '%':
-                    *buf = '%';
-                    buf++;
-                    fmt++;
-                    break;
-                case 's':
-                    buf += strcatlen(buf, va_arg(ap, char*));
-                    fmt++;
-                    break;
-                case 'x':
-                    buf += dumphex(buf, "0123456789abcdef", va_arg(ap, unsigned int));
-                    ++fmt;
-                    break;
-                case 'X':
-                    buf += dumphex(buf, "0123456789ABCDEF", va_arg(ap, unsigned int));
-                    ++fmt;
-                    break;
-                case 'd':
-                case 'u':
-                default:
-                    ++fmt;
-                    break;
-            }
-        } else {
-            *buf = *fmt;
-            ++buf;
-            ++fmt;
-        }
-    }
-
-    *buf = 0;
-}
-
-char buf[4096];
-
-void kprintf(const char* fmt, ...) {
-    va_list ap;
-    va_start(ap, fmt);
-
-    kvsprintf(buf, fmt, ap);
-
-    va_end(ap);
-
-    kwrite(buf);
-}
-
-void defer_kprintf(const char* fmt, ...) {
-    va_list ap;
-    va_start(ap, fmt);
-
-    kvsprintf(buf, fmt, ap);
-
-    va_end(ap);
-}
-
-void flush_defer_kprintf() {
-    kwrite(buf);
+void console_unreg(struct output* out) {
+    active = out;
 }
 
 void console_init() {
-    x = y = 0;
-    tab_w = 4;
-
     // Temporary
-    serial_init();
     biosvga_init();
-
-    console_mark_active(0);
-
-    clear();
 }
 
 void console_deinit() {
     // Temporary
     biosvga_deinit();
-    serial_deinit();
 }
index 2e7d2cf2f42b9523f1153a5dd32e0f4a8ab2020a..98fa2f72516428a57602e3e23ee5bc45bccaf396 100644 (file)
@@ -8,22 +8,17 @@ int is_transmit_empty() {
     return inb(PORT + 5) & 0x20;
 }
 
-void serial_put(char c, char color_fg, char color_bg, uint16_t x, uint16_t y) {
+void serial_wb(char c) {
     while (is_transmit_empty() == 0);
     outb(PORT, c);
 }
 
-void serial_get(char* c, char* color_fg, char* color_bg, uint16_t x, uint16_t y) {
+char serial_rb(void) {
 }
 
-int serial_tty() {
-    return 0;
-}
-
-struct console_module serial_module = {
-    .put     = serial_put,
-    .get     = serial_get,
-    .tty     = serial_tty
+struct port_module serial_module = {
+    .write = serial_wb,
+    .read  = serial_rb,
 };
 
 void serial_init() {
@@ -34,11 +29,7 @@ void serial_init() {
     outb(PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
     outb(PORT + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
     outb(PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
-
-    console_register_module(&serial_module);
 }
 
 void serial_deinit() {
-    console_unregister_module(&serial_module);
-    // Stub.
 }