VirtualBox

source: vbox/trunk/src/VBox/VMM/include/NEMInternal.h@ 71152

Last change on this file since 71152 was 71152, checked in by vboxsync, 7 years ago

VMM/NEM/win: Refactoring... bugref:9044

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/* $Id: NEMInternal.h 71152 2018-02-28 12:36:04Z vboxsync $ */
2/** @file
3 * NEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2018 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 ___NEMInternal_h
19#define ___NEMInternal_h
20
21#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/vmm/nem.h>
24#include <VBox/vmm/cpum.h> /* For CPUMCPUVENDOR. */
25#include <VBox/vmm/stam.h>
26#include <VBox/vmm/vmapi.h>
27#ifdef RT_OS_WINDOWS
28#include <iprt/nt/hyperv.h>
29#endif
30
31RT_C_DECLS_BEGIN
32
33
34/** @defgroup grp_nem_int Internal
35 * @ingroup grp_nem
36 * @internal
37 * @{
38 */
39
40
41#ifdef RT_OS_WINDOWS
42/*
43 * Windows: Code configuration.
44 */
45# define NEM_WIN_USE_HYPERCALLS_FOR_PAGES
46# define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
47# define NEM_WIN_USE_OUR_OWN_RUN_API
48# if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS)
49# error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS"
50# endif
51
52/**
53 * Windows VID I/O control information.
54 */
55typedef struct NEMWINIOCTL
56{
57 /** The I/O control function number. */
58 uint32_t uFunction;
59 uint32_t cbInput;
60 uint32_t cbOutput;
61} NEMWINIOCTL;
62
63/** @name Windows: Our two-bit physical page state for PGMPAGE
64 * @{ */
65# define NEM_WIN_PAGE_STATE_NOT_SET 0
66# define NEM_WIN_PAGE_STATE_UNMAPPED 1
67# define NEM_WIN_PAGE_STATE_READABLE 2
68# define NEM_WIN_PAGE_STATE_WRITABLE 3
69/** @} */
70
71/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */
72# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys) ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
73/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */
74# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \
75 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
76
77#endif /* RT_OS_WINDOWS */
78
79
80/** Trick to make slickedit see the static functions in the template. */
81#ifndef IN_SLICKEDIT
82# define NEM_TMPL_STATIC static
83#else
84# define NEM_TMPL_STATIC
85#endif
86
87
88/**
89 * NEM VM Instance data.
90 */
91typedef struct NEM
92{
93 /** NEM_MAGIC. */
94 uint32_t u32Magic;
95
96 /** Set if enabled. */
97 bool fEnabled;
98#ifdef RT_OS_WINDOWS
99 /** Set if we've created the EMTs. */
100 bool fCreatedEmts : 1;
101 /** WHvRunVpExitReasonX64Cpuid is supported. */
102 bool fExtendedMsrExit : 1;
103 /** WHvRunVpExitReasonX64MsrAccess is supported. */
104 bool fExtendedCpuIdExit : 1;
105 /** WHvRunVpExitReasonException is supported. */
106 bool fExtendedXcptExit : 1;
107 /** Set if we've started more than one CPU and cannot mess with A20. */
108 bool fA20Fixed : 1;
109 /** Set if A20 is enabled. */
110 bool fA20Enabled : 1;
111 /** The reported CPU vendor. */
112 CPUMCPUVENDOR enmCpuVendor;
113 /** Cache line flush size as a power of two. */
114 uint8_t cCacheLineFlushShift;
115 /** The result of WHvCapabilityCodeProcessorFeatures. */
116 union
117 {
118 /** 64-bit view. */
119 uint64_t u64;
120# ifdef _WINHVAPIDEFS_H_
121 /** Interpreed features. */
122 WHV_PROCESSOR_FEATURES u;
123# endif
124 } uCpuFeatures;
125
126 /** The partition handle. */
127# ifdef _WINHVAPIDEFS_H_
128 WHV_PARTITION_HANDLE
129# else
130 RTHCUINTPTR
131# endif
132 hPartition;
133 /** The device handle for the partition, for use with Vid APIs or direct I/O
134 * controls. */
135 RTR3PTR hPartitionDevice;
136 /** The Hyper-V partition ID. */
137 uint64_t idHvPartition;
138
139 /** Number of currently mapped pages. */
140 uint32_t volatile cMappedPages;
141
142 /** Info about the VidGetHvPartitionId I/O control interface. */
143 NEMWINIOCTL IoCtlGetHvPartitionId;
144 /** Info about the VidStartVirtualProcessor I/O control interface. */
145 NEMWINIOCTL IoCtlStartVirtualProcessor;
146 /** Info about the VidStopVirtualProcessor I/O control interface. */
147 NEMWINIOCTL IoCtlStopVirtualProcessor;
148 /** Info about the VidStopVirtualProcessor I/O control interface. */
149 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
150
151#endif /* RT_OS_WINDOWS */
152} NEM;
153/** Pointer to NEM VM instance data. */
154typedef NEM *PNEM;
155
156/** NEM::u32Magic value. */
157#define NEM_MAGIC UINT32_C(0x004d454e)
158/** NEM::u32Magic value after termination. */
159#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
160
161
162/**
163 * NEM VMCPU Instance data.
164 */
165typedef struct NEMCPU
166{
167 /** NEMCPU_MAGIC. */
168 uint32_t u32Magic;
169#ifdef RT_OS_WINDOWS
170# ifdef NEM_WIN_USE_OUR_OWN_RUN_API
171 /** We've got a message pending (NEM_WIN_MSG_STATE_XXX). */
172 uint8_t bMsgState;
173 /** What VidMessageSlotMap returns and is used for passing exit info. */
174 RTR3PTR pvMsgSlotMapping;
175# endif
176 /** The windows thread handle. */
177 RTR3PTR hNativeThreadHandle;
178 /** Parameters for making Hyper-V hypercalls. */
179 union
180 {
181 uint8_t ab[64];
182 /** Arguments for NEMR0MapPages (HvCallMapGpaPages). */
183 struct
184 {
185 RTGCPHYS GCPhysSrc;
186 RTGCPHYS GCPhysDst; /**< Same as GCPhysSrc except maybe when the A20 gate is disabled. */
187 uint32_t cPages;
188 HV_MAP_GPA_FLAGS fFlags;
189 } MapPages;
190 /** Arguments for NEMR0UnmapPages (HvCallUnmapGpaPages). */
191 struct
192 {
193 RTGCPHYS GCPhys;
194 uint32_t cPages;
195 } UnmapPages;
196 } Hypercall;
197 /** I/O control buffer, we always use this for I/O controls. */
198 union
199 {
200 uint8_t ab[64];
201 HV_PARTITION_ID idPartition;
202 } uIoCtlBuf;
203#endif
204} NEMCPU;
205/** Pointer to NEM VMCPU instance data. */
206typedef NEMCPU *PNEMCPU;
207
208/** NEMCPU::u32Magic value. */
209#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
210/** NEMCPU::u32Magic value after termination. */
211#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
212
213
214#if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_OUR_OWN_RUN_API)
215/** @name NEM_WIN_MSG_STATE_XXX - Windows message handling state.
216 * @{ */
217/** The CPU has not been started. */
218# define NEM_WIN_MSG_STATE_STOPPED UINT8_C(0x00)
219/** The CPU has been started, no messages are pending. */
220# define NEM_WIN_MSG_STATE_STARTED UINT8_C(0x01)
221/** Message is pending and needs to be ACKed. */
222# define NEM_WIN_MSG_STATE_PENDING_MSG UINT8_C(0x02)
223/** Both a message and execution stopping is pending. We need to ACK the
224 * current message and get the stop message, then ACK the stop message before
225 * the CPU can be started again. */
226# define NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG UINT8_C(0x03)
227/** @} */
228#endif
229
230
231
232#ifdef IN_RING0
233
234/**
235 * NEM GVMCPU instance data.
236 */
237typedef struct NEMR0PERVCPU
238{
239# ifdef RT_OS_WINDOWS
240 /** @name Hypercall input/ouput page.
241 * @{ */
242 /** Host physical address of the hypercall input/output page. */
243 RTHCPHYS HCPhysHypercallData;
244 /** Pointer to the hypercall input/output page. */
245 uint8_t *pbHypercallData;
246 /** Handle to the memory object of the hypercall input/output page. */
247 RTR0MEMOBJ hHypercallDataMemObj;
248 /** @} */
249# else
250 uint32_t uDummy;
251# endif
252} NEMR0PERVCPU;
253
254/**
255 * NEM GVM instance data.
256 */
257typedef struct NEMR0PERVM
258{
259# ifdef RT_OS_WINDOWS
260 /** The partition ID. */
261 uint64_t idHvPartition;
262 /** I/O control context. */
263 PSUPR0IOCTLCTX pIoCtlCtx;
264 /** Delta to add to convert a ring-0 pointer to a ring-3 one. */
265 uintptr_t offRing3ConversionDelta;
266 /** Info about the VidGetHvPartitionId I/O control interface. */
267 NEMWINIOCTL IoCtlGetHvPartitionId;
268 /** Info about the VidStartVirtualProcessor I/O control interface. */
269 NEMWINIOCTL IoCtlStartVirtualProcessor;
270 /** Info about the VidStopVirtualProcessor I/O control interface. */
271 NEMWINIOCTL IoCtlStopVirtualProcessor;
272 /** Info about the VidStopVirtualProcessor I/O control interface. */
273 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
274
275# else
276 uint32_t uDummy;
277# endif
278} NEMR0PERVM;
279
280#endif /* IN_RING*/
281
282
283#ifdef IN_RING3
284int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
285int nemR3NativeInitAfterCPUM(PVM pVM);
286int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
287int nemR3NativeTerm(PVM pVM);
288void nemR3NativeReset(PVM pVM);
289void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
290VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
291bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
292bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
293void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
294
295int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
296int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2);
297int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
298int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
299int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
300void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled);
301#endif
302
303void nemHCNativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
304void nemHCNativeNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,
305 int fRestoreAsRAM, bool fRestoreAsRAM2);
306void nemHCNativeNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
307 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
308int nemHCNativeNotifyPhysPageAllocated(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
309 PGMPAGETYPE enmType, uint8_t *pu2State);
310void nemHCNativeNotifyPhysPageProtChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
311 PGMPAGETYPE enmType, uint8_t *pu2State);
312void nemHCNativeNotifyPhysPageChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, uint32_t fPageProt,
313 PGMPAGETYPE enmType, uint8_t *pu2State);
314
315
316#ifdef RT_OS_WINDOWS
317/** Maximum number of pages we can map in a single NEMR0MapPages call. */
318# define NEM_MAX_MAP_PAGES ((PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
319/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
320# define NEM_MAX_UNMAP_PAGES 4095
321
322#endif
323/** @} */
324
325RT_C_DECLS_END
326
327#endif
328
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