diff options
author | Xander <xander@icth.xyz> | 2023-07-07 16:07:49 +0200 |
---|---|---|
committer | Xander <xander@icth.xyz> | 2023-07-07 16:07:49 +0200 |
commit | b14f83f53dfb1f4bf1b5eeb8162891a9aeeaff1c (patch) | |
tree | 402bfe2a7702e29be97ea479aadacdcdcbf6635f | |
parent | cd8a202caac232c7a5b05ad11eb5059d9ad3f002 (diff) | |
download | ats-os-b14f83f53dfb1f4bf1b5eeb8162891a9aeeaff1c.tar.xz ats-os-b14f83f53dfb1f4bf1b5eeb8162891a9aeeaff1c.zip |
Default interrupts
-rw-r--r-- | arch/x86_64/boot/boot.asm | 2 | ||||
-rw-r--r-- | kernel/interrupts/idt.dats | 54 | ||||
-rw-r--r-- | kernel/interrupts/idt.sats | 9 | ||||
-rw-r--r-- | kernel/main.dats | 21 |
4 files changed, 61 insertions, 25 deletions
diff --git a/arch/x86_64/boot/boot.asm b/arch/x86_64/boot/boot.asm index 2e334a8..1abda41 100644 --- a/arch/x86_64/boot/boot.asm +++ b/arch/x86_64/boot/boot.asm @@ -150,7 +150,7 @@ p3_table: p2_table: resb 4096 stack_bottom: - resb 64 + resb 4096 stack_top: section .rodata 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 diff --git a/kernel/main.dats b/kernel/main.dats index 0a325ff..26db859 100644 --- a/kernel/main.dats +++ b/kernel/main.dats @@ -1,6 +1,23 @@ #include "kernel/kernel_prelude.hats" +staload "kernel/interrupts/idt.sats" + +%{^ + void breakpoint(){ + __asm__("int3"); + } +%} + +extern fun breakpoint() :void = "mac#" + implement main0 () = ( - println!("Hello World"); - println!("Hello World"); + println!("Start"); + + // Initialize interrupt table + idt_init(); + + // Throws breakpoint exception + breakpoint(); + + println!("End"); ) |