From 068368d0bedc34f561ab0c9dd614c02b346d1d4e Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Wed, 20 Jan 2010 22:18:02 +0100 Subject: Added IRQ-support and timer interrupt. --- kernel/SConscript | 2 +- kernel/idt.c | 19 +++++++++++++++++++ kernel/irq.c | 42 ++++++++++++++++++++++++++++++++++++++++++ kernel/irq.h | 9 +++++++++ kernel/main.c | 6 ++++++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 kernel/irq.c create mode 100644 kernel/irq.h diff --git a/kernel/SConscript b/kernel/SConscript index 8b0ad5c..76d3aa6 100644 --- a/kernel/SConscript +++ b/kernel/SConscript @@ -27,4 +27,4 @@ kernel_bld = Builder( env.Append(BUILDERS = {'Kernel' : kernel_bld}) -kernel = env.Kernel('kernel', ['kernel.ld', 'entry.c', 'main.c', 'printf.c', 'gdt.c', 'idt.c', 'panic.c']) +kernel = env.Kernel('kernel', ['kernel.ld', 'entry.c', 'main.c', 'printf.c', 'gdt.c', 'idt.c', 'irq.c', 'panic.c']) diff --git a/kernel/idt.c b/kernel/idt.c index 5633c61..66e1fb8 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -73,6 +73,22 @@ isr_panic(29); isr_panic(30); isr_panic(31); +#include "irq.h" + +void tick() { + *(uint16_t*)(0xb8890) += 1; + irq_reset(); +} + + +asm( + ".globl isr_32\n" + "isr_32:\n" + "pusha\n" + "call tick\n" + "popa\n" + "iret\n" +); void idt_init() { idt_set_gate(0, (uint32_t)isr_0, 0x08, 0x8e00); @@ -108,6 +124,9 @@ void idt_init() { idt_set_gate(30, (uint32_t)isr_30, 0x08, 0x8e00); idt_set_gate(31, (uint32_t)isr_31, 0x08, 0x8e00); + void isr_32(); + idt_set_gate(32, (uint32_t)isr_32, 0x08, 0x8e00); + asm volatile( "lidt (%0)\n" : : "r" (&idtr) diff --git a/kernel/irq.c b/kernel/irq.c new file mode 100644 index 0000000..6034735 --- /dev/null +++ b/kernel/irq.c @@ -0,0 +1,42 @@ +#include "irq.h" +#include "portio.h" + +void irq_init() { + // ICW1 + outb(0x20, 0x11); + outb(0xa0, 0x11); + + // ICW2 - Offset. + outb(0x21, 0x20); + outb(0xa1, 0x28); + + // ICW3 + outb(0x21, 0x04); + outb(0xa1, 0x02); + + // ICW4 + outb(0x21, 0x01); + outb(0xa1, 0x01); + + // OCW1 - Mask. + outb(0x21, 0xfe); + outb(0xa1, 0xff); + + // Initialize timer. + // TODO: Move this elsewhere. + outb(0x43, 0x36); + outb(0x40, 0x00); + outb(0x40, 0x00); +} + +void irq_reset() { + // OCW2 + outb(0x20, 0x20); +} + +void irq_reset_slave() { + // OCW2 + outb(0xa0, 0x20); + + irq_reset(); +} diff --git a/kernel/irq.h b/kernel/irq.h new file mode 100644 index 0000000..2a5682a --- /dev/null +++ b/kernel/irq.h @@ -0,0 +1,9 @@ +#ifndef IRQ_H +#define IRQ_H + +void irq_init(); + +void irq_reset(); +void irq_reset_slave(); + +#endif diff --git a/kernel/main.c b/kernel/main.c index 55476ce..74ba441 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,6 +1,7 @@ #include "printf.h" #include "gdt.h" #include "idt.h" +#include "irq.h" void main() { printf("main()\n"); @@ -11,6 +12,11 @@ void main() { idt_init(); printf("IDT set.\n"); + irq_init(); + printf("IRQs set.\n"); + + asm volatile("sti"); + printf("Halting.\n"); asm volatile( -- cgit v1.2.3