xref: /kvm-unit-tests/lib/x86/desc.h (revision 03f37ef20df25a9c90fc9bc9380bb5ebba17bb00)
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