VirtualBox

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

Last change on this file since 24130 was 24061, checked in by vboxsync, 15 years ago

DBGF,DBGPlugInDiggers: Extended DBGFR3MemScan with an alignment restriction. Added DBGFR3CpuGetMode. Started on the WinNT debug digger - can detect the 32-bit kernel, locate the module list and report the nt version.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.4 KB
Line 
1/** @file
2 * CPUM - CPU Monitor(/ Manager). (VMM)
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
38RT_C_DECLS_BEGIN
39
40/** @defgroup grp_cpum The CPU Monitor / Manager API
41 * @{
42 */
43
44/**
45 * Selector hidden registers.
46 */
47typedef 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 */
69typedef 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)
88typedef 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)
193typedef 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 * Selector hidden registers, for version 1.6 saved state.
366 */
367typedef struct CPUMSELREGHID_VER1_6
368{
369 /** Base register. */
370 uint32_t u32Base;
371 /** Limit (expanded). */
372 uint32_t u32Limit;
373 /** Flags.
374 * This is the high 32-bit word of the descriptor entry.
375 * Only the flags, dpl and type are used. */
376 X86DESCATTR Attr;
377} CPUMSELREGHID_VER1_6;
378
379/**
380 * CPU context, for version 1.6 saved state.
381 * @remarks PATM uses this, which is why it has to be here.
382 */
383#pragma pack(1)
384typedef struct CPUMCTX_VER1_6
385{
386 /** FPU state. (16-byte alignment)
387 * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
388 * actual format or convert it (waste of time). */
389 X86FXSTATE fpu;
390
391 /** CPUMCTXCORE Part.
392 * @{ */
393 union
394 {
395 uint32_t edi;
396 uint64_t rdi;
397 };
398 union
399 {
400 uint32_t esi;
401 uint64_t rsi;
402 };
403 union
404 {
405 uint32_t ebp;
406 uint64_t rbp;
407 };
408 union
409 {
410 uint32_t eax;
411 uint64_t rax;
412 };
413 union
414 {
415 uint32_t ebx;
416 uint64_t rbx;
417 };
418 union
419 {
420 uint32_t edx;
421 uint64_t rdx;
422 };
423 union
424 {
425 uint32_t ecx;
426 uint64_t rcx;
427 };
428 /* Note: we rely on the exact layout, because we use lss esp, [] in the switcher */
429 uint32_t esp;
430 RTSEL ss;
431 RTSEL ssPadding;
432 /* Note: no overlap with esp here. */
433 uint64_t rsp_notused;
434
435 RTSEL gs;
436 RTSEL gsPadding;
437 RTSEL fs;
438 RTSEL fsPadding;
439 RTSEL es;
440 RTSEL esPadding;
441 RTSEL ds;
442 RTSEL dsPadding;
443 RTSEL cs;
444 RTSEL csPadding[3]; /* 3 words to force 8 byte alignment for the remainder */
445
446 union
447 {
448 X86EFLAGS eflags;
449 X86RFLAGS rflags;
450 };
451 union
452 {
453 uint32_t eip;
454 uint64_t rip;
455 };
456
457 uint64_t r8;
458 uint64_t r9;
459 uint64_t r10;
460 uint64_t r11;
461 uint64_t r12;
462 uint64_t r13;
463 uint64_t r14;
464 uint64_t r15;
465
466 /** Hidden selector registers.
467 * @{ */
468 CPUMSELREGHID_VER1_6 esHid;
469 CPUMSELREGHID_VER1_6 csHid;
470 CPUMSELREGHID_VER1_6 ssHid;
471 CPUMSELREGHID_VER1_6 dsHid;
472 CPUMSELREGHID_VER1_6 fsHid;
473 CPUMSELREGHID_VER1_6 gsHid;
474 /** @} */
475
476 /** @} */
477
478 /** Control registers.
479 * @{ */
480 uint64_t cr0;
481 uint64_t cr2;
482 uint64_t cr3;
483 uint64_t cr4;
484 uint64_t cr8;
485 /** @} */
486
487 /** Debug registers.
488 * @{ */
489 uint64_t dr0;
490 uint64_t dr1;
491 uint64_t dr2;
492 uint64_t dr3;
493 uint64_t dr4; /**< @todo remove dr4 and dr5. */
494 uint64_t dr5;
495 uint64_t dr6;
496 uint64_t dr7;
497 /* DR8-15 are currently not supported */
498 /** @} */
499
500 /** Global Descriptor Table register. */
501 VBOXGDTR_VER1_6 gdtr;
502 uint16_t gdtrPadding;
503 uint32_t gdtrPadding64;/** @todo fix this hack */
504 /** Interrupt Descriptor Table register. */
505 VBOXIDTR_VER1_6 idtr;
506 uint16_t idtrPadding;
507 uint32_t idtrPadding64;/** @todo fix this hack */
508 /** The task register.
509 * Only the guest context uses all the members. */
510 RTSEL ldtr;
511 RTSEL ldtrPadding;
512 /** The task register.
513 * Only the guest context uses all the members. */
514 RTSEL tr;
515 RTSEL trPadding;
516
517 /** The sysenter msr registers.
518 * This member is not used by the hypervisor context. */
519 CPUMSYSENTER SysEnter;
520
521 /** System MSRs.
522 * @{ */
523 uint64_t msrEFER;
524 uint64_t msrSTAR;
525 uint64_t msrPAT;
526 uint64_t msrLSTAR;
527 uint64_t msrCSTAR;
528 uint64_t msrSFMASK;
529 uint64_t msrFSBASE;
530 uint64_t msrGSBASE;
531 uint64_t msrKERNELGSBASE;
532 /** @} */
533
534 /** Hidden selector registers.
535 * @{ */
536 CPUMSELREGHID_VER1_6 ldtrHid;
537 CPUMSELREGHID_VER1_6 trHid;
538 /** @} */
539
540 /* padding to get 32byte aligned size */
541 uint32_t padding[2];
542} CPUMCTX_VER1_6;
543#pragma pack()
544
545/* Guest MSR state. */
546typedef union CPUMCTXMSR
547{
548 struct
549 {
550 uint64_t tscAux; /* MSR_K8_TSC_AUX */
551 } msr;
552 uint64_t au64[64];
553} CPUMCTXMSR;
554/** Pointer to the guest MSR state. */
555typedef CPUMCTXMSR *PCPUMCTXMSR;
556/** Pointer to the const guest MSR state. */
557typedef const CPUMCTXMSR *PCCPUMCTXMSR;
558
559
560/**
561 * The register set returned by a CPUID operation.
562 */
563typedef struct CPUMCPUID
564{
565 uint32_t eax;
566 uint32_t ebx;
567 uint32_t ecx;
568 uint32_t edx;
569} CPUMCPUID;
570/** Pointer to a CPUID leaf. */
571typedef CPUMCPUID *PCPUMCPUID;
572/** Pointer to a const CPUID leaf. */
573typedef const CPUMCPUID *PCCPUMCPUID;
574
575/**
576 * CPUID feature to set or clear.
577 */
578typedef enum CPUMCPUIDFEATURE
579{
580 CPUMCPUIDFEATURE_INVALID = 0,
581 /** The APIC feature bit. (Std+Ext) */
582 CPUMCPUIDFEATURE_APIC,
583 /** The sysenter/sysexit feature bit. (Std) */
584 CPUMCPUIDFEATURE_SEP,
585 /** The SYSCALL/SYSEXIT feature bit (64 bits mode only for Intel CPUs). (Ext) */
586 CPUMCPUIDFEATURE_SYSCALL,
587 /** The PAE feature bit. (Std+Ext) */
588 CPUMCPUIDFEATURE_PAE,
589 /** The NXE feature bit. (Ext) */
590 CPUMCPUIDFEATURE_NXE,
591 /** The LAHF/SAHF feature bit (64 bits mode only). (Ext) */
592 CPUMCPUIDFEATURE_LAHF,
593 /** The LONG MODE feature bit. (Ext) */
594 CPUMCPUIDFEATURE_LONG_MODE,
595 /** The PAT feature bit. (Std+Ext) */
596 CPUMCPUIDFEATURE_PAT,
597 /** The x2APIC feature bit. (Std) */
598 CPUMCPUIDFEATURE_X2APIC,
599 /** The RDTSCP feature bit. (Ext) */
600 CPUMCPUIDFEATURE_RDTSCP,
601 /** 32bit hackishness. */
602 CPUMCPUIDFEATURE_32BIT_HACK = 0x7fffffff
603} CPUMCPUIDFEATURE;
604
605/**
606 * CPU Vendor.
607 */
608typedef enum CPUMCPUVENDOR
609{
610 CPUMCPUVENDOR_INVALID = 0,
611 CPUMCPUVENDOR_INTEL,
612 CPUMCPUVENDOR_AMD,
613 CPUMCPUVENDOR_VIA,
614 CPUMCPUVENDOR_UNKNOWN,
615 CPUMCPUVENDOR_SYNTHETIC,
616 /** 32bit hackishness. */
617 CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff
618} CPUMCPUVENDOR;
619
620
621/** @name Guest Register Getters.
622 * @{ */
623VMMDECL(void) CPUMGetGuestGDTR(PVMCPU pVCpu, PVBOXGDTR pGDTR);
624VMMDECL(RTGCPTR) CPUMGetGuestIDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
625VMMDECL(RTSEL) CPUMGetGuestTR(PVMCPU pVCpu, PCPUMSELREGHID pHidden);
626VMMDECL(RTSEL) CPUMGetGuestLDTR(PVMCPU pVCpu);
627VMMDECL(uint64_t) CPUMGetGuestCR0(PVMCPU pVCpu);
628VMMDECL(uint64_t) CPUMGetGuestCR2(PVMCPU pVCpu);
629VMMDECL(uint64_t) CPUMGetGuestCR3(PVMCPU pVCpu);
630VMMDECL(uint64_t) CPUMGetGuestCR4(PVMCPU pVCpu);
631VMMDECL(int) CPUMGetGuestCRx(PVMCPU pVCpu, unsigned iReg, uint64_t *pValue);
632VMMDECL(uint32_t) CPUMGetGuestEFlags(PVMCPU pVCpu);
633VMMDECL(uint32_t) CPUMGetGuestEIP(PVMCPU pVCpu);
634VMMDECL(uint64_t) CPUMGetGuestRIP(PVMCPU pVCpu);
635VMMDECL(uint32_t) CPUMGetGuestEAX(PVMCPU pVCpu);
636VMMDECL(uint32_t) CPUMGetGuestEBX(PVMCPU pVCpu);
637VMMDECL(uint32_t) CPUMGetGuestECX(PVMCPU pVCpu);
638VMMDECL(uint32_t) CPUMGetGuestEDX(PVMCPU pVCpu);
639VMMDECL(uint32_t) CPUMGetGuestESI(PVMCPU pVCpu);
640VMMDECL(uint32_t) CPUMGetGuestEDI(PVMCPU pVCpu);
641VMMDECL(uint32_t) CPUMGetGuestESP(PVMCPU pVCpu);
642VMMDECL(uint32_t) CPUMGetGuestEBP(PVMCPU pVCpu);
643VMMDECL(RTSEL) CPUMGetGuestCS(PVMCPU pVCpu);
644VMMDECL(RTSEL) CPUMGetGuestDS(PVMCPU pVCpu);
645VMMDECL(RTSEL) CPUMGetGuestES(PVMCPU pVCpu);
646VMMDECL(RTSEL) CPUMGetGuestFS(PVMCPU pVCpu);
647VMMDECL(RTSEL) CPUMGetGuestGS(PVMCPU pVCpu);
648VMMDECL(RTSEL) CPUMGetGuestSS(PVMCPU pVCpu);
649VMMDECL(uint64_t) CPUMGetGuestDR0(PVMCPU pVCpu);
650VMMDECL(uint64_t) CPUMGetGuestDR1(PVMCPU pVCpu);
651VMMDECL(uint64_t) CPUMGetGuestDR2(PVMCPU pVCpu);
652VMMDECL(uint64_t) CPUMGetGuestDR3(PVMCPU pVCpu);
653VMMDECL(uint64_t) CPUMGetGuestDR6(PVMCPU pVCpu);
654VMMDECL(uint64_t) CPUMGetGuestDR7(PVMCPU pVCpu);
655VMMDECL(int) CPUMGetGuestDRx(PVMCPU pVCpu, uint32_t iReg, uint64_t *pValue);
656VMMDECL(void) CPUMGetGuestCpuId(PVMCPU pVCpu, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
657VMMDECL(uint32_t) CPUMGetGuestCpuIdStdMax(PVM pVM);
658VMMDECL(uint32_t) CPUMGetGuestCpuIdExtMax(PVM pVM);
659VMMDECL(uint32_t) CPUMGetGuestCpuIdCentaurMax(PVM pVM);
660VMMDECL(uint64_t) CPUMGetGuestEFER(PVMCPU pVCpu);
661VMMDECL(uint64_t) CPUMGetGuestMsr(PVMCPU pVCpu, unsigned idMsr);
662VMMDECL(void) CPUMSetGuestMsr(PVMCPU pVCpu, unsigned idMsr, uint64_t valMsr);
663/** @} */
664
665/** @name Guest Register Setters.
666 * @{ */
667VMMDECL(int) CPUMSetGuestGDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
668VMMDECL(int) CPUMSetGuestIDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
669VMMDECL(int) CPUMSetGuestTR(PVMCPU pVCpu, uint16_t tr);
670VMMDECL(int) CPUMSetGuestLDTR(PVMCPU pVCpu, uint16_t ldtr);
671VMMDECL(int) CPUMSetGuestCR0(PVMCPU pVCpu, uint64_t cr0);
672VMMDECL(int) CPUMSetGuestCR2(PVMCPU pVCpu, uint64_t cr2);
673VMMDECL(int) CPUMSetGuestCR3(PVMCPU pVCpu, uint64_t cr3);
674VMMDECL(int) CPUMSetGuestCR4(PVMCPU pVCpu, uint64_t cr4);
675VMMDECL(int) CPUMSetGuestDR0(PVMCPU pVCpu, uint64_t uDr0);
676VMMDECL(int) CPUMSetGuestDR1(PVMCPU pVCpu, uint64_t uDr1);
677VMMDECL(int) CPUMSetGuestDR2(PVMCPU pVCpu, uint64_t uDr2);
678VMMDECL(int) CPUMSetGuestDR3(PVMCPU pVCpu, uint64_t uDr3);
679VMMDECL(int) CPUMSetGuestDR6(PVMCPU pVCpu, uint64_t uDr6);
680VMMDECL(int) CPUMSetGuestDR7(PVMCPU pVCpu, uint64_t uDr7);
681VMMDECL(int) CPUMSetGuestDRx(PVMCPU pVCpu, uint32_t iReg, uint64_t Value);
682VMMDECL(int) CPUMSetGuestEFlags(PVMCPU pVCpu, uint32_t eflags);
683VMMDECL(int) CPUMSetGuestEIP(PVMCPU pVCpu, uint32_t eip);
684VMMDECL(int) CPUMSetGuestEAX(PVMCPU pVCpu, uint32_t eax);
685VMMDECL(int) CPUMSetGuestEBX(PVMCPU pVCpu, uint32_t ebx);
686VMMDECL(int) CPUMSetGuestECX(PVMCPU pVCpu, uint32_t ecx);
687VMMDECL(int) CPUMSetGuestEDX(PVMCPU pVCpu, uint32_t edx);
688VMMDECL(int) CPUMSetGuestESI(PVMCPU pVCpu, uint32_t esi);
689VMMDECL(int) CPUMSetGuestEDI(PVMCPU pVCpu, uint32_t edi);
690VMMDECL(int) CPUMSetGuestESP(PVMCPU pVCpu, uint32_t esp);
691VMMDECL(int) CPUMSetGuestEBP(PVMCPU pVCpu, uint32_t ebp);
692VMMDECL(int) CPUMSetGuestCS(PVMCPU pVCpu, uint16_t cs);
693VMMDECL(int) CPUMSetGuestDS(PVMCPU pVCpu, uint16_t ds);
694VMMDECL(int) CPUMSetGuestES(PVMCPU pVCpu, uint16_t es);
695VMMDECL(int) CPUMSetGuestFS(PVMCPU pVCpu, uint16_t fs);
696VMMDECL(int) CPUMSetGuestGS(PVMCPU pVCpu, uint16_t gs);
697VMMDECL(int) CPUMSetGuestSS(PVMCPU pVCpu, uint16_t ss);
698VMMDECL(void) CPUMSetGuestEFER(PVMCPU pVCpu, uint64_t val);
699VMMDECL(void) CPUMSetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
700VMMDECL(void) CPUMClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
701VMMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
702VMMDECL(void) CPUMSetGuestCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
703/** @} */
704
705/** @name Misc Guest Predicate Functions.
706 * @{ */
707
708
709VMMDECL(bool) CPUMIsGuestIn16BitCode(PVMCPU pVCpu);
710VMMDECL(bool) CPUMIsGuestIn32BitCode(PVMCPU pVCpu);
711
712VMMDECL(CPUMCPUVENDOR) CPUMGetGuestCpuVendor(PVM pVM);
713VMMDECL(CPUMCPUVENDOR) CPUMGetHostCpuVendor(PVM pVM);
714
715/**
716 * Tests if the guest is running in real mode or not.
717 *
718 * @returns true if in real mode, otherwise false.
719 * @param pVM The VM handle.
720 */
721DECLINLINE(bool) CPUMIsGuestInRealMode(PVMCPU pVCpu)
722{
723 return !(CPUMGetGuestCR0(pVCpu) & X86_CR0_PE);
724}
725
726/**
727 * Tests if the guest is running in real mode or not.
728 *
729 * @returns true if in real mode, otherwise false.
730 * @param pCtx Current CPU context
731 */
732DECLINLINE(bool) CPUMIsGuestInRealModeEx(PCPUMCTX pCtx)
733{
734 return !(pCtx->cr0 & X86_CR0_PE);
735}
736
737/**
738 * Tests if the guest is running in protected or not.
739 *
740 * @returns true if in protected mode, otherwise false.
741 * @param pVM The VM handle.
742 */
743DECLINLINE(bool) CPUMIsGuestInProtectedMode(PVMCPU pVCpu)
744{
745 return !!(CPUMGetGuestCR0(pVCpu) & X86_CR0_PE);
746}
747
748/**
749 * Tests if the guest is running in paged protected or not.
750 *
751 * @returns true if in paged protected mode, otherwise false.
752 * @param pVM The VM handle.
753 */
754DECLINLINE(bool) CPUMIsGuestInPagedProtectedMode(PVMCPU pVCpu)
755{
756 return (CPUMGetGuestCR0(pVCpu) & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
757}
758
759/**
760 * Tests if the guest is running in paged protected or not.
761 *
762 * @returns true if in paged protected mode, otherwise false.
763 * @param pVM The VM handle.
764 */
765DECLINLINE(bool) CPUMIsGuestInPagedProtectedModeEx(PCPUMCTX pCtx)
766{
767 return (pCtx->cr0 & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
768}
769
770/**
771 * Tests if the guest is running in long mode or not.
772 *
773 * @returns true if in long mode, otherwise false.
774 * @param pVM The VM handle.
775 */
776DECLINLINE(bool) CPUMIsGuestInLongMode(PVMCPU pVCpu)
777{
778 return (CPUMGetGuestEFER(pVCpu) & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
779}
780
781/**
782 * Tests if the guest is running in long mode or not.
783 *
784 * @returns true if in long mode, otherwise false.
785 * @param pCtx Current CPU context
786 */
787DECLINLINE(bool) CPUMIsGuestInLongModeEx(PCPUMCTX pCtx)
788{
789 return (pCtx->msrEFER & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
790}
791
792/**
793 * Tests if the guest is running in 64 bits mode or not.
794 *
795 * @returns true if in 64 bits protected mode, otherwise false.
796 * @param pVM The VM handle.
797 * @param pCtx Current CPU context
798 */
799DECLINLINE(bool) CPUMIsGuestIn64BitCode(PVMCPU pVCpu, PCCPUMCTXCORE pCtx)
800{
801 if (!CPUMIsGuestInLongMode(pVCpu))
802 return false;
803
804 return pCtx->csHid.Attr.n.u1Long;
805}
806
807/**
808 * Tests if the guest is running in 64 bits mode or not.
809 *
810 * @returns true if in 64 bits protected mode, otherwise false.
811 * @param pVM The VM handle.
812 * @param pCtx Current CPU context
813 */
814DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCCPUMCTX pCtx)
815{
816 if (!(pCtx->msrEFER & MSR_K6_EFER_LMA))
817 return false;
818
819 return pCtx->csHid.Attr.n.u1Long;
820}
821
822/**
823 * Tests if the guest is running in PAE mode or not.
824 *
825 * @returns true if in PAE mode, otherwise false.
826 * @param pVM The VM handle.
827 */
828DECLINLINE(bool) CPUMIsGuestInPAEMode(PVMCPU pVCpu)
829{
830 return ( CPUMIsGuestInPagedProtectedMode(pVCpu)
831 && (CPUMGetGuestCR4(pVCpu) & X86_CR4_PAE)
832 && !CPUMIsGuestInLongMode(pVCpu));
833}
834
835/**
836 * Tests if the guest is running in PAE mode or not.
837 *
838 * @returns true if in PAE mode, otherwise false.
839 * @param pCtx Current CPU context
840 */
841DECLINLINE(bool) CPUMIsGuestInPAEModeEx(PCPUMCTX pCtx)
842{
843 return ( CPUMIsGuestInPagedProtectedModeEx(pCtx)
844 && (pCtx->cr4 & X86_CR4_PAE)
845 && !CPUMIsGuestInLongModeEx(pCtx));
846}
847
848/** @} */
849
850
851/** @name Hypervisor Register Getters.
852 * @{ */
853VMMDECL(RTSEL) CPUMGetHyperCS(PVMCPU pVCpu);
854VMMDECL(RTSEL) CPUMGetHyperDS(PVMCPU pVCpu);
855VMMDECL(RTSEL) CPUMGetHyperES(PVMCPU pVCpu);
856VMMDECL(RTSEL) CPUMGetHyperFS(PVMCPU pVCpu);
857VMMDECL(RTSEL) CPUMGetHyperGS(PVMCPU pVCpu);
858VMMDECL(RTSEL) CPUMGetHyperSS(PVMCPU pVCpu);
859#if 0 /* these are not correct. */
860VMMDECL(uint32_t) CPUMGetHyperCR0(PVMCPU pVCpu);
861VMMDECL(uint32_t) CPUMGetHyperCR2(PVMCPU pVCpu);
862VMMDECL(uint32_t) CPUMGetHyperCR3(PVMCPU pVCpu);
863VMMDECL(uint32_t) CPUMGetHyperCR4(PVMCPU pVCpu);
864#endif
865/** This register is only saved on fatal traps. */
866VMMDECL(uint32_t) CPUMGetHyperEAX(PVMCPU pVCpu);
867VMMDECL(uint32_t) CPUMGetHyperEBX(PVMCPU pVCpu);
868/** This register is only saved on fatal traps. */
869VMMDECL(uint32_t) CPUMGetHyperECX(PVMCPU pVCpu);
870/** This register is only saved on fatal traps. */
871VMMDECL(uint32_t) CPUMGetHyperEDX(PVMCPU pVCpu);
872VMMDECL(uint32_t) CPUMGetHyperESI(PVMCPU pVCpu);
873VMMDECL(uint32_t) CPUMGetHyperEDI(PVMCPU pVCpu);
874VMMDECL(uint32_t) CPUMGetHyperEBP(PVMCPU pVCpu);
875VMMDECL(uint32_t) CPUMGetHyperESP(PVMCPU pVCpu);
876VMMDECL(uint32_t) CPUMGetHyperEFlags(PVMCPU pVCpu);
877VMMDECL(uint32_t) CPUMGetHyperEIP(PVMCPU pVCpu);
878VMMDECL(uint64_t) CPUMGetHyperRIP(PVMCPU pVCpu);
879VMMDECL(uint32_t) CPUMGetHyperIDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
880VMMDECL(uint32_t) CPUMGetHyperGDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
881VMMDECL(RTSEL) CPUMGetHyperLDTR(PVMCPU pVCpu);
882VMMDECL(RTGCUINTREG) CPUMGetHyperDR0(PVMCPU pVCpu);
883VMMDECL(RTGCUINTREG) CPUMGetHyperDR1(PVMCPU pVCpu);
884VMMDECL(RTGCUINTREG) CPUMGetHyperDR2(PVMCPU pVCpu);
885VMMDECL(RTGCUINTREG) CPUMGetHyperDR3(PVMCPU pVCpu);
886VMMDECL(RTGCUINTREG) CPUMGetHyperDR6(PVMCPU pVCpu);
887VMMDECL(RTGCUINTREG) CPUMGetHyperDR7(PVMCPU pVCpu);
888VMMDECL(void) CPUMGetHyperCtx(PVMCPU pVCpu, PCPUMCTX pCtx);
889VMMDECL(uint32_t) CPUMGetHyperCR3(PVMCPU pVCpu);
890/** @} */
891
892/** @name Hypervisor Register Setters.
893 * @{ */
894VMMDECL(void) CPUMSetHyperGDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
895VMMDECL(void) CPUMSetHyperLDTR(PVMCPU pVCpu, RTSEL SelLDTR);
896VMMDECL(void) CPUMSetHyperIDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
897VMMDECL(void) CPUMSetHyperCR3(PVMCPU pVCpu, uint32_t cr3);
898VMMDECL(void) CPUMSetHyperTR(PVMCPU pVCpu, RTSEL SelTR);
899VMMDECL(void) CPUMSetHyperCS(PVMCPU pVCpu, RTSEL SelCS);
900VMMDECL(void) CPUMSetHyperDS(PVMCPU pVCpu, RTSEL SelDS);
901VMMDECL(void) CPUMSetHyperES(PVMCPU pVCpu, RTSEL SelDS);
902VMMDECL(void) CPUMSetHyperFS(PVMCPU pVCpu, RTSEL SelDS);
903VMMDECL(void) CPUMSetHyperGS(PVMCPU pVCpu, RTSEL SelDS);
904VMMDECL(void) CPUMSetHyperSS(PVMCPU pVCpu, RTSEL SelSS);
905VMMDECL(void) CPUMSetHyperESP(PVMCPU pVCpu, uint32_t u32ESP);
906VMMDECL(int) CPUMSetHyperEFlags(PVMCPU pVCpu, uint32_t Efl);
907VMMDECL(void) CPUMSetHyperEIP(PVMCPU pVCpu, uint32_t u32EIP);
908VMMDECL(void) CPUMSetHyperDR0(PVMCPU pVCpu, RTGCUINTREG uDr0);
909VMMDECL(void) CPUMSetHyperDR1(PVMCPU pVCpu, RTGCUINTREG uDr1);
910VMMDECL(void) CPUMSetHyperDR2(PVMCPU pVCpu, RTGCUINTREG uDr2);
911VMMDECL(void) CPUMSetHyperDR3(PVMCPU pVCpu, RTGCUINTREG uDr3);
912VMMDECL(void) CPUMSetHyperDR6(PVMCPU pVCpu, RTGCUINTREG uDr6);
913VMMDECL(void) CPUMSetHyperDR7(PVMCPU pVCpu, RTGCUINTREG uDr7);
914VMMDECL(void) CPUMSetHyperCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
915VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu);
916/** @} */
917
918VMMDECL(void) CPUMPushHyper(PVMCPU pVCpu, uint32_t u32);
919VMMDECL(void) CPUMHyperSetCtxCore(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
920VMMDECL(int) CPUMQueryHyperCtxPtr(PVMCPU pVCpu, PCPUMCTX *ppCtx);
921VMMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVMCPU pVCpu);
922VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu);
923VMMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVMCPU pVCpu);
924VMMDECL(void) CPUMSetGuestCtxCore(PVMCPU pVCpu, PCCPUMCTXCORE pCtxCore);
925VMMDECL(int) CPUMRawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
926VMMDECL(int) CPUMRawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc);
927VMMDECL(uint32_t) CPUMRawGetEFlags(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
928VMMDECL(void) CPUMRawSetEFlags(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t eflags);
929VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu);
930
931/** @name Changed flags
932 * These flags are used to keep track of which important register that
933 * have been changed since last they were reset. The only one allowed
934 * to clear them is REM!
935 * @{
936 */
937#define CPUM_CHANGED_FPU_REM RT_BIT(0)
938#define CPUM_CHANGED_CR0 RT_BIT(1)
939#define CPUM_CHANGED_CR4 RT_BIT(2)
940#define CPUM_CHANGED_GLOBAL_TLB_FLUSH RT_BIT(3)
941#define CPUM_CHANGED_CR3 RT_BIT(4)
942#define CPUM_CHANGED_GDTR RT_BIT(5)
943#define CPUM_CHANGED_IDTR RT_BIT(6)
944#define CPUM_CHANGED_LDTR RT_BIT(7)
945#define CPUM_CHANGED_TR RT_BIT(8)
946#define CPUM_CHANGED_SYSENTER_MSR RT_BIT(9)
947#define CPUM_CHANGED_HIDDEN_SEL_REGS RT_BIT(10)
948#define CPUM_CHANGED_CPUID RT_BIT(11)
949#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)
950/** @} */
951
952VMMDECL(unsigned) CPUMGetAndClearChangedFlagsREM(PVMCPU pVCpu);
953VMMDECL(void) CPUMSetChangedFlags(PVMCPU pVCpu, uint32_t fChangedFlags);
954VMMDECL(bool) CPUMSupportsFXSR(PVM pVM);
955VMMDECL(bool) CPUMIsHostUsingSysEnter(PVM pVM);
956VMMDECL(bool) CPUMIsHostUsingSysCall(PVM pVM);
957VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCPU);
958VMMDECL(void) CPUMDeactivateGuestFPUState(PVMCPU pVCpu);
959VMMDECL(bool) CPUMIsGuestDebugStateActive(PVMCPU pVCpu);
960VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu);
961VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu);
962VMMDECL(void) CPUMDeactivateHyperDebugState(PVMCPU pVCpu);
963VMMDECL(uint32_t) CPUMGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
964VMMDECL(bool) CPUMAreHiddenSelRegsValid(PVM pVM);
965VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu);
966
967
968#ifdef IN_RING3
969/** @defgroup grp_cpum_r3 The CPU Monitor(/Manager) API
970 * @ingroup grp_cpum
971 * @{
972 */
973
974VMMR3DECL(int) CPUMR3Init(PVM pVM);
975VMMR3DECL(int) CPUMR3InitCPU(PVM pVM);
976VMMR3DECL(void) CPUMR3Relocate(PVM pVM);
977VMMR3DECL(int) CPUMR3Term(PVM pVM);
978VMMR3DECL(int) CPUMR3TermCPU(PVM pVM);
979VMMR3DECL(void) CPUMR3Reset(PVM pVM);
980VMMR3DECL(void) CPUMR3ResetCpu(PVMCPU pVCpu);
981# ifdef DEBUG
982VMMR3DECL(void) CPUMR3SaveEntryCtx(PVM pVM);
983# endif
984VMMR3DECL(int) CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd);
985
986VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdStdRCPtr(PVM pVM);
987VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdExtRCPtr(PVM pVM);
988VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdCentaurRCPtr(PVM pVM);
989VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdDefRCPtr(PVM pVM);
990
991/** @} */
992#endif /* IN_RING3 */
993
994#ifdef IN_RC
995/** @defgroup grp_cpum_gc The CPU Monitor(/Manager) API
996 * @ingroup grp_cpum
997 * @{
998 */
999
1000/**
1001 * Calls a guest trap/interrupt handler directly
1002 * Assumes a trap stack frame has already been setup on the guest's stack!
1003 *
1004 * @param pRegFrame Original trap/interrupt context
1005 * @param selCS Code selector of handler
1006 * @param pHandler GC virtual address of handler
1007 * @param eflags Callee's EFLAGS
1008 * @param selSS Stack selector for handler
1009 * @param pEsp Stack address for handler
1010 *
1011 * This function does not return!
1012 */
1013DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTRCPTR pHandler, uint32_t eflags, uint32_t selSS, RTRCPTR pEsp);
1014VMMRCDECL(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
1015
1016/** @} */
1017#endif /* IN_RC */
1018
1019#ifdef IN_RING0
1020/** @defgroup grp_cpum_r0 The CPU Monitor(/Manager) API
1021 * @ingroup grp_cpum
1022 * @{
1023 */
1024VMMR0DECL(int) CPUMR0Init(PVM pVM);
1025VMMR0DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
1026VMMR0DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
1027VMMR0DECL(int) CPUMR0SaveGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
1028VMMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
1029VMMR0DECL(int) CPUMR0LoadHostDebugState(PVM pVM, PVMCPU pVCpu);
1030VMMR0DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu);
1031VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
1032
1033/** @} */
1034#endif /* IN_RING0 */
1035
1036/** @} */
1037RT_C_DECLS_END
1038
1039
1040#endif
1041
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