VirtualBox

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

Last change on this file since 11318 was 10630, checked in by vboxsync, 16 years ago

Newer functions for handling fpu save/restore in ring 0.

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