VirtualBox

root/trunk/include/VBox/cpum.h

Revision 13975, 30.9 kB (checked in by vboxsync, 2 weeks ago)

Even more debugger fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /** @file
2  * CPUM - CPU Monitor(/ Manager).
3  */
4
5 /*
6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7  *
8  * This file is part of VirtualBox Open Source Edition (OSE), as
9  * available from http://www.virtualbox.org. This file is free software;
10  * you can redistribute it and/or modify it under the terms of the GNU
11  * General Public License (GPL) as published by the Free Software
12  * Foundation, in version 2 as it comes in the "COPYING" file of the
13  * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15  *
16  * The contents of this file may alternatively be used under the terms
17  * of the Common Development and Distribution License Version 1.0
18  * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19  * VirtualBox OSE distribution, in which case the provisions of the
20  * CDDL are applicable instead of those of the GPL.
21  *
22  * You may elect to license modified versions of this file under the
23  * terms and conditions of either the GPL or the CDDL or both.
24  *
25  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26  * Clara, CA 95054 USA or visit http://www.sun.com if you need
27  * additional information or have any questions.
28  */
29
30 #ifndef ___VBox_cpum_h
31 #define ___VBox_cpum_h
32
33 #include <VBox/cdefs.h>
34 #include <VBox/types.h>
35 #include <VBox/x86.h>
36
37
38 __BEGIN_DECLS
39
40 /** @defgroup grp_cpum      The CPU Monitor / Manager API
41  * @{
42  */
43
44 /**
45  * Selector hidden registers.
46  */
47 typedef struct CPUMSELREGHID
48 {
49     /** Base register.
50      *
51      *  Long mode remarks:
52      *  - Unused in long mode for CS, DS, ES, SS
53      *  - 32 bits for FS & GS; FS(GS)_BASE msr used for the base address
54      *  - 64 bits for TR & LDTR
55      */
56     uint64_t    u64Base;
57     /** Limit (expanded). */
58     uint32_t    u32Limit;
59     /** Flags.
60      * This is the high 32-bit word of the descriptor entry.
61      * Only the flags, dpl and type are used. */
62     X86DESCATTR Attr;
63 } CPUMSELREGHID;
64
65
66 /**
67  * The sysenter register set.
68  */
69 typedef struct CPUMSYSENTER
70 {
71     /** Ring 0 cs.
72      * This value +  8 is the Ring 0 ss.
73      * This value + 16 is the Ring 3 cs.
74      * This value + 24 is the Ring 3 ss.
75      */
76     uint64_t    cs;
77     /** Ring 0 eip. */
78     uint64_t    eip;
79     /** Ring 0 esp. */
80     uint64_t    esp;
81 } CPUMSYSENTER;
82
83
84 /**
85  * CPU context core.
86  */
87 #pragma pack(1)
88 typedef struct CPUMCTXCORE
89 {
90     union
91     {
92         uint16_t        di;
93         uint32_t        edi;
94         uint64_t        rdi;
95     };
96     union
97     {
98         uint16_t        si;
99         uint32_t        esi;
100         uint64_t        rsi;
101     };
102     union
103     {
104         uint16_t        bp;
105         uint32_t        ebp;
106         uint64_t        rbp;
107     };
108     union
109     {
110         uint16_t        ax;
111         uint32_t        eax;
112         uint64_t        rax;
113     };
114     union
115     {
116         uint16_t        bx;
117         uint32_t        ebx;
118         uint64_t        rbx;
119     };
120     union
121     {
122         uint16_t        dx;
123         uint32_t        edx;
124         uint64_t        rdx;
125     };
126     union
127     {
128         uint16_t        cx;
129         uint32_t        ecx;
130         uint64_t        rcx;
131     };
132     union
133     {
134         uint16_t        sp;
135         uint32_t        esp;
136         uint64_t        rsp;
137     };
138     /* Note: lss esp, [] in the switcher needs some space, so we reserve it here instead of relying on the exact esp & ss layout as before. */
139     uint32_t            lss_esp;
140     RTSEL               ss;
141     RTSEL               ssPadding;
142
143     RTSEL               gs;
144     RTSEL               gsPadding;
145     RTSEL               fs;
146     RTSEL               fsPadding;
147     RTSEL               es;
148     RTSEL               esPadding;
149     RTSEL               ds;
150     RTSEL               dsPadding;
151     RTSEL               cs;
152     RTSEL               csPadding[3];  /* 3 words to force 8 byte alignment for the remainder */
153
154     union
155     {
156         X86EFLAGS       eflags;
157         X86RFLAGS       rflags;
158     };
159     union
160     {
161         uint16_t        ip;
162         uint32_t        eip;
163         uint64_t        rip;
164     };
165
166     uint64_t            r8;
167     uint64_t            r9;
168     uint64_t            r10;
169     uint64_t            r11;
170     uint64_t            r12;
171     uint64_t            r13;
172     uint64_t            r14;
173     uint64_t            r15;
174
175     /** Hidden selector registers.
176      * @{ */
177     CPUMSELREGHID   esHid;
178     CPUMSELREGHID   csHid;
179     CPUMSELREGHID   ssHid;
180     CPUMSELREGHID   dsHid;
181     CPUMSELREGHID   fsHid;
182     CPUMSELREGHID   gsHid;
183     /** @} */
184
185 } CPUMCTXCORE;
186 #pragma pack()
187
188
189 /**
190  * CPU context.
191  */
192 #pragma pack(1)
193 typedef struct CPUMCTX
194 {
195     /** FPU state. (16-byte alignment)
196      * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
197      *       actual format or convert it (waste of time).  */
198     X86FXSTATE      fpu;
199
200     /** CPUMCTXCORE Part.
201      * @{ */
202     union
203     {
204         uint16_t        di;
205         uint32_t        edi;
206         uint64_t        rdi;
207     };
208     union
209     {
210         uint16_t        si;
211         uint32_t        esi;
212         uint64_t        rsi;
213     };
214     union
215     {
216         uint16_t        bp;
217         uint32_t        ebp;
218         uint64_t        rbp;
219     };
220     union
221     {
222         uint16_t        ax;
223         uint32_t        eax;
224         uint64_t        rax;
225     };
226     union
227     {
228         uint16_t        bx;
229         uint32_t        ebx;
230         uint64_t        rbx;
231     };
232     union
233     {
234         uint16_t        dx;
235         uint32_t        edx;
236         uint64_t        rdx;
237     };
238     union
239     {
240         uint16_t        cx;
241         uint32_t        ecx;
242         uint64_t        rcx;
243     };
244     union
245     {
246         uint16_t        sp;
247         uint32_t        esp;
248         uint64_t        rsp;
249     };
250     /* Note: lss esp, [] in the switcher needs some space, so we reserve it here instead of relying on the exact esp & ss layout as before (prevented us from using a union with rsp). */
251     uint32_t            lss_esp;
252     RTSEL               ss;
253     RTSEL               ssPadding;
254
255     RTSEL               gs;
256     RTSEL               gsPadding;
257     RTSEL               fs;
258     RTSEL               fsPadding;
259     RTSEL               es;
260     RTSEL               esPadding;
261     RTSEL               ds;
262     RTSEL               dsPadding;
263     RTSEL               cs;
264     RTSEL               csPadding[3];  /* 3 words to force 8 byte alignment for the remainder */
265
266     union
267     {
268         X86EFLAGS       eflags;
269         X86RFLAGS       rflags;
270     };
271     union
272     {
273         uint16_t        ip;
274         uint32_t        eip;
275         uint64_t        rip;
276     };
277
278     uint64_t            r8;
279     uint64_t            r9;
280     uint64_t            r10;
281     uint64_t            r11;
282     uint64_t            r12;
283     uint64_t            r13;
284     uint64_t            r14;
285     uint64_t            r15;
286
287     /** Hidden selector registers.
288      * @{ */
289     CPUMSELREGHID   esHid;
290     CPUMSELREGHID   csHid;
291     CPUMSELREGHID   ssHid;
292     CPUMSELREGHID   dsHid;
293     CPUMSELREGHID   fsHid;
294     CPUMSELREGHID   gsHid;
295     /** @} */
296
297     /** @} */
298
299     /** Control registers.
300      * @{ */
301     uint64_t        cr0;
302     uint64_t        cr2;
303     uint64_t        cr3;
304     uint64_t        cr4;
305     /** @} */
306
307     /** Debug registers.
308      * @remarks DR4 and DR5 should not be used since they are aliases for
309      *          DR6 and DR7 respectively on both AMD and Intel CPUs.
310      * @remarks DR8-15 are currently not supported by AMD or Intel, so
311      *          neither do we.
312      * @{ */
313     uint64_t        dr[8];
314     /** @} */
315
316     /** Global Descriptor Table register. */
317     VBOXGDTR        gdtr;
318     uint16_t        gdtrPadding;
319     /** Interrupt Descriptor Table register. */
320     VBOXIDTR        idtr;
321     uint16_t        idtrPadding;
322     /** The task register.
323      * Only the guest context uses all the members. */
324     RTSEL           ldtr;
325     RTSEL           ldtrPadding;
326     /** The task register.
327      * Only the guest context uses all the members. */
328     RTSEL           tr;
329     RTSEL           trPadding;
330
331     /** The sysenter msr registers.
332      * This member is not used by the hypervisor context. */
333     CPUMSYSENTER    SysEnter;
334
335     /** System MSRs.
336      * @{ */
337     uint64_t        msrEFER;
338     uint64_t        msrSTAR;        /* legacy syscall eip, cs & ss */
339     uint64_t        msrPAT;
340     uint64_t        msrLSTAR;       /* 64 bits mode syscall rip */
341     uint64_t        msrCSTAR;       /* compatibility mode syscall rip */
342     uint64_t        msrSFMASK;      /* syscall flag mask */
343     uint64_t        msrKERNELGSBASE;/* swapgs exchange value */
344     /** @} */
345
346     /** Hidden selector registers.
347      * @{ */
348     CPUMSELREGHID   ldtrHid;
349     CPUMSELREGHID   trHid;
350     /** @} */
351
352 #if 0
353     /*& Padding to align the size on a 64 byte boundrary. */
354     uint32_t        padding[6];
355 #endif
356 } CPUMCTX;
357 #pragma pack()
358
359 /**
360  * Gets the CPUMCTXCORE part of a CPUMCTX.
361  */
362 #define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->edi)
363
364
365 /**
366  * Selector hidden registers, for version 1.6 saved state.
367  */
368 typedef struct CPUMSELREGHID_VER1_6
369 {
370     /** Base register. */
371     uint32_t    u32Base;
372     /** Limit (expanded). */
373     uint32_t    u32Limit;
374     /** Flags.
375      * This is the high 32-bit word of the descriptor entry.
376      * Only the flags, dpl and type are used. */
377     X86DESCATTR Attr;
378 } CPUMSELREGHID_VER1_6;
379
380 /**
381  * CPU context, for version 1.6 saved state.
382  * @remarks PATM uses this, which is why it has to be here.
383  */
384 #pragma pack(1)
385 typedef struct CPUMCTX_VER1_6
386 {
387     /** FPU state. (16-byte alignment)
388      * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
389      *       actual format or convert it (waste of time).  */
390     X86FXSTATE      fpu;
391
392     /** CPUMCTXCORE Part.
393      * @{ */
394     union
395     {
396         uint32_t        edi;
397         uint64_t        rdi;
398     };
399     union
400     {
401         uint32_t        esi;
402         uint64_t        rsi;
403     };
404     union
405     {
406         uint32_t        ebp;
407         uint64_t        rbp;
408     };
409     union
410     {
411         uint32_t        eax;
412         uint64_t        rax;
413     };
414     union
415     {
416         uint32_t        ebx;
417         uint64_t        rbx;
418     };
419     union
420     {
421         uint32_t        edx;
422         uint64_t        rdx;
423     };
424     union
425     {
426         uint32_t        ecx;
427         uint64_t        rcx;
428     };
429     /* Note: we rely on the exact layout, because we use lss esp, [] in the switcher */
430     uint32_t        esp;
431     RTSEL           ss;
432     RTSEL           ssPadding;
433     /* Note: no overlap with esp here. */
434     uint64_t        rsp_notused;
435
436     RTSEL           gs;
437     RTSEL           gsPadding;
438     RTSEL           fs;
439     RTSEL           fsPadding;
440     RTSEL           es;
441     RTSEL           esPadding;
442     RTSEL           ds;
443     RTSEL           dsPadding;
444     RTSEL           cs;
445     RTSEL           csPadding[3];  /* 3 words to force 8 byte alignment for the remainder */
446
447     union
448     {
449         X86EFLAGS       eflags;
450         X86RFLAGS       rflags;
451     };
452     union
453     {
454         uint32_t        eip;
455         uint64_t        rip;
456     };
457
458     uint64_t            r8;
459     uint64_t            r9;
460     uint64_t            r10;
461     uint64_t            r11;
462     uint64_t            r12;
463     uint64_t            r13;
464     uint64_t            r14;
465     uint64_t            r15;
466
467     /** Hidden selector registers.
468      * @{ */
469     CPUMSELREGHID_VER1_6   esHid;
470     CPUMSELREGHID_VER1_6   csHid;
471     CPUMSELREGHID_VER1_6   ssHid;
472     CPUMSELREGHID_VER1_6   dsHid;
473     CPUMSELREGHID_VER1_6   fsHid;
474     CPUMSELREGHID_VER1_6   gsHid;
475     /** @} */
476
477     /** @} */
478
479     /** Control registers.
480      * @{ */
481     uint64_t        cr0;
482     uint64_t        cr2;
483     uint64_t        cr3;
484     uint64_t        cr4;
485     uint64_t        cr8;
486     /** @} */
487
488     /** Debug registers.
489      * @{ */
490     uint64_t        dr0;
491     uint64_t        dr1;
492     uint64_t        dr2;
493     uint64_t        dr3;
494     uint64_t        dr4; /**< @todo remove dr4 and dr5. */
495     uint64_t        dr5;
496     uint64_t        dr6;
497     uint64_t        dr7;
498     /* DR8-15 are currently not supported */
499     /** @} */
500
501     /** Global Descriptor Table register. */
502     VBOXGDTR_VER1_6 gdtr;
503     uint16_t        gdtrPadding;
504     uint32_t        gdtrPadding64;/** @todo fix this hack */
505     /** Interrupt Descriptor Table register. */
506     VBOXIDTR_VER1_6 idtr;
507     uint16_t        idtrPadding;
508     uint32_t        idtrPadding64;/** @todo fix this hack */
509     /** The task register.
510      * Only the guest context uses all the members. */
511     RTSEL           ldtr;
512     RTSEL           ldtrPadding;
513     /** The task register.
514      * Only the guest context uses all the members. */
515     RTSEL           tr;
516     RTSEL           trPadding;
517
518     /** The sysenter msr registers.
519      * This member is not used by the hypervisor context. */
520     CPUMSYSENTER    SysEnter;
521
522     /** System MSRs.
523      * @{ */
524     uint64_t        msrEFER;
525     uint64_t        msrSTAR;
526     uint64_t        msrPAT;
527     uint64_t        msrLSTAR;
528     uint64_t        msrCSTAR;
529     uint64_t        msrSFMASK;
530     uint64_t        msrFSBASE;
531     uint64_t        msrGSBASE;
532     uint64_t        msrKERNELGSBASE;
533     /** @} */
534
535     /** Hidden selector registers.
536      * @{ */
537     CPUMSELREGHID_VER1_6   ldtrHid;
538     CPUMSELREGHID_VER1_6   trHid;
539     /** @} */
540
541     /* padding to get 32byte aligned size */
542     uint32_t        padding[2];
543 } CPUMCTX_VER1_6;
544 #pragma pack()
545
546
547 /**
548  * The register set returned by a CPUID operation.
549  */
550 typedef struct CPUMCPUID
551 {
552     uint32_t eax;
553     uint32_t ebx;
554     uint32_t ecx;
555     uint32_t edx;
556 } CPUMCPUID;
557 /** Pointer to a CPUID leaf. */
558 typedef CPUMCPUID *PCPUMCPUID;
559 /** Pointer to a const CPUID leaf. */
560 typedef const CPUMCPUID *PCCPUMCPUID;
561
562 /**
563  * CPUID feature to set or clear.
564  */
565 typedef enum CPUMCPUIDFEATURE
566 {
567     CPUMCPUIDFEATURE_INVALID = 0,
568     /** The APIC feature bit. (Std+Ext) */
569     CPUMCPUIDFEATURE_APIC,
570     /** The sysenter/sysexit feature bit. (Std) */
571     CPUMCPUIDFEATURE_SEP,
572     /** The SYSCALL/SYSEXIT feature bit (64 bits mode only for Intel CPUs). (Ext) */
573     CPUMCPUIDFEATURE_SYSCALL,
574     /** The PAE feature bit. (Std+Ext) */
575     CPUMCPUIDFEATURE_PAE,
576     /** The NXE feature bit. (Ext) */
577     CPUMCPUIDFEATURE_NXE,
578     /** The LAHF/SAHF feature bit (64 bits mode only). (Ext) */
579     CPUMCPUIDFEATURE_LAHF,
580     /** The LONG MODE feature bit. (Ext) */
581     CPUMCPUIDFEATURE_LONG_MODE,
582     /** The PAT feature bit. (Std+Ext) */
583     CPUMCPUIDFEATURE_PAT,
584     /** The x2APIC  feature bit. (Std) */
585     CPUMCPUIDFEATURE_X2APIC,
586     /** 32bit hackishness. */
587     CPUMCPUIDFEATURE_32BIT_HACK = 0x7fffffff
588 } CPUMCPUIDFEATURE;
589
590 /**
591  * CPU Vendor.
592  */
593 typedef enum CPUMCPUVENDOR
594 {
595     CPUMCPUVENDOR_INVALID = 0,
596     CPUMCPUVENDOR_INTEL,
597     CPUMCPUVENDOR_AMD,
598     CPUMCPUVENDOR_VIA,
599     CPUMCPUVENDOR_UNKNOWN,
600     /** 32bit hackishness. */
601     CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff
602 } CPUMCPUVENDOR;
603
604
605 /** @name Guest Register Getters.
606  * @{ */
607 VMMDECL(void)       CPUMGetGuestGDTR(PVM pVM, PVBOXGDTR pGDTR);
608 VMMDECL(RTGCPTR)    CPUMGetGuestIDTR(PVM pVM, uint16_t *pcbLimit);
609 VMMDECL(RTSEL)      CPUMGetGuestTR(PVM pVM);
610 VMMDECL(RTSEL)      CPUMGetGuestLDTR(PVM pVM);
611 VMMDECL(uint64_t)   CPUMGetGuestCR0(PVM pVM);
612 VMMDECL(uint64_t)   CPUMGetGuestCR2(PVM pVM);
613 VMMDECL(uint64_t)   CPUMGetGuestCR3(PVM pVM);
614 VMMDECL(uint64_t)   CPUMGetGuestCR4(PVM pVM);
615 VMMDECL(int) CPUMGetGuestCRx(PVM pVM, unsigned iReg, uint64_t *pValue);
616 VMMDECL(uint32_t)   CPUMGetGuestEFlags(PVM pVM);
617 VMMDECL(uint32_t)   CPUMGetGuestEIP(PVM pVM);
618 VMMDECL(uint64_t)   CPUMGetGuestRIP(PVM pVM);
619 VMMDECL(uint32_t)   CPUMGetGuestEAX(PVM pVM);
620 VMMDECL(uint32_t)   CPUMGetGuestEBX(PVM pVM);
621 VMMDECL(uint32_t)   CPUMGetGuestECX(PVM pVM);
622 VMMDECL(uint32_t)   CPUMGetGuestEDX(PVM pVM);
623 VMMDECL(uint32_t)   CPUMGetGuestESI(PVM pVM);
624 VMMDECL(uint32_t)   CPUMGetGuestEDI(PVM pVM);
625 VMMDECL(uint32_t)   CPUMGetGuestESP(PVM pVM);
626 VMMDECL(uint32_t)   CPUMGetGuestEBP(PVM pVM);
627 VMMDECL(RTSEL)      CPUMGetGuestCS(PVM pVM);
628 VMMDECL(RTSEL)      CPUMGetGuestDS(PVM pVM);
629 VMMDECL(RTSEL)      CPUMGetGuestES(PVM pVM);
630 VMMDECL(RTSEL)      CPUMGetGuestFS(PVM pVM);
631 VMMDECL(RTSEL)      CPUMGetGuestGS(PVM pVM);
632 VMMDECL(RTSEL)      CPUMGetGuestSS(PVM pVM);
633 VMMDECL(uint64_t)   CPUMGetGuestDR0(PVM pVM);
634 VMMDECL(uint64_t)   CPUMGetGuestDR1(PVM pVM);
635 VMMDECL(uint64_t)   CPUMGetGuestDR2(PVM pVM);
636 VMMDECL(uint64_t)   CPUMGetGuestDR3(PVM pVM);
637 VMMDECL(uint64_t)   CPUMGetGuestDR6(PVM pVM);
638 VMMDECL(uint64_t)   CPUMGetGuestDR7(PVM pVM);
639 VMMDECL(int)        CPUMGetGuestDRx(PVM pVM, uint32_t iReg, uint64_t *pValue);
640 VMMDECL(void)       CPUMGetGuestCpuId(PVM pVM, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
641 VMMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdStdRCPtr(PVM pVM);
642 VMMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdExtRCPtr(PVM pVM);
643 VMMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdCentaurRCPtr(PVM pVM);
644 VMMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdDefRCPtr(PVM pVM);
645 VMMDECL(uint32_t)   CPUMGetGuestCpuIdStdMax(PVM pVM);
646 VMMDECL(uint32_t)   CPUMGetGuestCpuIdExtMax(PVM pVM);
647 VMMDECL(uint32_t)   CPUMGetGuestCpuIdCentaurMax(PVM pVM);
648 VMMDECL(CPUMSELREGHID *) CPUMGetGuestTRHid(PVM pVM);
649 VMMDECL(uint64_t)   CPUMGetGuestEFER(PVM pVM);
650 VMMDECL(uint64_t) CPUMGetGuestMsr(PVM pVM, unsigned idMsr);
651 /** @} */
652
653 /** @name Guest Register Setters.
654  * @{ */
655 VMMDECL(int)        CPUMSetGuestGDTR(PVM pVM, uint32_t addr, uint16_t limit);
656 VMMDECL(int)        CPUMSetGuestIDTR(PVM pVM, uint32_t addr, uint16_t limit);
657 VMMDECL(int)        CPUMSetGuestTR(PVM pVM, uint16_t tr);
658 VMMDECL(int)        CPUMSetGuestLDTR(PVM pVM, uint16_t ldtr);
659 VMMDECL(int)        CPUMSetGuestCR0(PVM pVM, uint64_t cr0);
660 VMMDECL(int)        CPUMSetGuestCR2(PVM pVM, uint64_t cr2);
661 VMMDECL(int)        CPUMSetGuestCR3(PVM pVM, uint64_t cr3);
662 VMMDECL(int)        CPUMSetGuestCR4(PVM pVM, uint64_t cr4);
663 VMMDECL(int)        CPUMSetGuestDR0(PVM pVM, uint64_t uDr0);
664 VMMDECL(int)        CPUMSetGuestDR1(PVM pVM, uint64_t uDr1);
665 VMMDECL(int)        CPUMSetGuestDR2(PVM pVM, uint64_t uDr2);
666 VMMDECL(int)        CPUMSetGuestDR3(PVM pVM, uint64_t uDr3);
667 VMMDECL(int)        CPUMSetGuestDR6(PVM pVM, uint64_t uDr6);
668 VMMDECL(int)        CPUMSetGuestDR7(PVM pVM, uint64_t uDr7);
669 VMMDECL(int)        CPUMSetGuestDRx(PVM pVM, uint32_t iReg, uint64_t Value);
670 VMMDECL(int)        CPUMSetGuestEFlags(PVM pVM, uint32_t eflags);
671 VMMDECL(int)        CPUMSetGuestEIP(PVM pVM, uint32_t eip);
672 VMMDECL(int)        CPUMSetGuestEAX(PVM pVM, uint32_t eax);
673 VMMDECL(int)        CPUMSetGuestEBX(PVM pVM, uint32_t ebx);
674 VMMDECL(int)        CPUMSetGuestECX(PVM pVM, uint32_t ecx);
675 VMMDECL(int)        CPUMSetGuestEDX(PVM pVM, uint32_t edx);
676 VMMDECL(int)        CPUMSetGuestESI(PVM pVM, uint32_t esi);
677 VMMDECL(int)        CPUMSetGuestEDI(PVM pVM, uint32_t edi);
678 VMMDECL(int)        CPUMSetGuestESP(PVM pVM, uint32_t esp);
679 VMMDECL(int)        CPUMSetGuestEBP(PVM pVM, uint32_t ebp);
680 VMMDECL(int)        CPUMSetGuestCS(PVM pVM, uint16_t cs);
681 VMMDECL(int)        CPUMSetGuestDS(PVM pVM, uint16_t ds);
682 VMMDECL(int)        CPUMSetGuestES(PVM pVM, uint16_t es);
683 VMMDECL(int)        CPUMSetGuestFS(PVM pVM, uint16_t fs);
684 VMMDECL(int)        CPUMSetGuestGS(PVM pVM, uint16_t gs);
685 VMMDECL(int)        CPUMSetGuestSS(PVM pVM, uint16_t ss);
686 VMMDECL(void)       CPUMSetGuestEFER(PVM pVM, uint64_t val);
687 VMMDECL(void)       CPUMSetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
688 VMMDECL(void)       CPUMClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
689 VMMDECL(bool)       CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
690 VMMDECL(void) CPUMSetGuestCtx(PVM pVM, const PCPUMCTX pCtx);
691 /** @} */
692
693 /** @name Misc Guest Predicate Functions.
694  * @{  */
695
696
697 VMMDECL(bool)       CPUMIsGuestIn16BitCode(PVM pVM);
698 VMMDECL(bool)       CPUMIsGuestIn32BitCode(PVM pVM);
699 VMMDECL(CPUMCPUVENDOR) CPUMGetCPUVendor(PVM pVM);
700
701 /**
702  * Tests if the guest is running in real mode or not.
703  *
704  * @returns true if in real mode, otherwise false.
705  * @param   pVM     The VM handle.
706  */
707 DECLINLINE(bool) CPUMIsGuestInRealMode(PVM pVM)
708 {
709     return !(CPUMGetGuestCR0(pVM) & X86_CR0_PE);
710 }
711
712 /**
713  * Tests if the guest is running in real mode or not.
714  *
715  * @returns true if in real mode, otherwise false.
716  * @param   pCtx    Current CPU context
717  */
718 DECLINLINE(bool) CPUMIsGuestInRealModeEx(PCPUMCTX pCtx)
719 {
720     return !(pCtx->cr0 & X86_CR0_PE);
721 }
722
723 /**
724  * Tests if the guest is running in protected or not.
725  *
726  * @returns true if in protected mode, otherwise false.
727  * @param   pVM     The VM handle.
728  */
729 DECLINLINE(bool) CPUMIsGuestInProtectedMode(PVM pVM)
730 {
731     return !!(CPUMGetGuestCR0(pVM) & X86_CR0_PE);
732 }
733
734 /**
735  * Tests if the guest is running in paged protected or not.
736  *
737  * @returns true if in paged protected mode, otherwise false.
738  * @param   pVM     The VM handle.
739  */
740 DECLINLINE(bool) CPUMIsGuestInPagedProtectedMode(PVM pVM)
741 {
742     return (CPUMGetGuestCR0(pVM) & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
743 }
744
745 /**
746  * Tests if the guest is running in paged protected or not.
747  *
748  * @returns true if in paged protected mode, otherwise false.
749  * @param   pVM     The VM handle.
750  */
751 DECLINLINE(bool) CPUMIsGuestInPagedProtectedModeEx(PCPUMCTX pCtx)
752 {
753     return (pCtx->cr0 & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
754 }
755
756 /**
757  * Tests if the guest is running in long mode or not.
758  *
759  * @returns true if in long mode, otherwise false.
760  * @param   pVM     The VM handle.
761  */
762 DECLINLINE(bool) CPUMIsGuestInLongMode(PVM pVM)
763 {
764     return (CPUMGetGuestEFER(pVM) & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
765 }
766
767 /**
768  * Tests if the guest is running in long mode or not.
769  *
770  * @returns true if in long mode, otherwise false.
771  * @param   pCtx    Current CPU context
772  */
773 DECLINLINE(bool) CPUMIsGuestInLongModeEx(PCPUMCTX pCtx)
774 {
775     return (pCtx->msrEFER & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
776 }
777
778 /**
779  * Tests if the guest is running in 64 bits mode or not.
780  *
781  * @returns true if in 64 bits protected mode, otherwise false.
782  * @param   pVM     The VM handle.
783  * @param   pCtx    Current CPU context
784  */
785 DECLINLINE(bool) CPUMIsGuestIn64BitCode(PVM pVM, PCCPUMCTXCORE pCtx)
786 {
787     if (!CPUMIsGuestInLongMode(pVM))
788         return false;
789
790     return pCtx->csHid.Attr.n.u1Long;
791 }
792
793 /**
794  * Tests if the guest is running in 64 bits mode or not.
795  *
796  * @returns true if in 64 bits protected mode, otherwise false.
797  * @param   pVM     The VM handle.
798  * @param   pCtx    Current CPU context
799  */
800 DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCCPUMCTX pCtx)
801 {
802     if (!(pCtx->msrEFER & MSR_K6_EFER_LMA))
803         return false;
804
805     return pCtx->csHid.Attr.n.u1Long;
806 }
807
808 /**
809  * Tests if the guest is running in PAE mode or not.
810  *
811  * @returns true if in PAE mode, otherwise false.
812  * @param   pCtx    Current CPU context
813  */
814 DECLINLINE(bool) CPUMIsGuestInPAEModeEx(PCPUMCTX pCtx)
815 {
816     return (    CPUMIsGuestInPagedProtectedModeEx(pCtx)
817             &&  (pCtx->cr4 & X86_CR4_PAE)
818             &&  !CPUMIsGuestInLongModeEx(pCtx));
819 }
820
821 /** @} */
822
823
824 /** @name Hypervisor Register Getters.
825  * @{ */
826 VMMDECL(RTSEL)          CPUMGetHyperCS(PVM pVM);
827 VMMDECL(RTSEL)          CPUMGetHyperDS(PVM pVM);
828 VMMDECL(RTSEL)          CPUMGetHyperES(PVM pVM);
829 VMMDECL(RTSEL)          CPUMGetHyperFS(PVM pVM);
830 VMMDECL(RTSEL)          CPUMGetHyperGS(PVM pVM);
831 VMMDECL(RTSEL)          CPUMGetHyperSS(PVM pVM);
832 #if 0 /* these are not correct. */
833 VMMDECL(uint32_t)       CPUMGetHyperCR0(PVM pVM);
834 VMMDECL(uint32_t)       CPUMGetHyperCR2(PVM pVM);
835 VMMDECL(uint32_t)       CPUMGetHyperCR3(PVM pVM);
836 VMMDECL(uint32_t)       CPUMGetHyperCR4(PVM pVM);
837 #endif
838 /** This register is only saved on fatal traps. */
839 VMMDECL(uint32_t)       CPUMGetHyperEAX(PVM pVM);
840 VMMDECL(uint32_t)       CPUMGetHyperEBX(PVM pVM);
841 /** This register is only saved on fatal traps. */
842 VMMDECL(uint32_t)       CPUMGetHyperECX(PVM pVM);
843 /** This register is only saved on fatal traps. */
844 VMMDECL(uint32_t)       CPUMGetHyperEDX(PVM pVM);
845 VMMDECL(uint32_t)       CPUMGetHyperESI(PVM pVM);
846 VMMDECL(uint32_t)       CPUMGetHyperEDI(PVM pVM);
847 VMMDECL(uint32_t)       CPUMGetHyperEBP(PVM pVM);
848 VMMDECL(uint32_t)       CPUMGetHyperESP(PVM pVM);
849 VMMDECL(uint32_t)       CPUMGetHyperEFlags(PVM pVM);
850 VMMDECL(uint32_t)       CPUMGetHyperEIP(PVM pVM);
851 VMMDECL(uint64_t)       CPUMGetHyperRIP(PVM pVM);
852 VMMDECL(uint32_t)       CPUMGetHyperIDTR(PVM pVM, uint16_t *pcbLimit);
853 VMMDECL(uint32_t)       CPUMGetHyperGDTR(PVM pVM, uint16_t *pcbLimit);
854 VMMDECL(RTSEL)          CPUMGetHyperLDTR(PVM pVM);
855 VMMDECL(RTGCUINTREG)    CPUMGetHyperDR0(PVM pVM);
856 VMMDECL(RTGCUINTREG)    CPUMGetHyperDR1(PVM pVM);
857 VMMDECL(RTGCUINTREG)    CPUMGetHyperDR2(PVM pVM);
858 VMMDECL(RTGCUINTREG)    CPUMGetHyperDR3(PVM pVM);
859 VMMDECL(RTGCUINTREG)    CPUMGetHyperDR6(PVM pVM);
860 VMMDECL(RTGCUINTREG)    CPUMGetHyperDR7(PVM pVM);
861 VMMDECL(void)           CPUMGetHyperCtx(PVM pVM, PCPUMCTX pCtx);
862 /** @} */
863
864 /** @name Hypervisor Register Setters.
865  * @{ */
866 VMMDECL(void)           CPUMSetHyperGDTR(PVM pVM, uint32_t addr, uint16_t limit);
867 VMMDECL(void)           CPUMSetHyperLDTR(PVM pVM, RTSEL SelLDTR);
868 VMMDECL(void)           CPUMSetHyperIDTR(PVM pVM, uint32_t addr, uint16_t limit);
869 VMMDECL(void)           CPUMSetHyperCR3(PVM pVM, uint32_t cr3);
870 VMMDECL(void)           CPUMSetHyperTR(PVM pVM, RTSEL SelTR);
871 VMMDECL(void)           CPUMSetHyperCS(PVM pVM, RTSEL SelCS);
872 VMMDECL(void)           CPUMSetHyperDS(PVM pVM, RTSEL SelDS);
873 VMMDECL(void)           CPUMSetHyperES(PVM pVM, RTSEL SelDS);
874 VMMDECL(void)           CPUMSetHyperFS(PVM pVM, RTSEL SelDS);
875 VMMDECL(void)           CPUMSetHyperGS(PVM pVM, RTSEL SelDS);
876 VMMDECL(void)           CPUMSetHyperSS(PVM pVM, RTSEL SelSS);
877 VMMDECL(void)           CPUMSetHyperESP(PVM pVM, uint32_t u32ESP);
878 VMMDECL(int)            CPUMSetHyperEFlags(PVM pVM, uint32_t Efl);
879 VMMDECL(void)           CPUMSetHyperEIP(PVM pVM, uint32_t u32EIP);
880 VMMDECL(void)           CPUMSetHyperDR0(PVM pVM, RTGCUINTREG uDr0);
881 VMMDECL(void)           CPUMSetHyperDR1(PVM pVM, RTGCUINTREG uDr1);
882 VMMDECL(void)           CPUMSetHyperDR2(PVM pVM, RTGCUINTREG uDr2);
883 VMMDECL(void)           CPUMSetHyperDR3(PVM pVM, RTGCUINTREG uDr3);
884 VMMDECL(void)           CPUMSetHyperDR6(PVM pVM, RTGCUINTREG uDr6);
885 VMMDECL(void)           CPUMSetHyperDR7(PVM pVM, RTGCUINTREG uDr7);
886 VMMDECL(void) CPUMSetHyperCtx(PVM pVM, const PCPUMCTX pCtx);
887 VMMDECL(int)            CPUMRecalcHyperDRx(PVM pVM);
888 /** @} */
889
890 VMMDECL(void)           CPUMPushHyper(PVM pVM, uint32_t u32);
891 VMMDECL(void)           CPUMHyperSetCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore);
892 VMMDECL(PCPUMCTX)       CPUMQueryGuestCtxPtr(PVM pVM);
893 VMMDECL(PCPUMCTX)       CPUMQueryGuestCtxPtrEx(PVM pVM, PVMCPU pVCpu);
894 VMMDECL(int)            CPUMQueryHyperCtxPtr(PVM pVM, PCPUMCTX *ppCtx);
895 VMMDECL(PCCPUMCTXCORE)  CPUMGetGuestCtxCore(PVM pVM);
896 VMMDECL(PCCPUMCTXCORE)  CPUMGetGuestCtxCoreEx(PVM pVM, PVMCPU pVCpu);
897 VMMDECL(PCCPUMCTXCORE)  CPUMGetHyperCtxCore(PVM pVM);
898 VMMDECL(void)           CPUMSetGuestCtxCore(PVM pVM, PCCPUMCTXCORE pCtxCore);
899 VMMDECL(int)            CPUMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore);
900 VMMDECL(int) CPUMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rc);
901 VMMDECL(uint32_t)       CPUMRawGetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore);
902 VMMDECL(void)           CPUMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t eflags);
903 VMMDECL(int)            CPUMHandleLazyFPU(PVM pVM, PVMCPU pVCpu);
904 VMMDECL(int)            CPUMRestoreHostFPUState(PVM pVM, PVMCPU pVCpu);
905
906 /** @name Changed flags
907  * These flags are used to keep track of which important register that
908  * have been changed since last they were reset. The only one allowed
909  * to clear them is REM!
910  * @{
911  */
912 #define CPUM_CHANGED_FPU_REM            RT_BIT(0)
913 #define CPUM_CHANGED_CR0                RT_BIT(1)
914 #define CPUM_CHANGED_CR4                RT_BIT(2)
915 #define CPUM_CHANGED_GLOBAL_TLB_FLUSH   RT_BIT(3)
916 #define CPUM_CHANGED_CR3                RT_BIT(4)
917 #define CPUM_CHANGED_GDTR               RT_BIT(5)
918 #define CPUM_CHANGED_IDTR               RT_BIT(6)
919 #define CPUM_CHANGED_LDTR               RT_BIT(7)
920 #define CPUM_CHANGED_TR                 RT_BIT(8)
921 #define CPUM_CHANGED_SYSENTER_MSR       RT_BIT(9)
922 #define CPUM_CHANGED_HIDDEN_SEL_REGS    RT_BIT(10)
923 #define CPUM_CHANGED_CPUID              RT_BIT(11)
924 #define CPUM_CHANGED_ALL                (CPUM_CHANGED_FPU_REM|CPUM_CHANGED_CR0|CPUM_CHANGED_CR3|CPUM_CHANGED_CR4|CPUM_CHANGED_GDTR|CPUM_CHANGED_IDTR|CPUM_CHANGED_LDTR|CPUM_CHANGED_TR|CPUM_CHANGED_SYSENTER_MSR|CPUM_CHANGED_HIDDEN_SEL_REGS|CPUM_CHANGED_CPUID)
925 /** @} */
926
927 VMMDECL(unsigned)       CPUMGetAndClearChangedFlagsREM(PVM pVM);
928 VMMDECL(void)           CPUMSetChangedFlags(PVM pVM, uint32_t fChangedFlags);
929 VMMDECL(bool)           CPUMSupportsFXSR(PVM pVM);
930 VMMDECL(bool)           CPUM