VirtualBox

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

Last change on this file since 23758 was 23758, checked in by vboxsync, 15 years ago

Skeleton code for synthetic cpu handling.

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