Add some interrupt handling
This commit is contained in:
parent
df8666fd73
commit
7f15ba0ac5
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Result.h>
|
#include <Result.h>
|
||||||
|
|
||||||
|
struct Registers;
|
||||||
|
|
||||||
namespace CPU
|
namespace CPU
|
||||||
{
|
{
|
||||||
Result<const char*> identify();
|
Result<const char*> identify();
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
section .data
|
||||||
|
global __divisor
|
||||||
|
__divisor:
|
||||||
|
dd 0
|
||||||
|
|
||||||
|
section .text
|
||||||
global enable_sse
|
global enable_sse
|
||||||
enable_sse:
|
enable_sse:
|
||||||
mov rax, cr0
|
mov rax, cr0
|
||||||
@ -45,4 +51,73 @@ global load_tr
|
|||||||
load_tr:
|
load_tr:
|
||||||
mov rax, rdi
|
mov rax, rdi
|
||||||
ltr ax
|
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 <String.h>
|
||||||
#include <Types.h>
|
#include <Types.h>
|
||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
@ -147,7 +148,7 @@ struct IDTR
|
|||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
} __attribute__((packed));
|
} __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(handler != nullptr);
|
||||||
check(num < 256);
|
check(num < 256);
|
||||||
@ -157,14 +158,38 @@ struct IDTR
|
|||||||
entry_for_handler->set_offset((u64)handler);
|
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;
|
static IDTR idtr;
|
||||||
idtr.limit = 0x0FFF;
|
idtr.limit = 0x0FFF;
|
||||||
idtr.offset = (u64)idt;
|
idtr.offset = (u64)idt;
|
||||||
asm("lidt %0" : : "m"(idtr));
|
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
|
// Generic CPU code
|
||||||
|
|
||||||
static bool test_nx()
|
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");
|
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();
|
CPU::efficient_halt();
|
||||||
}
|
}
|
@ -4,9 +4,7 @@ source $(dirname $0)/env.sh
|
|||||||
|
|
||||||
cd $LUNA_ROOT
|
cd $LUNA_ROOT
|
||||||
|
|
||||||
SOURCES=($(find kernel/src -type f | grep "\.c") $(find kernel/include -type f))
|
SOURCES=($(find kernel/src -type f | grep -v "\.asm"))
|
||||||
SOURCES+=($(find libs/libc/src -type f | grep "\.c") $(find libs/libc/include -type f))
|
|
||||||
SOURCES+=($(find apps/src -type f))
|
|
||||||
|
|
||||||
ALL_OK=1
|
ALL_OK=1
|
||||||
|
|
||||||
|
@ -5,9 +5,7 @@ source $(dirname $0)/env.sh
|
|||||||
|
|
||||||
cd $LUNA_ROOT
|
cd $LUNA_ROOT
|
||||||
|
|
||||||
SOURCES=($(find kernel/src -type f | grep "\.c") $(find kernel/include -type f))
|
SOURCES=($(find kernel/src -type f | grep -v "\.asm"))
|
||||||
SOURCES+=($(find libs/libc/src -type f | grep "\.c") $(find libs/libc/include -type f))
|
|
||||||
SOURCES+=($(find apps/src -type f))
|
|
||||||
|
|
||||||
for f in ${SOURCES[@]}
|
for f in ${SOURCES[@]}
|
||||||
do
|
do
|
||||||
|
Loading…
Reference in New Issue
Block a user