123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- #ifndef __IDT_TEST__
- #define __IDT_TEST__
- #include <setjmp.h>
- void setup_idt(void);
- void setup_alt_stack(void);
- struct ex_regs {
- unsigned long rax, rcx, rdx, rbx;
- unsigned long dummy, rbp, rsi, rdi;
- #ifdef __x86_64__
- unsigned long r8, r9, r10, r11;
- unsigned long r12, r13, r14, r15;
- #endif
- unsigned long vector;
- unsigned long error_code;
- unsigned long rip;
- unsigned long cs;
- unsigned long rflags;
- };
- typedef void (*handler)(struct ex_regs *regs);
- typedef struct {
- u16 prev;
- u16 res1;
- u32 esp0;
- u16 ss0;
- u16 res2;
- u32 esp1;
- u16 ss1;
- u16 res3;
- u32 esp2;
- u16 ss2;
- u16 res4;
- u32 cr3;
- u32 eip;
- u32 eflags;
- u32 eax, ecx, edx, ebx, esp, ebp, esi, edi;
- u16 es;
- u16 res5;
- u16 cs;
- u16 res6;
- u16 ss;
- u16 res7;
- u16 ds;
- u16 res8;
- u16 fs;
- u16 res9;
- u16 gs;
- u16 res10;
- u16 ldt;
- u16 res11;
- u16 t:1;
- u16 res12:15;
- u16 iomap_base;
- } tss32_t;
- typedef struct __attribute__((packed)) {
- u32 res1;
- u64 rsp0;
- u64 rsp1;
- u64 rsp2;
- u64 res2;
- u64 ist1;
- u64 ist2;
- u64 ist3;
- u64 ist4;
- u64 ist5;
- u64 ist6;
- u64 ist7;
- u64 res3;
- u16 res4;
- u16 iomap_base;
- } tss64_t;
- #define ASM_TRY(catch) \
- "movl $0, %%gs:4 \n\t" \
- ".pushsection .data.ex \n\t" \
- ".quad 1111f, " catch "\n\t" \
- ".popsection \n\t" \
- "1111:"
- #define DB_VECTOR 1
- #define BP_VECTOR 3
- #define UD_VECTOR 6
- #define GP_VECTOR 13
- /*
- * selector 32-bit 64-bit
- * 0x00 NULL descriptor NULL descriptor
- * 0x08 ring-0 code segment (32-bit) ring-0 code segment (64-bit)
- * 0x10 ring-0 data segment (32-bit) ring-0 data segment (32/64-bit)
- * 0x18 ring-0 code segment (P=0) ring-0 code segment (64-bit, P=0)
- * 0x20 intr_alt_stack TSS ring-0 code segment (32-bit)
- * 0x28 ring-0 code segment (16-bit) same
- * 0x30 ring-0 data segment (16-bit) same
- * 0x38 (0x3b) ring-3 code segment (32-bit) same
- * 0x40 (0x43) ring-3 data segment (32-bit) ring-3 data segment (32/64-bit)
- * 0x48 (0x4b) **unused** ring-3 code segment (64-bit)
- * 0x50--0x78 free to use for test cases same
- * 0x80 primary TSS (CPU 0) same
- *
- * Note that the same segment can be used for 32-bit and 64-bit data segments
- * (the L bit is only defined for code segments)
- *
- * Selectors 0x08-0x10 and 0x3b-0x4b are set up for use with the SYSCALL
- * and SYSRET instructions.
- */
- #define KERNEL_CS 0x08
- #define KERNEL_DS 0x10
- #define NP_SEL 0x18
- #ifdef __x86_64__
- #define KERNEL_CS32 0x20
- #else
- #define TSS_INTR 0x20
- #endif
- #define KERNEL_CS16 0x28
- #define KERNEL_DS16 0x30
- #define USER_CS32 0x3b
- #define USER_DS 0x43
- #ifdef __x86_64__
- #define USER_CS64 0x4b
- #endif
- /* Synonyms */
- #define KERNEL_DS32 KERNEL_DS
- #define USER_DS32 USER_DS
- #ifdef __x86_64__
- #define KERNEL_CS64 KERNEL_CS
- #define USER_CS USER_CS64
- #define KERNEL_DS64 KERNEL_DS
- #define USER_DS64 USER_DS
- #else
- #define KERNEL_CS32 KERNEL_CS
- #define USER_CS USER_CS32
- #endif
- #define FIRST_SPARE_SEL 0x50
- #define TSS_MAIN 0x80
- typedef struct {
- unsigned short offset0;
- unsigned short selector;
- unsigned short ist : 3;
- unsigned short : 5;
- unsigned short type : 4;
- unsigned short : 1;
- unsigned short dpl : 2;
- unsigned short p : 1;
- unsigned short offset1;
- #ifdef __x86_64__
- unsigned offset2;
- unsigned reserved;
- #endif
- } idt_entry_t;
- typedef struct {
- u16 limit_low;
- u16 base_low;
- u8 base_middle;
- u8 access;
- u8 granularity;
- u8 base_high;
- } gdt_entry_t;
- extern idt_entry_t boot_idt[256];
- #ifndef __x86_64__
- extern gdt_entry_t gdt32[];
- extern tss32_t tss;
- extern tss32_t tss_intr;
- void set_gdt_task_gate(u16 tss_sel, u16 sel);
- void set_idt_task_gate(int vec, u16 sel);
- void set_intr_task_gate(int vec, void *fn);
- void setup_tss32(void);
- #else
- extern tss64_t tss;
- #endif
- unsigned exception_vector(void);
- unsigned exception_error_code(void);
- bool exception_rflags_rf(void);
- void set_idt_entry(int vec, void *addr, int dpl);
- void set_idt_sel(int vec, u16 sel);
- void set_idt_dpl(int vec, u16 dpl);
- void set_gdt_entry(int sel, u32 base, u32 limit, u8 access, u8 gran);
- void set_intr_alt_stack(int e, void *fn);
- void print_current_tss_info(void);
- handler handle_exception(u8 v, handler fn);
- bool test_for_exception(unsigned int ex, void (*trigger_func)(void *data),
- void *data);
- void __set_exception_jmpbuf(jmp_buf *addr);
- #define set_exception_jmpbuf(jmpbuf) \
- (setjmp(jmpbuf) ? : (__set_exception_jmpbuf(&(jmpbuf)), 0))
- #endif
|