VirtualBox

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

Last change on this file since 5958 was 5605, checked in by vboxsync, 17 years ago

BIT => RT_BIT, BIT64 => RT_BIT_64. BIT() is defined in Linux 2.6.24

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