From b14f83f53dfb1f4bf1b5eeb8162891a9aeeaff1c Mon Sep 17 00:00:00 2001 From: Xander Date: Fri, 7 Jul 2023 16:07:49 +0200 Subject: Default interrupts --- kernel/interrupts/idt.dats | 54 ++++++++++++++++++++++++++++++---------------- kernel/interrupts/idt.sats | 9 ++++---- 2 files changed, 41 insertions(+), 22 deletions(-) (limited to 'kernel/interrupts') 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 + + diff --git a/kernel/interrupts/idt.sats b/kernel/interrupts/idt.sats index d8391aa..ce40cd8 100644 --- a/kernel/interrupts/idt.sats +++ b/kernel/interrupts/idt.sats @@ -1,20 +1,21 @@ - #define TRAP_GATE_FLAGS 0x8F // p=1, dpl=0b00, type=0b1111 +#define +INT_GATE_FLAGS 0x8E // p=1, dpl=0b00, type=0b1110 typedef idt_entry_t = @{ isr_low = uint16, // The lower 16 bits of the ISR's address kernel_cs = uint16, // The GDT segment selector that the CPU will load into CS before calling the ISR - ist = uint8, // The IST in the TSS that the CPU will load into RSP; set to zero for now + ist = uint8 0, // The IST in the TSS that the CPU will load into RSP; set to zero for now attributes = uint8, // Type and attributes; see the IDT page isr_mid = uint16, // The higher 16 bits of the lower 32 bits of the ISR's address isr_high = uint32, // The higher 32 bits of the ISR's address - reserved = uint32 // Set to zero + reserved = uint32 0 // Set to zero } typedef idtr_t = @{ limit = uint16, - base = uint64 + base = [l : addr] ptr l } // Interrupt frame to pass to ISR -- cgit v1.2.3