VirtualBox

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

Last change on this file since 13287 was 13198, checked in by vboxsync, 16 years ago

Recommitted 37737 & 37738 minus the dangerous changes.

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