Add some interrupt handling

This commit is contained in:
apio 2022-11-16 17:37:18 +01:00
parent df8666fd73
commit 7f15ba0ac5
7 changed files with 123 additions and 11 deletions

View File

@ -1,6 +1,8 @@
#pragma once
#include <Result.h>
struct Registers;
namespace CPU
{
Result<const char*> identify();

View File

@ -1,3 +1,9 @@
section .data
global __divisor
__divisor:
dd 0
section .text
global enable_sse
enable_sse:
mov rax, cr0
@ -46,3 +52,72 @@ load_tr:
mov rax, rdi
ltr ax
ret
%macro ISR 1
global _isr%1
_isr%1:
push byte 0
push byte %1
jmp _asm_interrupt_entry
%endmacro
%macro ISR_ERROR 1
global _isr%1
_isr%1:
push byte %1
jmp _asm_interrupt_entry
%endmacro
%macro IRQ 2
global _isr%1
_isr%1:
push byte %2
push byte %1
jmp _asm_interrupt_entry
%endmacro
extern arch_interrupt_entry
_asm_interrupt_entry:
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
cld
mov rdi, rsp
call arch_interrupt_entry
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
add rsp, 16
iretq
ISR 0 ; divide by zero

View File

@ -1,4 +1,5 @@
#include "arch/CPU.h"
#include "arch/x86_64/CPU.h"
#include "arch/Serial.h"
#include <String.h>
#include <Types.h>
#include <cpuid.h>
@ -147,7 +148,7 @@ struct IDTR
uint64_t offset;
} __attribute__((packed));
[[maybe_unused]] static void idt_add_handler(short num, void* handler, u8 type_attr)
static void idt_add_handler(short num, void* handler, u8 type_attr)
{
check(handler != nullptr);
check(num < 256);
@ -157,14 +158,38 @@ struct IDTR
entry_for_handler->set_offset((u64)handler);
}
static void setup_idt() // FIXME: Add entries to the IDT.
#define INT(x) extern "C" void _isr##x()
#define TRAP(x) idt_add_handler(x, (void*)_isr##x, IDT_TA_TrapGate)
INT(0);
static void setup_idt()
{
TRAP(0); // divide by zero
static IDTR idtr;
idtr.limit = 0x0FFF;
idtr.offset = (u64)idt;
asm("lidt %0" : : "m"(idtr));
}
// Interrupt handling
// Called from _asm_interrupt_entry
extern "C" void arch_interrupt_entry(Registers* regs)
{
if (regs->isr < 32)
{
Serial::println("Exception catched! Halting.");
CPU::efficient_halt();
}
else
{
Serial::println("IRQ catched! Halting.");
CPU::efficient_halt();
}
}
// Generic CPU code
static bool test_nx()

View File

@ -0,0 +1,10 @@
#include "arch/CPU.h"
#include <Types.h>
struct Registers // Saved CPU registers for x86-64
{
u64 r15, r14, r13, r12, r11, r10, r9, r8;
u64 rbp, rdi, rsi, rdx, rcx, rbx, rax;
u64 isr, error;
u64 rip, cs, rflags, rsp, ss;
};

View File

@ -84,7 +84,11 @@ extern "C" [[noreturn]] void _start()
Serial::println("Successfully unmapped address");
check(false);
extern int __divisor; // divisor is defined as 0, we do it this way so the compiler doesn't catch it (this is
// testing exception handling)
[[maybe_unused]] volatile int div_rc = 4 / __divisor;
Serial::println("ERROR: Still here after division by zero");
CPU::efficient_halt();
}

View File

@ -4,9 +4,7 @@ source $(dirname $0)/env.sh
cd $LUNA_ROOT
SOURCES=($(find kernel/src -type f | grep "\.c") $(find kernel/include -type f))
SOURCES+=($(find libs/libc/src -type f | grep "\.c") $(find libs/libc/include -type f))
SOURCES+=($(find apps/src -type f))
SOURCES=($(find kernel/src -type f | grep -v "\.asm"))
ALL_OK=1

View File

@ -5,9 +5,7 @@ source $(dirname $0)/env.sh
cd $LUNA_ROOT
SOURCES=($(find kernel/src -type f | grep "\.c") $(find kernel/include -type f))
SOURCES+=($(find libs/libc/src -type f | grep "\.c") $(find libs/libc/include -type f))
SOURCES+=($(find apps/src -type f))
SOURCES=($(find kernel/src -type f | grep -v "\.asm"))
for f in ${SOURCES[@]}
do