VirtualBox

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

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

Extended the CPUMCTX structure for 64 bits mode.

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