VirtualBox

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

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

Removed the anonymous struct

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