add basic interrupt support
This commit is contained in:
parent
340557f5ab
commit
25262960d9
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
void setup_ints();
|
||||
Loading…
Reference in New Issue