VirtualBox

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

Last change on this file since 11454 was 11424, checked in by vboxsync, 16 years ago

Emulate stosw/d/q ourselves.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.0 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 * @{ */
309 uint64_t dr0;
310 uint64_t dr1;
311 uint64_t dr2;
312 uint64_t dr3;
313 uint64_t dr4; /**< @todo remove dr4 and dr5. */
314 uint64_t dr5;
315 uint64_t dr6;
316 uint64_t dr7;
317 /* DR8-15 are currently not supported */
318 /** @} */
319
320 /** Global Descriptor Table register. */
321 VBOXGDTR gdtr;
322 uint16_t gdtrPadding;
323 /** Interrupt Descriptor Table register. */
324 VBOXIDTR idtr;
325 uint16_t idtrPadding;
326 /** The task register.
327 * Only the guest context uses all the members. */
328 RTSEL ldtr;
329 RTSEL ldtrPadding;
330 /** The task register.
331 * Only the guest context uses all the members. */
332 RTSEL tr;
333 RTSEL trPadding;
334
335 /** The sysenter msr registers.
336 * This member is not used by the hypervisor context. */
337 CPUMSYSENTER SysEnter;
338
339 /** System MSRs.
340 * @{ */
341 uint64_t msrEFER;
342 uint64_t msrSTAR; /* legacy syscall eip, cs & ss */
343 uint64_t msrPAT;
344 uint64_t msrLSTAR; /* 64 bits mode syscall rip */
345 uint64_t msrCSTAR; /* compatibility mode syscall rip */
346 uint64_t msrSFMASK; /* syscall flag mask */
347 uint64_t msrKERNELGSBASE;/* swapgs exchange value */
348 /** @} */
349
350 /** Hidden selector registers.
351 * @{ */
352 CPUMSELREGHID ldtrHid;
353 CPUMSELREGHID trHid;
354 /** @} */
355
356 /* padding to get 32byte aligned size */
357//// uint32_t padding[6];
358} CPUMCTX;
359#pragma pack()
360
361/**
362 * Gets the CPUMCTXCORE part of a CPUMCTX.
363 */
364#define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->edi)
365
366/**
367 * The register set returned by a CPUID operation.
368 */
369typedef struct CPUMCPUID
370{
371 uint32_t eax;
372 uint32_t ebx;
373 uint32_t ecx;
374 uint32_t edx;
375} CPUMCPUID;
376/** Pointer to a CPUID leaf. */
377typedef CPUMCPUID *PCPUMCPUID;
378/** Pointer to a const CPUID leaf. */
379typedef const CPUMCPUID *PCCPUMCPUID;
380
381/**
382 * CPUID feature to set or clear.
383 */
384typedef enum CPUMCPUIDFEATURE
385{
386 CPUMCPUIDFEATURE_INVALID = 0,
387 /** The APIC feature bit. (Std+Ext) */
388 CPUMCPUIDFEATURE_APIC,
389 /** The sysenter/sysexit feature bit. (Std) */
390 CPUMCPUIDFEATURE_SEP,
391 /** The SYSCALL/SYSEXIT feature bit (64 bits mode only for Intel CPUs). (Ext) */
392 CPUMCPUIDFEATURE_SYSCALL,
393 /** The PAE feature bit. (Std+Ext) */
394 CPUMCPUIDFEATURE_PAE,
395 /** The NXE feature bit. (Ext) */
396 CPUMCPUIDFEATURE_NXE,
397 /** The LAHF/SAHF feature bit (64 bits mode only). (Ext) */
398 CPUMCPUIDFEATURE_LAHF,
399 /** The LONG MODE feature bit. (Ext) */
400 CPUMCPUIDFEATURE_LONG_MODE
401} CPUMCPUIDFEATURE;
402
403/*
404 * CPU Vendor.
405 */
406typedef enum CPUMCPUVENDOR
407{
408 CPUMCPUVENDOR_INVALID = 0,
409 CPUMCPUVENDOR_INTEL,
410 CPUMCPUVENDOR_AMD,
411 CPUMCPUVENDOR_VIA,
412 CPUMCPUVENDOR_UNKNOWN,
413 /** 32bit hackishness. */
414 CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff
415} CPUMCPUVENDOR;
416
417
418/** @name Guest Register Getters.
419 * @{ */
420CPUMDECL(void) CPUMGetGuestGDTR(PVM pVM, PVBOXGDTR pGDTR);
421CPUMDECL(RTGCPTR) CPUMGetGuestIDTR(PVM pVM, uint16_t *pcbLimit);
422CPUMDECL(RTSEL) CPUMGetGuestTR(PVM pVM);
423CPUMDECL(RTSEL) CPUMGetGuestLDTR(PVM pVM);
424CPUMDECL(uint64_t) CPUMGetGuestCR0(PVM pVM);
425CPUMDECL(uint64_t) CPUMGetGuestCR2(PVM pVM);
426CPUMDECL(uint64_t) CPUMGetGuestCR3(PVM pVM);
427CPUMDECL(uint64_t) CPUMGetGuestCR4(PVM pVM);
428CPUMDECL(int) CPUMGetGuestCRx(PVM pVM, unsigned iReg, uint64_t *pValue);
429CPUMDECL(uint32_t) CPUMGetGuestEFlags(PVM pVM);
430CPUMDECL(uint32_t) CPUMGetGuestEIP(PVM pVM);
431CPUMDECL(uint64_t) CPUMGetGuestRIP(PVM pVM);
432CPUMDECL(uint32_t) CPUMGetGuestEAX(PVM pVM);
433CPUMDECL(uint32_t) CPUMGetGuestEBX(PVM pVM);
434CPUMDECL(uint32_t) CPUMGetGuestECX(PVM pVM);
435CPUMDECL(uint32_t) CPUMGetGuestEDX(PVM pVM);
436CPUMDECL(uint32_t) CPUMGetGuestESI(PVM pVM);
437CPUMDECL(uint32_t) CPUMGetGuestEDI(PVM pVM);
438CPUMDECL(uint32_t) CPUMGetGuestESP(PVM pVM);
439CPUMDECL(uint32_t) CPUMGetGuestEBP(PVM pVM);
440CPUMDECL(RTSEL) CPUMGetGuestCS(PVM pVM);
441CPUMDECL(RTSEL) CPUMGetGuestDS(PVM pVM);
442CPUMDECL(RTSEL) CPUMGetGuestES(PVM pVM);
443CPUMDECL(RTSEL) CPUMGetGuestFS(PVM pVM);
444CPUMDECL(RTSEL) CPUMGetGuestGS(PVM pVM);
445CPUMDECL(RTSEL) CPUMGetGuestSS(PVM pVM);
446CPUMDECL(uint64_t) CPUMGetGuestDR0(PVM pVM);
447CPUMDECL(uint64_t) CPUMGetGuestDR1(PVM pVM);
448CPUMDECL(uint64_t) CPUMGetGuestDR2(PVM pVM);
449CPUMDECL(uint64_t) CPUMGetGuestDR3(PVM pVM);
450CPUMDECL(uint64_t) CPUMGetGuestDR6(PVM pVM);
451CPUMDECL(uint64_t) CPUMGetGuestDR7(PVM pVM);
452CPUMDECL(int) CPUMGetGuestDRx(PVM pVM, uint32_t iReg, uint64_t *pValue);
453CPUMDECL(void) CPUMGetGuestCpuId(PVM pVM, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
454CPUMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdStdGCPtr(PVM pVM);
455CPUMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdExtGCPtr(PVM pVM);
456CPUMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdCentaurGCPtr(PVM pVM);
457CPUMDECL(RCPTRTYPE(PCCPUMCPUID)) CPUMGetGuestCpuIdDefGCPtr(PVM pVM);
458CPUMDECL(uint32_t) CPUMGetGuestCpuIdStdMax(PVM pVM);
459CPUMDECL(uint32_t) CPUMGetGuestCpuIdExtMax(PVM pVM);
460CPUMDECL(uint32_t) CPUMGetGuestCpuIdCentaurMax(PVM pVM);
461CPUMDECL(CPUMSELREGHID *) CPUMGetGuestTRHid(PVM pVM);
462CPUMDECL(uint64_t) CPUMGetGuestEFER(PVM pVM);
463CPUMDECL(uint64_t) CPUMGetGuestMsr(PVM pVM, unsigned idMsr);
464/** @} */
465
466/** @name Guest Register Setters.
467 * @{ */
468CPUMDECL(int) CPUMSetGuestGDTR(PVM pVM, uint32_t addr, uint16_t limit);
469CPUMDECL(int) CPUMSetGuestIDTR(PVM pVM, uint32_t addr, uint16_t limit);
470CPUMDECL(int) CPUMSetGuestTR(PVM pVM, uint16_t tr);
471CPUMDECL(int) CPUMSetGuestLDTR(PVM pVM, uint16_t ldtr);
472CPUMDECL(int) CPUMSetGuestCR0(PVM pVM, uint64_t cr0);
473CPUMDECL(int) CPUMSetGuestCR2(PVM pVM, uint64_t cr2);
474CPUMDECL(int) CPUMSetGuestCR3(PVM pVM, uint64_t cr3);
475CPUMDECL(int) CPUMSetGuestCR4(PVM pVM, uint64_t cr4);
476CPUMDECL(int) CPUMSetGuestDR0(PVM pVM, uint64_t uDr0);
477CPUMDECL(int) CPUMSetGuestDR1(PVM pVM, uint64_t uDr1);
478CPUMDECL(int) CPUMSetGuestDR2(PVM pVM, uint64_t uDr2);
479CPUMDECL(int) CPUMSetGuestDR3(PVM pVM, uint64_t uDr3);
480CPUMDECL(int) CPUMSetGuestDR6(PVM pVM, uint64_t uDr6);
481CPUMDECL(int) CPUMSetGuestDR7(PVM pVM, uint64_t uDr7);
482CPUMDECL(int) CPUMSetGuestDRx(PVM pVM, uint32_t iReg, uint64_t Value);
483CPUMDECL(int) CPUMSetGuestEFlags(PVM pVM, uint32_t eflags);
484CPUMDECL(int) CPUMSetGuestEIP(PVM pVM, uint32_t eip);
485CPUMDECL(int) CPUMSetGuestEAX(PVM pVM, uint32_t eax);
486CPUMDECL(int) CPUMSetGuestEBX(PVM pVM, uint32_t ebx);
487CPUMDECL(int) CPUMSetGuestECX(PVM pVM, uint32_t ecx);
488CPUMDECL(int) CPUMSetGuestEDX(PVM pVM, uint32_t edx);
489CPUMDECL(int) CPUMSetGuestESI(PVM pVM, uint32_t esi);
490CPUMDECL(int) CPUMSetGuestEDI(PVM pVM, uint32_t edi);
491CPUMDECL(int) CPUMSetGuestESP(PVM pVM, uint32_t esp);
492CPUMDECL(int) CPUMSetGuestEBP(PVM pVM, uint32_t ebp);
493CPUMDECL(int) CPUMSetGuestCS(PVM pVM, uint16_t cs);
494CPUMDECL(int) CPUMSetGuestDS(PVM pVM, uint16_t ds);
495CPUMDECL(int) CPUMSetGuestES(PVM pVM, uint16_t es);
496CPUMDECL(int) CPUMSetGuestFS(PVM pVM, uint16_t fs);
497CPUMDECL(int) CPUMSetGuestGS(PVM pVM, uint16_t gs);
498CPUMDECL(int) CPUMSetGuestSS(PVM pVM, uint16_t ss);
499CPUMDECL(void) CPUMSetGuestEFER(PVM pVM, uint64_t val);
500CPUMDECL(void) CPUMSetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
501CPUMDECL(void) CPUMClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
502CPUMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
503CPUMDECL(void) CPUMSetGuestCtx(PVM pVM, const PCPUMCTX pCtx);
504/** @} */
505
506/** @name Misc Guest Predicate Functions.
507 * @{ */
508
509/**
510 * Tests if the guest is running in real mode or not.
511 *
512 * @returns true if in real mode, otherwise false.
513 * @param pVM The VM handle.
514 */
515DECLINLINE(bool) CPUMIsGuestInRealMode(PVM pVM)
516{
517 return !(CPUMGetGuestCR0(pVM) & X86_CR0_PE);
518}
519
520/**
521 * Tests if the guest is running in protected or not.
522 *
523 * @returns true if in protected mode, otherwise false.
524 * @param pVM The VM handle.
525 */
526DECLINLINE(bool) CPUMIsGuestInProtectedMode(PVM pVM)
527{
528 return !!(CPUMGetGuestCR0(pVM) & X86_CR0_PE);
529}
530
531/**
532 * Tests if the guest is running in paged protected or not.
533 *
534 * @returns true if in paged protected mode, otherwise false.
535 * @param pVM The VM handle.
536 */
537DECLINLINE(bool) CPUMIsGuestInPagedProtectedMode(PVM pVM)
538{
539 return (CPUMGetGuestCR0(pVM) & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
540}
541
542/**
543 * Tests if the guest is running in long mode or not.
544 *
545 * @returns true if in long mode, otherwise false.
546 * @param pVM The VM handle.
547 */
548DECLINLINE(bool) CPUMIsGuestInLongMode(PVM pVM)
549{
550 return (CPUMGetGuestEFER(pVM) & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
551}
552
553/**
554 * Tests if the guest is running in long mode or not.
555 *
556 * @returns true if in long mode, otherwise false.
557 * @param pCtx Current CPU context
558 */
559DECLINLINE(bool) CPUMIsGuestInLongModeEx(PCPUMCTX pCtx)
560{
561 return (pCtx->msrEFER & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
562}
563
564/**
565 * Tests if the guest is running in 16 bits paged protected or not.
566 *
567 * @returns true if in paged protected mode, otherwise false.
568 * @param pVM The VM handle.
569 */
570CPUMDECL(bool) CPUMIsGuestIn16BitCode(PVM pVM);
571
572/**
573 * Tests if the guest is running in 32 bits paged protected or not.
574 *
575 * @returns true if in paged protected mode, otherwise false.
576 * @param pVM The VM handle.
577 */
578CPUMDECL(bool) CPUMIsGuestIn32BitCode(PVM pVM);
579
580/**
581 * Tests if the guest is running in 64 bits mode or not.
582 *
583 * @returns true if in 64 bits protected mode, otherwise false.
584 * @param pVM The VM handle.
585 * @param pCtx Current CPU context
586 */
587DECLINLINE(bool) CPUMIsGuestIn64BitCode(PVM pVM, PCCPUMCTXCORE pCtx)
588{
589 if (!CPUMIsGuestInLongMode(pVM))
590 return false;
591
592 return pCtx->csHid.Attr.n.u1Long;
593}
594
595/**
596 * Tests if the guest is running in 64 bits mode or not.
597 *
598 * @returns true if in 64 bits protected mode, otherwise false.
599 * @param pVM The VM handle.
600 * @param pCtx Current CPU context
601 */
602DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCCPUMCTX pCtx)
603{
604 if (!(pCtx->msrEFER & MSR_K6_EFER_LMA))
605 return false;
606
607 return pCtx->csHid.Attr.n.u1Long;
608}
609
610/**
611 * Gets the CPU vendor
612 *
613 * @returns CPU vendor
614 * @param pVM The VM handle.
615 */
616CPUMDECL(CPUMCPUVENDOR) CPUMGetCPUVendor(PVM pVM);
617
618
619/** @} */
620
621
622
623/** @name Hypervisor Register Getters.
624 * @{ */
625CPUMDECL(RTSEL) CPUMGetHyperCS(PVM pVM);
626CPUMDECL(RTSEL) CPUMGetHyperDS(PVM pVM);
627CPUMDECL(RTSEL) CPUMGetHyperES(PVM pVM);
628CPUMDECL(RTSEL) CPUMGetHyperFS(PVM pVM);
629CPUMDECL(RTSEL) CPUMGetHyperGS(PVM pVM);
630CPUMDECL(RTSEL) CPUMGetHyperSS(PVM pVM);
631#if 0 /* these are not correct. */
632CPUMDECL(uint32_t) CPUMGetHyperCR0(PVM pVM);
633CPUMDECL(uint32_t) CPUMGetHyperCR2(PVM pVM);
634CPUMDECL(uint32_t) CPUMGetHyperCR3(PVM pVM);
635CPUMDECL(uint32_t) CPUMGetHyperCR4(PVM pVM);
636#endif
637/** This register is only saved on fatal traps. */
638CPUMDECL(uint32_t) CPUMGetHyperEAX(PVM pVM);
639CPUMDECL(uint32_t) CPUMGetHyperEBX(PVM pVM);
640/** This register is only saved on fatal traps. */
641CPUMDECL(uint32_t) CPUMGetHyperECX(PVM pVM);
642/** This register is only saved on fatal traps. */
643CPUMDECL(uint32_t) CPUMGetHyperEDX(PVM pVM);
644CPUMDECL(uint32_t) CPUMGetHyperESI(PVM pVM);
645CPUMDECL(uint32_t) CPUMGetHyperEDI(PVM pVM);
646CPUMDECL(uint32_t) CPUMGetHyperEBP(PVM pVM);
647CPUMDECL(uint32_t) CPUMGetHyperESP(PVM pVM);
648CPUMDECL(uint32_t) CPUMGetHyperEFlags(PVM pVM);
649CPUMDECL(uint32_t) CPUMGetHyperEIP(PVM pVM);
650CPUMDECL(uint64_t) CPUMGetHyperRIP(PVM pVM);
651CPUMDECL(uint32_t) CPUMGetHyperIDTR(PVM pVM, uint16_t *pcbLimit);
652CPUMDECL(uint32_t) CPUMGetHyperGDTR(PVM pVM, uint16_t *pcbLimit);
653CPUMDECL(RTSEL) CPUMGetHyperLDTR(PVM pVM);
654CPUMDECL(RTGCUINTREG) CPUMGetHyperDR0(PVM pVM);
655CPUMDECL(RTGCUINTREG) CPUMGetHyperDR1(PVM pVM);
656CPUMDECL(RTGCUINTREG) CPUMGetHyperDR2(PVM pVM);
657CPUMDECL(RTGCUINTREG) CPUMGetHyperDR3(PVM pVM);
658CPUMDECL(RTGCUINTREG) CPUMGetHyperDR6(PVM pVM);
659CPUMDECL(RTGCUINTREG) CPUMGetHyperDR7(PVM pVM);
660CPUMDECL(void) CPUMGetHyperCtx(PVM pVM, PCPUMCTX pCtx);
661/** @} */
662
663/** @name Hypervisor Register Setters.
664 * @{ */
665CPUMDECL(void) CPUMSetHyperGDTR(PVM pVM, uint32_t addr, uint16_t limit);
666CPUMDECL(void) CPUMSetHyperLDTR(PVM pVM, RTSEL SelLDTR);
667CPUMDECL(void) CPUMSetHyperIDTR(PVM pVM, uint32_t addr, uint16_t limit);
668CPUMDECL(void) CPUMSetHyperCR3(PVM pVM, uint32_t cr3);
669CPUMDECL(void) CPUMSetHyperTR(PVM pVM, RTSEL SelTR);
670CPUMDECL(void) CPUMSetHyperCS(PVM pVM, RTSEL SelCS);
671CPUMDECL(void) CPUMSetHyperDS(PVM pVM, RTSEL SelDS);
672CPUMDECL(void) CPUMSetHyperES(PVM pVM, RTSEL SelDS);
673CPUMDECL(void) CPUMSetHyperFS(PVM pVM, RTSEL SelDS);
674CPUMDECL(void) CPUMSetHyperGS(PVM pVM, RTSEL SelDS);
675CPUMDECL(void) CPUMSetHyperSS(PVM pVM, RTSEL SelSS);
676CPUMDECL(void) CPUMSetHyperESP(PVM pVM, uint32_t u32ESP);
677CPUMDECL(int) CPUMSetHyperEFlags(PVM pVM, uint32_t Efl);
678CPUMDECL(void) CPUMSetHyperEIP(PVM pVM, uint32_t u32EIP);
679CPUMDECL(void) CPUMSetHyperDR0(PVM pVM, RTGCUINTREG uDr0);
680CPUMDECL(void) CPUMSetHyperDR1(PVM pVM, RTGCUINTREG uDr1);
681CPUMDECL(void) CPUMSetHyperDR2(PVM pVM, RTGCUINTREG uDr2);
682CPUMDECL(void) CPUMSetHyperDR3(PVM pVM, RTGCUINTREG uDr3);
683CPUMDECL(void) CPUMSetHyperDR6(PVM pVM, RTGCUINTREG uDr6);
684CPUMDECL(void) CPUMSetHyperDR7(PVM pVM, RTGCUINTREG uDr7);
685CPUMDECL(void) CPUMSetHyperCtx(PVM pVM, const PCPUMCTX pCtx);
686CPUMDECL(int) CPUMRecalcHyperDRx(PVM pVM);
687/** @} */
688
689CPUMDECL(void) CPUMPushHyper(PVM pVM, uint32_t u32);
690
691/**
692 * Sets or resets an alternative hypervisor context core.
693 *
694 * This is called when we get a hypervisor trap set switch the context
695 * core with the trap frame on the stack. It is called again to reset
696 * back to the default context core when resuming hypervisor execution.
697 *
698 * @param pVM The VM handle.
699 * @param pCtxCore Pointer to the alternative context core or NULL
700 * to go back to the default context core.
701 */
702CPUMDECL(void) CPUMHyperSetCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore);
703
704
705/**
706 * Queries the pointer to the internal CPUMCTX structure
707 *
708 * @returns VBox status code.
709 * @param pVM Handle to the virtual machine.
710 * @param ppCtx Receives the CPUMCTX pointer when successful.
711 */
712CPUMDECL(int) CPUMQueryGuestCtxPtr(PVM pVM, PCPUMCTX *ppCtx);
713
714/**
715 * Queries the pointer to the internal CPUMCTX structure for the hypervisor.
716 *
717 * @returns VBox status code.
718 * @param pVM Handle to the virtual machine.
719 * @param ppCtx Receives the hyper CPUMCTX pointer when successful.
720 */
721CPUMDECL(int) CPUMQueryHyperCtxPtr(PVM pVM, PCPUMCTX *ppCtx);
722
723
724/**
725 * Gets the pointer to the internal CPUMCTXCORE structure.
726 * This is only for reading in order to save a few calls.
727 *
728 * @param pVM Handle to the virtual machine.
729 */
730CPUMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVM pVM);
731
732/**
733 * Gets the pointer to the internal CPUMCTXCORE structure for the hypervisor.
734 * This is only for reading in order to save a few calls.
735 *
736 * @param pVM Handle to the virtual machine.
737 */
738CPUMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVM pVM);
739
740/**
741 * Sets the guest context core registers.
742 *
743 * @param pVM Handle to the virtual machine.
744 * @param pCtxCore The new context core values.
745 */
746CPUMDECL(void) CPUMSetGuestCtxCore(PVM pVM, PCCPUMCTXCORE pCtxCore);
747
748
749/**
750 * Transforms the guest CPU state to raw-ring mode.
751 *
752 * This function will change the any of the cs and ss register with DPL=0 to DPL=1.
753 *
754 * @returns VBox status. (recompiler failure)
755 * @param pVM VM handle.
756 * @param pCtxCore The context core (for trap usage).
757 * @see @ref pg_raw
758 */
759CPUMDECL(int) CPUMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore);
760
761/**
762 * Transforms the guest CPU state from raw-ring mode to correct values.
763 *
764 * This function will change any selector registers with DPL=1 to DPL=0.
765 *
766 * @returns Adjusted rc.
767 * @param pVM VM handle.
768 * @param rc Raw mode return code
769 * @param pCtxCore The context core (for trap usage).
770 * @see @ref pg_raw
771 */
772CPUMDECL(int) CPUMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rc);
773
774/**
775 * Gets the EFLAGS while we're in raw-mode.
776 *
777 * @returns The eflags.
778 * @param pVM The VM handle.
779 * @param pCtxCore The context core.
780 */
781CPUMDECL(uint32_t) CPUMRawGetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore);
782
783/**
784 * Updates the EFLAGS while we're in raw-mode.
785 *
786 * @param pVM The VM handle.
787 * @param pCtxCore The context core.
788 * @param eflags The new EFLAGS value.
789 */
790CPUMDECL(void) CPUMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t eflags);
791
792/**
793 * Lazily sync in the FPU/XMM state
794 *
795 * This function will change any selector registers with DPL=1 to DPL=0.
796 *
797 * @returns VBox status code.
798 * @param pVM VM handle.
799 */
800CPUMDECL(int) CPUMHandleLazyFPU(PVM pVM);
801
802
803/**
804 * Restore host FPU/XMM state
805 *
806 * @returns VBox status code.
807 * @param pVM VM handle.
808 */
809CPUMDECL(int) CPUMRestoreHostFPUState(PVM pVM);
810
811/** @name Changed flags
812 * These flags are used to keep track of which important register that
813 * have been changed since last they were reset. The only one allowed
814 * to clear them is REM!
815 * @{
816 */
817#define CPUM_CHANGED_FPU_REM RT_BIT(0)
818#define CPUM_CHANGED_CR0 RT_BIT(1)
819#define CPUM_CHANGED_CR4 RT_BIT(2)
820#define CPUM_CHANGED_GLOBAL_TLB_FLUSH RT_BIT(3)
821#define CPUM_CHANGED_CR3 RT_BIT(4)
822#define CPUM_CHANGED_GDTR RT_BIT(5)
823#define CPUM_CHANGED_IDTR RT_BIT(6)
824#define CPUM_CHANGED_LDTR RT_BIT(7)
825#define CPUM_CHANGED_TR RT_BIT(8)
826#define CPUM_CHANGED_SYSENTER_MSR RT_BIT(9)
827#define CPUM_CHANGED_HIDDEN_SEL_REGS RT_BIT(10)
828#define CPUM_CHANGED_CPUID RT_BIT(11)
829/** @} */
830
831/**
832 * Gets and resets the changed flags (CPUM_CHANGED_*).
833 *
834 * @returns The changed flags.
835 * @param pVM VM handle.
836 */
837CPUMDECL(unsigned) CPUMGetAndClearChangedFlagsREM(PVM pVM);
838
839/**
840 * Sets the specified changed flags (CPUM_CHANGED_*).
841 *
842 * @param pVM The VM handle.
843 */
844CPUMDECL(void) CPUMSetChangedFlags(PVM pVM, uint32_t fChangedFlags);
845
846/**
847 * Checks if the CPU supports the FXSAVE and FXRSTOR instruction.
848 * @returns true if supported.
849 * @returns false if not supported.
850 * @param pVM The VM handle.
851 */
852CPUMDECL(bool) CPUMSupportsFXSR(PVM pVM);
853
854/**
855 * Checks if the host OS uses the SYSENTER / SYSEXIT instructions.
856 * @returns true if used.
857 * @returns false if not used.
858 * @param pVM The VM handle.
859 */
860CPUMDECL(bool) CPUMIsHostUsingSysEnter(PVM pVM);
861
862/**
863 * Checks if the host OS uses the SYSCALL / SYSRET instructions.
864 * @returns true if used.
865 * @returns false if not used.
866 * @param pVM The VM handle.
867 */
868CPUMDECL(bool) CPUMIsHostUsingSysCall(PVM pVM);
869
870/**
871 * Checks if we activated the FPU/XMM state of the guest OS
872 * @returns true if we did.
873 * @returns false if not.
874 * @param pVM The VM handle.
875 */
876CPUMDECL(bool) CPUMIsGuestFPUStateActive(PVM pVM);
877
878/**
879 * Deactivate the FPU/XMM state of the guest OS
880 * @param pVM The VM handle.
881 */
882CPUMDECL(void) CPUMDeactivateGuestFPUState(PVM pVM);
883
884
885/**
886 * Checks if the hidden selector registers are valid
887 * @returns true if they are.
888 * @returns false if not.
889 * @param pVM The VM handle.
890 */
891CPUMDECL(bool) CPUMAreHiddenSelRegsValid(PVM pVM);
892
893/**
894 * Checks if the hidden selector registers are valid
895 * @param pVM The VM handle.
896 * @param fValid Valid or not
897 */
898CPUMDECL(void) CPUMSetHiddenSelRegsValid(PVM pVM, bool fValid);
899
900/**
901 * Get the current privilege level of the guest.
902 *
903 * @returns cpl
904 * @param pVM VM Handle.
905 * @param pRegFrame Trap register frame.
906 */
907CPUMDECL(uint32_t) CPUMGetGuestCPL(PVM pVM, PCPUMCTXCORE pCtxCore);
908
909/**
910 * CPU modes.
911 */
912typedef enum CPUMMODE
913{
914 /** The usual invalid zero entry. */
915 CPUMMODE_INVALID = 0,
916 /** Real mode. */
917 CPUMMODE_REAL,
918 /** Protected mode (32-bit). */
919 CPUMMODE_PROTECTED,
920 /** Long mode (64-bit). */
921 CPUMMODE_LONG
922} CPUMMODE;
923
924/**
925 * Gets the current guest CPU mode.
926 *
927 * If paging mode is what you need, check out PGMGetGuestMode().
928 *
929 * @returns The CPU mode.
930 * @param pVM The VM handle.
931 */
932CPUMDECL(CPUMMODE) CPUMGetGuestMode(PVM pVM);
933
934
935#ifdef IN_RING3
936/** @defgroup grp_cpum_r3 The CPU Monitor(/Manager) API
937 * @ingroup grp_cpum
938 * @{
939 */
940
941/**
942 * Initializes the CPUM.
943 *
944 * @returns VBox status code.
945 * @param pVM The VM to operate on.
946 */
947CPUMR3DECL(int) CPUMR3Init(PVM pVM);
948
949/**
950 * Applies relocations to data and code managed by this
951 * component. This function will be called at init and
952 * whenever the VMM need to relocate it self inside the GC.
953 *
954 * The CPUM will update the addresses used by the switcher.
955 *
956 * @param pVM The VM.
957 */
958CPUMR3DECL(void) CPUMR3Relocate(PVM pVM);
959
960/**
961 * Terminates the CPUM.
962 *
963 * Termination means cleaning up and freeing all resources,
964 * the VM it self is at this point powered off or suspended.
965 *
966 * @returns VBox status code.
967 * @param pVM The VM to operate on.
968 */
969CPUMR3DECL(int) CPUMR3Term(PVM pVM);
970
971/**
972 * Resets the CPU.
973 *
974 * @param pVM The VM handle.
975 */
976CPUMR3DECL(void) CPUMR3Reset(PVM pVM);
977
978/**
979 * Queries the pointer to the internal CPUMCTX structure
980 *
981 * @returns VBox status code.
982 * @param pVM Handle to the virtual machine.
983 * @param ppCtx Receives the CPUMCTX GC pointer when successful.
984 */
985CPUMR3DECL(int) CPUMR3QueryGuestCtxGCPtr(PVM pVM, RCPTRTYPE(PCPUMCTX) *ppCtx);
986
987
988#ifdef DEBUG
989/**
990 * Debug helper - Saves guest context on raw mode entry (for fatal dump)
991 *
992 * @internal
993 */
994CPUMR3DECL(void) CPUMR3SaveEntryCtx(PVM pVM);
995#endif
996
997/**
998 * API for controlling a few of the CPU features found in CR4.
999 *
1000 * Currently only X86_CR4_TSD is accepted as input.
1001 *
1002 * @returns VBox status code.
1003 *
1004 * @param pVM The VM handle.
1005 * @param fOr The CR4 OR mask.
1006 * @param fAnd The CR4 AND mask.
1007 */
1008CPUMR3DECL(int) CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd);
1009
1010/** @} */
1011#endif
1012
1013#ifdef IN_GC
1014/** @defgroup grp_cpum_gc The CPU Monitor(/Manager) API
1015 * @ingroup grp_cpum
1016 * @{
1017 */
1018
1019/**
1020 * Calls a guest trap/interrupt handler directly
1021 * Assumes a trap stack frame has already been setup on the guest's stack!
1022 *
1023 * @param pRegFrame Original trap/interrupt context
1024 * @param selCS Code selector of handler
1025 * @param pHandler GC virtual address of handler
1026 * @param eflags Callee's EFLAGS
1027 * @param selSS Stack selector for handler
1028 * @param pEsp Stack address for handler
1029 *
1030 * This function does not return!
1031 *
1032 */
1033DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTRCPTR pHandler, uint32_t eflags, uint32_t selSS, RTRCPTR pEsp);
1034
1035/**
1036 * Performs an iret to V86 code
1037 * Assumes a trap stack frame has already been setup on the guest's stack!
1038 *
1039 * @param pRegFrame Original trap/interrupt context
1040 *
1041 * This function does not return!
1042 */
1043CPUMGCDECL(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
1044
1045/** @} */
1046#endif
1047
1048#ifdef IN_RING0
1049/** @defgroup grp_cpum_r0 The CPU Monitor(/Manager) API
1050 * @ingroup grp_cpum
1051 * @{
1052 */
1053
1054/**
1055 * Does Ring-0 CPUM initialization.
1056 *
1057 * This is mainly to check that the Host CPU mode is compatible
1058 * with VBox.
1059 *
1060 * @returns VBox status code.
1061 * @param pVM The VM to operate on.
1062 */
1063CPUMR0DECL(int) CPUMR0Init(PVM pVM);
1064
1065/**
1066 * Lazily sync in the FPU/XMM state
1067 *
1068 * @returns VBox status code.
1069 * @param pVM VM handle.
1070 * @param pCtx CPU context
1071 */
1072CPUMR0DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PCPUMCTX pCtx);
1073
1074/**
1075 * Save guest FPU/XMM state
1076 *
1077 * @returns VBox status code.
1078 * @param pVM VM handle.
1079 * @param pCtx CPU context
1080 */
1081CPUMR0DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PCPUMCTX pCtx);
1082
1083/** @} */
1084#endif
1085
1086/** @} */
1087__END_DECLS
1088
1089
1090#endif
1091
1092
1093
1094
1095
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