VirtualBox

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

Last change on this file since 9569 was 9430, checked in by vboxsync, 17 years ago

Made the base of GDTR and IDTR 64 bits.

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