mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-22 00:12:18 +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
|
;push ebx ; Call our function to set up basic paging
|
||||||
;call amd64_shim
|
;call amd64_shim
|
||||||
|
|
||||||
|
|
||||||
mov eax, cr4 ; Enable the PAE bit
|
mov eax, cr4 ; Enable the PAE bit
|
||||||
or eax, 1 << 5
|
or eax, 1 << 5
|
||||||
mov cr4, eax
|
mov cr4, eax
|
||||||
|
@ -139,6 +138,7 @@ code64:
|
||||||
pop rdi
|
pop rdi
|
||||||
call amd64_shim
|
call amd64_shim
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
|
sti
|
||||||
call kmain
|
call kmain
|
||||||
cli
|
cli
|
||||||
halt:
|
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 "paging.h"
|
||||||
#include "mboot.h"
|
#include "mboot.h"
|
||||||
|
#include "idt.h"
|
||||||
static struct boot_info boot_info;
|
static struct boot_info boot_info;
|
||||||
|
|
||||||
// entry point for amd64
|
|
||||||
void* amd64_shim(void *mboot_data_ptr) {
|
void* amd64_shim(void *mboot_data_ptr) {
|
||||||
serial_init();
|
serial_init();
|
||||||
paging_init();
|
paging_init();
|
||||||
|
idt_init();
|
||||||
|
|
||||||
kmap_page(mboot_data_ptr, mboot_data_ptr, F_WRITEABLE);
|
kmap_page(mboot_data_ptr, mboot_data_ptr, F_WRITEABLE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue