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 /* 89 * selector 32-bit 64-bit 90 * 0x00 NULL descriptor NULL descriptor 91 * 0x08 ring-0 code segment (32-bit) ring-0 code segment (64-bit) 92 * 0x10 ring-0 data segment (32-bit) ring-0 data segment (32/64-bit) 93 * 0x18 ring-0 code segment (P=0) ring-0 code segment (64-bit, P=0) 94 * 0x20 intr_alt_stack TSS ring-0 code segment (32-bit) 95 * 0x28 ring-0 code segment (16-bit) same 96 * 0x30 ring-0 data segment (16-bit) same 97 * 0x38 (0x3b) ring-3 code segment (32-bit) same 98 * 0x40 (0x43) ring-3 data segment (32-bit) ring-3 data segment (32/64-bit) 99 * 0x48 (0x4b) **unused** ring-3 code segment (64-bit) 100 * 0x50--0x78 free to use for test cases same 101 * 0x80 primary TSS (CPU 0) same 102 * 103 * Note that the same segment can be used for 32-bit and 64-bit data segments 104 * (the L bit is only defined for code segments) 105 * 106 * Selectors 0x08-0x10 and 0x3b-0x4b are set up for use with the SYSCALL 107 * and SYSRET instructions. 108 */ 109 110 #define KERNEL_CS 0x08 111 #define KERNEL_DS 0x10 112 #define NP_SEL 0x18 113 #ifdef __x86_64__ 114 #define KERNEL_CS32 0x20 115 #else 116 #define TSS_INTR 0x20 117 #endif 118 #define KERNEL_CS16 0x28 119 #define KERNEL_DS16 0x30 120 #define USER_CS32 0x3b 121 #define USER_DS 0x43 122 #ifdef __x86_64__ 123 #define USER_CS64 0x4b 124 #endif 125 126 /* Synonyms */ 127 #define KERNEL_DS32 KERNEL_DS 128 #define USER_DS32 USER_DS 129 130 #ifdef __x86_64__ 131 #define KERNEL_CS64 KERNEL_CS 132 #define USER_CS USER_CS64 133 #define KERNEL_DS64 KERNEL_DS 134 #define USER_DS64 USER_DS 135 #else 136 #define KERNEL_CS32 KERNEL_CS 137 #define USER_CS USER_CS32 138 #endif 139 140 #define FIRST_SPARE_SEL 0x50 141 #define TSS_MAIN 0x80 142 143 typedef struct { 144 unsigned short offset0; 145 unsigned short selector; 146 unsigned short ist : 3; 147 unsigned short : 5; 148 unsigned short type : 4; 149 unsigned short : 1; 150 unsigned short dpl : 2; 151 unsigned short p : 1; 152 unsigned short offset1; 153 #ifdef __x86_64__ 154 unsigned offset2; 155 unsigned reserved; 156 #endif 157 } idt_entry_t; 158 159 typedef struct { 160 u16 limit_low; 161 u16 base_low; 162 u8 base_middle; 163 u8 access; 164 u8 granularity; 165 u8 base_high; 166 } gdt_entry_t; 167 168 extern idt_entry_t boot_idt[256]; 169 170 #ifndef __x86_64__ 171 extern gdt_entry_t gdt32[]; 172 extern tss32_t tss; 173 extern tss32_t tss_intr; 174 void set_gdt_task_gate(u16 tss_sel, u16 sel); 175 void set_idt_task_gate(int vec, u16 sel); 176 void set_intr_task_gate(int vec, void *fn); 177 void setup_tss32(void); 178 #else 179 extern tss64_t tss; 180 #endif 181 182 unsigned exception_vector(void); 183 unsigned exception_error_code(void); 184 bool exception_rflags_rf(void); 185 void set_idt_entry(int vec, void *addr, int dpl); 186 void set_idt_sel(int vec, u16 sel); 187 void set_idt_dpl(int vec, u16 dpl); 188 void set_gdt_entry(int sel, u32 base, u32 limit, u8 access, u8 gran); 189 void set_intr_alt_stack(int e, void *fn); 190 void print_current_tss_info(void); 191 void handle_exception(u8 v, void (*func)(struct ex_regs *regs)); 192 193 bool test_for_exception(unsigned int ex, void (*trigger_func)(void *data), 194 void *data); 195 void __set_exception_jmpbuf(jmp_buf *addr); 196 #define set_exception_jmpbuf(jmpbuf) \ 197 (setjmp(jmpbuf) ? : (__set_exception_jmpbuf(&(jmpbuf)), 0)) 198 199 #endif 200