VirtualBox

source: vbox/trunk/include/VBox/cpum.h@ 30681

Last change on this file since 30681 was 30263, checked in by vboxsync, 14 years ago

VMM,REM: Only invalidate hidden registers when using raw-mode. Fixes save restore during mode switching code like the windows boot menu. (#5057)

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette