1 #ifndef __IDT_TEST__ 2 #define __IDT_TEST__ 3 4 #include <setjmp.h> 5 6 void setup_idt(void); 7 void setup_alt_stack(void); 8 9 struct ex_regs { 10 unsigned long rax, rcx, rdx, rbx; 11 unsigned long dummy, rbp, rsi, rdi; 12 #ifdef __x86_64__ 13 unsigned long r8, r9, r10, r11; 14 unsigned long r12, r13, r14, r15; 15 #endif 16 unsigned long vector; 17 unsigned long error_code; 18 unsigned long rip; 19 unsigned long cs; 20 unsigned long rflags; 21 }; 22 23 typedef struct { 24 u16 prev; 25 u16 res1; 26 u32 esp0; 27 u16 ss0; 28 u16 res2; 29 u32 esp1; 30 u16 ss1; 31 u16 res3; 32 u32 esp2; 33 u16 ss2; 34 u16 res4; 35 u32 cr3; 36 u32 eip; 37 u32 eflags; 38 u32 eax, ecx, edx, ebx, esp, ebp, esi, edi; 39 u16 es; 40 u16 res5; 41 u16 cs; 42 u16 res6; 43 u16 ss; 44 u16 res7; 45 u16 ds; 46 u16 res8; 47 u16 fs; 48 u16 res9; 49 u16 gs; 50 u16 res10; 51 u16 ldt; 52 u16 res11; 53 u16 t:1; 54 u16 res12:15; 55 u16 iomap_base; 56 } tss32_t; 57 58 typedef struct __attribute__((packed)) { 59 u32 res1; 60 u64 rsp0; 61 u64 rsp1; 62 u64 rsp2; 63 u64 res2; 64 u64 ist1; 65 u64 ist2; 66 u64 ist3; 67 u64 ist4; 68 u64 ist5; 69 u64 ist6; 70 u64 ist7; 71 u64 res3; 72 u16 res4; 73 u16 iomap_base; 74 } tss64_t; 75 76 #define ASM_TRY(catch) \ 77 "movl $0, %%gs:4 \n\t" \ 78 ".pushsection .data.ex \n\t" \ 79 ".quad 1111f, " catch "\n\t" \ 80 ".popsection \n\t" \ 81 "1111:" 82 83 #define DB_VECTOR 1 84 #define BP_VECTOR 3 85 #define UD_VECTOR 6 86 #define GP_VECTOR 13 87 88 #define KERNEL_CS 0x08 89 #define KERNEL_DS 0x10 90 #define NP_SEL 0x18 91 #define USER_CS 0x23 92 #define USER_DS 0x2b 93 #ifdef __x86_64__ 94 #define KERNEL_CS64 KERNEL_CS 95 #define KERNEL_DS64 KERNEL_DS 96 #define KERNEL_CS32 0x30 97 #define KERNEL_DS32 0x38 98 #define KERNEL_CS16 0x40 99 #define KERNEL_DS16 0x48 100 #else 101 #define KERNEL_CS32 KERNEL_CS 102 #define KERNEL_DS32 KERNEL_DS 103 #endif 104 #define TSS_INTR 0x50 105 #define FIRST_SPARE_SEL 0x58 106 #define TSS_MAIN 0x80 107 108 typedef struct { 109 unsigned short offset0; 110 unsigned short selector; 111 unsigned short ist : 3; 112 unsigned short : 5; 113 unsigned short type : 4; 114 unsigned short : 1; 115 unsigned short dpl : 2; 116 unsigned short p : 1; 117 unsigned short offset1; 118 #ifdef __x86_64__ 119 unsigned offset2; 120 unsigned reserved; 121 #endif 122 } idt_entry_t; 123 124 typedef struct { 125 u16 limit_low; 126 u16 base_low; 127 u8 base_middle; 128 u8 access; 129 u8 granularity; 130 u8 base_high; 131 } gdt_entry_t; 132 133 extern idt_entry_t boot_idt[256]; 134 135 #ifndef __x86_64__ 136 extern gdt_entry_t gdt32[]; 137 extern tss32_t tss; 138 extern tss32_t tss_intr; 139 void set_gdt_task_gate(u16 tss_sel, u16 sel); 140 void set_idt_task_gate(int vec, u16 sel); 141 void set_intr_task_gate(int vec, void *fn); 142 void setup_tss32(void); 143 #else 144 extern tss64_t tss; 145 #endif 146 147 unsigned exception_vector(void); 148 unsigned exception_error_code(void); 149 bool exception_rflags_rf(void); 150 void set_idt_entry(int vec, void *addr, int dpl); 151 void set_idt_sel(int vec, u16 sel); 152 void set_idt_dpl(int vec, u16 dpl); 153 void set_gdt_entry(int sel, u32 base, u32 limit, u8 access, u8 gran); 154 void set_intr_alt_stack(int e, void *fn); 155 void print_current_tss_info(void); 156 void handle_exception(u8 v, void (*func)(struct ex_regs *regs)); 157 158 bool test_for_exception(unsigned int ex, void (*trigger_func)(void *data), 159 void *data); 160 void __set_exception_jmpbuf(jmp_buf *addr); 161 #define set_exception_jmpbuf(jmpbuf) \ 162 (setjmp(jmpbuf) ? : (__set_exception_jmpbuf(&(jmpbuf)), 0)) 163 164 #endif 165