VirtualBox

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

Last change on this file since 32238 was 31489, checked in by vboxsync, 14 years ago

CPUMGetGuestCRx,CPUMGetGuestCR8: Do the PDM TPR querying in CPUM instead of EM so we don't need to duplicate code.

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