[Stage1] Add IRQ remapping [Stage1] Handle IRQ0 gracefully [Stage1] Add error output functions
91 lines
No EOL
2.2 KiB
C
91 lines
No EOL
2.2 KiB
C
#include "include/interrupts.h"
|
|
#include "datatypes.h"
|
|
#include "packing.h"
|
|
#include "include/screen.h"
|
|
#include "include/pic_8259.h"
|
|
|
|
OS_PACK_START
|
|
typedef struct __idt_attributes {
|
|
os_u8 gate_type: 4;
|
|
os_u8 empty : 1;
|
|
os_u8 dpl : 2;
|
|
os_u8 present: 1;
|
|
} OS_PACK_MID idt_attributes;
|
|
OS_PACK_END
|
|
|
|
#define IDT_GATE_TYPE_TASK 0x5
|
|
#define IDT_GATE_TYPE_INTERRUPT_16 0x6
|
|
#define IDT_GATE_TYPE_TRAP_16 0x7
|
|
#define IDT_GATE_TYPE_INTERRUPT_32 0xE
|
|
#define IDT_GATE_TYPE_TRAP_32 0xF
|
|
|
|
OS_PACK_START
|
|
typedef struct __idt_entry {
|
|
os_u16 isr_low;
|
|
os_u16 kernel_gdt_code_segment;
|
|
os_u8 reserved;
|
|
idt_attributes attributes;
|
|
//os_u8 attributes;
|
|
os_u16 isr_high;
|
|
} OS_PACK_MID idt_entry;
|
|
OS_PACK_END
|
|
|
|
OS_PACK_START
|
|
typedef struct __idt_ptr {
|
|
os_u16 limit;
|
|
os_u32 base;
|
|
} OS_PACK_MID idt_ptr;
|
|
OS_PACK_END
|
|
|
|
|
|
#define EFFECTIVE_INTERRUPT_AMOUNT 256
|
|
|
|
__attribute__((aligned(0x10)))
|
|
idt_entry main_idt[EFFECTIVE_INTERRUPT_AMOUNT];
|
|
idt_ptr main_idt_ptr;
|
|
volatile void* interrupt_service_list[EFFECTIVE_INTERRUPT_AMOUNT];
|
|
|
|
void generic_exception(os_u32 interrupt_id) {
|
|
//screen_clear();
|
|
screen_set_pos(0, 0);
|
|
screen_write_error("Exception received: ", 0);
|
|
screen_write_number_error(interrupt_id);
|
|
screen_write_string("\n", 0);
|
|
while(1) {
|
|
|
|
}
|
|
}
|
|
|
|
void handle_irq0(os_u32) {
|
|
pic_sendEOI(0);
|
|
}
|
|
|
|
/* The following is defined in interrupt_utils.asm */
|
|
extern void* interrupt_service_table[];
|
|
extern void load_idt();
|
|
/* --- */
|
|
|
|
void setup_interrupts() {
|
|
|
|
main_idt_ptr.base = (os_u32) &main_idt[0];
|
|
main_idt_ptr.limit = ((os_u16) (sizeof(idt_entry) * EFFECTIVE_INTERRUPT_AMOUNT)) - 1;
|
|
for (int i = 0; i < EFFECTIVE_INTERRUPT_AMOUNT; i++) {
|
|
|
|
os_u32 val = (os_u32) interrupt_service_table[i];
|
|
//os_u32 val = (os_u32) &generic_exception;
|
|
main_idt[i].isr_low = (os_u16)(val & 0xFFFF);
|
|
main_idt[i].isr_high = (os_u16)(val >> 16);
|
|
main_idt[i].kernel_gdt_code_segment = 0x08;
|
|
main_idt[i].reserved = 0;
|
|
|
|
main_idt[i].attributes.present = 1;
|
|
main_idt[i].attributes.gate_type = IDT_GATE_TYPE_INTERRUPT_32;
|
|
main_idt[i].attributes.empty = 0;
|
|
main_idt[i].attributes.dpl = i == 0x49 ? 3 : 0;
|
|
|
|
interrupt_service_list[i] = (void*)&generic_exception;
|
|
}
|
|
interrupt_service_list[32] = (void*)&handle_irq0;
|
|
|
|
load_idt();
|
|
} |