VirtualBox

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

Last change on this file since 6561 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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