summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2010-01-20 22:18:02 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2010-01-20 22:18:02 +0100
commit068368d0bedc34f561ab0c9dd614c02b346d1d4e (patch)
tree5951082c13767904c9995c759263c18fcd17845e
parentbfa24f7e97eebd26561d87bbab643a9825e93392 (diff)
Added IRQ-support and timer interrupt.
-rw-r--r--kernel/SConscript2
-rw-r--r--kernel/idt.c19
-rw-r--r--kernel/irq.c42
-rw-r--r--kernel/irq.h9
-rw-r--r--kernel/main.c6
5 files changed, 77 insertions, 1 deletions
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(