VirtualBox

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

Last change on this file since 33000 was 30263, checked in by vboxsync, 14 years ago

VMM,REM: Only invalidate hidden registers when using raw-mode. Fixes save restore during mode switching code like the windows boot menu. (#5057)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.9 KB
Line 
1/* $Id: CPUMInternal.h 30263 2010-06-16 18:31:42Z 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 <VBox/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 /** Indiciates 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 leafs. */
306 CPUMCPUID aGuestCpuIdStd[6];
307 /** The extended set of CpuId leafs. */
308 CPUMCPUID aGuestCpuIdExt[10];
309 /** The centaur set of CpuId leafs. */
310 CPUMCPUID aGuestCpuIdCentaur[4];
311 /** The default set of CpuId leafs. */
312 CPUMCPUID GuestCpuIdDef;
313
314#if HC_ARCH_BITS == 32
315 /** Align the next member, and thereby the structure, on a 64-byte boundrary. */
316 uint8_t abPadding2[4];
317#endif
318
319 /**
320 * Guest context on raw mode entry.
321 * This a debug feature, see CPUMR3SaveEntryCtx.
322 */
323 CPUMCTX GuestEntry;
324} CPUM;
325/** Pointer to the CPUM instance data residing in the shared VM structure. */
326typedef CPUM *PCPUM;
327
328/**
329 * CPUM Data (part of VMCPU)
330 */
331typedef struct CPUMCPU
332{
333 /**
334 * Hypervisor context.
335 * Aligned on a 64-byte boundrary.
336 */
337 CPUMCTX Hyper;
338
339 /**
340 * Saved host context. Only valid while inside GC.
341 * Aligned on a 64-byte boundrary.
342 */
343 CPUMHOSTCTX Host;
344
345#ifdef VBOX_WITH_CRASHDUMP_MAGIC
346 uint8_t aMagic[56];
347 uint64_t uMagic;
348#endif
349
350 /**
351 * Guest context.
352 * Aligned on a 64-byte boundrary.
353 */
354 CPUMCTX Guest;
355
356 /**
357 * Guest context - misc MSRs
358 * Aligned on a 64-byte boundrary.
359 */
360 CPUMCTXMSR GuestMsr;
361
362 /** Pointer to the current hypervisor core context - R3Ptr. */
363 R3PTRTYPE(PCPUMCTXCORE) pHyperCoreR3;
364 /** Pointer to the current hypervisor core context - R0Ptr. */
365 R0PTRTYPE(PCPUMCTXCORE) pHyperCoreR0;
366 /** Pointer to the current hypervisor core context - RCPtr. */
367 RCPTRTYPE(PCPUMCTXCORE) pHyperCoreRC;
368
369 /** Use flags.
370 * These flags indicates both what is to be used and what has been used.
371 */
372 uint32_t fUseFlags;
373
374 /** Changed flags.
375 * These flags indicates to REM (and others) which important guest
376 * registers which has been changed since last time the flags were cleared.
377 * See the CPUM_CHANGED_* defines for what we keep track of.
378 */
379 uint32_t fChanged;
380
381 /** Offset from CPUM to CPUMCPU. */
382 uint32_t offCPUM;
383
384 /** Temporary storage for the return code of the function called in the
385 * 32-64 switcher. */
386 uint32_t u32RetCode;
387
388 /** Have we entered raw-mode? */
389 bool fRawEntered;
390 /** Have we entered the recompiler? */
391 bool fRemEntered;
392
393 /** Align the structure on a 64-byte boundrary. */
394 uint8_t abPadding2[HC_ARCH_BITS == 32 ? 34 : 26];
395} CPUMCPU, *PCPUMCPU;
396/** Pointer to the CPUMCPU instance data residing in the shared VMCPU structure. */
397typedef CPUMCPU *PCPUMCPU;
398
399RT_C_DECLS_BEGIN
400
401DECLASM(int) cpumHandleLazyFPUAsm(PCPUMCPU pCPUM);
402
403#ifdef IN_RING0
404DECLASM(int) cpumR0SaveHostRestoreGuestFPUState(PCPUMCPU pCPUM);
405DECLASM(int) cpumR0SaveGuestRestoreHostFPUState(PCPUMCPU pCPUM);
406DECLASM(int) cpumR0SaveHostFPUState(PCPUMCPU pCPUM);
407DECLASM(int) cpumR0RestoreHostFPUState(PCPUMCPU pCPUM);
408DECLASM(void) cpumR0LoadFPU(PCPUMCTX pCtx);
409DECLASM(void) cpumR0SaveFPU(PCPUMCTX pCtx);
410DECLASM(void) cpumR0LoadXMM(PCPUMCTX pCtx);
411DECLASM(void) cpumR0SaveXMM(PCPUMCTX pCtx);
412DECLASM(void) cpumR0SetFCW(uint16_t u16FCW);
413DECLASM(uint16_t) cpumR0GetFCW(void);
414DECLASM(void) cpumR0SetMXCSR(uint32_t u32MXCSR);
415DECLASM(uint32_t) cpumR0GetMXCSR(void);
416DECLASM(void) cpumR0LoadDRx(uint64_t const *pa4Regs);
417DECLASM(void) cpumR0SaveDRx(uint64_t *pa4Regs);
418#endif
419
420RT_C_DECLS_END
421
422/** @} */
423
424#endif
425
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use