diff options
Diffstat (limited to 'kernel/interrupts/idt.dats')
-rw-r--r-- | kernel/interrupts/idt.dats | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/kernel/interrupts/idt.dats b/kernel/interrupts/idt.dats index 380260a..fa141f6 100644 --- a/kernel/interrupts/idt.dats +++ b/kernel/interrupts/idt.dats @@ -4,11 +4,7 @@ staload "./idt.sats" -extern castfn i2u8 {n: nat} (i: int n): uint8 n -extern castfn i2u16 {n: nat} (i: int n): uint16 n -extern castfn i2u32 {n: nat} (i: int n): uint32 n -extern castfn i2u64 {n: nat} (i: int n): uint64 n -extern castfn i2u {n: int} (i: uint8 n): int n +staload UN = "prelude/SATS/unsafe.sats" %{ __attribute__ ((interrupt)) @@ -16,10 +12,9 @@ extern castfn i2u {n: int} (i: uint8 n): int n // Default exception handler fun default_exception_handler(frame: &int_frame) : void = let in - println!("DEFAULT EXCEPTION HANDLER - NO ERROR CODE") + println!("DEFAULT EXCEPTION HANDLER - NO ERROR CODE"); end - %{ __attribute__ ((interrupt)) %} @@ -32,21 +27,44 @@ end var idt : @[idt_entry_t][256] // The table var idtr : idtr_t // interrupt descriptor table register instance -fun idt_set_descriptor {l : agz} {n : nat | n < 256} (vector: uint8 n, isr: ptr l, flags: uint8) : void = let +fun idt_set_descriptor {l:addr} {n : nat | n < 256} (vector: int n, isr: (&int_frame) -> void, flags: uint8) : void = let extern praxi __assert{l:addr} (ptr: ptr (l)): vtakeout0 (@[idt_entry_t][256]@l) prval (pf, fpf) = __assert (addr@(idt)) - val t = @{ - isr_low = i2u16(0), - kernel_cs = i2u16(0) , - ist = i2u8(0), - attributes = i2u8(0) , - isr_mid = i2u16(0), - isr_high = i2u32(0), - reserved = i2u32(0) + val x = $UN.cast{uint64}(0xFFFF) + val y = $UN.cast{uint64}(0xFFFFFFF) + val entry = @{ + isr_low = $UN.cast($UN.cast{uint64}(isr) land x), + kernel_cs = $UN.cast(0x08), + ist = $UN.cast(0), + attributes = flags, + isr_mid = $UN.cast(($UN.cast{uint64}(isr) >> 16) land x), + isr_high = $UN.cast(($UN.cast{uint64}(isr) >> 32) land y), + reserved = $UN.cast(0) } in - idt[i2u(vector)] := t; + idt[vector] := entry; let prval () = fpf(pf) in end end -implement idt_init() : void = let in end +extern typedef "idtr_t" = idtr_t +%{$ + void setup(idtr_t idtr) { + __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT + } +%} + +extern fun setup(idtr : idtr_t) : void = "ext#" + +implement idt_init() : void = let + extern praxi __assert{l:addr} (ptr: ptr (l)): vtakeout0 (idtr_t@l) + prval (pf, fpf) = __assert (addr@(idtr)) + fun loop {n : nat | n <= 32} (i : int n) : void = if (i < 32) then (idt_set_descriptor(i,default_exception_handler,$UN.cast(TRAP_GATE_FLAGS)); loop(i + 1)) +in + idtr.base := addr@(idt); + idtr.limit := $UN.cast{uint16}(8 * 256); + loop(0); + setup(idtr); + let prval () = fpf(pf) in end +end + + |