VirtualBox

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

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

The recompiler must refresh its cpuid cache when we change a cpuid feature.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use