Xen Test Framework
lib.h
Go to the documentation of this file.
1 #ifndef XTF_X86_LIB_H
2 #define XTF_X86_LIB_H
3 
4 #include <xtf/types.h>
5 #include <xtf/extable.h>
6 #include <xen/arch-x86/xen.h>
7 #include <arch/desc.h>
8 #include <arch/msr.h>
9 
10 static inline void cpuid(uint32_t leaf,
11  uint32_t *eax, uint32_t *ebx,
12  uint32_t *ecx, uint32_t *edx)
13 {
14  asm volatile ("cpuid"
15  : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
16  : "0" (leaf));
17 }
18 
19 static inline uint32_t cpuid_eax(uint32_t leaf)
20 {
21  uint32_t eax, tmp;
22 
23  cpuid(leaf, &eax, &tmp, &tmp, &tmp);
24 
25  return eax;
26 }
27 
28 static inline uint32_t cpuid_ebx(uint32_t leaf)
29 {
30  uint32_t ebx, tmp;
31 
32  cpuid(leaf, &tmp, &ebx, &tmp, &tmp);
33 
34  return ebx;
35 }
36 
37 static inline uint32_t cpuid_ecx(uint32_t leaf)
38 {
39  uint32_t ecx, tmp;
40 
41  cpuid(leaf, &tmp, &tmp, &ecx, &tmp);
42 
43  return ecx;
44 }
45 
46 static inline uint32_t cpuid_edx(uint32_t leaf)
47 {
48  uint32_t edx, tmp;
49 
50  cpuid(leaf, &tmp, &tmp, &tmp, &edx);
51 
52  return edx;
53 }
54 
55 static inline void pv_cpuid(uint32_t leaf,
56  uint32_t *eax, uint32_t *ebx,
57  uint32_t *ecx, uint32_t *edx)
58 {
59  asm volatile (_ASM_XEN_FEP "cpuid"
60  : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
61  : "0" (leaf));
62 }
63 
64 static inline void cpuid_count(uint32_t leaf, uint32_t subleaf,
65  uint32_t *eax, uint32_t *ebx,
66  uint32_t *ecx, uint32_t *edx)
67 {
68  asm volatile ("cpuid"
69  : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
70  : "0" (leaf), "2" (subleaf));
71 }
72 
73 static inline void pv_cpuid_count(uint32_t leaf, uint32_t subleaf,
74  uint32_t *eax, uint32_t *ebx,
75  uint32_t *ecx, uint32_t *edx)
76 {
77  asm volatile (_ASM_XEN_FEP "cpuid"
78  : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
79  : "0" (leaf), "2" (subleaf));
80 }
81 
82 static inline uint8_t inb(uint16_t port)
83 {
84  uint8_t val;
85 
86  asm volatile("inb %w1, %b0": "=a" (val): "Nd" (port));
87 
88  return val;
89 }
90 
91 static inline uint16_t inw(uint16_t port)
92 {
93  uint16_t val;
94 
95  asm volatile("inw %w1, %w0": "=a" (val): "Nd" (port));
96 
97  return val;
98 }
99 
100 static inline uint32_t inl(uint16_t port)
101 {
102  uint32_t val;
103 
104  asm volatile("inl %w1, %k0": "=a" (val): "Nd" (port));
105 
106  return val;
107 }
108 
109 static inline void outb(uint8_t val, uint16_t port)
110 {
111  asm volatile("outb %b0, %w1": : "a" (val), "Nd" (port));
112 }
113 
114 static inline void outw(uint16_t val, uint16_t port)
115 {
116  asm volatile("outw %w0, %w1": : "a" (val), "Nd" (port));
117 }
118 
119 static inline void outl(uint32_t val, uint16_t port)
120 {
121  asm volatile("outl %k0, %w1": : "a" (val), "Nd" (port));
122 }
123 
124 static inline unsigned int read_cs(void)
125 {
126  unsigned int cs;
127 
128  asm volatile ("mov %%cs, %0" : "=rm" (cs));
129 
130  return cs;
131 }
132 
133 static inline unsigned int read_ds(void)
134 {
135  unsigned int ds;
136 
137  asm volatile ("mov %%ds, %0" : "=rm" (ds));
138 
139  return ds;
140 }
141 
142 static inline unsigned int read_es(void)
143 {
144  unsigned int es;
145 
146  asm volatile ("mov %%es, %0" : "=rm" (es));
147 
148  return es;
149 }
150 
151 static inline unsigned int read_fs(void)
152 {
153  unsigned int fs;
154 
155  asm volatile ("mov %%fs, %0" : "=rm" (fs));
156 
157  return fs;
158 }
159 
160 static inline unsigned int read_gs(void)
161 {
162  unsigned int gs;
163 
164  asm volatile ("mov %%gs, %0" : "=rm" (gs));
165 
166  return gs;
167 }
168 
169 static inline unsigned int read_ss(void)
170 {
171  unsigned int ss;
172 
173  asm volatile ("mov %%ss, %0" : "=rm" (ss));
174 
175  return ss;
176 }
177 
178 static inline void write_cs(unsigned long cs)
179 {
180  asm volatile ("push %0;"
181  "push $1f;"
182  __ASM_SEL(lretl, lretq) "; 1:"
183  :: "rme" (cs));
184 }
185 
186 static inline void write_ds(unsigned int ds)
187 {
188  asm volatile ("mov %0, %%ds" :: "rm" (ds));
189 }
190 
191 static inline void write_es(unsigned int es)
192 {
193  asm volatile ("mov %0, %%es" :: "rm" (es));
194 }
195 
196 static inline void write_fs(unsigned int fs)
197 {
198  asm volatile ("mov %0, %%fs" :: "rm" (fs));
199 }
200 
201 static inline void write_gs(unsigned int gs)
202 {
203  asm volatile ("mov %0, %%gs" :: "rm" (gs));
204 }
205 
206 static inline void write_ss(unsigned int ss)
207 {
208  asm volatile ("mov %0, %%ss" :: "rm" (ss));
209 }
210 
211 static inline unsigned long read_flags(void)
212 {
213  unsigned long flags;
214 
215  asm volatile ("pushf; pop %0" : "=rm" (flags));
216 
217  return flags;
218 }
219 
220 static inline void write_flags(unsigned long flags)
221 {
222  asm volatile ("push %0; popf" :: "rme" (flags));
223 }
224 
225 static inline unsigned long read_cr0(void)
226 {
227  unsigned long cr0;
228 
229  asm volatile ("mov %%cr0, %0" : "=r" (cr0));
230 
231  return cr0;
232 }
233 
234 static inline unsigned long read_cr2(void)
235 {
236  unsigned long cr2;
237 
238  asm volatile ("mov %%cr2, %0" : "=r" (cr2));
239 
240  return cr2;
241 }
242 
243 static inline unsigned long read_cr3(void)
244 {
245  unsigned long cr3;
246 
247  asm volatile ("mov %%cr3, %0" : "=r" (cr3));
248 
249  return cr3;
250 }
251 
252 static inline unsigned long read_cr4(void)
253 {
254  unsigned long cr4;
255 
256  asm volatile ("mov %%cr4, %0" : "=r" (cr4));
257 
258  return cr4;
259 }
260 
261 static inline unsigned long read_cr8(void)
262 {
263  unsigned long cr8;
264 
265  asm volatile ("mov %%cr8, %0" : "=r" (cr8));
266 
267  return cr8;
268 }
269 
270 static inline void write_cr0(unsigned long cr0)
271 {
272  asm volatile ("mov %0, %%cr0" :: "r" (cr0));
273 }
274 
275 static inline void write_cr2(unsigned long cr2)
276 {
277  asm volatile ("mov %0, %%cr2" :: "r" (cr2));
278 }
279 
280 static inline void write_cr3(unsigned long cr3)
281 {
282  asm volatile ("mov %0, %%cr3" :: "r" (cr3));
283 }
284 
285 static inline void write_cr4(unsigned long cr4)
286 {
287  asm volatile ("mov %0, %%cr4" :: "r" (cr4));
288 }
289 
290 static inline bool write_cr4_safe(unsigned long cr4)
291 {
292  exinfo_t fault = 0;
293 
294  asm volatile ("1: mov %[cr4], %%cr4; 2:"
295  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
296  : "+D" (fault)
297  : [cr4] "r" (cr4),
298  [rec] "p" (ex_record_fault_edi));
299 
300  return fault;
301 }
302 
303 static inline void write_cr8(unsigned long cr8)
304 {
305  asm volatile ("mov %0, %%cr8" :: "r" (cr8));
306 }
307 
308 static inline uint32_t read_mxcsr(void)
309 {
310  uint32_t mxcsr;
311 
312  asm volatile ("stmxcsr %0" : "=m" (mxcsr));
313 
314  return mxcsr;
315 }
316 
317 static inline void write_mxcsr(uint32_t mxcsr)
318 {
319  asm volatile ("ldmxcsr %0" :: "m" (mxcsr));
320 }
321 
322 static inline void invlpg(const void *va)
323 {
324  asm volatile ("invlpg (%0)" :: "r" (va));
325 }
326 
327 static inline void lgdt(const desc_ptr *gdtr)
328 {
329  asm volatile ("lgdt %0" :: "m" (*gdtr));
330 }
331 
332 static inline void lidt(const desc_ptr *idtr)
333 {
334  asm volatile ("lidt %0" :: "m" (*idtr));
335 }
336 
337 static inline void lldt(unsigned int sel)
338 {
339  asm volatile ("lldt %w0" :: "rm" (sel));
340 }
341 
342 static inline void ltr(unsigned int sel)
343 {
344  asm volatile ("ltr %w0" :: "rm" (sel));
345 }
346 
347 static inline void sgdt(desc_ptr *gdtr)
348 {
349  asm volatile ("sgdt %0" : "=m" (*gdtr));
350 }
351 
352 static inline void sidt(desc_ptr *idtr)
353 {
354  asm volatile ("sidt %0" : "=m" (*idtr));
355 }
356 
357 static inline unsigned int sldt(void)
358 {
359  unsigned int sel;
360 
361  asm volatile ("sldt %0" : "=r" (sel));
362 
363  return sel;
364 }
365 
366 static inline unsigned int str(void)
367 {
368  unsigned int sel;
369 
370  asm volatile ("str %0" : "=r" (sel));
371 
372  return sel;
373 }
374 
375 static inline uint64_t xgetbv(uint32_t index)
376 {
377  uint32_t feat_lo, feat_hi;
378 
379  asm volatile ("xgetbv" : "=a" (feat_lo), "=d" (feat_hi)
380  : "c" (index) );
381 
382  return feat_lo | ((uint64_t)feat_hi << 32);
383 }
384 
385 static inline void xsetbv(uint32_t index, uint64_t value)
386 {
387  asm volatile ("xsetbv" :: "a" ((uint32_t)value),
388  "d" ((uint32_t)(value >> 32)),
389  "c" (index) );
390 }
391 
392 static inline uint64_t read_xcr0(void)
393 {
394  return xgetbv(0);
395 }
396 
397 static inline void write_xcr0(uint64_t xcr0)
398 {
399  xsetbv(0, xcr0);
400 }
401 
402 static inline void clflush(const void *ptr)
403 {
404  asm volatile ("clflush %0" :: "m" (*(const char *)ptr));
405 }
406 
407 static inline void flush_tlb(void)
408 {
409  write_cr3(read_cr3());
410 }
411 
412 #endif /* XTF_X86_LIB_H */
413 
414 /*
415  * Local variables:
416  * mode: C
417  * c-file-style: "BSD"
418  * c-basic-offset: 4
419  * tab-width: 4
420  * indent-tabs-mode: nil
421  * End:
422  */
static void outw(uint16_t val, uint16_t port)
Definition: lib.h:114
static unsigned long read_cr8(void)
Definition: lib.h:261
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
#define _ASM_XEN_FEP
Xen Forced Emulation Prefix.
Definition: xen.h:150
static uint32_t cpuid_ecx(uint32_t leaf)
Definition: lib.h:37
static unsigned int read_cs(void)
Definition: lib.h:124
Common declarations for all tests.
static void clflush(const void *ptr)
Definition: lib.h:402
static void lidt(const desc_ptr *idtr)
Definition: lib.h:332
Exception table support.
x86 segment descriptor infrastructure.
static void lgdt(const desc_ptr *gdtr)
Definition: lib.h:327
bool ex_record_fault_edi(struct cpu_regs *regs, const struct extable_entry *ex)
Record the current fault in %edi.
Definition: extable.c:16
static void cpuid_count(uint32_t leaf, uint32_t subleaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Definition: lib.h:64
static void lldt(unsigned int sel)
Definition: lib.h:337
static void pv_cpuid_count(uint32_t leaf, uint32_t subleaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Definition: lib.h:73
static void sidt(desc_ptr *idtr)
Definition: lib.h:352
static unsigned int sldt(void)
Definition: lib.h:357
static void outl(uint32_t val, uint16_t port)
Definition: lib.h:119
static uint64_t read_xcr0(void)
Definition: lib.h:392
static void write_xcr0(uint64_t xcr0)
Definition: lib.h:397
static uint32_t cpuid_eax(uint32_t leaf)
Definition: lib.h:19
static uint32_t read_mxcsr(void)
Definition: lib.h:308
static void flush_tlb(void)
Definition: lib.h:407
static void write_mxcsr(uint32_t mxcsr)
Definition: lib.h:317
static void write_gs(unsigned int gs)
Definition: lib.h:201
static void sgdt(desc_ptr *gdtr)
Definition: lib.h:347
static unsigned int read_es(void)
Definition: lib.h:142
static void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Definition: lib.h:10
static unsigned long read_cr2(void)
Definition: lib.h:234
static void ltr(unsigned int sel)
Definition: lib.h:342
static unsigned long read_cr3(void)
Definition: lib.h:243
static uint16_t inw(uint16_t port)
Definition: lib.h:91
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
static void invlpg(const void *va)
Definition: lib.h:322
static void outb(uint8_t val, uint16_t port)
Definition: lib.h:109
static unsigned int read_ds(void)
Definition: lib.h:133
static unsigned int str(void)
Definition: lib.h:366
static void write_ds(unsigned int ds)
Definition: lib.h:186
static void xsetbv(uint32_t index, uint64_t value)
Definition: lib.h:385
static void write_es(unsigned int es)
Definition: lib.h:191
static void write_cr2(unsigned long cr2)
Definition: lib.h:275
static unsigned long read_cr4(void)
Definition: lib.h:252
__UINT32_TYPE__ uint32_t
Definition: stdint.h:16
static void write_flags(unsigned long flags)
Definition: lib.h:220
static unsigned long read_flags(void)
Definition: lib.h:211
static void write_cr0(unsigned long cr0)
Definition: lib.h:270
static uint32_t cpuid_edx(uint32_t leaf)
Definition: lib.h:46
static void write_cr4(unsigned long cr4)
Definition: lib.h:285
static bool write_cr4_safe(unsigned long cr4)
Definition: lib.h:290
static uint32_t inl(uint16_t port)
Definition: lib.h:100
static unsigned long read_cr0(void)
Definition: lib.h:225
static uint32_t cpuid_ebx(uint32_t leaf)
Definition: lib.h:28
static void pv_cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Definition: lib.h:55
static unsigned int read_gs(void)
Definition: lib.h:160
static void write_cr8(unsigned long cr8)
Definition: lib.h:303
__UINT16_TYPE__ uint16_t
Definition: stdint.h:15
static void write_ss(unsigned int ss)
Definition: lib.h:206
#define __ASM_SEL(c, l)
Definition: asm_macros.h:25
static uint8_t inb(uint16_t port)
Definition: lib.h:82
__UINT8_TYPE__ uint8_t
Definition: stdint.h:14
static void write_fs(unsigned int fs)
Definition: lib.h:196
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38
static void write_cr3(unsigned long cr3)
Definition: lib.h:280
static void write_cs(unsigned long cs)
Definition: lib.h:178
Model Specific Register mnemonics and bit definitions.
static unsigned int read_ss(void)
Definition: lib.h:169
static unsigned int read_fs(void)
Definition: lib.h:151
static uint64_t xgetbv(uint32_t index)
Definition: lib.h:375