diff --git a/src/kernel/entry.asm b/src/kernel/entry.asm index 72211fd..2e24798 100644 --- a/src/kernel/entry.asm +++ b/src/kernel/entry.asm @@ -4,17 +4,23 @@ [extern main] [extern idtp] [extern faultHandler] +[extern irqHandler] +;; Calls the main function in 'main.c' _start: call main cli hlt +;; +;; --- IDT --- +;; [global idtLoad] idtLoad: lidt [idtp] ret +;; Isrs (exceptions) [global isr0] isr0: cli @@ -226,3 +232,125 @@ isrCommon: ; No clue how this works, i'm pretty sure it calls the C functio add esp, 8 iret +;; IRQs +[global irq0] +irq0: + cli + push 0 + push 32 + jmp irqCommon +[global irq1] +irq1: + cli + push 0 + push 33 + jmp irqCommon +[global irq2] +irq2: + cli + push 0 + push 34 + jmp irqCommon +[global irq3] +irq3: + cli + push 0 + push 35 + jmp irqCommon +[global irq4] +irq4: + cli + push 0 + push 36 + jmp irqCommon +[global irq5] +irq5: + cli + push 0 + push 37 + jmp irqCommon +[global irq6] +irq6: + cli + push 0 + push 38 + jmp irqCommon +[global irq7] +irq7: + cli + push 0 + push 39 + jmp irqCommon +[global irq8] +irq8: + cli + push 0 + push 40 + jmp irqCommon +[global irq9] +irq9: + cli + push 0 + push 41 + jmp irqCommon +[global irq10] +irq10: + cli + push 0 + push 42 + jmp irqCommon +[global irq11] +irq11: + cli + push 0 + push 43 + jmp irqCommon +[global irq12] +irq12: + cli + push 0 + push 44 + jmp irqCommon +[global irq13] +irq13: + cli + push 0 + push 45 + jmp irqCommon +[global irq14] +irq14: + cli + push 0 + push 46 + jmp irqCommon +[global irq15] +irq15: + cli + push 0 + push 47 + jmp irqCommon + +irqCommon: ; Simular to isrCommon, probaly calls the C function + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp + push eax + mov eax, irqHandler + call eax + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 + iret + diff --git a/src/kernel/idt.c b/src/kernel/idt.c index b1aa4d9..9aaa593 100644 --- a/src/kernel/idt.c +++ b/src/kernel/idt.c @@ -1,5 +1,6 @@ #include "idt.h" #include "stdint.h" +#include "system.h" struct idtEntry { uint16_t offsetLow; @@ -30,5 +31,6 @@ void setupIdt() { idtp.base = (uint32_t)&idt; idtLoad(); + sti(); } diff --git a/src/kernel/idt.h b/src/kernel/idt.h index bc394c6..fa0ab7a 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -7,5 +7,13 @@ void setupIdt(); void idtSetGate(uint8_t i, uint32_t offset, uint16_t selector, uint8_t typeAttr); extern void idtLoad(); +// Contains values of registers and exception info from isrs +struct regs { + unsigned int gs, fs, es, ds; + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned int intNo, errCode; + unsigned int eip, cs, eflags, useresp, ss; +}; + #endif diff --git a/src/kernel/irq.c b/src/kernel/irq.c new file mode 100644 index 0000000..d1c310d --- /dev/null +++ b/src/kernel/irq.c @@ -0,0 +1,61 @@ +#include "irq.h" +#include "stdint.h" +#include "system.h" + +void* irqRoutines[16] = { 0 }; + +void installIrqHandler(uint32_t irq, void (*handler)(struct regs* r)) { + irqRoutines[irq] = handler; +} + +void uninstallIrqHandler(uint32_t irq) { + irqRoutines[irq] = 0; +} + +// I have no clue how or what this does, but it makes everything work +void irqRemap(void) { + outb(0xA0, 0x11); + outb(0x20, 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); +} + +void irqHandler(struct regs* r) { + void (*handler)(struct regs* r); + + handler = irqRoutines[r->intNo - 32]; // Offset by 32 because of isrs + if (handler) handler(r); + + // Something about master and slave handlers + if (r->intNo >= 40) outb(0xa0, 0x20); + outb(0x20, 0x20); +} + +void setupIrqs() { + irqRemap(); + + // Same as isrs, but differnet handlers :o + idtSetGate(32, (unsigned)irq0, 0x08, 0x8e); + idtSetGate(33, (unsigned)irq1, 0x08, 0x8e); + idtSetGate(34, (unsigned)irq2, 0x08, 0x8e); + idtSetGate(35, (unsigned)irq3, 0x08, 0x8e); + idtSetGate(36, (unsigned)irq4, 0x08, 0x8e); + idtSetGate(37, (unsigned)irq5, 0x08, 0x8e); + idtSetGate(38, (unsigned)irq6, 0x08, 0x8e); + idtSetGate(39, (unsigned)irq7, 0x08, 0x8e); + idtSetGate(40, (unsigned)irq8, 0x08, 0x8e); + idtSetGate(41, (unsigned)irq9, 0x08, 0x8e); + idtSetGate(42, (unsigned)irq10, 0x08, 0x8e); + idtSetGate(43, (unsigned)irq11, 0x08, 0x8e); + idtSetGate(44, (unsigned)irq12, 0x08, 0x8e); + idtSetGate(45, (unsigned)irq13, 0x08, 0x8e); + idtSetGate(46, (unsigned)irq14, 0x08, 0x8e); + idtSetGate(47, (unsigned)irq15, 0x08, 0x8e); +} + diff --git a/src/kernel/irq.h b/src/kernel/irq.h new file mode 100644 index 0000000..eed3916 --- /dev/null +++ b/src/kernel/irq.h @@ -0,0 +1,29 @@ +#ifndef IRQ_H +#define IRQ_H + +#include "stdint.h" +#include "idt.h" + +void setupIrqs(); +void installIrqHandler(uint32_t irq, void (*handler)(struct regs* r)); +void uninstallIrqHandler(uint32_t irq); +void irqHandler(struct regs* r); + +extern void irq0(); +extern void irq1(); +extern void irq2(); +extern void irq3(); +extern void irq4(); +extern void irq5(); +extern void irq6(); +extern void irq7(); +extern void irq8(); +extern void irq9(); +extern void irq10(); +extern void irq11(); +extern void irq12(); +extern void irq13(); +extern void irq14(); +extern void irq15(); + +#endif diff --git a/src/kernel/isrs.h b/src/kernel/isrs.h index 50f7368..e1ea18c 100644 --- a/src/kernel/isrs.h +++ b/src/kernel/isrs.h @@ -3,14 +3,6 @@ void setupIsrs(); -// Contains values of registers and exception info from isrs -struct regs { - unsigned int gs, fs, es, ds; - unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; - unsigned int intNo, errCode; - unsigned int eip, cs, eflags, useresp, ss; -}; - // Repetative isr definitions extern void isr0(); extern void isr1(); diff --git a/src/kernel/main.c b/src/kernel/main.c index 20fb4a8..f5dde2f 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,12 +1,14 @@ #include "screen.h" #include "idt.h" #include "isrs.h" +#include "irq.h" void main() { setupIdt(); setupIsrs(); - clear(0x0f); + setupIrqs(); + clear(0x0f); print("kern.\n\n", 0x0f); }