From 04768924e8a84f6c6c08cc7538f675e10d5f1246 Mon Sep 17 00:00:00 2001 From: Nathan Cannon Date: Sat, 28 Apr 2018 01:06:02 +0100 Subject: [PATCH] Receiving an interrupt no longer crashes, does seem to cause a general protection fault though (infinite loop time!). --- kernel/arch/i386/interrupts.nim | 159 +++++++++++++++++--------------- 1 file changed, 87 insertions(+), 72 deletions(-) diff --git a/kernel/arch/i386/interrupts.nim b/kernel/arch/i386/interrupts.nim index 25d6082..67920fd 100644 --- a/kernel/arch/i386/interrupts.nim +++ b/kernel/arch/i386/interrupts.nim @@ -18,43 +18,40 @@ type int_no, err_code: uint32 # Interrupt number and error code (if applicable) eip, cs, eflags, useresp, ss: uint32 # Pushed by the processor automatically. -var - idt: IDT - idtAddr: uint32 = cast[uint32](idt.addr) +const + idtAddress: uint32 = 0x00000000 + idt = cast[ptr IDT](idtAddress) -{.push stackTrace:off.} proc idtFlush(){.inline,asmNoStackFrame.} = asm """ - lidt [`idtAddr`] + lidtl (0x0) ret """ -{.pop.} -proc isrHandler(registers: Registers){.exportc.} = - serial.write("Recieved interrupt:") +proc isrHandler(registers: Registers){.exportc, codegenDecl: "__attribute__((interrupt)) $# $#$#".} = + serial.write("Recieved interrupt handler:") serial.write(registers.int_no) serial.write("\L") -proc isrCommon() = +proc isrCommon(){.asmNoStackFrame,exportc.} = asm """ - pusha - movw %ax, %ds - push %eax - movw $0x10, %ax - movw %ds, %ax - movw %es, %ax - movw %fs, %ax - movw %gs, %ax - call `isrHandler` - pop %eax - movw %ds, %ax - movw %es, %ax - movw %fs, %ax - movw %gs, %ax - popa - add $8, %esp - sti - iret + pusha + mov %ds, %ax + push %eax + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + call `isrHandler` + pop %eax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + popa + add $8, %esp + iret """ macro generateISR(code: static[uint8], isError: static[bool]): typed = @@ -66,13 +63,36 @@ macro generateISR(code: static[uint8], isError: static[bool]): typed = nnkFormalParams.newTree( newEmptyNode() ), - newEmptyNode(), + nnkPragma.newTree( + newIdentNode("exportc") + ), newEmptyNode(), nnkStmtList.newTree( nnkAsmStmt.newTree( newEmptyNode(), - newLit("cli\x0A" & (if isError: "" else: "push 0\x0A") & "push " & $code & "\x0A") + newLit((if isError: "" else: "push 0\x0A") & "push " & $code & "\x0A") ), + nnkCall.newTree( + nnkDotExpr.newTree( + newIdentNode("serial"), + newIdentNode("write") + ), + newLit("Recieved interrupt:") + ), + nnkCall.newTree( + nnkDotExpr.newTree( + newIdentNode("serial"), + newIdentNode("write") + ), + newLit(code) + ), + nnkCall.newTree( + nnkDotExpr.newTree( + newIdentNode("serial"), + newIdentNode("write") + ), + newLit("\x0A") + ), nnkCall.newTree( newIdentNode("isrCommon") ) @@ -84,17 +104,9 @@ proc idtSetGate(num: uint8, base: uint32, sel: uint16, flags: uint8) = idt.entries[num].base_low = uint16(base and 0xFFFF) idt.entries[num].base_high = uint16((base shr 16) and 0xFFFF) idt.entries[num].zero = 0 - idt.entries[num].flags = flags + idt.entries[num].flags = flags or 0x60 idt.entries[num].kernel_selector = sel -# Would like to generate these in a loop, but apparently -# Error: type mismatch: got -# but expected one of: -# macro generateISR(code: static[uint8]; isError: static[bool]): typed -# first type mismatch at position: 1 -# required type: static[uint8] -# but expression 'uint8(i)' is of type: uint8 - static: generateISR(0, false) generateISR(1, false) @@ -129,43 +141,46 @@ static: generateISR(30, false) generateISR(31, false) -let +const selector: uint16 = 0x08 flags: uint8 = 0x8E proc idtInstall*() = - idt.descriptor.limit = uint16(sizeof(IDTEntry) * idt.entries.len) - 1 + idt.descriptor.limit = uint16(sizeof(idt.entries)) - 1 idt.descriptor.base = cast[uint32](idt.entries.addr) - idtSetGate(0, cast[uint32](isr0) ,selector, flags) - idtSetGate(1, cast[uint32](isr1) ,selector, flags) - idtSetGate(2, cast[uint32](isr2) ,selector, flags) - idtSetGate(3, cast[uint32](isr3) ,selector, flags) - idtSetGate(4, cast[uint32](isr4) ,selector, flags) - idtSetGate(5, cast[uint32](isr5) ,selector, flags) - idtSetGate(6, cast[uint32](isr6) ,selector, flags) - idtSetGate(7, cast[uint32](isr7) ,selector, flags) - idtSetGate(8, cast[uint32](isr8) ,selector, flags) - idtSetGate(9, cast[uint32](isr9) ,selector, flags) - idtSetGate(10, cast[uint32](isr10) ,selector, flags) - idtSetGate(11, cast[uint32](isr11) ,selector, flags) - idtSetGate(12, cast[uint32](isr12) ,selector, flags) - idtSetGate(13, cast[uint32](isr13) ,selector, flags) - idtSetGate(14, cast[uint32](isr14) ,selector, flags) - idtSetGate(15, cast[uint32](isr15) ,selector, flags) - idtSetGate(16, cast[uint32](isr16) ,selector, flags) - idtSetGate(17, cast[uint32](isr17) ,selector, flags) - idtSetGate(18, cast[uint32](isr18) ,selector, flags) - idtSetGate(19, cast[uint32](isr19) ,selector, flags) - idtSetGate(20, cast[uint32](isr20) ,selector, flags) - idtSetGate(21, cast[uint32](isr21) ,selector, flags) - idtSetGate(22, cast[uint32](isr22) ,selector, flags) - idtSetGate(23, cast[uint32](isr23) ,selector, flags) - idtSetGate(24, cast[uint32](isr24) ,selector, flags) - idtSetGate(25, cast[uint32](isr25) ,selector, flags) - idtSetGate(26, cast[uint32](isr26) ,selector, flags) - idtSetGate(27, cast[uint32](isr27) ,selector, flags) - idtSetGate(28, cast[uint32](isr28) ,selector, flags) - idtSetGate(29, cast[uint32](isr29) ,selector, flags) - idtSetGate(30, cast[uint32](isr30) ,selector, flags) - idtSetGate(31, cast[uint32](isr31) ,selector, flags) + for i in 0..idt.entries.len: # Zero IDT memory space + idtSetGate(uint8(i),0,0,0) + idtSetGate(0, cast[uint32](isr0), selector, flags) + idtSetGate(1, cast[uint32](isr1), selector, flags) + idtSetGate(2, cast[uint32](isr2), selector, flags) + idtSetGate(3, cast[uint32](isr3), selector, flags) + idtSetGate(4, cast[uint32](isr4), selector, flags) + idtSetGate(5, cast[uint32](isr5), selector, flags) + idtSetGate(6, cast[uint32](isr6), selector, flags) + idtSetGate(7, cast[uint32](isr7), selector, flags) + idtSetGate(8, cast[uint32](isr8), selector, flags) + idtSetGate(9, cast[uint32](isr9), selector, flags) + idtSetGate(10, cast[uint32](isr10), selector, flags) + idtSetGate(11, cast[uint32](isr11), selector, flags) + idtSetGate(12, cast[uint32](isr12), selector, flags) + idtSetGate(13, cast[uint32](isr13), selector, flags) + idtSetGate(14, cast[uint32](isr14), selector, flags) + idtSetGate(15, cast[uint32](isr15), selector, flags) + idtSetGate(16, cast[uint32](isr16), selector, flags) + idtSetGate(17, cast[uint32](isr17), selector, flags) + idtSetGate(18, cast[uint32](isr18), selector, flags) + idtSetGate(19, cast[uint32](isr19), selector, flags) + idtSetGate(20, cast[uint32](isr20), selector, flags) + idtSetGate(21, cast[uint32](isr21), selector, flags) + idtSetGate(22, cast[uint32](isr22), selector, flags) + idtSetGate(23, cast[uint32](isr23), selector, flags) + idtSetGate(24, cast[uint32](isr24), selector, flags) + idtSetGate(25, cast[uint32](isr25), selector, flags) + idtSetGate(26, cast[uint32](isr26), selector, flags) + idtSetGate(27, cast[uint32](isr27), selector, flags) + idtSetGate(28, cast[uint32](isr28), selector, flags) + idtSetGate(29, cast[uint32](isr29), selector, flags) + idtSetGate(30, cast[uint32](isr30), selector, flags) + idtSetGate(31, cast[uint32](isr31), selector, flags) + serial.write("Flushing IDT.\L") idtFlush() \ No newline at end of file