]> Chaos Git - misc/eidos.git/commitdiff
Set up IRQs
authorJon Feldman <chaos.kagami@gmail.com>
Mon, 20 Feb 2017 20:58:10 +0000 (15:58 -0500)
committerJon Feldman <chaos.kagami@gmail.com>
Mon, 20 Feb 2017 20:58:10 +0000 (15:58 -0500)
common/kernel_main.c
i686/entry.S
i686/utils.c

index 53c994ab4d561871e576ab8c63d26d0e7ef7b510..e46e46b4aebe2460560964354145758613781ced 100644 (file)
@@ -10,10 +10,11 @@ int kernel_main(struct multiboot *mboot_ptr)
 
     console_deinit();
 
-    asm volatile("int $4");
-    asm volatile("int $3");
-
-    while(1);
+    while(1) {
+        uint64_t clock = kclock();
+        kprintf("%X%X\r", ((uint32_t*)&clock)[1], ((uint32_t*)&clock)[0]);
+        asm("hlt");
+    }
 
     return 0xDEADBEEF;
 }
index 649c07d4fa8b8839252bc148a8c3e5669dfd1b68..dd0ff0bc727b6e9c53688de640b1dc1c1455671d 100644 (file)
@@ -104,6 +104,15 @@ gdt_flush:
          jmp isr_stub
 .endm
 
+.macro IRQ index
+    .global irq_\index
+    .type irq_\index , @function
+     irq_\index :
+         push $0
+         push $\index
+         jmp irq_stub
+.endm
+
 ISR 0
 ISR 1
 ISR 2
@@ -137,6 +146,23 @@ ISR 29
 ISR_E 30
 ISR 31
 
+IRQ 0
+IRQ 1
+IRQ 2
+IRQ 3
+IRQ 4
+IRQ 5
+IRQ 6
+IRQ 7
+IRQ 8
+IRQ 9
+IRQ 10
+IRQ 11
+IRQ 12
+IRQ 13
+IRQ 14
+IRQ 15
+
 isr_stub:
         pusha
 
@@ -166,6 +192,37 @@ isr_stub:
         add $8, %esp
         iret
 
+
+irq_stub:
+        pusha
+
+        mov %ds, %ax
+        push %eax
+
+        mov    $0x10,%ax
+        mov    %ax,%ds
+        mov    %ax,%es
+        mov    %ax,%fs
+        mov    %ax,%gs
+
+        push %esp
+
+        cld
+        call irq_handler
+
+        pop    %ebx
+
+        pop    %ebx
+        mov    %bx,%ds
+        mov    %bx,%es
+        mov    %bx,%fs
+        mov    %bx,%gs
+
+        popa
+        add $8, %esp
+       sti
+        iret
+
 .global idt_flush
 .type idt_flush, @function
 idt_flush:
index 9c5382e1e85b876148e1d149a1401e33939c9276..ea4be47bc47e81aeb5887f8ceb7e8e5255efd013 100644 (file)
@@ -145,7 +145,7 @@ struct interrupt_frame
    uint32_t eip, cs, eflags, esp, ss; // Pushed by the processor automatically.
 };
 
-char *strs[] = {
+char *strs_isr[] = {
     "divide by zero",
     "debug exception",
     "non maskable interrupt",
@@ -170,12 +170,57 @@ char *strs[] = {
 void isr_handler(struct interrupt_frame* esp) {
     kprintf("int %x: ", esp->int_no);
     if (esp->int_no <= 18) {
-        kprintf("%s\n", strs[esp->int_no]);
+        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();
@@ -209,9 +254,29 @@ 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;
@@ -252,10 +317,58 @@ static void init_idt()
     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 i686_init() {
     init_gdt();
     init_idt();
+    set_pitdiv(1000);
 }