VirtualBox

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

Last change on this file since 9387 was 9354, checked in by vboxsync, 17 years ago

Added CPUMGetCPUVendor.
Added CPUMCPUIDFEATURE_NXE, CPUMCPUIDFEATURE_LONG_MODE, CPUMCPUIDFEATURE_LAHF & CPUMCPUIDFEATURE_SYSCALL cpuid feature bits.

Enable the required cpuid feature bits in 64 bits mode.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette