Receiving an interrupt no longer crashes, does seem to cause a general protection fault though (infinite loop time!).

This commit is contained in:
neviyn 2018-04-28 01:06:02 +01:00
parent 347a5cbff3
commit 04768924e8

View File

@ -18,42 +18,39 @@ type
int_no, err_code: uint32 # Interrupt number and error code (if applicable) int_no, err_code: uint32 # Interrupt number and error code (if applicable)
eip, cs, eflags, useresp, ss: uint32 # Pushed by the processor automatically. eip, cs, eflags, useresp, ss: uint32 # Pushed by the processor automatically.
var const
idt: IDT idtAddress: uint32 = 0x00000000
idtAddr: uint32 = cast[uint32](idt.addr) idt = cast[ptr IDT](idtAddress)
{.push stackTrace:off.}
proc idtFlush(){.inline,asmNoStackFrame.} = proc idtFlush(){.inline,asmNoStackFrame.} =
asm """ asm """
lidt [`idtAddr`] lidtl (0x0)
ret ret
""" """
{.pop.}
proc isrHandler(registers: Registers){.exportc.} = proc isrHandler(registers: Registers){.exportc, codegenDecl: "__attribute__((interrupt)) $# $#$#".} =
serial.write("Recieved interrupt:") serial.write("Recieved interrupt handler:")
serial.write(registers.int_no) serial.write(registers.int_no)
serial.write("\L") serial.write("\L")
proc isrCommon() = proc isrCommon(){.asmNoStackFrame,exportc.} =
asm """ asm """
pusha pusha
movw %ax, %ds mov %ds, %ax
push %eax push %eax
movw $0x10, %ax mov $0x10, %ax
movw %ds, %ax mov %ax, %ds
movw %es, %ax mov %ax, %es
movw %fs, %ax mov %ax, %fs
movw %gs, %ax mov %ax, %gs
call `isrHandler` call `isrHandler`
pop %eax pop %eax
movw %ds, %ax mov %ax, %ds
movw %es, %ax mov %ax, %es
movw %fs, %ax mov %ax, %fs
movw %gs, %ax mov %ax, %gs
popa popa
add $8, %esp add $8, %esp
sti
iret iret
""" """
@ -66,12 +63,35 @@ macro generateISR(code: static[uint8], isError: static[bool]): typed =
nnkFormalParams.newTree( nnkFormalParams.newTree(
newEmptyNode() newEmptyNode()
), ),
newEmptyNode(), nnkPragma.newTree(
newIdentNode("exportc")
),
newEmptyNode(), newEmptyNode(),
nnkStmtList.newTree( nnkStmtList.newTree(
nnkAsmStmt.newTree( nnkAsmStmt.newTree(
newEmptyNode(), 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( nnkCall.newTree(
newIdentNode("isrCommon") 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_low = uint16(base and 0xFFFF)
idt.entries[num].base_high = uint16((base shr 16) and 0xFFFF) idt.entries[num].base_high = uint16((base shr 16) and 0xFFFF)
idt.entries[num].zero = 0 idt.entries[num].zero = 0
idt.entries[num].flags = flags idt.entries[num].flags = flags or 0x60
idt.entries[num].kernel_selector = sel idt.entries[num].kernel_selector = sel
# Would like to generate these in a loop, but apparently
# Error: type mismatch: got <uint8, bool>
# 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: static:
generateISR(0, false) generateISR(0, false)
generateISR(1, false) generateISR(1, false)
@ -129,43 +141,46 @@ static:
generateISR(30, false) generateISR(30, false)
generateISR(31, false) generateISR(31, false)
let const
selector: uint16 = 0x08 selector: uint16 = 0x08
flags: uint8 = 0x8E flags: uint8 = 0x8E
proc idtInstall*() = 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) idt.descriptor.base = cast[uint32](idt.entries.addr)
idtSetGate(0, cast[uint32](isr0) ,selector, flags) for i in 0..idt.entries.len: # Zero IDT memory space
idtSetGate(1, cast[uint32](isr1) ,selector, flags) idtSetGate(uint8(i),0,0,0)
idtSetGate(2, cast[uint32](isr2) ,selector, flags) idtSetGate(0, cast[uint32](isr0), selector, flags)
idtSetGate(3, cast[uint32](isr3) ,selector, flags) idtSetGate(1, cast[uint32](isr1), selector, flags)
idtSetGate(4, cast[uint32](isr4) ,selector, flags) idtSetGate(2, cast[uint32](isr2), selector, flags)
idtSetGate(5, cast[uint32](isr5) ,selector, flags) idtSetGate(3, cast[uint32](isr3), selector, flags)
idtSetGate(6, cast[uint32](isr6) ,selector, flags) idtSetGate(4, cast[uint32](isr4), selector, flags)
idtSetGate(7, cast[uint32](isr7) ,selector, flags) idtSetGate(5, cast[uint32](isr5), selector, flags)
idtSetGate(8, cast[uint32](isr8) ,selector, flags) idtSetGate(6, cast[uint32](isr6), selector, flags)
idtSetGate(9, cast[uint32](isr9) ,selector, flags) idtSetGate(7, cast[uint32](isr7), selector, flags)
idtSetGate(10, cast[uint32](isr10) ,selector, flags) idtSetGate(8, cast[uint32](isr8), selector, flags)
idtSetGate(11, cast[uint32](isr11) ,selector, flags) idtSetGate(9, cast[uint32](isr9), selector, flags)
idtSetGate(12, cast[uint32](isr12) ,selector, flags) idtSetGate(10, cast[uint32](isr10), selector, flags)
idtSetGate(13, cast[uint32](isr13) ,selector, flags) idtSetGate(11, cast[uint32](isr11), selector, flags)
idtSetGate(14, cast[uint32](isr14) ,selector, flags) idtSetGate(12, cast[uint32](isr12), selector, flags)
idtSetGate(15, cast[uint32](isr15) ,selector, flags) idtSetGate(13, cast[uint32](isr13), selector, flags)
idtSetGate(16, cast[uint32](isr16) ,selector, flags) idtSetGate(14, cast[uint32](isr14), selector, flags)
idtSetGate(17, cast[uint32](isr17) ,selector, flags) idtSetGate(15, cast[uint32](isr15), selector, flags)
idtSetGate(18, cast[uint32](isr18) ,selector, flags) idtSetGate(16, cast[uint32](isr16), selector, flags)
idtSetGate(19, cast[uint32](isr19) ,selector, flags) idtSetGate(17, cast[uint32](isr17), selector, flags)
idtSetGate(20, cast[uint32](isr20) ,selector, flags) idtSetGate(18, cast[uint32](isr18), selector, flags)
idtSetGate(21, cast[uint32](isr21) ,selector, flags) idtSetGate(19, cast[uint32](isr19), selector, flags)
idtSetGate(22, cast[uint32](isr22) ,selector, flags) idtSetGate(20, cast[uint32](isr20), selector, flags)
idtSetGate(23, cast[uint32](isr23) ,selector, flags) idtSetGate(21, cast[uint32](isr21), selector, flags)
idtSetGate(24, cast[uint32](isr24) ,selector, flags) idtSetGate(22, cast[uint32](isr22), selector, flags)
idtSetGate(25, cast[uint32](isr25) ,selector, flags) idtSetGate(23, cast[uint32](isr23), selector, flags)
idtSetGate(26, cast[uint32](isr26) ,selector, flags) idtSetGate(24, cast[uint32](isr24), selector, flags)
idtSetGate(27, cast[uint32](isr27) ,selector, flags) idtSetGate(25, cast[uint32](isr25), selector, flags)
idtSetGate(28, cast[uint32](isr28) ,selector, flags) idtSetGate(26, cast[uint32](isr26), selector, flags)
idtSetGate(29, cast[uint32](isr29) ,selector, flags) idtSetGate(27, cast[uint32](isr27), selector, flags)
idtSetGate(30, cast[uint32](isr30) ,selector, flags) idtSetGate(28, cast[uint32](isr28), selector, flags)
idtSetGate(31, cast[uint32](isr31) ,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() idtFlush()