#ifndef IDT_H #define IDT_H #include #include "gdt.h" #include "isr.h" #define IDT_NB_ENTRIES 34 #define IDT_SIZE (IDT_NB_ENTRIES * sizeof(struct idt_entry)) #define INTEL_DEFINED 21 #define INTEL_UNUSED 31 #define INTERRUPT_TYPE 0x6 #define TRAP_TYPE 0x7 struct idt_entry { uint16_t offset_1 : 16; // 16 lsb of isr address struct segment_selector selector; uint8_t zero_1 : 8; // unused, set to 0 uint8_t type : 3; // gate type uint8_t size : 1; // 0 => 16-bits 1 => 32-bits uint8_t zero_2 : 1; // set to 0 for interrupt and trap gates uint8_t desc_priv : 2; // descriptor privilege uint8_t present : 1; // always 1 uint16_t offset_2 : 16; // 16 msb of isr address } __attribute__ ((packed)); struct idt { struct idt_entry entries[IDT_NB_ENTRIES]; }; struct idt_r { uint16_t limit; // total size of the IDT - 1 in bytes uint32_t addr; // base address of the IDT } __attribute__ ((packed)); // FIXME: This struct is used to get int_code and err_code pushed to the stack // by the isr. We can refactor this by offsetting esp before pushing it. struct int_args { uint32_t int_code; uint32_t err_code; } __attribute__ ((packed)); // This struct is used to know how to fill the idt entries struct idt_entry_info { void (*isr)(void); // function pointer on interrupt service routine (isr) uint32_t type; // gate type }; void init_idt(void); void handle_interrupt(struct int_args *args); #endif /* !IDT_H */