xref: /openbmc/qemu/target/i386/hvf/x86.h (revision 69e0a03c)
1*69e0a03cSPaolo Bonzini /*
2*69e0a03cSPaolo Bonzini  * Copyright (C) 2016 Veertu Inc,
3*69e0a03cSPaolo Bonzini  * Copyright (C) 2017 Veertu Inc,
4*69e0a03cSPaolo Bonzini  *
5*69e0a03cSPaolo Bonzini  * This program is free software; you can redistribute it and/or
6*69e0a03cSPaolo Bonzini  * modify it under the terms of the GNU Lesser General Public
7*69e0a03cSPaolo Bonzini  * License as published by the Free Software Foundation; either
8*69e0a03cSPaolo Bonzini  * version 2 of the License, or (at your option) any later version.
9*69e0a03cSPaolo Bonzini  *
10*69e0a03cSPaolo Bonzini  * This program is distributed in the hope that it will be useful,
11*69e0a03cSPaolo Bonzini  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*69e0a03cSPaolo Bonzini  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*69e0a03cSPaolo Bonzini  * Lesser General Public License for more details.
14*69e0a03cSPaolo Bonzini  *
15*69e0a03cSPaolo Bonzini  * You should have received a copy of the GNU Lesser General Public
16*69e0a03cSPaolo Bonzini  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
17*69e0a03cSPaolo Bonzini  */
18*69e0a03cSPaolo Bonzini 
19*69e0a03cSPaolo Bonzini #pragma once
20*69e0a03cSPaolo Bonzini 
21*69e0a03cSPaolo Bonzini #include <sys/types.h>
22*69e0a03cSPaolo Bonzini #include <sys/ioctl.h>
23*69e0a03cSPaolo Bonzini #include <sys/mman.h>
24*69e0a03cSPaolo Bonzini #include <stdarg.h>
25*69e0a03cSPaolo Bonzini #include "qemu-common.h"
26*69e0a03cSPaolo Bonzini #include "x86_gen.h"
27*69e0a03cSPaolo Bonzini 
28*69e0a03cSPaolo Bonzini /* exceptions */
29*69e0a03cSPaolo Bonzini typedef enum x86_exception {
30*69e0a03cSPaolo Bonzini     EXCEPTION_DE,           /* divide error */
31*69e0a03cSPaolo Bonzini     EXCEPTION_DB,           /* debug fault */
32*69e0a03cSPaolo Bonzini     EXCEPTION_NMI,          /* non-maskable interrupt */
33*69e0a03cSPaolo Bonzini     EXCEPTION_BP,           /* breakpoint trap */
34*69e0a03cSPaolo Bonzini     EXCEPTION_OF,           /* overflow trap */
35*69e0a03cSPaolo Bonzini     EXCEPTION_BR,           /* boundary range exceeded fault */
36*69e0a03cSPaolo Bonzini     EXCEPTION_UD,           /* undefined opcode */
37*69e0a03cSPaolo Bonzini     EXCEPTION_NM,           /* device not available */
38*69e0a03cSPaolo Bonzini     EXCEPTION_DF,           /* double fault */
39*69e0a03cSPaolo Bonzini     EXCEPTION_RSVD,         /* not defined */
40*69e0a03cSPaolo Bonzini     EXCEPTION_TS,           /* invalid TSS fault */
41*69e0a03cSPaolo Bonzini     EXCEPTION_NP,           /* not present fault */
42*69e0a03cSPaolo Bonzini     EXCEPTION_GP,           /* general protection fault */
43*69e0a03cSPaolo Bonzini     EXCEPTION_PF,           /* page fault */
44*69e0a03cSPaolo Bonzini     EXCEPTION_RSVD2,        /* not defined */
45*69e0a03cSPaolo Bonzini } x86_exception;
46*69e0a03cSPaolo Bonzini 
47*69e0a03cSPaolo Bonzini /* general purpose regs */
48*69e0a03cSPaolo Bonzini typedef enum x86_reg_name {
49*69e0a03cSPaolo Bonzini     REG_RAX = 0,
50*69e0a03cSPaolo Bonzini     REG_RCX = 1,
51*69e0a03cSPaolo Bonzini     REG_RDX = 2,
52*69e0a03cSPaolo Bonzini     REG_RBX = 3,
53*69e0a03cSPaolo Bonzini     REG_RSP = 4,
54*69e0a03cSPaolo Bonzini     REG_RBP = 5,
55*69e0a03cSPaolo Bonzini     REG_RSI = 6,
56*69e0a03cSPaolo Bonzini     REG_RDI = 7,
57*69e0a03cSPaolo Bonzini     REG_R8 = 8,
58*69e0a03cSPaolo Bonzini     REG_R9 = 9,
59*69e0a03cSPaolo Bonzini     REG_R10 = 10,
60*69e0a03cSPaolo Bonzini     REG_R11 = 11,
61*69e0a03cSPaolo Bonzini     REG_R12 = 12,
62*69e0a03cSPaolo Bonzini     REG_R13 = 13,
63*69e0a03cSPaolo Bonzini     REG_R14 = 14,
64*69e0a03cSPaolo Bonzini     REG_R15 = 15,
65*69e0a03cSPaolo Bonzini } x86_reg_name;
66*69e0a03cSPaolo Bonzini 
67*69e0a03cSPaolo Bonzini /* segment regs */
68*69e0a03cSPaolo Bonzini typedef enum x86_reg_segment {
69*69e0a03cSPaolo Bonzini     REG_SEG_ES = 0,
70*69e0a03cSPaolo Bonzini     REG_SEG_CS = 1,
71*69e0a03cSPaolo Bonzini     REG_SEG_SS = 2,
72*69e0a03cSPaolo Bonzini     REG_SEG_DS = 3,
73*69e0a03cSPaolo Bonzini     REG_SEG_FS = 4,
74*69e0a03cSPaolo Bonzini     REG_SEG_GS = 5,
75*69e0a03cSPaolo Bonzini     REG_SEG_LDTR = 6,
76*69e0a03cSPaolo Bonzini     REG_SEG_TR = 7,
77*69e0a03cSPaolo Bonzini } x86_reg_segment;
78*69e0a03cSPaolo Bonzini 
79*69e0a03cSPaolo Bonzini typedef struct x86_register {
80*69e0a03cSPaolo Bonzini     union {
81*69e0a03cSPaolo Bonzini         struct {
82*69e0a03cSPaolo Bonzini             uint64_t rrx;               /* full 64 bit */
83*69e0a03cSPaolo Bonzini         };
84*69e0a03cSPaolo Bonzini         struct {
85*69e0a03cSPaolo Bonzini             uint32_t erx;               /* low 32 bit part */
86*69e0a03cSPaolo Bonzini             uint32_t hi32_unused1;
87*69e0a03cSPaolo Bonzini         };
88*69e0a03cSPaolo Bonzini         struct {
89*69e0a03cSPaolo Bonzini             uint16_t rx;                /* low 16 bit part */
90*69e0a03cSPaolo Bonzini             uint16_t hi16_unused1;
91*69e0a03cSPaolo Bonzini             uint32_t hi32_unused2;
92*69e0a03cSPaolo Bonzini         };
93*69e0a03cSPaolo Bonzini         struct {
94*69e0a03cSPaolo Bonzini             uint8_t lx;                 /* low 8 bit part */
95*69e0a03cSPaolo Bonzini             uint8_t hx;                 /* high 8 bit */
96*69e0a03cSPaolo Bonzini             uint16_t hi16_unused2;
97*69e0a03cSPaolo Bonzini             uint32_t hi32_unused3;
98*69e0a03cSPaolo Bonzini         };
99*69e0a03cSPaolo Bonzini     };
100*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_register;
101*69e0a03cSPaolo Bonzini 
102*69e0a03cSPaolo Bonzini typedef enum x86_rflags {
103*69e0a03cSPaolo Bonzini     RFLAGS_CF       = (1L << 0),
104*69e0a03cSPaolo Bonzini     RFLAGS_PF       = (1L << 2),
105*69e0a03cSPaolo Bonzini     RFLAGS_AF       = (1L << 4),
106*69e0a03cSPaolo Bonzini     RFLAGS_ZF       = (1L << 6),
107*69e0a03cSPaolo Bonzini     RFLAGS_SF       = (1L << 7),
108*69e0a03cSPaolo Bonzini     RFLAGS_TF       = (1L << 8),
109*69e0a03cSPaolo Bonzini     RFLAGS_IF       = (1L << 9),
110*69e0a03cSPaolo Bonzini     RFLAGS_DF       = (1L << 10),
111*69e0a03cSPaolo Bonzini     RFLAGS_OF       = (1L << 11),
112*69e0a03cSPaolo Bonzini     RFLAGS_IOPL     = (3L << 12),
113*69e0a03cSPaolo Bonzini     RFLAGS_NT       = (1L << 14),
114*69e0a03cSPaolo Bonzini     RFLAGS_RF       = (1L << 16),
115*69e0a03cSPaolo Bonzini     RFLAGS_VM       = (1L << 17),
116*69e0a03cSPaolo Bonzini     RFLAGS_AC       = (1L << 18),
117*69e0a03cSPaolo Bonzini     RFLAGS_VIF      = (1L << 19),
118*69e0a03cSPaolo Bonzini     RFLAGS_VIP      = (1L << 20),
119*69e0a03cSPaolo Bonzini     RFLAGS_ID       = (1L << 21),
120*69e0a03cSPaolo Bonzini } x86_rflags;
121*69e0a03cSPaolo Bonzini 
122*69e0a03cSPaolo Bonzini /* rflags register */
123*69e0a03cSPaolo Bonzini typedef struct x86_reg_flags {
124*69e0a03cSPaolo Bonzini     union {
125*69e0a03cSPaolo Bonzini         struct {
126*69e0a03cSPaolo Bonzini             uint64_t rflags;
127*69e0a03cSPaolo Bonzini         };
128*69e0a03cSPaolo Bonzini         struct {
129*69e0a03cSPaolo Bonzini             uint32_t eflags;
130*69e0a03cSPaolo Bonzini             uint32_t hi32_unused1;
131*69e0a03cSPaolo Bonzini         };
132*69e0a03cSPaolo Bonzini         struct {
133*69e0a03cSPaolo Bonzini             uint32_t cf:1;
134*69e0a03cSPaolo Bonzini             uint32_t unused1:1;
135*69e0a03cSPaolo Bonzini             uint32_t pf:1;
136*69e0a03cSPaolo Bonzini             uint32_t unused2:1;
137*69e0a03cSPaolo Bonzini             uint32_t af:1;
138*69e0a03cSPaolo Bonzini             uint32_t unused3:1;
139*69e0a03cSPaolo Bonzini             uint32_t zf:1;
140*69e0a03cSPaolo Bonzini             uint32_t sf:1;
141*69e0a03cSPaolo Bonzini             uint32_t tf:1;
142*69e0a03cSPaolo Bonzini             uint32_t ief:1;
143*69e0a03cSPaolo Bonzini             uint32_t df:1;
144*69e0a03cSPaolo Bonzini             uint32_t of:1;
145*69e0a03cSPaolo Bonzini             uint32_t iopl:2;
146*69e0a03cSPaolo Bonzini             uint32_t nt:1;
147*69e0a03cSPaolo Bonzini             uint32_t unused4:1;
148*69e0a03cSPaolo Bonzini             uint32_t rf:1;
149*69e0a03cSPaolo Bonzini             uint32_t vm:1;
150*69e0a03cSPaolo Bonzini             uint32_t ac:1;
151*69e0a03cSPaolo Bonzini             uint32_t vif:1;
152*69e0a03cSPaolo Bonzini             uint32_t vip:1;
153*69e0a03cSPaolo Bonzini             uint32_t id:1;
154*69e0a03cSPaolo Bonzini             uint32_t unused5:10;
155*69e0a03cSPaolo Bonzini             uint32_t hi32_unused2;
156*69e0a03cSPaolo Bonzini         };
157*69e0a03cSPaolo Bonzini     };
158*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_reg_flags;
159*69e0a03cSPaolo Bonzini 
160*69e0a03cSPaolo Bonzini typedef enum x86_reg_efer {
161*69e0a03cSPaolo Bonzini     EFER_SCE =          (1L << 0),
162*69e0a03cSPaolo Bonzini     EFER_LME =          (1L << 8),
163*69e0a03cSPaolo Bonzini     EFER_LMA =          (1L << 10),
164*69e0a03cSPaolo Bonzini     EFER_NXE =          (1L << 11),
165*69e0a03cSPaolo Bonzini     EFER_SVME =         (1L << 12),
166*69e0a03cSPaolo Bonzini     EFER_FXSR =         (1L << 14),
167*69e0a03cSPaolo Bonzini } x86_reg_efer;
168*69e0a03cSPaolo Bonzini 
169*69e0a03cSPaolo Bonzini typedef struct x86_efer {
170*69e0a03cSPaolo Bonzini     uint64_t efer;
171*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_efer;
172*69e0a03cSPaolo Bonzini 
173*69e0a03cSPaolo Bonzini typedef enum x86_reg_cr0 {
174*69e0a03cSPaolo Bonzini     CR0_PE =            (1L << 0),
175*69e0a03cSPaolo Bonzini     CR0_MP =            (1L << 1),
176*69e0a03cSPaolo Bonzini     CR0_EM =            (1L << 2),
177*69e0a03cSPaolo Bonzini     CR0_TS =            (1L << 3),
178*69e0a03cSPaolo Bonzini     CR0_ET =            (1L << 4),
179*69e0a03cSPaolo Bonzini     CR0_NE =            (1L << 5),
180*69e0a03cSPaolo Bonzini     CR0_WP =            (1L << 16),
181*69e0a03cSPaolo Bonzini     CR0_AM =            (1L << 18),
182*69e0a03cSPaolo Bonzini     CR0_NW =            (1L << 29),
183*69e0a03cSPaolo Bonzini     CR0_CD =            (1L << 30),
184*69e0a03cSPaolo Bonzini     CR0_PG =            (1L << 31),
185*69e0a03cSPaolo Bonzini } x86_reg_cr0;
186*69e0a03cSPaolo Bonzini 
187*69e0a03cSPaolo Bonzini typedef enum x86_reg_cr4 {
188*69e0a03cSPaolo Bonzini     CR4_VME =            (1L << 0),
189*69e0a03cSPaolo Bonzini     CR4_PVI =            (1L << 1),
190*69e0a03cSPaolo Bonzini     CR4_TSD =            (1L << 2),
191*69e0a03cSPaolo Bonzini     CR4_DE  =            (1L << 3),
192*69e0a03cSPaolo Bonzini     CR4_PSE =            (1L << 4),
193*69e0a03cSPaolo Bonzini     CR4_PAE =            (1L << 5),
194*69e0a03cSPaolo Bonzini     CR4_MSE =            (1L << 6),
195*69e0a03cSPaolo Bonzini     CR4_PGE =            (1L << 7),
196*69e0a03cSPaolo Bonzini     CR4_PCE =            (1L << 8),
197*69e0a03cSPaolo Bonzini     CR4_OSFXSR =         (1L << 9),
198*69e0a03cSPaolo Bonzini     CR4_OSXMMEXCPT =     (1L << 10),
199*69e0a03cSPaolo Bonzini     CR4_VMXE =           (1L << 13),
200*69e0a03cSPaolo Bonzini     CR4_SMXE =           (1L << 14),
201*69e0a03cSPaolo Bonzini     CR4_FSGSBASE =       (1L << 16),
202*69e0a03cSPaolo Bonzini     CR4_PCIDE =          (1L << 17),
203*69e0a03cSPaolo Bonzini     CR4_OSXSAVE =        (1L << 18),
204*69e0a03cSPaolo Bonzini     CR4_SMEP =           (1L << 20),
205*69e0a03cSPaolo Bonzini } x86_reg_cr4;
206*69e0a03cSPaolo Bonzini 
207*69e0a03cSPaolo Bonzini /* 16 bit Task State Segment */
208*69e0a03cSPaolo Bonzini typedef struct x86_tss_segment16 {
209*69e0a03cSPaolo Bonzini     uint16_t link;
210*69e0a03cSPaolo Bonzini     uint16_t sp0;
211*69e0a03cSPaolo Bonzini     uint16_t ss0;
212*69e0a03cSPaolo Bonzini     uint32_t sp1;
213*69e0a03cSPaolo Bonzini     uint16_t ss1;
214*69e0a03cSPaolo Bonzini     uint32_t sp2;
215*69e0a03cSPaolo Bonzini     uint16_t ss2;
216*69e0a03cSPaolo Bonzini     uint16_t ip;
217*69e0a03cSPaolo Bonzini     uint16_t flags;
218*69e0a03cSPaolo Bonzini     uint16_t ax;
219*69e0a03cSPaolo Bonzini     uint16_t cx;
220*69e0a03cSPaolo Bonzini     uint16_t dx;
221*69e0a03cSPaolo Bonzini     uint16_t bx;
222*69e0a03cSPaolo Bonzini     uint16_t sp;
223*69e0a03cSPaolo Bonzini     uint16_t bp;
224*69e0a03cSPaolo Bonzini     uint16_t si;
225*69e0a03cSPaolo Bonzini     uint16_t di;
226*69e0a03cSPaolo Bonzini     uint16_t es;
227*69e0a03cSPaolo Bonzini     uint16_t cs;
228*69e0a03cSPaolo Bonzini     uint16_t ss;
229*69e0a03cSPaolo Bonzini     uint16_t ds;
230*69e0a03cSPaolo Bonzini     uint16_t ldtr;
231*69e0a03cSPaolo Bonzini } __attribute__((packed)) x86_tss_segment16;
232*69e0a03cSPaolo Bonzini 
233*69e0a03cSPaolo Bonzini /* 32 bit Task State Segment */
234*69e0a03cSPaolo Bonzini typedef struct x86_tss_segment32 {
235*69e0a03cSPaolo Bonzini     uint32_t prev_tss;
236*69e0a03cSPaolo Bonzini     uint32_t esp0;
237*69e0a03cSPaolo Bonzini     uint32_t ss0;
238*69e0a03cSPaolo Bonzini     uint32_t esp1;
239*69e0a03cSPaolo Bonzini     uint32_t ss1;
240*69e0a03cSPaolo Bonzini     uint32_t esp2;
241*69e0a03cSPaolo Bonzini     uint32_t ss2;
242*69e0a03cSPaolo Bonzini     uint32_t cr3;
243*69e0a03cSPaolo Bonzini     uint32_t eip;
244*69e0a03cSPaolo Bonzini     uint32_t eflags;
245*69e0a03cSPaolo Bonzini     uint32_t eax;
246*69e0a03cSPaolo Bonzini     uint32_t ecx;
247*69e0a03cSPaolo Bonzini     uint32_t edx;
248*69e0a03cSPaolo Bonzini     uint32_t ebx;
249*69e0a03cSPaolo Bonzini     uint32_t esp;
250*69e0a03cSPaolo Bonzini     uint32_t ebp;
251*69e0a03cSPaolo Bonzini     uint32_t esi;
252*69e0a03cSPaolo Bonzini     uint32_t edi;
253*69e0a03cSPaolo Bonzini     uint32_t es;
254*69e0a03cSPaolo Bonzini     uint32_t cs;
255*69e0a03cSPaolo Bonzini     uint32_t ss;
256*69e0a03cSPaolo Bonzini     uint32_t ds;
257*69e0a03cSPaolo Bonzini     uint32_t fs;
258*69e0a03cSPaolo Bonzini     uint32_t gs;
259*69e0a03cSPaolo Bonzini     uint32_t ldt;
260*69e0a03cSPaolo Bonzini     uint16_t trap;
261*69e0a03cSPaolo Bonzini     uint16_t iomap_base;
262*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_tss_segment32;
263*69e0a03cSPaolo Bonzini 
264*69e0a03cSPaolo Bonzini /* 64 bit Task State Segment */
265*69e0a03cSPaolo Bonzini typedef struct x86_tss_segment64 {
266*69e0a03cSPaolo Bonzini     uint32_t unused;
267*69e0a03cSPaolo Bonzini     uint64_t rsp0;
268*69e0a03cSPaolo Bonzini     uint64_t rsp1;
269*69e0a03cSPaolo Bonzini     uint64_t rsp2;
270*69e0a03cSPaolo Bonzini     uint64_t unused1;
271*69e0a03cSPaolo Bonzini     uint64_t ist1;
272*69e0a03cSPaolo Bonzini     uint64_t ist2;
273*69e0a03cSPaolo Bonzini     uint64_t ist3;
274*69e0a03cSPaolo Bonzini     uint64_t ist4;
275*69e0a03cSPaolo Bonzini     uint64_t ist5;
276*69e0a03cSPaolo Bonzini     uint64_t ist6;
277*69e0a03cSPaolo Bonzini     uint64_t ist7;
278*69e0a03cSPaolo Bonzini     uint64_t unused2;
279*69e0a03cSPaolo Bonzini     uint16_t unused3;
280*69e0a03cSPaolo Bonzini     uint16_t iomap_base;
281*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_tss_segment64;
282*69e0a03cSPaolo Bonzini 
283*69e0a03cSPaolo Bonzini /* segment descriptors */
284*69e0a03cSPaolo Bonzini typedef struct x86_segment_descriptor {
285*69e0a03cSPaolo Bonzini     uint64_t    limit0:16;
286*69e0a03cSPaolo Bonzini     uint64_t    base0:16;
287*69e0a03cSPaolo Bonzini     uint64_t    base1:8;
288*69e0a03cSPaolo Bonzini     uint64_t    type:4;
289*69e0a03cSPaolo Bonzini     uint64_t    s:1;
290*69e0a03cSPaolo Bonzini     uint64_t    dpl:2;
291*69e0a03cSPaolo Bonzini     uint64_t    p:1;
292*69e0a03cSPaolo Bonzini     uint64_t    limit1:4;
293*69e0a03cSPaolo Bonzini     uint64_t    avl:1;
294*69e0a03cSPaolo Bonzini     uint64_t    l:1;
295*69e0a03cSPaolo Bonzini     uint64_t    db:1;
296*69e0a03cSPaolo Bonzini     uint64_t    g:1;
297*69e0a03cSPaolo Bonzini     uint64_t    base2:8;
298*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_segment_descriptor;
299*69e0a03cSPaolo Bonzini 
300*69e0a03cSPaolo Bonzini static inline uint32_t x86_segment_base(x86_segment_descriptor *desc)
301*69e0a03cSPaolo Bonzini {
302*69e0a03cSPaolo Bonzini     return (uint32_t)((desc->base2 << 24) | (desc->base1 << 16) | desc->base0);
303*69e0a03cSPaolo Bonzini }
304*69e0a03cSPaolo Bonzini 
305*69e0a03cSPaolo Bonzini static inline void x86_set_segment_base(x86_segment_descriptor *desc,
306*69e0a03cSPaolo Bonzini                                         uint32_t base)
307*69e0a03cSPaolo Bonzini {
308*69e0a03cSPaolo Bonzini     desc->base2 = base >> 24;
309*69e0a03cSPaolo Bonzini     desc->base1 = (base >> 16) & 0xff;
310*69e0a03cSPaolo Bonzini     desc->base0 = base & 0xffff;
311*69e0a03cSPaolo Bonzini }
312*69e0a03cSPaolo Bonzini 
313*69e0a03cSPaolo Bonzini static inline uint32_t x86_segment_limit(x86_segment_descriptor *desc)
314*69e0a03cSPaolo Bonzini {
315*69e0a03cSPaolo Bonzini     uint32_t limit = (uint32_t)((desc->limit1 << 16) | desc->limit0);
316*69e0a03cSPaolo Bonzini     if (desc->g) {
317*69e0a03cSPaolo Bonzini         return (limit << 12) | 0xfff;
318*69e0a03cSPaolo Bonzini     }
319*69e0a03cSPaolo Bonzini     return limit;
320*69e0a03cSPaolo Bonzini }
321*69e0a03cSPaolo Bonzini 
322*69e0a03cSPaolo Bonzini static inline void x86_set_segment_limit(x86_segment_descriptor *desc,
323*69e0a03cSPaolo Bonzini                                          uint32_t limit)
324*69e0a03cSPaolo Bonzini {
325*69e0a03cSPaolo Bonzini     desc->limit0 = limit & 0xffff;
326*69e0a03cSPaolo Bonzini     desc->limit1 = limit >> 16;
327*69e0a03cSPaolo Bonzini }
328*69e0a03cSPaolo Bonzini 
329*69e0a03cSPaolo Bonzini typedef struct x86_call_gate {
330*69e0a03cSPaolo Bonzini     uint64_t offset0:16;
331*69e0a03cSPaolo Bonzini     uint64_t selector:16;
332*69e0a03cSPaolo Bonzini     uint64_t param_count:4;
333*69e0a03cSPaolo Bonzini     uint64_t reserved:3;
334*69e0a03cSPaolo Bonzini     uint64_t type:4;
335*69e0a03cSPaolo Bonzini     uint64_t dpl:1;
336*69e0a03cSPaolo Bonzini     uint64_t p:1;
337*69e0a03cSPaolo Bonzini     uint64_t offset1:16;
338*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x86_call_gate;
339*69e0a03cSPaolo Bonzini 
340*69e0a03cSPaolo Bonzini static inline uint32_t x86_call_gate_offset(x86_call_gate *gate)
341*69e0a03cSPaolo Bonzini {
342*69e0a03cSPaolo Bonzini     return (uint32_t)((gate->offset1 << 16) | gate->offset0);
343*69e0a03cSPaolo Bonzini }
344*69e0a03cSPaolo Bonzini 
345*69e0a03cSPaolo Bonzini #define LDT_SEL     0
346*69e0a03cSPaolo Bonzini #define GDT_SEL     1
347*69e0a03cSPaolo Bonzini 
348*69e0a03cSPaolo Bonzini typedef struct x68_segment_selector {
349*69e0a03cSPaolo Bonzini     union {
350*69e0a03cSPaolo Bonzini         uint16_t sel;
351*69e0a03cSPaolo Bonzini         struct {
352*69e0a03cSPaolo Bonzini             uint16_t rpl:3;
353*69e0a03cSPaolo Bonzini             uint16_t ti:1;
354*69e0a03cSPaolo Bonzini             uint16_t index:12;
355*69e0a03cSPaolo Bonzini         };
356*69e0a03cSPaolo Bonzini     };
357*69e0a03cSPaolo Bonzini } __attribute__ ((__packed__)) x68_segment_selector;
358*69e0a03cSPaolo Bonzini 
359*69e0a03cSPaolo Bonzini typedef struct lazy_flags {
360*69e0a03cSPaolo Bonzini     addr_t result;
361*69e0a03cSPaolo Bonzini     addr_t auxbits;
362*69e0a03cSPaolo Bonzini } lazy_flags;
363*69e0a03cSPaolo Bonzini 
364*69e0a03cSPaolo Bonzini /* Definition of hvf_x86_state is here */
365*69e0a03cSPaolo Bonzini struct HVFX86EmulatorState {
366*69e0a03cSPaolo Bonzini     int interruptable;
367*69e0a03cSPaolo Bonzini     uint64_t fetch_rip;
368*69e0a03cSPaolo Bonzini     uint64_t rip;
369*69e0a03cSPaolo Bonzini     struct x86_register regs[16];
370*69e0a03cSPaolo Bonzini     struct x86_reg_flags   rflags;
371*69e0a03cSPaolo Bonzini     struct lazy_flags   lflags;
372*69e0a03cSPaolo Bonzini     struct x86_efer efer;
373*69e0a03cSPaolo Bonzini     uint8_t mmio_buf[4096];
374*69e0a03cSPaolo Bonzini };
375*69e0a03cSPaolo Bonzini 
376*69e0a03cSPaolo Bonzini /* useful register access  macros */
377*69e0a03cSPaolo Bonzini #define RIP(cpu)    (cpu->hvf_emul->rip)
378*69e0a03cSPaolo Bonzini #define EIP(cpu)    ((uint32_t)cpu->hvf_emul->rip)
379*69e0a03cSPaolo Bonzini #define RFLAGS(cpu) (cpu->hvf_emul->rflags.rflags)
380*69e0a03cSPaolo Bonzini #define EFLAGS(cpu) (cpu->hvf_emul->rflags.eflags)
381*69e0a03cSPaolo Bonzini 
382*69e0a03cSPaolo Bonzini #define RRX(cpu, reg) (cpu->hvf_emul->regs[reg].rrx)
383*69e0a03cSPaolo Bonzini #define RAX(cpu)        RRX(cpu, REG_RAX)
384*69e0a03cSPaolo Bonzini #define RCX(cpu)        RRX(cpu, REG_RCX)
385*69e0a03cSPaolo Bonzini #define RDX(cpu)        RRX(cpu, REG_RDX)
386*69e0a03cSPaolo Bonzini #define RBX(cpu)        RRX(cpu, REG_RBX)
387*69e0a03cSPaolo Bonzini #define RSP(cpu)        RRX(cpu, REG_RSP)
388*69e0a03cSPaolo Bonzini #define RBP(cpu)        RRX(cpu, REG_RBP)
389*69e0a03cSPaolo Bonzini #define RSI(cpu)        RRX(cpu, REG_RSI)
390*69e0a03cSPaolo Bonzini #define RDI(cpu)        RRX(cpu, REG_RDI)
391*69e0a03cSPaolo Bonzini #define R8(cpu)         RRX(cpu, REG_R8)
392*69e0a03cSPaolo Bonzini #define R9(cpu)         RRX(cpu, REG_R9)
393*69e0a03cSPaolo Bonzini #define R10(cpu)        RRX(cpu, REG_R10)
394*69e0a03cSPaolo Bonzini #define R11(cpu)        RRX(cpu, REG_R11)
395*69e0a03cSPaolo Bonzini #define R12(cpu)        RRX(cpu, REG_R12)
396*69e0a03cSPaolo Bonzini #define R13(cpu)        RRX(cpu, REG_R13)
397*69e0a03cSPaolo Bonzini #define R14(cpu)        RRX(cpu, REG_R14)
398*69e0a03cSPaolo Bonzini #define R15(cpu)        RRX(cpu, REG_R15)
399*69e0a03cSPaolo Bonzini 
400*69e0a03cSPaolo Bonzini #define ERX(cpu, reg)   (cpu->hvf_emul->regs[reg].erx)
401*69e0a03cSPaolo Bonzini #define EAX(cpu)        ERX(cpu, REG_RAX)
402*69e0a03cSPaolo Bonzini #define ECX(cpu)        ERX(cpu, REG_RCX)
403*69e0a03cSPaolo Bonzini #define EDX(cpu)        ERX(cpu, REG_RDX)
404*69e0a03cSPaolo Bonzini #define EBX(cpu)        ERX(cpu, REG_RBX)
405*69e0a03cSPaolo Bonzini #define ESP(cpu)        ERX(cpu, REG_RSP)
406*69e0a03cSPaolo Bonzini #define EBP(cpu)        ERX(cpu, REG_RBP)
407*69e0a03cSPaolo Bonzini #define ESI(cpu)        ERX(cpu, REG_RSI)
408*69e0a03cSPaolo Bonzini #define EDI(cpu)        ERX(cpu, REG_RDI)
409*69e0a03cSPaolo Bonzini 
410*69e0a03cSPaolo Bonzini #define RX(cpu, reg)   (cpu->hvf_emul->regs[reg].rx)
411*69e0a03cSPaolo Bonzini #define AX(cpu)        RX(cpu, REG_RAX)
412*69e0a03cSPaolo Bonzini #define CX(cpu)        RX(cpu, REG_RCX)
413*69e0a03cSPaolo Bonzini #define DX(cpu)        RX(cpu, REG_RDX)
414*69e0a03cSPaolo Bonzini #define BP(cpu)        RX(cpu, REG_RBP)
415*69e0a03cSPaolo Bonzini #define SP(cpu)        RX(cpu, REG_RSP)
416*69e0a03cSPaolo Bonzini #define BX(cpu)        RX(cpu, REG_RBX)
417*69e0a03cSPaolo Bonzini #define SI(cpu)        RX(cpu, REG_RSI)
418*69e0a03cSPaolo Bonzini #define DI(cpu)        RX(cpu, REG_RDI)
419*69e0a03cSPaolo Bonzini 
420*69e0a03cSPaolo Bonzini #define RL(cpu, reg)   (cpu->hvf_emul->regs[reg].lx)
421*69e0a03cSPaolo Bonzini #define AL(cpu)        RL(cpu, REG_RAX)
422*69e0a03cSPaolo Bonzini #define CL(cpu)        RL(cpu, REG_RCX)
423*69e0a03cSPaolo Bonzini #define DL(cpu)        RL(cpu, REG_RDX)
424*69e0a03cSPaolo Bonzini #define BL(cpu)        RL(cpu, REG_RBX)
425*69e0a03cSPaolo Bonzini 
426*69e0a03cSPaolo Bonzini #define RH(cpu, reg)   (cpu->hvf_emul->regs[reg].hx)
427*69e0a03cSPaolo Bonzini #define AH(cpu)        RH(cpu, REG_RAX)
428*69e0a03cSPaolo Bonzini #define CH(cpu)        RH(cpu, REG_RCX)
429*69e0a03cSPaolo Bonzini #define DH(cpu)        RH(cpu, REG_RDX)
430*69e0a03cSPaolo Bonzini #define BH(cpu)        RH(cpu, REG_RBX)
431*69e0a03cSPaolo Bonzini 
432*69e0a03cSPaolo Bonzini /* deal with GDT/LDT descriptors in memory */
433*69e0a03cSPaolo Bonzini bool x86_read_segment_descriptor(struct CPUState *cpu,
434*69e0a03cSPaolo Bonzini                                  struct x86_segment_descriptor *desc,
435*69e0a03cSPaolo Bonzini                                  x68_segment_selector sel);
436*69e0a03cSPaolo Bonzini bool x86_write_segment_descriptor(struct CPUState *cpu,
437*69e0a03cSPaolo Bonzini                                   struct x86_segment_descriptor *desc,
438*69e0a03cSPaolo Bonzini                                   x68_segment_selector sel);
439*69e0a03cSPaolo Bonzini 
440*69e0a03cSPaolo Bonzini bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
441*69e0a03cSPaolo Bonzini                         int gate);
442*69e0a03cSPaolo Bonzini 
443*69e0a03cSPaolo Bonzini /* helpers */
444*69e0a03cSPaolo Bonzini bool x86_is_protected(struct CPUState *cpu);
445*69e0a03cSPaolo Bonzini bool x86_is_real(struct CPUState *cpu);
446*69e0a03cSPaolo Bonzini bool x86_is_v8086(struct CPUState *cpu);
447*69e0a03cSPaolo Bonzini bool x86_is_long_mode(struct CPUState *cpu);
448*69e0a03cSPaolo Bonzini bool x86_is_long64_mode(struct CPUState *cpu);
449*69e0a03cSPaolo Bonzini bool x86_is_paging_mode(struct CPUState *cpu);
450*69e0a03cSPaolo Bonzini bool x86_is_pae_enabled(struct CPUState *cpu);
451*69e0a03cSPaolo Bonzini 
452*69e0a03cSPaolo Bonzini addr_t linear_addr(struct CPUState *cpu, addr_t addr, x86_reg_segment seg);
453*69e0a03cSPaolo Bonzini addr_t linear_addr_size(struct CPUState *cpu, addr_t addr, int size,
454*69e0a03cSPaolo Bonzini                         x86_reg_segment seg);
455*69e0a03cSPaolo Bonzini addr_t linear_rip(struct CPUState *cpu, addr_t rip);
456*69e0a03cSPaolo Bonzini 
457*69e0a03cSPaolo Bonzini static inline uint64_t rdtscp(void)
458*69e0a03cSPaolo Bonzini {
459*69e0a03cSPaolo Bonzini     uint64_t tsc;
460*69e0a03cSPaolo Bonzini     __asm__ __volatile__("rdtscp; "         /* serializing read of tsc */
461*69e0a03cSPaolo Bonzini                          "shl $32,%%rdx; "  /* shift higher 32 bits stored in rdx up */
462*69e0a03cSPaolo Bonzini                          "or %%rdx,%%rax"   /* and or onto rax */
463*69e0a03cSPaolo Bonzini                          : "=a"(tsc)        /* output to tsc variable */
464*69e0a03cSPaolo Bonzini                          :
465*69e0a03cSPaolo Bonzini                          : "%rcx", "%rdx"); /* rcx and rdx are clobbered */
466*69e0a03cSPaolo Bonzini 
467*69e0a03cSPaolo Bonzini     return tsc;
468*69e0a03cSPaolo Bonzini }
469*69e0a03cSPaolo Bonzini 
470