add basic interrupt support

This commit is contained in:
Quinten Kock 2020-12-14 23:10:58 +01:00
parent 340557f5ab
commit 25262960d9
6 changed files with 111 additions and 1 deletions

View File

@ -4,6 +4,7 @@
#include <arch/x86/stivale2-parse.h>
#include <arch/x86_64/gdt.h>
#include <arch/x86_64/interrupt.h>
#include <print/print.h>
#include <main.h>
@ -46,6 +47,7 @@ void stivale2_main(struct stivale2_struct *info) {
loadgdt();
print_gdt();
asmpanic();
setup_ints();
kmain();
}

View File

@ -0,0 +1,26 @@
#include "idt.h"
struct IDTInfo {
uint16_t size;
uint64_t offset;
} __attribute__((packed));
struct IDTDescr IDT[256];
static struct IDTInfo idt_info;
void set_idt_ent(uint8_t index, uint64_t offset, uint8_t ist, uint8_t min_priv_level, enum GateType type) {
IDT[index].offset_1 = offset & 0xFFFF;
IDT[index].offset_2 = (offset >> 16) & 0xFFFF;
IDT[index].offset_3 = (offset >> 32) & 0xFFFFFFFF;
IDT[index].ist = ist;
IDT[index].selector = 8; // assume for now that it's always in-kernel
IDT[index].zero = 0;
IDT[index].type_attr = type | (min_priv_level << 5) | 0x80;
}
void* get_idt_fn(uint8_t index) {
struct IDTDescr* i = &IDT[index];
return (uintptr_t)( ((uint64_t)i->offset_3 << 32) | ((uint64_t)i->offset_2 << 16) | (uint64_t)i->offset_1);
}
void clear_idt_ent(uint8_t index);

View File

@ -0,0 +1,22 @@
#include <stdint.h>
struct IDTDescr {
uint16_t offset_1; // offset bits 0..15
uint16_t selector; // a code segment selector in GDT or LDT
uint8_t ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero.
uint8_t type_attr; // type and attributes
uint16_t offset_2; // offset bits 16..31
uint32_t offset_3; // offset bits 32..63
uint32_t zero; // reserved
};
enum GateType {
CALL64 = 0xC,
INT64 = 0xE,
TRAP64 = 0xF,
};
void init_idt();
void set_idt_ent(uint8_t index, uint64_t offset, uint8_t ist, uint8_t min_priv_level, enum GateType type);
void* get_idt_fn(uint8_t index);
void clear_idt_ent(uint8_t index);

View File

@ -0,0 +1,20 @@
extern IDT;
section .rodata
align 8
idtpointer:
dw (256*16) - 1
dq IDT
section .text
global init_idt
init_idt:
lidt [idtpointer]
ret
global isr_wrapper
extern interrupt_handler
align 8
isr_wrapper:
call interrupt_handler
iretq

View File

@ -0,0 +1,39 @@
#include <stdint.h>
#include "idt.h"
#include "interrupt.h"
typedef uint64_t uword_t;
extern void isr_wrapper();
struct interrupt_frame
{
uword_t ip;
uword_t cs;
uword_t flags;
uword_t sp;
uword_t ss;
};
void interrupt_handler()
{
printf("interrupted\n");
// panic("ee");
}
void setup_ints() {
set_idt_ent(0x80, (uint64_t)&isr_wrapper, 0, 0, INT64);
init_idt();
typedef void (*MyFunctionType)(void);
MyFunctionType handler_0x80 = get_idt_fn(0x80);
printf("interrupt handler: %x\n", handler_0x80);
// interrupt_handler(0);
__asm__ volatile("int $0x80");
printf("interrupt handled!\n");
}

View File

@ -0,0 +1 @@
void setup_ints();