Add some interrupt handling
This commit is contained in:
parent
df8666fd73
commit
7f15ba0ac5
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include <Result.h>
|
||||
|
||||
struct Registers;
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
Result<const char*> identify();
|
||||
|
@ -1,3 +1,9 @@
|
||||
section .data
|
||||
global __divisor
|
||||
__divisor:
|
||||
dd 0
|
||||
|
||||
section .text
|
||||
global enable_sse
|
||||
enable_sse:
|
||||
mov rax, cr0
|
||||
@ -45,4 +51,73 @@ global load_tr
|
||||
load_tr:
|
||||
mov rax, rdi
|
||||
ltr ax
|
||||
ret
|
||||
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
|
@ -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()
|
||||
|
10
kernel/src/arch/x86_64/CPU.h
Normal file
10
kernel/src/arch/x86_64/CPU.h
Normal 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;
|
||||
};
|
@ -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();
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user