117 lines
3.3 KiB
C
117 lines
3.3 KiB
C
struct idt_entry_struct
|
|
{
|
|
uint16_t base_lo; // The lower 16 bits of the ISR's address
|
|
uint16_t sel; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
|
uint8_t always0; // Always set to zero
|
|
uint8_t flags; // Type and attributes
|
|
uint16_t base_hi; // The higher 16 bits of the ISR's address
|
|
} __attribute__((packed));
|
|
typedef struct idt_entry_struct idt_entry_t;
|
|
|
|
struct idt_ptr_struct {
|
|
uint16_t limit;
|
|
uint32_t base;
|
|
} __attribute__((packed));
|
|
typedef struct idt_ptr_struct idt_ptr_t;
|
|
|
|
idt_entry_t idt_entries[256];
|
|
idt_ptr_t idt_ptr;
|
|
|
|
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
|
|
idt_entries[num].base_lo = base & 0xFFFF;
|
|
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
|
|
|
|
idt_entries[num].sel = sel;
|
|
idt_entries[num].always0 = 0;
|
|
|
|
idt_entries[num].flags = flags;
|
|
}
|
|
|
|
void idt_init(void);
|
|
void idt_init() {
|
|
idt_ptr.base = (uintptr_t)&idt_entries;
|
|
idt_ptr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1;
|
|
|
|
memset(&idt_entries, 0, sizeof(idt_entry_t)*256);
|
|
|
|
extern isr0;
|
|
extern isr1;
|
|
extern isr2;
|
|
extern isr3;
|
|
extern isr4;
|
|
extern isr5;
|
|
extern isr6;
|
|
extern isr7;
|
|
extern isr8;
|
|
extern isr9;
|
|
extern isr10;
|
|
extern isr11;
|
|
extern isr12;
|
|
extern isr13;
|
|
extern isr14;
|
|
extern isr15;
|
|
extern isr16;
|
|
extern isr17;
|
|
extern isr18;
|
|
extern isr19;
|
|
extern isr20;
|
|
extern isr21;
|
|
extern isr22;
|
|
extern isr23;
|
|
extern isr24;
|
|
extern isr25;
|
|
extern isr26;
|
|
extern isr27;
|
|
extern isr28;
|
|
extern isr29;
|
|
extern isr30;
|
|
extern isr31;
|
|
|
|
idt_set_gate(0, (uint32_t)isr0, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr1, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr2, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr3, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr4, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr5, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr6, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr7, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr8, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr9, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr10, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr11, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr12, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr13, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr14, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr15, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr16, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr17, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr18, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr19, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr20, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr21, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr22, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr23, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr24, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr25, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr26, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr27, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr28, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr29, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr30, 0x08, 0x8E);
|
|
idt_set_gate(0, (uint32_t)isr31, 0x08, 0x8E);
|
|
|
|
|
|
//__asm__ volatile ("lidt %0" : : "memory"(idt_ptr)); // load the new IDT
|
|
//__asm__ volatile ("sti"); // set the interrupt flag
|
|
|
|
extern void idt_flush(uint32);
|
|
idt_flush((uint32_t)&idt_ptr);
|
|
|
|
}
|
|
|
|
void isr_handler()
|
|
{
|
|
serial_printf("Received interrupt\n");
|
|
}
|
|
|