mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-21 23:42:21 +00:00
add interrupts (not yet fully working)
This commit is contained in:
parent
e57c64c0e9
commit
5726080194
5 changed files with 216 additions and 3 deletions
|
@ -117,7 +117,6 @@ start:
|
|||
;push ebx ; Call our function to set up basic paging
|
||||
;call amd64_shim
|
||||
|
||||
|
||||
mov eax, cr4 ; Enable the PAE bit
|
||||
or eax, 1 << 5
|
||||
mov cr4, eax
|
||||
|
@ -139,6 +138,7 @@ code64:
|
|||
pop rdi
|
||||
call amd64_shim
|
||||
mov rdi, rax
|
||||
sti
|
||||
call kmain
|
||||
cli
|
||||
halt:
|
||||
|
|
92
src/arch/amd64/idt.S
Normal file
92
src/arch/amd64/idt.S
Normal file
|
@ -0,0 +1,92 @@
|
|||
extern idt_exception_handler
|
||||
global isr_stub_table
|
||||
|
||||
; call the exception handler with the interrupt number
|
||||
; args: interrupt number
|
||||
%macro ISRException 1
|
||||
align 8
|
||||
isr_stub_%+%1:
|
||||
cld
|
||||
mov rdi, %1
|
||||
mov rsi, 0
|
||||
call idt_exception_handler
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
; call the exception handler with the interrupt number
|
||||
; these exceptions also put an error code on the stack
|
||||
; args: interrupt number
|
||||
%macro ISRExceptionCode 1
|
||||
align 8
|
||||
isr_stub_%+%1:
|
||||
cld
|
||||
mov rdi, %1
|
||||
pop rsi
|
||||
call idt_exception_handler
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
; do nothing
|
||||
; args: interrupt number
|
||||
%macro ISRIgnore 1
|
||||
align 8
|
||||
isr_stub_%+%1:
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
; isr stubs
|
||||
section .text
|
||||
bits 64
|
||||
|
||||
ISRException 0
|
||||
ISRException 1
|
||||
ISRException 2
|
||||
ISRException 3
|
||||
ISRException 4
|
||||
ISRException 5
|
||||
ISRException 6
|
||||
ISRException 7
|
||||
ISRExceptionCode 8
|
||||
ISRException 9
|
||||
ISRExceptionCode 10
|
||||
ISRExceptionCode 11
|
||||
ISRExceptionCode 12
|
||||
ISRExceptionCode 13
|
||||
ISRExceptionCode 14
|
||||
ISRException 15
|
||||
ISRException 16
|
||||
ISRExceptionCode 17
|
||||
ISRException 18
|
||||
ISRException 19
|
||||
ISRException 20
|
||||
ISRExceptionCode 21
|
||||
ISRException 22
|
||||
ISRException 23
|
||||
ISRException 24
|
||||
ISRException 25
|
||||
ISRException 26
|
||||
ISRException 27
|
||||
ISRException 28
|
||||
ISRExceptionCode 29
|
||||
ISRExceptionCode 30
|
||||
ISRException 31
|
||||
|
||||
%assign i 32
|
||||
|
||||
; ignore other interrupts
|
||||
%rep 0x100 - i
|
||||
ISRIgnore i
|
||||
%assign i i+1
|
||||
%endrep
|
||||
|
||||
; isr stub table
|
||||
section .rodata
|
||||
bits 64
|
||||
align 16
|
||||
|
||||
isr_stub_table:
|
||||
%assign i 0
|
||||
%rep 256
|
||||
dq isr_stub_%+i
|
||||
%assign i i+1
|
||||
%endrep
|
118
src/arch/amd64/idt.c
Normal file
118
src/arch/amd64/idt.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <panic.h>
|
||||
#include <lib.h>
|
||||
#include <serial.h>
|
||||
|
||||
#include "idt.h"
|
||||
|
||||
#define IDT_SIZE 256
|
||||
|
||||
struct idt_entry {
|
||||
uint16_t isr_low; // low 16 bits of isr
|
||||
uint16_t kernel_cs; // kernel segment selector
|
||||
uint8_t ist; // interrupt stack table
|
||||
uint8_t flags; // gate type, privilege level, present bit
|
||||
uint16_t isr_mid; // middle 16 bits of isr
|
||||
uint32_t isr_high; // high 32 bits of isr
|
||||
uint32_t reserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idtr {
|
||||
uint16_t size;
|
||||
void *address;
|
||||
} __attribute__((packed));
|
||||
|
||||
// interrupt gate
|
||||
#define GATE_64BIT_INT 0x0E
|
||||
// trap gate
|
||||
#define GATE_64BIT_TRAP 0x0F
|
||||
|
||||
// privilege ring allowed to call interrupt
|
||||
#define RING0 0x00
|
||||
#define RING1 0x20
|
||||
#define RING2 0x40
|
||||
#define RING3 0x60
|
||||
|
||||
// interrupt is present in IDT
|
||||
#define PRESENT 0x80
|
||||
|
||||
__attribute__((aligned(0x10)))
|
||||
static struct idt_entry idt[256];
|
||||
|
||||
static struct idtr idtr;
|
||||
// from idt.S
|
||||
extern void *isr_stub_table[];
|
||||
|
||||
// initialize and load the IDT
|
||||
void idt_init(void) {
|
||||
// initialize idtr
|
||||
idtr.address = &idt;
|
||||
idtr.size = (uint16_t)sizeof(struct idt_entry) * IDT_SIZE - 1;
|
||||
|
||||
// initialize idt
|
||||
for(size_t vector = 0; vector < IDT_SIZE; vector++) {
|
||||
struct idt_entry* entry = &idt[vector];
|
||||
|
||||
uint64_t isr = (uint64_t)isr_stub_table[vector];
|
||||
// interrupts before 0x20 are for cpu exceptions
|
||||
uint8_t gate_type = (vector < 0x20) ? GATE_64BIT_TRAP : GATE_64BIT_INT;
|
||||
|
||||
entry->kernel_cs = 0x08; // offset of 1 into GDT
|
||||
entry->ist = 0;
|
||||
entry->flags = PRESENT | RING0 | gate_type;
|
||||
entry->isr_low = isr & 0xffff;
|
||||
entry->isr_mid = (isr >> 16) & 0xffff;
|
||||
entry->isr_high = isr >> 32;
|
||||
entry->reserved = 0;
|
||||
}
|
||||
|
||||
__asm__ volatile ("lidt %0" : : "m"(idtr));
|
||||
}
|
||||
|
||||
|
||||
// Intel manual vol 3 ch 6.3.1
|
||||
char *EXCEPTIONS[] = {
|
||||
"Exception 0x00 Divide Error",
|
||||
"Exception 0x01 Debug Exception",
|
||||
"Exception 0x02 NMI Interrupt",
|
||||
"Exception 0x03 Breakpoint",
|
||||
"Exception 0x04 Overflow",
|
||||
"Exception 0x05 BOUND Range Exceeded",
|
||||
"Exception 0x06 Invalid Opcode",
|
||||
"Exception 0x07 Device Not Available",
|
||||
"Exception 0x08 Double Fault",
|
||||
"Exception 0x09 Coprocessor Segment Overrun",
|
||||
"Exception 0x0A Invalid TSS",
|
||||
"Exception 0x0B Segment Not Present",
|
||||
"Exception 0x0C Stack-Segment Fault",
|
||||
"Exception 0x0D General Protection",
|
||||
"Exception 0x0E Page Fault",
|
||||
"Exception 0x0F Reserved",
|
||||
"Exception 0x10 x87 FPU Floating-Point Error",
|
||||
"Exception 0x11 Alignment Check",
|
||||
"Exception 0x12 Machine Check",
|
||||
"Exception 0x13 SIMD Floaing-Point Exception",
|
||||
"Exception 0x14 Virtualization Exception",
|
||||
"Exception 0x15 Control Protection Exception",
|
||||
"Exception 0x16 Reserved",
|
||||
"Exception 0x17 Reserved",
|
||||
"Exception 0x18 Reserved",
|
||||
"Exception 0x19 Reserved",
|
||||
"Exception 0x1A Reserved",
|
||||
"Exception 0x1B Reserved",
|
||||
"Exception 0x1C Reserved",
|
||||
"Exception 0x1D Reserved",
|
||||
"Exception 0x1E Reserved",
|
||||
"Exception 0x1F Reserved",
|
||||
};
|
||||
|
||||
void idt_exception_handler(uint64_t exception, uint64_t code) {
|
||||
// TODO don't just panic
|
||||
char buf[80];
|
||||
char *end = strcpy(buf, EXCEPTIONS[exception]);
|
||||
end = strcpy(end, "\nError code 0x");
|
||||
ltoa(code, end, 16);
|
||||
panic(buf);
|
||||
}
|
||||
|
3
src/arch/amd64/idt.h
Normal file
3
src/arch/amd64/idt.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void idt_init();
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
#include "paging.h"
|
||||
#include "mboot.h"
|
||||
|
||||
#include "idt.h"
|
||||
static struct boot_info boot_info;
|
||||
|
||||
// entry point for amd64
|
||||
void* amd64_shim(void *mboot_data_ptr) {
|
||||
serial_init();
|
||||
paging_init();
|
||||
idt_init();
|
||||
|
||||
kmap_page(mboot_data_ptr, mboot_data_ptr, F_WRITEABLE);
|
||||
|
||||
|
|
Loading…
Reference in a new issue