From: Jon Feldman Date: Mon, 20 Feb 2017 20:58:10 +0000 (-0500) Subject: Set up IRQs X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=c4b0994d231b6adb36b02004c9dab15245bcd074;p=misc%2Feidos.git Set up IRQs --- diff --git a/common/kernel_main.c b/common/kernel_main.c index 53c994a..e46e46b 100644 --- a/common/kernel_main.c +++ b/common/kernel_main.c @@ -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; } diff --git a/i686/entry.S b/i686/entry.S index 649c07d..dd0ff0b 100644 --- a/i686/entry.S +++ b/i686/entry.S @@ -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: diff --git a/i686/utils.c b/i686/utils.c index 9c5382e..ea4be47 100644 --- a/i686/utils.c +++ b/i686/utils.c @@ -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); }