forked from hermit-os/hermit-caves
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuhyve-x86_64.h
98 lines (82 loc) · 3.18 KB
/
uhyve-x86_64.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef __UHYVE_CPU_H__
#define __UHYVE_CPU_H__
#ifndef _BITUL
#ifdef __ASSEMBLY__
#define _AC(X,Y) X
#define _AT(T,X) X
#else
#define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y)
#define _AT(T,X) ((T)(X))
#endif
#define _BITUL(x) (_AC(1,UL) << (x))
#define _BITULL(x) (_AC(1,ULL) << (x))
#endif
/*
* EFLAGS bits
*/
#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
/*
* Basic CPU control in CR0
*/
#define X86_CR0_PE_BIT 0 /* Protection Enable */
#define X86_CR0_PE _BITUL(X86_CR0_PE_BIT)
#define X86_CR0_PG_BIT 31 /* Paging */
#define X86_CR0_PG _BITUL(X86_CR0_PG_BIT)
/*
* Intel CPU features in CR4
*/
#define X86_CR4_PAE_BIT 5 /* enable physical address extensions */
#define X86_CR4_PAE _BITUL(X86_CR4_PAE_BIT)
/*
* Intel long mode page directory/table entries
*/
#define X86_PDPT_P_BIT 0 /* Present */
#define X86_PDPT_P _BITUL(X86_PDPT_P_BIT)
#define X86_PDPT_RW_BIT 1 /* Writable */
#define X86_PDPT_RW _BITUL(X86_PDPT_RW_BIT)
#define X86_PDPT_PS_BIT 7 /* Page size */
#define X86_PDPT_PS _BITUL(X86_PDPT_PS_BIT)
/*
* GDT and KVM segment manipulation
*/
#define GDT_DESC_OFFSET(n) ((n) * 0x8)
#define GDT_GET_BASE(x) ( \
(((x) & 0xFF00000000000000) >> 32) | \
(((x) & 0x000000FF00000000) >> 16) | \
(((x) & 0x00000000FFFF0000) >> 16))
#define GDT_GET_LIMIT(x) (__u32)( \
(((x) & 0x000F000000000000) >> 32) | \
(((x) & 0x000000000000FFFF)))
/* Constructor for a conventional segment GDT (or LDT) entry */
/* This is a macro so it can be used in initializers */
#define GDT_ENTRY(flags, base, limit) \
((((base) & _AC(0xff000000, ULL)) << (56-24)) | \
(((flags) & _AC(0x0000f0ff, ULL)) << 40) | \
(((limit) & _AC(0x000f0000, ULL)) << (48-16)) | \
(((base) & _AC(0x00ffffff, ULL)) << 16) | \
(((limit) & _AC(0x0000ffff, ULL))))
#define GDT_GET_G(x) (__u8)(((x) & 0x0080000000000000) >> 55)
#define GDT_GET_DB(x) (__u8)(((x) & 0x0040000000000000) >> 54)
#define GDT_GET_L(x) (__u8)(((x) & 0x0020000000000000) >> 53)
#define GDT_GET_AVL(x) (__u8)(((x) & 0x0010000000000000) >> 52)
#define GDT_GET_P(x) (__u8)(((x) & 0x0000800000000000) >> 47)
#define GDT_GET_DPL(x) (__u8)(((x) & 0x0000600000000000) >> 45)
#define GDT_GET_S(x) (__u8)(((x) & 0x0000100000000000) >> 44)
#define GDT_GET_TYPE(x)(__u8)(((x) & 0x00000F0000000000) >> 40)
#define GDT_TO_KVM_SEGMENT(seg, gdt_table, sel) \
do { \
__u64 gdt_ent = gdt_table[sel]; \
seg.base = GDT_GET_BASE(gdt_ent); \
seg.limit = GDT_GET_LIMIT(gdt_ent); \
seg.selector = sel * 8; \
seg.type = GDT_GET_TYPE(gdt_ent); \
seg.present = GDT_GET_P(gdt_ent); \
seg.dpl = GDT_GET_DPL(gdt_ent); \
seg.db = GDT_GET_DB(gdt_ent); \
seg.s = GDT_GET_S(gdt_ent); \
seg.l = GDT_GET_L(gdt_ent); \
seg.g = GDT_GET_G(gdt_ent); \
seg.avl = GDT_GET_AVL(gdt_ent); \
} while (0)
#endif