VirtualBox

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

Last change on this file since 41459 was 41271, checked in by vboxsync, 13 years ago

cleanup.

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