VirtualBox

source: vbox/trunk/src/VBox/VMM/include/CPUMInternal.h@ 40837

Last change on this file since 40837 was 40234, checked in by vboxsync, 13 years ago

Optionally present basic hypervisor CPUID leaves.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.2 KB
Line 
1/* $Id: CPUMInternal.h 40234 2012-02-23 14:48:24Z vboxsync $ */
2/** @file
3 * CPUM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___CPUMInternal_h
19#define ___CPUMInternal_h
20
21#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <iprt/x86.h>
24
25
26
27/** @defgroup grp_cpum_int Internals
28 * @ingroup grp_cpum
29 * @internal
30 * @{
31 */
32
33/** Flags and types for CPUM fault handlers
34 * @{ */
35/** Type: Load DS */
36#define CPUM_HANDLER_DS 1
37/** Type: Load ES */
38#define CPUM_HANDLER_ES 2
39/** Type: Load FS */
40#define CPUM_HANDLER_FS 3
41/** Type: Load GS */
42#define CPUM_HANDLER_GS 4
43/** Type: IRET */
44#define CPUM_HANDLER_IRET 5
45/** Type mask. */
46#define CPUM_HANDLER_TYPEMASK 0xff
47/** If set EBP points to the CPUMCTXCORE that's being used. */
48#define CPUM_HANDLER_CTXCORE_IN_EBP RT_BIT(31)
49/** @} */
50
51
52/** Use flags (CPUM::fUseFlags).
53 * (Don't forget to sync this with CPUMInternal.mac!)
54 * @{ */
55/** Used the FPU, SSE or such stuff. */
56#define CPUM_USED_FPU RT_BIT(0)
57/** Used the FPU, SSE or such stuff since last we were in REM.
58 * REM syncing is clearing this, lazy FPU is setting it. */
59#define CPUM_USED_FPU_SINCE_REM RT_BIT(1)
60/** Host OS is using SYSENTER and we must NULL the CS. */
61#define CPUM_USE_SYSENTER RT_BIT(2)
62/** Host OS is using SYSENTER and we must NULL the CS. */
63#define CPUM_USE_SYSCALL RT_BIT(3)
64/** Debug registers are used by host and must be disabled. */
65#define CPUM_USE_DEBUG_REGS_HOST RT_BIT(4)
66/** Enabled use of debug registers in guest context. */
67#define CPUM_USE_DEBUG_REGS RT_BIT(5)
68/** The XMM state was manually restored. (AMD only) */
69#define CPUM_MANUAL_XMM_RESTORE RT_BIT(6)
70/** Sync the FPU state on entry (32->64 switcher only). */
71#define CPUM_SYNC_FPU_STATE RT_BIT(7)
72/** Sync the debug state on entry (32->64 switcher only). */
73#define CPUM_SYNC_DEBUG_STATE RT_BIT(8)
74/** Enabled use of hypervisor debug registers in guest context. */
75#define CPUM_USE_DEBUG_REGS_HYPER RT_BIT(9)
76/** @} */
77
78/* Sanity check. */
79#if defined(VBOX_WITH_HYBRID_32BIT_KERNEL) && (HC_ARCH_BITS != 32 || R0_ARCH_BITS != 32)
80# error "VBOX_WITH_HYBRID_32BIT_KERNEL is only for 32 bit builds."
81#endif
82
83
84/**
85 * The saved host CPU state.
86 *
87 * @remark The special VBOX_WITH_HYBRID_32BIT_KERNEL checks here are for the 10.4.x series
88 * of Mac OS X where the OS is essentially 32-bit but the cpu mode can be 64-bit.
89 */
90typedef struct CPUMHOSTCTX
91{
92 /** FPU state. (16-byte alignment)
93 * @remark On x86, the format isn't necessarily X86FXSTATE (not important). */
94 X86FXSTATE fpu;
95
96 /** General purpose register, selectors, flags and more
97 * @{ */
98#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
99 /** General purpose register ++
100 * { */
101 //uint64_t rax; - scratch
102 uint64_t rbx;
103 //uint64_t rcx; - scratch
104 //uint64_t rdx; - scratch
105 uint64_t rdi;
106 uint64_t rsi;
107 uint64_t rbp;
108 uint64_t rsp;
109 //uint64_t r8; - scratch
110 //uint64_t r9; - scratch
111 uint64_t r10;
112 uint64_t r11;
113 uint64_t r12;
114 uint64_t r13;
115 uint64_t r14;
116 uint64_t r15;
117 //uint64_t rip; - scratch
118 uint64_t rflags;
119#endif
120
121#if HC_ARCH_BITS == 32
122 //uint32_t eax; - scratch
123 uint32_t ebx;
124 //uint32_t ecx; - scratch
125 //uint32_t edx; - scratch
126 uint32_t edi;
127 uint32_t esi;
128 uint32_t ebp;
129 X86EFLAGS eflags;
130 //uint32_t eip; - scratch
131 /* lss pair! */
132 uint32_t esp;
133#endif
134 /** @} */
135
136 /** Selector registers
137 * @{ */
138 RTSEL ss;
139 RTSEL ssPadding;
140 RTSEL gs;
141 RTSEL gsPadding;
142 RTSEL fs;
143 RTSEL fsPadding;
144 RTSEL es;
145 RTSEL esPadding;
146 RTSEL ds;
147 RTSEL dsPadding;
148 RTSEL cs;
149 RTSEL csPadding;
150 /** @} */
151
152#if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
153 /** Control registers.
154 * @{ */
155 uint32_t cr0;
156 //uint32_t cr2; - scratch
157 uint32_t cr3;
158 uint32_t cr4;
159 /** @} */
160
161 /** Debug registers.
162 * @{ */
163 uint32_t dr0;
164 uint32_t dr1;
165 uint32_t dr2;
166 uint32_t dr3;
167 uint32_t dr6;
168 uint32_t dr7;
169 /** @} */
170
171 /** Global Descriptor Table register. */
172 X86XDTR32 gdtr;
173 uint16_t gdtrPadding;
174 /** Interrupt Descriptor Table register. */
175 X86XDTR32 idtr;
176 uint16_t idtrPadding;
177 /** The task register. */
178 RTSEL ldtr;
179 RTSEL ldtrPadding;
180 /** The task register. */
181 RTSEL tr;
182 RTSEL trPadding;
183 uint32_t SysEnterPadding;
184
185 /** The sysenter msr registers.
186 * This member is not used by the hypervisor context. */
187 CPUMSYSENTER SysEnter;
188
189 /** MSRs
190 * @{ */
191 uint64_t efer;
192 /** @} */
193
194 /* padding to get 64byte aligned size */
195 uint8_t auPadding[16+32];
196
197#elif HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
198
199 /** Control registers.
200 * @{ */
201 uint64_t cr0;
202 //uint64_t cr2; - scratch
203 uint64_t cr3;
204 uint64_t cr4;
205 uint64_t cr8;
206 /** @} */
207
208 /** Debug registers.
209 * @{ */
210 uint64_t dr0;
211 uint64_t dr1;
212 uint64_t dr2;
213 uint64_t dr3;
214 uint64_t dr6;
215 uint64_t dr7;
216 /** @} */
217
218 /** Global Descriptor Table register. */
219 X86XDTR64 gdtr;
220 uint16_t gdtrPadding;
221 /** Interrupt Descriptor Table register. */
222 X86XDTR64 idtr;
223 uint16_t idtrPadding;
224 /** The task register. */
225 RTSEL ldtr;
226 RTSEL ldtrPadding;
227 /** The task register. */
228 RTSEL tr;
229 RTSEL trPadding;
230
231 /** MSRs
232 * @{ */
233 CPUMSYSENTER SysEnter;
234 uint64_t FSbase;
235 uint64_t GSbase;
236 uint64_t efer;
237 /** @} */
238
239 /* padding to get 32byte aligned size */
240# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
241 uint8_t auPadding[16];
242# else
243 uint8_t auPadding[8+32];
244# endif
245
246#else
247# error HC_ARCH_BITS not defined
248#endif
249} CPUMHOSTCTX;
250/** Pointer to the saved host CPU state. */
251typedef CPUMHOSTCTX *PCPUMHOSTCTX;
252
253
254/**
255 * CPUM Data (part of VM)
256 */
257typedef struct CPUM
258{
259 /** Offset from CPUM to CPUMCPU for the first CPU. */
260 uint32_t offCPUMCPU0;
261
262 /** Use flags.
263 * These flags indicates which CPU features the host uses.
264 */
265 uint32_t fHostUseFlags;
266
267 /** Host CPU Features - ECX */
268 struct
269 {
270 /** edx part */
271 X86CPUIDFEATEDX edx;
272 /** ecx part */
273 X86CPUIDFEATECX ecx;
274 } CPUFeatures;
275 /** Host extended CPU features. */
276 struct
277 {
278 /** edx part */
279 uint32_t edx;
280 /** ecx part */
281 uint32_t ecx;
282 } CPUFeaturesExt;
283
284 /** Host CPU manufacturer. */
285 CPUMCPUVENDOR enmHostCpuVendor;
286 /** Guest CPU manufacturer. */
287 CPUMCPUVENDOR enmGuestCpuVendor;
288
289 /** CR4 mask */
290 struct
291 {
292 uint32_t AndMask;
293 uint32_t OrMask;
294 } CR4;
295
296 /** Synthetic CPU type? */
297 bool fSyntheticCpu;
298 /** The (more) portable CPUID level. */
299 uint8_t u8PortableCpuIdLevel;
300 /** Indicates that a state restore is pending.
301 * This is used to verify load order dependencies (PGM). */
302 bool fPendingRestore;
303 uint8_t abPadding[HC_ARCH_BITS == 64 ? 5 : 1];
304
305 /** The standard set of CpuId leaves. */
306 CPUMCPUID aGuestCpuIdStd[6];
307 /** The extended set of CpuId leaves. */
308 CPUMCPUID aGuestCpuIdExt[10];
309 /** The centaur set of CpuId leaves. */
310 CPUMCPUID aGuestCpuIdCentaur[4];
311 /** The hypervisor specific set of CpuId leaves. */
312 CPUMCPUID aGuestCpuIdHyper[4];
313 /** The default set of CpuId leaves. */
314 CPUMCPUID GuestCpuIdDef;
315
316#if HC_ARCH_BITS == 32
317 uint8_t abPadding2[4];
318#endif
319
320#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
321 RTHCPTR pvApicBase;
322 uint32_t fApicDisVectors;
323 uint8_t abPadding3[HC_ARCH_BITS == 32 ? 56 : 52];
324#endif
325
326 /**
327 * Guest context on raw mode entry. 64-byte aligned!
328 * This a debug feature, see CPUMR3SaveEntryCtx.
329 */
330 CPUMCTX GuestEntry;
331} CPUM;
332/** Pointer to the CPUM instance data residing in the shared VM structure. */
333typedef CPUM *PCPUM;
334
335/**
336 * CPUM Data (part of VMCPU)
337 */
338typedef struct CPUMCPU
339{
340 /**
341 * Hypervisor context.
342 * Aligned on a 64-byte boundary.
343 */
344 CPUMCTX Hyper;
345
346 /**
347 * Saved host context. Only valid while inside GC.
348 * Aligned on a 64-byte boundary.
349 */
350 CPUMHOSTCTX Host;
351
352#ifdef VBOX_WITH_CRASHDUMP_MAGIC
353 uint8_t aMagic[56];
354 uint64_t uMagic;
355#endif
356
357 /**
358 * Guest context.
359 * Aligned on a 64-byte boundary.
360 */
361 CPUMCTX Guest;
362
363 /**
364 * Guest context - misc MSRs
365 * Aligned on a 64-byte boundary.
366 */
367 CPUMCTXMSRS GuestMsrs;
368
369 /** Pointer to the current hypervisor core context - R3Ptr. */
370 R3PTRTYPE(PCPUMCTXCORE) pHyperCoreR3;
371 /** Pointer to the current hypervisor core context - R0Ptr. */
372 R0PTRTYPE(PCPUMCTXCORE) pHyperCoreR0;
373 /** Pointer to the current hypervisor core context - RCPtr. */
374 RCPTRTYPE(PCPUMCTXCORE) pHyperCoreRC;
375
376 /** Use flags.
377 * These flags indicates both what is to be used and what has been used.
378 */
379 uint32_t fUseFlags;
380
381 /** Changed flags.
382 * These flags indicates to REM (and others) which important guest
383 * registers which has been changed since last time the flags were cleared.
384 * See the CPUM_CHANGED_* defines for what we keep track of.
385 */
386 uint32_t fChanged;
387
388 /** Offset from CPUM to CPUMCPU. */
389 uint32_t offCPUM;
390
391 /** Temporary storage for the return code of the function called in the
392 * 32-64 switcher. */
393 uint32_t u32RetCode;
394
395 /** Have we entered raw-mode? */
396 bool fRawEntered;
397 /** Have we entered the recompiler? */
398 bool fRemEntered;
399
400 /** Align the structure on a 64-byte boundary. */
401 uint8_t abPadding2[HC_ARCH_BITS == 32 ? 34 : 26];
402} CPUMCPU, *PCPUMCPU;
403/** Pointer to the CPUMCPU instance data residing in the shared VMCPU structure. */
404typedef CPUMCPU *PCPUMCPU;
405
406RT_C_DECLS_BEGIN
407
408#ifdef IN_RING3
409int cpumR3DbgInit(PVM pVM);
410#endif
411
412DECLASM(int) cpumHandleLazyFPUAsm(PCPUMCPU pCPUM);
413
414#ifdef IN_RING0
415DECLASM(int) cpumR0SaveHostRestoreGuestFPUState(PCPUMCPU pCPUM);
416DECLASM(int) cpumR0SaveGuestRestoreHostFPUState(PCPUMCPU pCPUM);
417DECLASM(int) cpumR0SaveHostFPUState(PCPUMCPU pCPUM);
418DECLASM(int) cpumR0RestoreHostFPUState(PCPUMCPU pCPUM);
419DECLASM(void) cpumR0LoadFPU(PCPUMCTX pCtx);
420DECLASM(void) cpumR0SaveFPU(PCPUMCTX pCtx);
421DECLASM(void) cpumR0LoadXMM(PCPUMCTX pCtx);
422DECLASM(void) cpumR0SaveXMM(PCPUMCTX pCtx);
423DECLASM(void) cpumR0SetFCW(uint16_t u16FCW);
424DECLASM(uint16_t) cpumR0GetFCW(void);
425DECLASM(void) cpumR0SetMXCSR(uint32_t u32MXCSR);
426DECLASM(uint32_t) cpumR0GetMXCSR(void);
427DECLASM(void) cpumR0LoadDRx(uint64_t const *pa4Regs);
428DECLASM(void) cpumR0SaveDRx(uint64_t *pa4Regs);
429#endif
430
431RT_C_DECLS_END
432
433/** @} */
434
435#endif
436
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette