1/**
2 * \file
3 */
4
5/*
6 * Copyright (c) 2009, ETH Zurich.
7 * All rights reserved.
8 *
9 * This file is distributed under the terms in the attached LICENSE file.
10 * If you do not find this file, copies can be found by writing to:
11 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
12 */
13
14#ifndef VMKITMON_X86_H
15#define VMKITMON_X86_H
16
17#include <stdint.h>
18
19/**
20 * \brief Structure to represent a ModR/M byte used by certain instructions
21 */
22union x86_modrm {
23    struct {
24        uint32_t     rm : 3;
25        uint32_t     regop : 3;
26        uint32_t     mod : 2;
27    } __attribute__((packed)) u;
28    uint8_t raw;
29} __attribute__((packed));
30
31/**
32 * \brief This enumeration represents the state of an IO-port access.
33 */
34enum x86_io_access {
35    X86_IO_ACCESS_TYPE  = (1 << 0),     ///< 0 = output (write), 1 = input (read)
36    X86_IO_ACCESS_STR   = (1 << 1),     ///< String based port access (INS, OUTS)
37    X86_IO_ACCESS_REP   = (1 << 2),     ///< Repeated port access
38    X86_IO_ACCESS_SZ8   = (1 << 3),     ///< 8-bit operand size
39    X86_IO_ACCESS_SZ16  = (1 << 4),     ///< 16-bit operand size
40    X86_IO_ACCESS_SZ32  = (1 << 5),     ///< 32-bit operand size
41    X86_IO_ACCESS_A16   = (1 << 6),     ///< 16-bit address size
42    X86_IO_ACCESS_A32   = (1 << 7),     ///< 32-bit address size
43    X86_IO_ACCESS_A64   = (1 << 8)      ///< 64-bit address size
44};
45
46// MSRs
47#define X86_MSR_SYSENTER_CS     0x00000174
48#define X86_MSR_SYSENTER_ESP    0x00000175
49#define X86_MSR_SYSENTER_EIP    0x00000176
50#define X86_MSR_EFER            0xc0000080
51#define X86_MSR_STAR            0xc0000081
52#define X86_MSR_LSTAR           0xc0000082
53#define X86_MSR_CSTAR           0xc0000083
54#define X86_MSR_SFMASK          0xc0000084
55#define X86_MSR_FS_BASE         0xc0000100
56#define X86_MSR_GS_BASE         0xc0000101
57#define X86_MSR_KERNEL_GS_BASE  0xc0000102
58
59
60// Long Mode Paging
61
62/**
63 * \brief Long mode virtual address
64 */
65union x86_lm_va {
66    struct {
67        uint32_t    pa_offset           : 12;
68        uint32_t    pt_idx              : 9;
69        uint32_t    pd_idx              : 9;
70        uint32_t    pdp_idx             : 9;
71        uint32_t    pml4_idx            : 9;
72        uint32_t    sign_extend         : 16;
73    } __attribute__((packed)) u;
74    struct {
75        uint32_t    pa_offset           : 21;
76        uint32_t    pd_idx              : 9;
77        uint32_t    pdp_idx             : 9;
78        uint32_t    pml4_idx            : 9;
79        uint32_t    sign_extend         : 16;
80    } __attribute__((packed)) u2mb;
81    struct {
82        uint32_t    pa_offset           : 30;
83        uint32_t    pdp_idx             : 9;
84        uint32_t    pml4_idx            : 9;
85        uint32_t    sign_extend         : 16;
86    } __attribute__((packed)) u1gb;
87    uint64_t raw;
88} __attribute__((packed));
89
90/**
91 * \brief PML4 Record
92 */
93union x86_lm_pml4_entry {
94    struct {
95        uint32_t    p                   : 1;
96        uint32_t    rw                  : 1;
97        uint32_t    us                  : 1;
98        uint32_t    pwt                 : 1;
99        uint32_t    pcd                 : 1;
100        uint32_t    a                   : 1;
101        uint32_t    ign                 : 1;
102        uint32_t    rsvd                : 2;
103        uint32_t    avl                 : 3;
104        uint64_t    pdp_base_pa         : 40;
105        uint32_t    avail               : 11;
106        uint32_t    nx                  : 1;
107    } __attribute__((packed)) u;
108    uint64_t raw;
109} __attribute__((packed));
110
111/**
112 * \brief Page Directory Pointer Entry
113 */
114union x86_lm_pdp_entry {
115    struct {
116        uint32_t    p                   : 1;
117        uint32_t    rw                  : 1;
118        uint32_t    us                  : 1;
119        uint32_t    pwt                 : 1;
120        uint32_t    pcd                 : 1;
121        uint32_t    a                   : 1;
122        uint32_t    ign                 : 1;
123        uint32_t    ps                  : 1;
124        uint32_t    rsvd                : 1;
125        uint32_t    avl                 : 3;
126        uint64_t    pd_base_pa          : 40;
127        uint32_t    avail               : 11;
128        uint32_t    nx                  : 1;
129    } __attribute__((packed)) u;
130    struct {
131        uint32_t    p                   : 1;
132        uint32_t    rw                  : 1;
133        uint32_t    us                  : 1;
134        uint32_t    pwt                 : 1;
135        uint32_t    pcd                 : 1;
136        uint32_t    a                   : 1;
137        uint32_t    d                   : 1;
138        uint32_t    ps                  : 1;
139        uint32_t    g                   : 1;
140        uint32_t    avl                 : 3;
141        uint32_t    pat                 : 1;
142        uint32_t    rsvd                : 17;
143        uint64_t    base_pa             : 22;
144        uint32_t    avail               : 11;
145        uint32_t    nx                  : 1;
146    } __attribute__((packed)) u1gb;
147    uint64_t raw;
148} __attribute__((packed));
149
150/**
151 * \brief Long mode page directory entry
152 */
153union x86_lm_pd_entry {
154    struct {
155        uint32_t    p                   : 1;
156        uint32_t    rw                  : 1;
157        uint32_t    us                  : 1;
158        uint32_t    pwt                 : 1;
159        uint32_t    pcd                 : 1;
160        uint32_t    a                   : 1;
161        uint32_t    ign1                : 1;
162        uint32_t    ps                  : 1;
163        uint32_t    ign2                : 1;
164        uint32_t    avl                 : 3;
165        uint64_t    pt_base_pa          : 40;
166        uint32_t    avail               : 11;
167        uint32_t    nx                  : 1;
168    } __attribute__((packed)) u;
169    struct {
170        uint32_t    p                   : 1;
171        uint32_t    rw                  : 1;
172        uint32_t    us                  : 1;
173        uint32_t    pwt                 : 1;
174        uint32_t    pcd                 : 1;
175        uint32_t    a                   : 1;
176        uint32_t    d                   : 1;
177        uint32_t    ps                  : 1;
178        uint32_t    g                   : 1;
179        uint32_t    avl                 : 3;
180        uint32_t    pat                 : 1;
181        uint32_t    rsvd                : 8;
182        uint64_t    base_pa             : 31;
183        uint32_t    avail               : 11;
184        uint32_t    nx                  : 1;
185    } __attribute__((packed)) u2mb;
186    uint64_t raw;
187} __attribute__((packed));
188
189/**
190 * \brief Long mode page table entry
191 */
192union x86_lm_pt_entry {
193    struct {
194        uint32_t    p                   : 1;
195        uint32_t    rw                  : 1;
196        uint32_t    us                  : 1;
197        uint32_t    pwt                 : 1;
198        uint32_t    pcd                 : 1;
199        uint32_t    a                   : 1;
200        uint32_t    d                   : 1;
201        uint32_t    pat                 : 1;
202        uint32_t    g                   : 1;
203        uint32_t    avl                 : 3;
204        uint64_t    base_pa             : 40;
205        uint32_t    avail               : 11;
206        uint32_t    nx                  : 1;
207    } __attribute__((packed)) u;
208    uint64_t raw;
209} __attribute__((packed));
210
211
212// Legacy Mode Paging
213
214/**
215 * \brief Legacy mode virtual address
216 */
217union x86_legm_va {
218    struct {
219        uint32_t    pa_offset           : 12;
220        uint32_t    pt_idx              : 10;
221        uint32_t    pd_idx              : 10;
222    } __attribute__((packed)) u;
223    struct {
224        uint32_t    pa_offset           : 22;
225        uint32_t    pd_idx              : 10;
226    } __attribute__((packed)) u4mb;
227    uint32_t raw;
228} __attribute__((packed));
229
230/**
231 * \brief Legacy mode page directory entry
232 */
233union x86_legm_pd_entry {
234    struct {
235        uint32_t    p                   : 1;
236        uint32_t    rw                  : 1;
237        uint32_t    us                  : 1;
238        uint32_t    pwt                 : 1;
239        uint32_t    pcd                 : 1;
240        uint32_t    a                   : 1;
241        uint32_t    ign1                : 1;
242        uint32_t    ps                  : 1;
243        uint32_t    ign2                : 1;
244        uint32_t    avl                 : 3;
245        uint32_t    pt_base_pa          : 20;
246    } __attribute__((packed)) u;
247    struct {
248        uint32_t    p                   : 1;
249        uint32_t    rw                  : 1;
250        uint32_t    us                  : 1;
251        uint32_t    pwt                 : 1;
252        uint32_t    pcd                 : 1;
253        uint32_t    a                   : 1;
254        uint32_t    d                   : 1;
255        uint32_t    ps                  : 1;
256        uint32_t    g                   : 1;
257        uint32_t    avl                 : 3;
258        uint32_t    pat                 : 1;
259        uint32_t    rsvd                : 9;
260        uint32_t    base_pa             : 10;
261    } __attribute__((packed)) u4mb;
262    uint32_t raw;
263} __attribute__((packed));
264
265/**
266 * \brief Legacy mode page table entry
267 */
268union x86_legm_pt_entry {
269    struct {
270        uint32_t    p                   : 1;
271        uint32_t    rw                  : 1;
272        uint32_t    us                  : 1;
273        uint32_t    pwt                 : 1;
274        uint32_t    pcd                 : 1;
275        uint32_t    a                   : 1;
276        uint32_t    d                   : 1;
277        uint32_t    pat                 : 1;
278        uint32_t    g                   : 1;
279        uint32_t    avl                 : 3;
280        uint32_t    base_pa             : 20;
281    } __attribute__((packed)) u;
282    uint32_t raw;
283} __attribute__((packed));
284
285#endif // VMKITMON_X86_H
286