VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp@ 95421

Last change on this file since 95421 was 95248, checked in by vboxsync, 3 years ago

VMM/CPUM: Started changing the way we advertise SYSCALL, SEP, NX, and others as well as deduplicating the code for enabling 64-bit guest support (long mode). Also, the SYSCALL CPUID bit is now correctly suppressed when not in 64-bit mode on Intel CPUs. bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 250.0 KB
Line 
1/* $Id: PDMDevHlp.cpp 95248 2022-06-10 16:40:34Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_PDM_DEVICE
23#define PDMPCIDEV_INCLUDE_PRIVATE /* Hack to get pdmpcidevint.h included at the right point. */
24#include "PDMInternal.h"
25#include <VBox/vmm/pdm.h>
26#include <VBox/vmm/mm.h>
27#include <VBox/vmm/hm.h>
28#include <VBox/vmm/pgm.h>
29#include <VBox/vmm/iom.h>
30#include <VBox/vmm/dbgf.h>
31#include <VBox/vmm/ssm.h>
32#include <VBox/vmm/vmapi.h>
33#include <VBox/vmm/vmm.h>
34#include <VBox/vmm/vmcc.h>
35
36#include <VBox/version.h>
37#include <VBox/log.h>
38#include <VBox/pci.h>
39#include <VBox/err.h>
40#include <iprt/asm.h>
41#include <iprt/assert.h>
42#include <iprt/ctype.h>
43#include <iprt/string.h>
44#include <iprt/thread.h>
45#include <iprt/mem.h>
46
47#include "dtrace/VBoxVMM.h"
48#include "PDMInline.h"
49
50
51/*********************************************************************************************************************************
52* Defined Constants And Macros *
53*********************************************************************************************************************************/
54/** @def PDM_DEVHLP_DEADLOCK_DETECTION
55 * Define this to enable the deadlock detection when accessing physical memory.
56 */
57#if /*defined(DEBUG_bird) ||*/ defined(DOXYGEN_RUNNING)
58# define PDM_DEVHLP_DEADLOCK_DETECTION /**< @todo enable DevHlp deadlock detection! */
59#endif
60
61
62
63/** @name R3 DevHlp
64 * @{
65 */
66
67
68/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortCreateEx} */
69static DECLCALLBACK(int) pdmR3DevHlp_IoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
70 uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
71 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, RTR3PTR pvUser,
72 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
73{
74 PDMDEV_ASSERT_DEVINS(pDevIns);
75 LogFlow(("pdmR3DevHlp_IoPortCreateEx: caller='%s'/%d: cPorts=%#x fFlags=%#x pPciDev=%p iPciRegion=%#x pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p pvUser=%p pszDesc=%p:{%s} paExtDescs=%p phIoPorts=%p\n",
76 pDevIns->pReg->szName, pDevIns->iInstance, cPorts, fFlags, pPciDev, iPciRegion, pfnOut, pfnIn, pfnOutStr, pfnInStr,
77 pvUser, pszDesc, pszDesc, paExtDescs, phIoPorts));
78 PVM pVM = pDevIns->Internal.s.pVMR3;
79 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
80 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
81
82 int rc = IOMR3IoPortCreate(pVM, pDevIns, cPorts, fFlags, pPciDev, iPciRegion,
83 pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser, pszDesc, paExtDescs, phIoPorts);
84
85 LogFlow(("pdmR3DevHlp_IoPortCreateEx: caller='%s'/%d: returns %Rrc (*phIoPorts=%#x)\n",
86 pDevIns->pReg->szName, pDevIns->iInstance, rc, *phIoPorts));
87 return rc;
88}
89
90
91/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortMap} */
92static DECLCALLBACK(int) pdmR3DevHlp_IoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port)
93{
94 PDMDEV_ASSERT_DEVINS(pDevIns);
95 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: hIoPorts=%#x Port=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts, Port));
96 PVM pVM = pDevIns->Internal.s.pVMR3;
97 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
98
99 int rc = IOMR3IoPortMap(pVM, pDevIns, hIoPorts, Port);
100
101 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
102 return rc;
103}
104
105
106/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortUnmap} */
107static DECLCALLBACK(int) pdmR3DevHlp_IoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
108{
109 PDMDEV_ASSERT_DEVINS(pDevIns);
110 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: hIoPorts=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts));
111 PVM pVM = pDevIns->Internal.s.pVMR3;
112 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
113
114 int rc = IOMR3IoPortUnmap(pVM, pDevIns, hIoPorts);
115
116 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
117 return rc;
118}
119
120
121/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortGetMappingAddress} */
122static DECLCALLBACK(uint32_t) pdmR3DevHlp_IoPortGetMappingAddress(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
123{
124 PDMDEV_ASSERT_DEVINS(pDevIns);
125 LogFlow(("pdmR3DevHlp_IoPortGetMappingAddress: caller='%s'/%d: hIoPorts=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts));
126
127 uint32_t uAddress = IOMR3IoPortGetMappingAddress(pDevIns->Internal.s.pVMR3, pDevIns, hIoPorts);
128
129 LogFlow(("pdmR3DevHlp_IoPortGetMappingAddress: caller='%s'/%d: returns %#RX32\n", pDevIns->pReg->szName, pDevIns->iInstance, uAddress));
130 return uAddress;
131}
132
133
134/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortWrite} */
135static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_IoPortWrite(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
136{
137 PDMDEV_ASSERT_DEVINS(pDevIns);
138 LogFlow(("pdmR3DevHlp_IoPortWrite: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
139 PVM pVM = pDevIns->Internal.s.pVMR3;
140 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
141
142 PVMCPU pVCpu = VMMGetCpu(pVM);
143 AssertPtrReturn(pVCpu, VERR_ACCESS_DENIED);
144
145 VBOXSTRICTRC rcStrict = IOMIOPortWrite(pVM, pVCpu, Port, u32Value, cbValue);
146
147 LogFlow(("pdmR3DevHlp_IoPortWrite: caller='%s'/%d: returns %Rrc\n",
148 pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict)));
149 return rcStrict;
150}
151
152
153/** @interface_method_impl{PDMDEVHLPR3,pfnMmioCreateEx} */
154static DECLCALLBACK(int) pdmR3DevHlp_MmioCreateEx(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
155 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
156 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill,
157 void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
158{
159 PDMDEV_ASSERT_DEVINS(pDevIns);
160 LogFlow(("pdmR3DevHlp_MmioCreateEx: caller='%s'/%d: cbRegion=%#RGp fFlags=%#x pPciDev=%p iPciRegion=%#x pfnWrite=%p pfnRead=%p pfnFill=%p pvUser=%p pszDesc=%p:{%s} phRegion=%p\n",
161 pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, fFlags, pPciDev, iPciRegion, pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, pszDesc, phRegion));
162 PVM pVM = pDevIns->Internal.s.pVMR3;
163 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
164 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
165
166 if (pDevIns->iInstance > 0)
167 {
168 pszDesc = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
169 AssertReturn(pszDesc, VERR_NO_STR_MEMORY);
170 }
171
172 /* HACK ALERT! Round the size up to page size. The PCI bus should do something similar before mapping it. */
173 /** @todo It's possible we need to do dummy MMIO fill-in of the PCI bus or
174 * guest adds more alignment to an region. */
175 cbRegion = RT_ALIGN_T(cbRegion, GUEST_PAGE_SIZE, RTGCPHYS);
176
177 int rc = IOMR3MmioCreate(pVM, pDevIns, cbRegion, fFlags, pPciDev, iPciRegion,
178 pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, phRegion);
179
180 LogFlow(("pdmR3DevHlp_MmioCreateEx: caller='%s'/%d: returns %Rrc (*phRegion=%#x)\n",
181 pDevIns->pReg->szName, pDevIns->iInstance, rc, *phRegion));
182 return rc;
183}
184
185
186/** @interface_method_impl{PDMDEVHLPR3,pfnMmioMap} */
187static DECLCALLBACK(int) pdmR3DevHlp_MmioMap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
188{
189 PDMDEV_ASSERT_DEVINS(pDevIns);
190 LogFlow(("pdmR3DevHlp_MmioMap: caller='%s'/%d: hRegion=%#x GCPhys=%#RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion, GCPhys));
191 PVM pVM = pDevIns->Internal.s.pVMR3;
192 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
193
194 int rc = IOMR3MmioMap(pVM, pDevIns, hRegion, GCPhys);
195
196 LogFlow(("pdmR3DevHlp_MmioMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
197 return rc;
198}
199
200
201/** @interface_method_impl{PDMDEVHLPR3,pfnMmioUnmap} */
202static DECLCALLBACK(int) pdmR3DevHlp_MmioUnmap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
203{
204 PDMDEV_ASSERT_DEVINS(pDevIns);
205 LogFlow(("pdmR3DevHlp_MmioUnmap: caller='%s'/%d: hRegion=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion));
206 PVM pVM = pDevIns->Internal.s.pVMR3;
207 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
208
209 int rc = IOMR3MmioUnmap(pVM, pDevIns, hRegion);
210
211 LogFlow(("pdmR3DevHlp_MmioUnmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
212 return rc;
213}
214
215
216/** @interface_method_impl{PDMDEVHLPR3,pfnMmioReduce} */
217static DECLCALLBACK(int) pdmR3DevHlp_MmioReduce(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion)
218{
219 PDMDEV_ASSERT_DEVINS(pDevIns);
220 LogFlow(("pdmR3DevHlp_MmioReduce: caller='%s'/%d: hRegion=%#x cbRegion=%#RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion, cbRegion));
221 PVM pVM = pDevIns->Internal.s.pVMR3;
222 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
223 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_LOADING, VERR_VM_INVALID_VM_STATE);
224
225 int rc = IOMR3MmioReduce(pVM, pDevIns, hRegion, cbRegion);
226
227 LogFlow(("pdmR3DevHlp_MmioReduce: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
228 return rc;
229}
230
231
232/** @interface_method_impl{PDMDEVHLPR3,pfnMmioGetMappingAddress} */
233static DECLCALLBACK(RTGCPHYS) pdmR3DevHlp_MmioGetMappingAddress(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
234{
235 PDMDEV_ASSERT_DEVINS(pDevIns);
236 LogFlow(("pdmR3DevHlp_MmioGetMappingAddress: caller='%s'/%d: hRegion=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion));
237
238 RTGCPHYS GCPhys = IOMR3MmioGetMappingAddress(pDevIns->Internal.s.pVMR3, pDevIns, hRegion);
239
240 LogFlow(("pdmR3DevHlp_MmioGetMappingAddress: caller='%s'/%d: returns %RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, GCPhys));
241 return GCPhys;
242}
243
244
245/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2Create} */
246static DECLCALLBACK(int) pdmR3DevHlp_Mmio2Create(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iPciRegion, RTGCPHYS cbRegion,
247 uint32_t fFlags, const char *pszDesc, void **ppvMapping, PPGMMMIO2HANDLE phRegion)
248{
249 PDMDEV_ASSERT_DEVINS(pDevIns);
250 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
251 LogFlow(("pdmR3DevHlp_Mmio2Create: caller='%s'/%d: pPciDev=%p (%#x) iPciRegion=%#x cbRegion=%#RGp fFlags=%RX32 pszDesc=%p:{%s} ppvMapping=%p phRegion=%p\n",
252 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iPciRegion, cbRegion,
253 fFlags, pszDesc, pszDesc, ppvMapping, phRegion));
254 *ppvMapping = NULL;
255 *phRegion = NIL_PGMMMIO2HANDLE;
256 AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
257
258 PVM pVM = pDevIns->Internal.s.pVMR3;
259 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
260 AssertMsgReturn( pVM->enmVMState == VMSTATE_CREATING
261 || pVM->enmVMState == VMSTATE_LOADING,
262 ("state %s, expected CREATING or LOADING\n", VMGetStateName(pVM->enmVMState)), VERR_VM_INVALID_VM_STATE);
263
264 AssertReturn(!(iPciRegion & UINT16_MAX), VERR_INVALID_PARAMETER); /* not implemented. */
265
266 /** @todo PGMR3PhysMmio2Register mangles the description, move it here and
267 * use a real string cache. */
268 int rc = PGMR3PhysMmio2Register(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iPciRegion >> 16,
269 cbRegion, fFlags, pszDesc, ppvMapping, phRegion);
270
271 LogFlow(("pdmR3DevHlp_Mmio2Create: caller='%s'/%d: returns %Rrc *ppvMapping=%p phRegion=%#RX64\n",
272 pDevIns->pReg->szName, pDevIns->iInstance, rc, *ppvMapping, *phRegion));
273 return rc;
274}
275
276
277/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2Destroy} */
278static DECLCALLBACK(int) pdmR3DevHlp_Mmio2Destroy(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion)
279{
280 PDMDEV_ASSERT_DEVINS(pDevIns);
281 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
282 LogFlow(("pdmR3DevHlp_Mmio2Destroy: caller='%s'/%d: hRegion=%#RX64\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion));
283
284 PVM pVM = pDevIns->Internal.s.pVMR3;
285 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
286 AssertMsgReturn( pVM->enmVMState == VMSTATE_DESTROYING
287 || pVM->enmVMState == VMSTATE_LOADING,
288 ("state %s, expected DESTROYING or LOADING\n", VMGetStateName(pVM->enmVMState)), VERR_VM_INVALID_VM_STATE);
289
290 int rc = PGMR3PhysMmio2Deregister(pDevIns->Internal.s.pVMR3, pDevIns, hRegion);
291
292 LogFlow(("pdmR3DevHlp_Mmio2Destroy: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
293 return rc;
294}
295
296
297/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2Map} */
298static DECLCALLBACK(int) pdmR3DevHlp_Mmio2Map(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, RTGCPHYS GCPhys)
299{
300 PDMDEV_ASSERT_DEVINS(pDevIns);
301 LogFlow(("pdmR3DevHlp_Mmio2Map: caller='%s'/%d: hRegion=%#RX64 GCPhys=%RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion, GCPhys));
302
303 PVM pVM = pDevIns->Internal.s.pVMR3;
304 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
305
306 int rc = PGMR3PhysMmio2Map(pDevIns->Internal.s.pVMR3, pDevIns, hRegion, GCPhys);
307
308 LogFlow(("pdmR3DevHlp_Mmio2Map: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
309 return rc;
310}
311
312
313/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2Unmap} */
314static DECLCALLBACK(int) pdmR3DevHlp_Mmio2Unmap(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion)
315{
316 PDMDEV_ASSERT_DEVINS(pDevIns);
317 LogFlow(("pdmR3DevHlp_Mmio2Unmap: caller='%s'/%d: hRegion=%#RX64\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion));
318
319 PVM pVM = pDevIns->Internal.s.pVMR3;
320 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
321
322 int rc = PGMR3PhysMmio2Unmap(pDevIns->Internal.s.pVMR3, pDevIns, hRegion, NIL_RTGCPHYS);
323
324 LogFlow(("pdmR3DevHlp_Mmio2Unmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
325 return rc;
326}
327
328
329/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2Reduce} */
330static DECLCALLBACK(int) pdmR3DevHlp_Mmio2Reduce(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, RTGCPHYS cbRegion)
331{
332 PDMDEV_ASSERT_DEVINS(pDevIns);
333 LogFlow(("pdmR3DevHlp_Mmio2Reduce: caller='%s'/%d: hRegion=%#RX64 cbRegion=%RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion, cbRegion));
334 PVM pVM = pDevIns->Internal.s.pVMR3;
335 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
336 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_LOADING, VERR_VM_INVALID_VM_STATE);
337
338 int rc = PGMR3PhysMmio2Reduce(pDevIns->Internal.s.pVMR3, pDevIns, hRegion, cbRegion);
339
340 LogFlow(("pdmR3DevHlp_Mmio2Reduce: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
341 return rc;
342}
343
344
345/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2GetMappingAddress} */
346static DECLCALLBACK(RTGCPHYS) pdmR3DevHlp_Mmio2GetMappingAddress(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion)
347{
348 PDMDEV_ASSERT_DEVINS(pDevIns);
349 PVM pVM = pDevIns->Internal.s.pVMR3;
350 LogFlow(("pdmR3DevHlp_Mmio2GetMappingAddress: caller='%s'/%d: hRegion=%#RX64\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion));
351 VM_ASSERT_EMT0_RETURN(pVM, NIL_RTGCPHYS);
352
353 RTGCPHYS GCPhys = PGMR3PhysMmio2GetMappingAddress(pVM, pDevIns, hRegion);
354
355 LogFlow(("pdmR3DevHlp_Mmio2GetMappingAddress: caller='%s'/%d: returns %RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, GCPhys));
356 return GCPhys;
357}
358
359
360/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2QueryAndResetDirtyBitmap} */
361static DECLCALLBACK(int) pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion,
362 void *pvBitmap, size_t cbBitmap)
363{
364 PDMDEV_ASSERT_DEVINS(pDevIns);
365 PVM pVM = pDevIns->Internal.s.pVMR3;
366 LogFlow(("pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap: caller='%s'/%d: hRegion=%#RX64 pvBitmap=%p cbBitmap=%#zx\n",
367 pDevIns->pReg->szName, pDevIns->iInstance, hRegion, pvBitmap, cbBitmap));
368
369 int rc = PGMR3PhysMmio2QueryAndResetDirtyBitmap(pVM, pDevIns, hRegion, pvBitmap, cbBitmap);
370
371 LogFlow(("pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
372 return rc;
373}
374
375
376/** @interface_method_impl{PDMDEVHLPR3,pfnMmio2ControlDirtyPageTracking} */
377static DECLCALLBACK(int) pdmR3DevHlp_Mmio2ControlDirtyPageTracking(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, bool fEnabled)
378{
379 PDMDEV_ASSERT_DEVINS(pDevIns);
380 PVM pVM = pDevIns->Internal.s.pVMR3;
381 LogFlow(("pdmR3DevHlp_Mmio2ControlDirtyPageTracking: caller='%s'/%d: hRegion=%#RX64 fEnabled=%RTbool\n",
382 pDevIns->pReg->szName, pDevIns->iInstance, hRegion, fEnabled));
383
384 int rc = PGMR3PhysMmio2ControlDirtyPageTracking(pVM, pDevIns, hRegion, fEnabled);
385
386 LogFlow(("pdmR3DevHlp_Mmio2ControlDirtyPageTracking: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
387 return rc;
388}
389
390
391/**
392 * @copydoc PDMDEVHLPR3::pfnMmio2ChangeRegionNo
393 */
394static DECLCALLBACK(int) pdmR3DevHlp_Mmio2ChangeRegionNo(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, uint32_t iNewRegion)
395{
396 PDMDEV_ASSERT_DEVINS(pDevIns);
397 PVM pVM = pDevIns->Internal.s.pVMR3;
398 LogFlow(("pdmR3DevHlp_Mmio2ChangeRegionNo: caller='%s'/%d: hRegion=%#RX64 iNewRegion=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion, iNewRegion));
399 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
400
401 int rc = PGMR3PhysMmio2ChangeRegionNo(pVM, pDevIns, hRegion, iNewRegion);
402
403 LogFlow(("pdmR3DevHlp_Mmio2ChangeRegionNo: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
404 return rc;
405}
406
407
408/** @interface_method_impl{PDMDEVHLPR3,pfnMmioMapMmio2Page} */
409static DECLCALLBACK(int) pdmR3DevHlp_MmioMapMmio2Page(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS offRegion,
410 uint64_t hMmio2, RTGCPHYS offMmio2, uint64_t fPageFlags)
411{
412 PDMDEV_ASSERT_DEVINS(pDevIns);
413 LogFlow(("pdmR3DevHlp_MmioMapMmio2Page: caller='%s'/%d: hRegion=%RX64 offRegion=%RGp hMmio2=%RX64 offMmio2=%RGp fPageFlags=%RX64\n",
414 pDevIns->pReg->szName, pDevIns->iInstance, hRegion, offRegion, hMmio2, offMmio2, fPageFlags));
415
416 int rc = IOMMmioMapMmio2Page(pDevIns->Internal.s.pVMR3, pDevIns, hRegion, offRegion, hMmio2, offMmio2, fPageFlags);
417
418 Log(("pdmR3DevHlp_MmioMapMmio2Page: caller='%s'/%d: returns %Rrc\n",
419 pDevIns->pReg->szName, pDevIns->iInstance, rc));
420 return rc;
421}
422
423
424/** @interface_method_impl{PDMDEVHLPR3,pfnMmioResetRegion} */
425static DECLCALLBACK(int) pdmR3DevHlp_MmioResetRegion(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
426{
427 PDMDEV_ASSERT_DEVINS(pDevIns);
428 LogFlow(("pdmR3DevHlp_MmioResetRegion: caller='%s'/%d: hRegion=%RX64\n",
429 pDevIns->pReg->szName, pDevIns->iInstance, hRegion));
430
431 int rc = IOMMmioResetRegion(pDevIns->Internal.s.pVMR3, pDevIns, hRegion);
432
433 Log(("pdmR3DevHlp_MmioResetRegion: caller='%s'/%d: returns %Rrc\n",
434 pDevIns->pReg->szName, pDevIns->iInstance, rc));
435 return rc;
436}
437
438
439/** @interface_method_impl{PDMDEVHLPR3,pfnROMRegister} */
440static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
441 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
442{
443 PDMDEV_ASSERT_DEVINS(pDevIns);
444 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
445 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%RGp cbRange=%#x pvBinary=%p cbBinary=%#x fFlags=%#RX32 pszDesc=%p:{%s}\n",
446 pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc, pszDesc));
447
448/** @todo can we mangle pszDesc? */
449 int rc = PGMR3PhysRomRegister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc);
450
451 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
452 return rc;
453}
454
455
456/** @interface_method_impl{PDMDEVHLPR3,pfnROMProtectShadow} */
457static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt)
458{
459 PDMDEV_ASSERT_DEVINS(pDevIns);
460 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%RGp cbRange=%#x enmProt=%d\n",
461 pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, enmProt));
462
463 int rc = PGMR3PhysRomProtect(pDevIns->Internal.s.pVMR3, GCPhysStart, cbRange, enmProt);
464
465 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
466 return rc;
467}
468
469
470/** @interface_method_impl{PDMDEVHLPR3,pfnSSMRegister} */
471static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
472 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
473 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
474 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
475{
476 PDMDEV_ASSERT_DEVINS(pDevIns);
477 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
478 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: uVersion=%#x cbGuess=%#x pszBefore=%p:{%s}\n"
479 " pfnLivePrep=%p pfnLiveExec=%p pfnLiveVote=%p pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pfnLoadPrep=%p pfnLoadExec=%p pfnLoadDone=%p\n",
480 pDevIns->pReg->szName, pDevIns->iInstance, uVersion, cbGuess, pszBefore, pszBefore,
481 pfnLivePrep, pfnLiveExec, pfnLiveVote,
482 pfnSavePrep, pfnSaveExec, pfnSaveDone,
483 pfnLoadPrep, pfnLoadExec, pfnLoadDone));
484
485 int rc = SSMR3RegisterDevice(pDevIns->Internal.s.pVMR3, pDevIns, pDevIns->pReg->szName, pDevIns->iInstance,
486 uVersion, cbGuess, pszBefore,
487 pfnLivePrep, pfnLiveExec, pfnLiveVote,
488 pfnSavePrep, pfnSaveExec, pfnSaveDone,
489 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
490
491 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
492 return rc;
493}
494
495
496/** @interface_method_impl{PDMDEVHLPR3,pfnSSMRegisterLegacy} */
497static DECLCALLBACK(int) pdmR3DevHlp_SSMRegisterLegacy(PPDMDEVINS pDevIns, const char *pszOldName, PFNSSMDEVLOADPREP pfnLoadPrep,
498 PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
499{
500 PDMDEV_ASSERT_DEVINS(pDevIns);
501 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
502 LogFlow(("pdmR3DevHlp_SSMRegisterLegacy: caller='%s'/%d: pszOldName=%p:{%s} pfnLoadPrep=%p pfnLoadExec=%p pfnLoadDone=%p\n",
503 pDevIns->pReg->szName, pDevIns->iInstance, pszOldName, pszOldName, pfnLoadPrep, pfnLoadExec, pfnLoadDone));
504
505 int rc = SSMR3RegisterDevice(pDevIns->Internal.s.pVMR3, pDevIns, pszOldName, pDevIns->iInstance,
506 0 /*uVersion*/, 0 /*cbGuess*/, NULL /*pszBefore*/,
507 NULL, NULL, NULL,
508 NULL, NULL, NULL,
509 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
510
511 LogFlow(("pdmR3DevHlp_SSMRegisterLegacy: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
512 return rc;
513}
514
515
516/** @interface_method_impl{PDMDEVHLPR3,pfnTimerCreate} */
517static DECLCALLBACK(int) pdmR3DevHlp_TimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
518 void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
519{
520 PDMDEV_ASSERT_DEVINS(pDevIns);
521 PVM pVM = pDevIns->Internal.s.pVMR3;
522 VM_ASSERT_EMT(pVM);
523 LogFlow(("pdmR3DevHlp_TimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} phTimer=%p\n",
524 pDevIns->pReg->szName, pDevIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, phTimer));
525
526 /* Mangle the timer name if there are more than one instance of this device. */
527 char szName[32];
528 AssertReturn(strlen(pszDesc) < sizeof(szName) - 3, VERR_INVALID_NAME);
529 if (pDevIns->iInstance > 0)
530 {
531 RTStrPrintf(szName, sizeof(szName), "%s[%u]", pszDesc, pDevIns->iInstance);
532 pszDesc = szName;
533 }
534
535 /* Clear the ring-0 flag if the device isn't configured for ring-0. */
536 if (fFlags & TMTIMER_FLAGS_RING0)
537 {
538 Assert(pDevIns->Internal.s.pDevR3->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
539 if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED))
540 fFlags &= ~TMTIMER_FLAGS_RING0;
541 }
542 else
543 Assert(fFlags & TMTIMER_FLAGS_NO_RING0 /* just to make sure all devices has been considered */);
544
545 int rc = TMR3TimerCreateDevice(pVM, pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
546
547 LogFlow(("pdmR3DevHlp_TimerCreate: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
548 return rc;
549}
550
551
552/** @interface_method_impl{PDMDEVHLPR3,pfnTimerFromMicro} */
553static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
554{
555 PDMDEV_ASSERT_DEVINS(pDevIns);
556 return TMTimerFromMicro(pDevIns->Internal.s.pVMR3, hTimer, cMicroSecs);
557}
558
559
560/** @interface_method_impl{PDMDEVHLPR3,pfnTimerFromMilli} */
561static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromMilli(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
562{
563 PDMDEV_ASSERT_DEVINS(pDevIns);
564 return TMTimerFromMilli(pDevIns->Internal.s.pVMR3, hTimer, cMilliSecs);
565}
566
567
568/** @interface_method_impl{PDMDEVHLPR3,pfnTimerFromNano} */
569static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
570{
571 PDMDEV_ASSERT_DEVINS(pDevIns);
572 return TMTimerFromNano(pDevIns->Internal.s.pVMR3, hTimer, cNanoSecs);
573}
574
575/** @interface_method_impl{PDMDEVHLPR3,pfnTimerGet} */
576static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
577{
578 PDMDEV_ASSERT_DEVINS(pDevIns);
579 return TMTimerGet(pDevIns->Internal.s.pVMR3, hTimer);
580}
581
582
583/** @interface_method_impl{PDMDEVHLPR3,pfnTimerGetFreq} */
584static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
585{
586 PDMDEV_ASSERT_DEVINS(pDevIns);
587 return TMTimerGetFreq(pDevIns->Internal.s.pVMR3, hTimer);
588}
589
590
591/** @interface_method_impl{PDMDEVHLPR3,pfnTimerGetNano} */
592static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
593{
594 PDMDEV_ASSERT_DEVINS(pDevIns);
595 return TMTimerGetNano(pDevIns->Internal.s.pVMR3, hTimer);
596}
597
598
599/** @interface_method_impl{PDMDEVHLPR3,pfnTimerIsActive} */
600static DECLCALLBACK(bool) pdmR3DevHlp_TimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
601{
602 PDMDEV_ASSERT_DEVINS(pDevIns);
603 return TMTimerIsActive(pDevIns->Internal.s.pVMR3, hTimer);
604}
605
606
607/** @interface_method_impl{PDMDEVHLPR3,pfnTimerIsLockOwner} */
608static DECLCALLBACK(bool) pdmR3DevHlp_TimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
609{
610 PDMDEV_ASSERT_DEVINS(pDevIns);
611 return TMTimerIsLockOwner(pDevIns->Internal.s.pVMR3, hTimer);
612}
613
614
615/** @interface_method_impl{PDMDEVHLPR3,pfnTimerLockClock} */
616static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_TimerLockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
617{
618 PDMDEV_ASSERT_DEVINS(pDevIns);
619 return TMTimerLock(pDevIns->Internal.s.pVMR3, hTimer, rcBusy);
620}
621
622
623/** @interface_method_impl{PDMDEVHLPR3,pfnTimerLockClock2} */
624static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_TimerLockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer,
625 PPDMCRITSECT pCritSect, int rcBusy)
626{
627 PDMDEV_ASSERT_DEVINS(pDevIns);
628 PVM const pVM = pDevIns->Internal.s.pVMR3;
629 VBOXSTRICTRC rc = TMTimerLock(pVM, hTimer, rcBusy);
630 if (rc == VINF_SUCCESS)
631 {
632 rc = PDMCritSectEnter(pVM, pCritSect, rcBusy);
633 if (rc == VINF_SUCCESS)
634 return rc;
635 AssertRC(VBOXSTRICTRC_VAL(rc));
636 TMTimerUnlock(pVM, hTimer);
637 }
638 else
639 AssertRC(VBOXSTRICTRC_VAL(rc));
640 return rc;
641}
642
643
644/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSet} */
645static DECLCALLBACK(int) pdmR3DevHlp_TimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
646{
647 PDMDEV_ASSERT_DEVINS(pDevIns);
648 return TMTimerSet(pDevIns->Internal.s.pVMR3, hTimer, uExpire);
649}
650
651
652/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetFrequencyHint} */
653static DECLCALLBACK(int) pdmR3DevHlp_TimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
654{
655 PDMDEV_ASSERT_DEVINS(pDevIns);
656 return TMTimerSetFrequencyHint(pDevIns->Internal.s.pVMR3, hTimer, uHz);
657}
658
659
660/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetMicro} */
661static DECLCALLBACK(int) pdmR3DevHlp_TimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
662{
663 PDMDEV_ASSERT_DEVINS(pDevIns);
664 return TMTimerSetMicro(pDevIns->Internal.s.pVMR3, hTimer, cMicrosToNext);
665}
666
667
668/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetMillies} */
669static DECLCALLBACK(int) pdmR3DevHlp_TimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
670{
671 PDMDEV_ASSERT_DEVINS(pDevIns);
672 return TMTimerSetMillies(pDevIns->Internal.s.pVMR3, hTimer, cMilliesToNext);
673}
674
675
676/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetNano} */
677static DECLCALLBACK(int) pdmR3DevHlp_TimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
678{
679 PDMDEV_ASSERT_DEVINS(pDevIns);
680 return TMTimerSetNano(pDevIns->Internal.s.pVMR3, hTimer, cNanosToNext);
681}
682
683
684/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetRelative} */
685static DECLCALLBACK(int) pdmR3DevHlp_TimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
686{
687 PDMDEV_ASSERT_DEVINS(pDevIns);
688 return TMTimerSetRelative(pDevIns->Internal.s.pVMR3, hTimer, cTicksToNext, pu64Now);
689}
690
691
692/** @interface_method_impl{PDMDEVHLPR3,pfnTimerStop} */
693static DECLCALLBACK(int) pdmR3DevHlp_TimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
694{
695 PDMDEV_ASSERT_DEVINS(pDevIns);
696 return TMTimerStop(pDevIns->Internal.s.pVMR3, hTimer);
697}
698
699
700/** @interface_method_impl{PDMDEVHLPR3,pfnTimerUnlockClock} */
701static DECLCALLBACK(void) pdmR3DevHlp_TimerUnlockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
702{
703 PDMDEV_ASSERT_DEVINS(pDevIns);
704 TMTimerUnlock(pDevIns->Internal.s.pVMR3, hTimer);
705}
706
707
708/** @interface_method_impl{PDMDEVHLPR3,pfnTimerUnlockClock2} */
709static DECLCALLBACK(void) pdmR3DevHlp_TimerUnlockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
710{
711 PDMDEV_ASSERT_DEVINS(pDevIns);
712 PVM const pVM = pDevIns->Internal.s.pVMR3;
713 TMTimerUnlock(pVM, hTimer);
714 int rc = PDMCritSectLeave(pVM, pCritSect);
715 AssertRC(rc);
716}
717
718
719/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetCritSect} */
720static DECLCALLBACK(int) pdmR3DevHlp_TimerSetCritSect(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
721{
722 PDMDEV_ASSERT_DEVINS(pDevIns);
723 return TMR3TimerSetCritSect(pDevIns->Internal.s.pVMR3, hTimer, pCritSect);
724}
725
726
727/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSave} */
728static DECLCALLBACK(int) pdmR3DevHlp_TimerSave(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
729{
730 PDMDEV_ASSERT_DEVINS(pDevIns);
731 return TMR3TimerSave(pDevIns->Internal.s.pVMR3, hTimer, pSSM);
732}
733
734
735/** @interface_method_impl{PDMDEVHLPR3,pfnTimerLoad} */
736static DECLCALLBACK(int) pdmR3DevHlp_TimerLoad(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
737{
738 PDMDEV_ASSERT_DEVINS(pDevIns);
739 return TMR3TimerLoad(pDevIns->Internal.s.pVMR3, hTimer, pSSM);
740}
741
742
743/** @interface_method_impl{PDMDEVHLPR3,pfnTimerDestroy} */
744static DECLCALLBACK(int) pdmR3DevHlp_TimerDestroy(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
745{
746 PDMDEV_ASSERT_DEVINS(pDevIns);
747 return TMR3TimerDestroy(pDevIns->Internal.s.pVMR3, hTimer);
748}
749
750
751/** @interface_method_impl{PDMDEVHLPR3,pfnTMUtcNow} */
752static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_TMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
753{
754 PDMDEV_ASSERT_DEVINS(pDevIns);
755 LogFlow(("pdmR3DevHlp_TMUtcNow: caller='%s'/%d: pTime=%p\n",
756 pDevIns->pReg->szName, pDevIns->iInstance, pTime));
757
758 pTime = TMR3UtcNow(pDevIns->Internal.s.pVMR3, pTime);
759
760 LogFlow(("pdmR3DevHlp_TMUtcNow: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, RTTimeSpecGetNano(pTime)));
761 return pTime;
762}
763
764
765/** @interface_method_impl{PDMDEVHLPR3,pfnTMTimeVirtGet} */
766static DECLCALLBACK(uint64_t) pdmR3DevHlp_TMTimeVirtGet(PPDMDEVINS pDevIns)
767{
768 PDMDEV_ASSERT_DEVINS(pDevIns);
769 LogFlow(("pdmR3DevHlp_TMTimeVirtGet: caller='%s'/%d\n",
770 pDevIns->pReg->szName, pDevIns->iInstance));
771
772 uint64_t u64Time = TMVirtualSyncGet(pDevIns->Internal.s.pVMR3);
773
774 LogFlow(("pdmR3DevHlp_TMTimeVirtGet: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64Time));
775 return u64Time;
776}
777
778
779/** @interface_method_impl{PDMDEVHLPR3,pfnTMTimeVirtGetFreq} */
780static DECLCALLBACK(uint64_t) pdmR3DevHlp_TMTimeVirtGetFreq(PPDMDEVINS pDevIns)
781{
782 PDMDEV_ASSERT_DEVINS(pDevIns);
783 LogFlow(("pdmR3DevHlp_TMTimeVirtGetFreq: caller='%s'/%d\n",
784 pDevIns->pReg->szName, pDevIns->iInstance));
785
786 uint64_t u64Freq = TMVirtualGetFreq(pDevIns->Internal.s.pVMR3);
787
788 LogFlow(("pdmR3DevHlp_TMTimeVirtGetFreq: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64Freq));
789 return u64Freq;
790}
791
792
793/** @interface_method_impl{PDMDEVHLPR3,pfnTMTimeVirtGetNano} */
794static DECLCALLBACK(uint64_t) pdmR3DevHlp_TMTimeVirtGetNano(PPDMDEVINS pDevIns)
795{
796 PDMDEV_ASSERT_DEVINS(pDevIns);
797 LogFlow(("pdmR3DevHlp_TMTimeVirtGetNano: caller='%s'/%d\n",
798 pDevIns->pReg->szName, pDevIns->iInstance));
799
800 uint64_t u64Time = TMVirtualGet(pDevIns->Internal.s.pVMR3);
801 uint64_t u64Nano = TMVirtualToNano(pDevIns->Internal.s.pVMR3, u64Time);
802
803 LogFlow(("pdmR3DevHlp_TMTimeVirtGetNano: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64Nano));
804 return u64Nano;
805}
806
807
808/** @interface_method_impl{PDMDEVHLPR3,pfnTMCpuTicksPerSecond} */
809static DECLCALLBACK(uint64_t) pdmR3DevHlp_TMCpuTicksPerSecond(PPDMDEVINS pDevIns)
810{
811 PDMDEV_ASSERT_DEVINS(pDevIns);
812 LogFlow(("pdmR3DevHlp_TMCpuTicksPerSecond: caller='%s'/%d\n",
813 pDevIns->pReg->szName, pDevIns->iInstance));
814
815 uint64_t u64CpuTicksPerSec = TMCpuTicksPerSecond(pDevIns->Internal.s.pVMR3);
816
817 LogFlow(("pdmR3DevHlp_TMCpuTicksPerSecond: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64CpuTicksPerSec));
818 return u64CpuTicksPerSec;
819}
820
821
822/** @interface_method_impl{PDMDEVHLPR3,pfnGetSupDrvSession} */
823static DECLCALLBACK(PSUPDRVSESSION) pdmR3DevHlp_GetSupDrvSession(PPDMDEVINS pDevIns)
824{
825 PDMDEV_ASSERT_DEVINS(pDevIns);
826 LogFlow(("pdmR3DevHlp_GetSupDrvSession: caller='%s'/%d\n",
827 pDevIns->pReg->szName, pDevIns->iInstance));
828
829 PSUPDRVSESSION pSession = pDevIns->Internal.s.pVMR3->pSession;
830
831 LogFlow(("pdmR3DevHlp_GetSupDrvSession: caller='%s'/%d: returns %#p\n", pDevIns->pReg->szName, pDevIns->iInstance, pSession));
832 return pSession;
833}
834
835
836/** @interface_method_impl{PDMDEVHLPR3,pfnQueryGenericUserObject} */
837static DECLCALLBACK(void *) pdmR3DevHlp_QueryGenericUserObject(PPDMDEVINS pDevIns, PCRTUUID pUuid)
838{
839 PDMDEV_ASSERT_DEVINS(pDevIns);
840 LogFlow(("pdmR3DevHlp_QueryGenericUserObject: caller='%s'/%d: pUuid=%p:%RTuuid\n",
841 pDevIns->pReg->szName, pDevIns->iInstance, pUuid, pUuid));
842
843#if defined(DEBUG_bird) || defined(DEBUG_ramshankar) || defined(DEBUG_sunlover) || defined(DEBUG_michael) || defined(DEBUG_andy)
844 AssertMsgFailed(("'%s' wants %RTuuid - external only interface!\n", pDevIns->pReg->szName, pUuid));
845#endif
846
847 void *pvRet;
848 PUVM pUVM = pDevIns->Internal.s.pVMR3->pUVM;
849 if (pUVM->pVmm2UserMethods->pfnQueryGenericObject)
850 pvRet = pUVM->pVmm2UserMethods->pfnQueryGenericObject(pUVM->pVmm2UserMethods, pUVM, pUuid);
851 else
852 pvRet = NULL;
853
854 LogRel(("pdmR3DevHlp_QueryGenericUserObject: caller='%s'/%d: returns %#p for %RTuuid\n",
855 pDevIns->pReg->szName, pDevIns->iInstance, pvRet, pUuid));
856 return pvRet;
857}
858
859
860/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalTypeRegister} */
861static DECLCALLBACK(int) pdmR3DevHlp_PGMHandlerPhysicalTypeRegister(PPDMDEVINS pDevIns, PGMPHYSHANDLERKIND enmKind,
862 PFNPGMPHYSHANDLER pfnHandler, const char *pszDesc,
863 PPGMPHYSHANDLERTYPE phType)
864{
865 PDMDEV_ASSERT_DEVINS(pDevIns);
866 PVM pVM = pDevIns->Internal.s.pVMR3;
867 LogFlow(("pdmR3DevHlp_PGMHandlerPhysicalTypeRegister: caller='%s'/%d: enmKind=%d pfnHandler=%p pszDesc=%p:{%s} phType=%p\n",
868 pDevIns->pReg->szName, pDevIns->iInstance, enmKind, pfnHandler, pszDesc, pszDesc, phType));
869
870 int rc = PGMR3HandlerPhysicalTypeRegister(pVM, enmKind,
871 pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED
872 ? PGMPHYSHANDLER_F_R0_DEVINS_IDX : 0,
873 pfnHandler, pszDesc, phType);
874
875 Log(("pdmR3DevHlp_PGMHandlerPhysicalTypeRegister: caller='%s'/%d: returns %Rrc\n",
876 pDevIns->pReg->szName, pDevIns->iInstance, rc));
877 return rc;
878}
879
880
881/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalRegister} */
882static DECLCALLBACK(int) pdmR3DevHlp_PGMHandlerPhysicalRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
883 PGMPHYSHANDLERTYPE hType, R3PTRTYPE(const char *) pszDesc)
884{
885 PDMDEV_ASSERT_DEVINS(pDevIns);
886 PVM pVM = pDevIns->Internal.s.pVMR3;
887 LogFlow(("pdmR3DevHlp_PGMHandlerPhysicalRegister: caller='%s'/%d: GCPhys=%RGp GCPhysLast=%RGp hType=%u pszDesc=%p:{%s}\n",
888 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, GCPhysLast, hType, pszDesc, pszDesc));
889
890 int rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, hType,
891 pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED
892 ? pDevIns->Internal.s.idxR0Device : (uintptr_t)pDevIns,
893 pszDesc);
894
895 Log(("pdmR3DevHlp_PGMHandlerPhysicalRegister: caller='%s'/%d: returns %Rrc\n",
896 pDevIns->pReg->szName, pDevIns->iInstance, rc));
897 return rc;
898}
899
900
901/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalDeregister} */
902static DECLCALLBACK(int) pdmR3DevHlp_PGMHandlerPhysicalDeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
903{
904 PDMDEV_ASSERT_DEVINS(pDevIns);
905 PVM pVM = pDevIns->Internal.s.pVMR3;
906 LogFlow(("pdmR3DevHlp_PGMHandlerPhysicalDeregister: caller='%s'/%d: GCPhys=%RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, GCPhys));
907
908 int rc = PGMHandlerPhysicalDeregister(pVM, GCPhys);
909
910 Log(("pdmR3DevHlp_PGMHandlerPhysicalDeregister: caller='%s'/%d: returns %Rrc\n",
911 pDevIns->pReg->szName, pDevIns->iInstance, rc));
912 return rc;
913}
914
915
916/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalPageTempOff} */
917static DECLCALLBACK(int) pdmR3DevHlp_PGMHandlerPhysicalPageTempOff(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage)
918{
919 PDMDEV_ASSERT_DEVINS(pDevIns);
920 PVM pVM = pDevIns->Internal.s.pVMR3;
921 LogFlow(("pdmR3DevHlp_PGMHandlerPhysicalPageTempOff: caller='%s'/%d: GCPhys=%RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, GCPhys));
922
923 int rc = PGMHandlerPhysicalPageTempOff(pVM, GCPhys, GCPhysPage);
924
925 Log(("pdmR3DevHlp_PGMHandlerPhysicalPageTempOff: caller='%s'/%d: returns %Rrc\n",
926 pDevIns->pReg->szName, pDevIns->iInstance, rc));
927 return rc;
928}
929
930
931/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalReset} */
932static DECLCALLBACK(int) pdmR3DevHlp_PGMHandlerPhysicalReset(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
933{
934 PDMDEV_ASSERT_DEVINS(pDevIns);
935 PVM pVM = pDevIns->Internal.s.pVMR3;
936 LogFlow(("pdmR3DevHlp_PGMHandlerPhysicalReset: caller='%s'/%d: GCPhys=%RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, GCPhys));
937
938 int rc = PGMHandlerPhysicalReset(pVM, GCPhys);
939
940 Log(("pdmR3DevHlp_PGMHandlerPhysicalReset: caller='%s'/%d: returns %Rrc\n",
941 pDevIns->pReg->szName, pDevIns->iInstance, rc));
942 return rc;
943}
944
945
946/** @interface_method_impl{PDMDEVHLPR3,pfnPhysRead} */
947static DECLCALLBACK(int) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags)
948{
949 RT_NOREF(fFlags);
950
951 PDMDEV_ASSERT_DEVINS(pDevIns);
952 PVM pVM = pDevIns->Internal.s.pVMR3;
953 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
954 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
955
956#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
957 if (!VM_IS_EMT(pVM))
958 {
959 char szNames[128];
960 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
961 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
962 }
963#endif
964
965 VBOXSTRICTRC rcStrict;
966 if (VM_IS_EMT(pVM))
967 rcStrict = PGMPhysRead(pVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
968 else
969 rcStrict = PGMR3PhysReadExternal(pVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
970 AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
971
972 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
973 return VBOXSTRICTRC_VAL(rcStrict);
974}
975
976
977/** @interface_method_impl{PDMDEVHLPR3,pfnPhysWrite} */
978static DECLCALLBACK(int) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags)
979{
980 RT_NOREF(fFlags);
981
982 PDMDEV_ASSERT_DEVINS(pDevIns);
983 PVM pVM = pDevIns->Internal.s.pVMR3;
984 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
985 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
986
987#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
988 if (!VM_IS_EMT(pVM))
989 {
990 char szNames[128];
991 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
992 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
993 }
994#endif
995
996 VBOXSTRICTRC rcStrict;
997 if (VM_IS_EMT(pVM))
998 rcStrict = PGMPhysWrite(pVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
999 else
1000 rcStrict = PGMR3PhysWriteExternal(pVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
1001 AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
1002
1003 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
1004 return VBOXSTRICTRC_VAL(rcStrict);
1005}
1006
1007
1008/** @interface_method_impl{PDMDEVHLPR3,pfnPhysGCPhys2CCPtr} */
1009static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
1010{
1011 PDMDEV_ASSERT_DEVINS(pDevIns);
1012 PVM pVM = pDevIns->Internal.s.pVMR3;
1013 LogFlow(("pdmR3DevHlp_PhysGCPhys2CCPtr: caller='%s'/%d: GCPhys=%RGp fFlags=%#x ppv=%p pLock=%p\n",
1014 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, fFlags, ppv, pLock));
1015 AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
1016
1017#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
1018 if (!VM_IS_EMT(pVM))
1019 {
1020 char szNames[128];
1021 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
1022 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
1023 }
1024#endif
1025
1026 int rc = PGMR3PhysGCPhys2CCPtrExternal(pVM, GCPhys, ppv, pLock);
1027
1028 Log(("pdmR3DevHlp_PhysGCPhys2CCPtr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1029 return rc;
1030}
1031
1032
1033/** @interface_method_impl{PDMDEVHLPR3,pfnPhysGCPhys2CCPtrReadOnly} */
1034static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, const void **ppv, PPGMPAGEMAPLOCK pLock)
1035{
1036 PDMDEV_ASSERT_DEVINS(pDevIns);
1037 PVM pVM = pDevIns->Internal.s.pVMR3;
1038 LogFlow(("pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly: caller='%s'/%d: GCPhys=%RGp fFlags=%#x ppv=%p pLock=%p\n",
1039 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, fFlags, ppv, pLock));
1040 AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
1041
1042#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
1043 if (!VM_IS_EMT(pVM))
1044 {
1045 char szNames[128];
1046 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
1047 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
1048 }
1049#endif
1050
1051 int rc = PGMR3PhysGCPhys2CCPtrReadOnlyExternal(pVM, GCPhys, ppv, pLock);
1052
1053 Log(("pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1054 return rc;
1055}
1056
1057
1058/** @interface_method_impl{PDMDEVHLPR3,pfnPhysReleasePageMappingLock} */
1059static DECLCALLBACK(void) pdmR3DevHlp_PhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
1060{
1061 PDMDEV_ASSERT_DEVINS(pDevIns);
1062 PVM pVM = pDevIns->Internal.s.pVMR3;
1063 LogFlow(("pdmR3DevHlp_PhysReleasePageMappingLock: caller='%s'/%d: pLock=%p\n",
1064 pDevIns->pReg->szName, pDevIns->iInstance, pLock));
1065
1066 PGMPhysReleasePageMappingLock(pVM, pLock);
1067
1068 Log(("pdmR3DevHlp_PhysReleasePageMappingLock: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
1069}
1070
1071
1072/** @interface_method_impl{PDMDEVHLPR3,pfnPhysBulkGCPhys2CCPtr} */
1073static DECLCALLBACK(int) pdmR3DevHlp_PhysBulkGCPhys2CCPtr(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
1074 uint32_t fFlags, void **papvPages, PPGMPAGEMAPLOCK paLocks)
1075{
1076 PDMDEV_ASSERT_DEVINS(pDevIns);
1077 PVM pVM = pDevIns->Internal.s.pVMR3;
1078 LogFlow(("pdmR3DevHlp_PhysBulkGCPhys2CCPtr: caller='%s'/%d: cPages=%#x paGCPhysPages=%p (%RGp,..) fFlags=%#x papvPages=%p paLocks=%p\n",
1079 pDevIns->pReg->szName, pDevIns->iInstance, cPages, paGCPhysPages, paGCPhysPages[0], fFlags, papvPages, paLocks));
1080 AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
1081 AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
1082
1083#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
1084 if (!VM_IS_EMT(pVM))
1085 {
1086 char szNames[128];
1087 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
1088 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
1089 }
1090#endif
1091
1092 int rc = PGMR3PhysBulkGCPhys2CCPtrExternal(pVM, cPages, paGCPhysPages, papvPages, paLocks);
1093
1094 Log(("pdmR3DevHlp_PhysBulkGCPhys2CCPtr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1095 return rc;
1096}
1097
1098
1099/** @interface_method_impl{PDMDEVHLPR3,pfnPhysBulkGCPhys2CCPtrReadOnly} */
1100static DECLCALLBACK(int) pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
1101 uint32_t fFlags, const void **papvPages, PPGMPAGEMAPLOCK paLocks)
1102{
1103 PDMDEV_ASSERT_DEVINS(pDevIns);
1104 PVM pVM = pDevIns->Internal.s.pVMR3;
1105 LogFlow(("pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly: caller='%s'/%d: cPages=%#x paGCPhysPages=%p (%RGp,...) fFlags=%#x papvPages=%p paLocks=%p\n",
1106 pDevIns->pReg->szName, pDevIns->iInstance, cPages, paGCPhysPages, paGCPhysPages[0], fFlags, papvPages, paLocks));
1107 AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
1108 AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
1109
1110#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
1111 if (!VM_IS_EMT(pVM))
1112 {
1113 char szNames[128];
1114 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
1115 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
1116 }
1117#endif
1118
1119 int rc = PGMR3PhysBulkGCPhys2CCPtrReadOnlyExternal(pVM, cPages, paGCPhysPages, papvPages, paLocks);
1120
1121 Log(("pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1122 return rc;
1123}
1124
1125
1126/** @interface_method_impl{PDMDEVHLPR3,pfnPhysBulkReleasePageMappingLocks} */
1127static DECLCALLBACK(void) pdmR3DevHlp_PhysBulkReleasePageMappingLocks(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks)
1128{
1129 PDMDEV_ASSERT_DEVINS(pDevIns);
1130 PVM pVM = pDevIns->Internal.s.pVMR3;
1131 LogFlow(("pdmR3DevHlp_PhysBulkReleasePageMappingLocks: caller='%s'/%d: cPages=%#x paLocks=%p\n",
1132 pDevIns->pReg->szName, pDevIns->iInstance, cPages, paLocks));
1133 Assert(cPages > 0);
1134
1135 PGMPhysBulkReleasePageMappingLocks(pVM, cPages, paLocks);
1136
1137 Log(("pdmR3DevHlp_PhysBulkReleasePageMappingLocks: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
1138}
1139
1140
1141/** @interface_method_impl{PDMDEVHLPR3,pfnPhysIsGCPhysNormal} */
1142static DECLCALLBACK(bool) pdmR3DevHlp_PhysIsGCPhysNormal(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
1143{
1144 PDMDEV_ASSERT_DEVINS(pDevIns);
1145 LogFlow(("pdmR3DevHlp_PhysIsGCPhysNormal: caller='%s'/%d: GCPhys=%RGp\n",
1146 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys));
1147
1148 bool fNormal = PGMPhysIsGCPhysNormal(pDevIns->Internal.s.pVMR3, GCPhys);
1149
1150 Log(("pdmR3DevHlp_PhysIsGCPhysNormal: caller='%s'/%d: returns %RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance, fNormal));
1151 return fNormal;
1152}
1153
1154
1155/** @interface_method_impl{PDMDEVHLPR3,pfnPhysChangeMemBalloon} */
1156static DECLCALLBACK(int) pdmR3DevHlp_PhysChangeMemBalloon(PPDMDEVINS pDevIns, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage)
1157{
1158 PDMDEV_ASSERT_DEVINS(pDevIns);
1159 LogFlow(("pdmR3DevHlp_PhysChangeMemBalloon: caller='%s'/%d: fInflate=%RTbool cPages=%u paPhysPage=%p\n",
1160 pDevIns->pReg->szName, pDevIns->iInstance, fInflate, cPages, paPhysPage));
1161
1162 int rc = PGMR3PhysChangeMemBalloon(pDevIns->Internal.s.pVMR3, fInflate, cPages, paPhysPage);
1163
1164 Log(("pdmR3DevHlp_PhysChangeMemBalloon: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1165 return rc;
1166}
1167
1168
1169/** @interface_method_impl{PDMDEVHLPR3,pfnCpuGetGuestMicroarch} */
1170static DECLCALLBACK(CPUMMICROARCH) pdmR3DevHlp_CpuGetGuestMicroarch(PPDMDEVINS pDevIns)
1171{
1172 PDMDEV_ASSERT_DEVINS(pDevIns);
1173 PVM pVM = pDevIns->Internal.s.pVMR3;
1174 LogFlow(("pdmR3DevHlp_CpuGetGuestMicroarch: caller='%s'/%d\n",
1175 pDevIns->pReg->szName, pDevIns->iInstance));
1176
1177 CPUMMICROARCH enmMicroarch = CPUMGetGuestMicroarch(pVM);
1178
1179 Log(("pdmR3DevHlp_CpuGetGuestMicroarch: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, enmMicroarch));
1180 return enmMicroarch;
1181}
1182
1183
1184/** @interface_method_impl{PDMDEVHLPR3,pfnCpuGetGuestAddrWidths} */
1185static DECLCALLBACK(void) pdmR3DevHlp_CpuGetGuestAddrWidths(PPDMDEVINS pDevIns, uint8_t *pcPhysAddrWidth,
1186 uint8_t *pcLinearAddrWidth)
1187{
1188 PDMDEV_ASSERT_DEVINS(pDevIns);
1189 PVM pVM = pDevIns->Internal.s.pVMR3;
1190 LogFlow(("pdmR3DevHlp_CpuGetGuestAddrWidths: caller='%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
1191 AssertPtrReturnVoid(pcPhysAddrWidth);
1192 AssertPtrReturnVoid(pcLinearAddrWidth);
1193
1194 CPUMGetGuestAddrWidths(pVM, pcPhysAddrWidth, pcLinearAddrWidth);
1195
1196 Log(("pdmR3DevHlp_CpuGetGuestAddrWidths: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
1197}
1198
1199
1200/** @interface_method_impl{PDMDEVHLPR3,pfnCpuGetGuestScalableBusFrequency} */
1201static DECLCALLBACK(uint64_t) pdmR3DevHlp_CpuGetGuestScalableBusFrequency(PPDMDEVINS pDevIns)
1202{
1203 PDMDEV_ASSERT_DEVINS(pDevIns);
1204 LogFlow(("pdmR3DevHlp_CpuGetGuestScalableBusFrequency: caller='%s'/%d\n",
1205 pDevIns->pReg->szName, pDevIns->iInstance));
1206
1207 uint64_t u64Fsb = CPUMGetGuestScalableBusFrequency(pDevIns->Internal.s.pVMR3);
1208
1209 Log(("pdmR3DevHlp_CpuGetGuestScalableBusFrequency: caller='%s'/%d: returns %#RX64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64Fsb));
1210 return u64Fsb;
1211}
1212
1213
1214/** @interface_method_impl{PDMDEVHLPR3,pfnPhysReadGCVirt} */
1215static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
1216{
1217 PDMDEV_ASSERT_DEVINS(pDevIns);
1218 PVM pVM = pDevIns->Internal.s.pVMR3;
1219 VM_ASSERT_EMT(pVM);
1220 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%RGv cb=%#x\n",
1221 pDevIns->pReg->szName, pDevIns->iInstance, pvDst, GCVirtSrc, cb));
1222
1223 PVMCPU pVCpu = VMMGetCpu(pVM);
1224 if (!pVCpu)
1225 return VERR_ACCESS_DENIED;
1226#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
1227 /** @todo SMP. */
1228#endif
1229
1230 int rc = PGMPhysSimpleReadGCPtr(pVCpu, pvDst, GCVirtSrc, cb);
1231
1232 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1233
1234 return rc;
1235}
1236
1237
1238/** @interface_method_impl{PDMDEVHLPR3,pfnPhysWriteGCVirt} */
1239static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
1240{
1241 PDMDEV_ASSERT_DEVINS(pDevIns);
1242 PVM pVM = pDevIns->Internal.s.pVMR3;
1243 VM_ASSERT_EMT(pVM);
1244 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%RGv pvSrc=%p cb=%#x\n",
1245 pDevIns->pReg->szName, pDevIns->iInstance, GCVirtDst, pvSrc, cb));
1246
1247 PVMCPU pVCpu = VMMGetCpu(pVM);
1248 if (!pVCpu)
1249 return VERR_ACCESS_DENIED;
1250#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
1251 /** @todo SMP. */
1252#endif
1253
1254 int rc = PGMPhysSimpleWriteGCPtr(pVCpu, GCVirtDst, pvSrc, cb);
1255
1256 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1257
1258 return rc;
1259}
1260
1261
1262/** @interface_method_impl{PDMDEVHLPR3,pfnPhysGCPtr2GCPhys} */
1263static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
1264{
1265 PDMDEV_ASSERT_DEVINS(pDevIns);
1266 PVM pVM = pDevIns->Internal.s.pVMR3;
1267 VM_ASSERT_EMT(pVM);
1268 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%RGv pGCPhys=%p\n",
1269 pDevIns->pReg->szName, pDevIns->iInstance, GCPtr, pGCPhys));
1270
1271 PVMCPU pVCpu = VMMGetCpu(pVM);
1272 if (!pVCpu)
1273 return VERR_ACCESS_DENIED;
1274#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
1275 /** @todo SMP. */
1276#endif
1277
1278 int rc = PGMPhysGCPtr2GCPhys(pVCpu, GCPtr, pGCPhys);
1279
1280 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Rrc *pGCPhys=%RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pGCPhys));
1281
1282 return rc;
1283}
1284
1285
1286/** @interface_method_impl{PDMDEVHLPR3,pfnMMHeapAlloc} */
1287static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
1288{
1289 PDMDEV_ASSERT_DEVINS(pDevIns);
1290 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, cb));
1291
1292 void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);
1293
1294 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pv));
1295 return pv;
1296}
1297
1298
1299/** @interface_method_impl{PDMDEVHLPR3,pfnMMHeapAllocZ} */
1300static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
1301{
1302 PDMDEV_ASSERT_DEVINS(pDevIns);
1303 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, cb));
1304
1305 void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);
1306
1307 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pv));
1308 return pv;
1309}
1310
1311
1312/** @interface_method_impl{PDMDEVHLPR3,pfnMMHeapAPrintfV} */
1313static DECLCALLBACK(char *) pdmR3DevHlp_MMHeapAPrintfV(PPDMDEVINS pDevIns, MMTAG enmTag, const char *pszFormat, va_list va)
1314{
1315 PDMDEV_ASSERT_DEVINS(pDevIns);
1316 LogFlow(("pdmR3DevHlp_MMHeapAPrintfV: caller='%s'/%d: enmTag=%u pszFormat=%p:{%s}\n",
1317 pDevIns->pReg->szName, pDevIns->iInstance, enmTag, pszFormat, pszFormat));
1318
1319 char *psz = MMR3HeapAPrintfV(pDevIns->Internal.s.pVMR3, enmTag, pszFormat, va);
1320
1321 LogFlow(("pdmR3DevHlp_MMHeapAPrintfV: caller='%s'/%d: returns %p:{%s}\n",
1322 pDevIns->pReg->szName, pDevIns->iInstance, psz, psz));
1323 return psz;
1324}
1325
1326
1327/** @interface_method_impl{PDMDEVHLPR3,pfnMMHeapFree} */
1328static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv)
1329{
1330 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
1331 LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pv));
1332
1333 MMR3HeapFree(pv);
1334
1335 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
1336}
1337
1338
1339/** @interface_method_impl{PDMDEVHLPR3,pfnMMPhysGetRamSize} */
1340static DECLCALLBACK(uint64_t) pdmR3DevHlp_MMPhysGetRamSize(PPDMDEVINS pDevIns)
1341{
1342 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
1343 LogFlow(("pdmR3DevHlp_MMPhysGetRamSize: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
1344
1345 uint64_t cb = MMR3PhysGetRamSize(pDevIns->Internal.s.pVMR3);
1346
1347 LogFlow(("pdmR3DevHlp_MMPhysGetRamSize: caller='%s'/%d: returns %RU64\n",
1348 pDevIns->pReg->szName, pDevIns->iInstance, cb));
1349 return cb;
1350}
1351
1352
1353/** @interface_method_impl{PDMDEVHLPR3,pfnMMPhysGetRamSizeBelow4GB} */
1354static DECLCALLBACK(uint32_t) pdmR3DevHlp_MMPhysGetRamSizeBelow4GB(PPDMDEVINS pDevIns)
1355{
1356 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
1357 LogFlow(("pdmR3DevHlp_MMPhysGetRamSizeBelow4GB: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
1358
1359 uint32_t cb = MMR3PhysGetRamSizeBelow4GB(pDevIns->Internal.s.pVMR3);
1360
1361 LogFlow(("pdmR3DevHlp_MMPhysGetRamSizeBelow4GB: caller='%s'/%d: returns %RU32\n",
1362 pDevIns->pReg->szName, pDevIns->iInstance, cb));
1363 return cb;
1364}
1365
1366
1367/** @interface_method_impl{PDMDEVHLPR3,pfnMMPhysGetRamSizeAbove4GB} */
1368static DECLCALLBACK(uint64_t) pdmR3DevHlp_MMPhysGetRamSizeAbove4GB(PPDMDEVINS pDevIns)
1369{
1370 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
1371 LogFlow(("pdmR3DevHlp_MMPhysGetRamSizeAbove4GB: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
1372
1373 uint64_t cb = MMR3PhysGetRamSizeAbove4GB(pDevIns->Internal.s.pVMR3);
1374
1375 LogFlow(("pdmR3DevHlp_MMPhysGetRamSizeAbove4GB: caller='%s'/%d: returns %RU64\n",
1376 pDevIns->pReg->szName, pDevIns->iInstance, cb));
1377 return cb;
1378}
1379
1380
1381/** @interface_method_impl{PDMDEVHLPR3,pfnVMState} */
1382static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns)
1383{
1384 PDMDEV_ASSERT_DEVINS(pDevIns);
1385
1386 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);
1387
1388 LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pReg->szName, pDevIns->iInstance,
1389 enmVMState, VMR3GetStateName(enmVMState)));
1390 return enmVMState;
1391}
1392
1393
1394/** @interface_method_impl{PDMDEVHLPR3,pfnVMTeleportedAndNotFullyResumedYet} */
1395static DECLCALLBACK(bool) pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
1396{
1397 PDMDEV_ASSERT_DEVINS(pDevIns);
1398
1399 bool fRc = VMR3TeleportedAndNotFullyResumedYet(pDevIns->Internal.s.pVMR3);
1400
1401 LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance,
1402 fRc));
1403 return fRc;
1404}
1405
1406
1407/** @interface_method_impl{PDMDEVHLPR3,pfnVMSetErrorV} */
1408static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
1409{
1410 PDMDEV_ASSERT_DEVINS(pDevIns);
1411 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
1412 return rc;
1413}
1414
1415
1416/** @interface_method_impl{PDMDEVHLPR3,pfnVMSetRuntimeErrorV} */
1417static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
1418{
1419 PDMDEV_ASSERT_DEVINS(pDevIns);
1420 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFlags, pszErrorId, pszFormat, va);
1421 return rc;
1422}
1423
1424
1425/** @interface_method_impl{PDMDEVHLPR3,pfnVMWaitForDeviceReady} */
1426static DECLCALLBACK(int) pdmR3DevHlp_VMWaitForDeviceReady(PPDMDEVINS pDevIns, VMCPUID idCpu)
1427{
1428 PDMDEV_ASSERT_DEVINS(pDevIns);
1429 LogFlow(("pdmR3DevHlp_VMWaitForDeviceReady: caller='%s'/%d: idCpu=%u\n", pDevIns->pReg->szName, pDevIns->iInstance, idCpu));
1430
1431 int rc = VMR3WaitForDeviceReady(pDevIns->Internal.s.pVMR3, idCpu);
1432
1433 LogFlow(("pdmR3DevHlp_VMWaitForDeviceReady: caller='%s'/%d: returns %Rrc\n",
1434 pDevIns->pReg->szName, pDevIns->iInstance, rc));
1435 return rc;
1436}
1437
1438
1439/** @interface_method_impl{PDMDEVHLPR3,pfnVMNotifyCpuDeviceReady} */
1440static DECLCALLBACK(int) pdmR3DevHlp_VMNotifyCpuDeviceReady(PPDMDEVINS pDevIns, VMCPUID idCpu)
1441{
1442 PDMDEV_ASSERT_DEVINS(pDevIns);
1443 LogFlow(("pdmR3DevHlp_VMNotifyCpuDeviceReady: caller='%s'/%d: idCpu=%u\n", pDevIns->pReg->szName, pDevIns->iInstance, idCpu));
1444
1445 int rc = VMR3NotifyCpuDeviceReady(pDevIns->Internal.s.pVMR3, idCpu);
1446
1447 LogFlow(("pdmR3DevHlp_VMNotifyCpuDeviceReady: caller='%s'/%d: returns %Rrc\n",
1448 pDevIns->pReg->szName, pDevIns->iInstance, rc));
1449 return rc;
1450}
1451
1452
1453/** @interface_method_impl{PDMDEVHLPR3,pfnVMReqCallNoWaitV} */
1454static DECLCALLBACK(int) pdmR3DevHlp_VMReqCallNoWaitV(PPDMDEVINS pDevIns, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, va_list Args)
1455{
1456 PDMDEV_ASSERT_DEVINS(pDevIns);
1457 LogFlow(("pdmR3DevHlp_VMReqCallNoWaitV: caller='%s'/%d: idDstCpu=%u pfnFunction=%p cArgs=%u\n",
1458 pDevIns->pReg->szName, pDevIns->iInstance, idDstCpu, pfnFunction, cArgs));
1459
1460 int rc = VMR3ReqCallVU(pDevIns->Internal.s.pVMR3->pUVM, idDstCpu, NULL, 0, VMREQFLAGS_VBOX_STATUS | VMREQFLAGS_NO_WAIT,
1461 pfnFunction, cArgs, Args);
1462
1463 LogFlow(("pdmR3DevHlp_VMReqCallNoWaitV: caller='%s'/%d: returns %Rrc\n",
1464 pDevIns->pReg->szName, pDevIns->iInstance, rc));
1465 return rc;
1466}
1467
1468
1469/** @interface_method_impl{PDMDEVHLPR3,pfnVMReqPriorityCallWaitV} */
1470static DECLCALLBACK(int) pdmR3DevHlp_VMReqPriorityCallWaitV(PPDMDEVINS pDevIns, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, va_list Args)
1471{
1472 PDMDEV_ASSERT_DEVINS(pDevIns);
1473 LogFlow(("pdmR3DevHlp_VMReqCallNoWaitV: caller='%s'/%d: idDstCpu=%u pfnFunction=%p cArgs=%u\n",
1474 pDevIns->pReg->szName, pDevIns->iInstance, idDstCpu, pfnFunction, cArgs));
1475
1476 PVMREQ pReq;
1477 int rc = VMR3ReqCallVU(pDevIns->Internal.s.pVMR3->pUVM, idDstCpu, &pReq, RT_INDEFINITE_WAIT, VMREQFLAGS_VBOX_STATUS | VMREQFLAGS_PRIORITY,
1478 pfnFunction, cArgs, Args);
1479 if (RT_SUCCESS(rc))
1480 rc = pReq->iStatus;
1481 VMR3ReqFree(pReq);
1482
1483 LogFlow(("pdmR3DevHlp_VMReqCallNoWaitV: caller='%s'/%d: returns %Rrc\n",
1484 pDevIns->pReg->szName, pDevIns->iInstance, rc));
1485 return rc;
1486}
1487
1488
1489/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFStopV} */
1490static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args)
1491{
1492 PDMDEV_ASSERT_DEVINS(pDevIns);
1493#ifdef LOG_ENABLED
1494 va_list va2;
1495 va_copy(va2, args);
1496 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n",
1497 pDevIns->pReg->szName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2));
1498 va_end(va2);
1499#endif
1500
1501 PVM pVM = pDevIns->Internal.s.pVMR3;
1502 VM_ASSERT_EMT(pVM);
1503 int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args);
1504 if (rc == VERR_DBGF_NOT_ATTACHED)
1505 rc = VINF_SUCCESS;
1506
1507 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1508 return rc;
1509}
1510
1511
1512/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFInfoRegister} */
1513static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
1514{
1515 PDMDEV_ASSERT_DEVINS(pDevIns);
1516 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n",
1517 pDevIns->pReg->szName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler));
1518
1519 PVM pVM = pDevIns->Internal.s.pVMR3;
1520 VM_ASSERT_EMT(pVM);
1521 int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns);
1522
1523 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1524 return rc;
1525}
1526
1527
1528/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFInfoRegisterArgv} */
1529static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegisterArgv(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDEV pfnHandler)
1530{
1531 PDMDEV_ASSERT_DEVINS(pDevIns);
1532 LogFlow(("pdmR3DevHlp_DBGFInfoRegisterArgv: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n",
1533 pDevIns->pReg->szName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler));
1534
1535 PVM pVM = pDevIns->Internal.s.pVMR3;
1536 VM_ASSERT_EMT(pVM);
1537 int rc = DBGFR3InfoRegisterDeviceArgv(pVM, pszName, pszDesc, pfnHandler, pDevIns);
1538
1539 LogFlow(("pdmR3DevHlp_DBGFInfoRegisterArgv: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1540 return rc;
1541}
1542
1543
1544/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFRegRegister} */
1545static DECLCALLBACK(int) pdmR3DevHlp_DBGFRegRegister(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters)
1546{
1547 PDMDEV_ASSERT_DEVINS(pDevIns);
1548 LogFlow(("pdmR3DevHlp_DBGFRegRegister: caller='%s'/%d: paRegisters=%p\n",
1549 pDevIns->pReg->szName, pDevIns->iInstance, paRegisters));
1550
1551 PVM pVM = pDevIns->Internal.s.pVMR3;
1552 VM_ASSERT_EMT(pVM);
1553 int rc = DBGFR3RegRegisterDevice(pVM, paRegisters, pDevIns, pDevIns->pReg->szName, pDevIns->iInstance);
1554
1555 LogFlow(("pdmR3DevHlp_DBGFRegRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1556 return rc;
1557}
1558
1559
1560/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFTraceBuf} */
1561static DECLCALLBACK(RTTRACEBUF) pdmR3DevHlp_DBGFTraceBuf(PPDMDEVINS pDevIns)
1562{
1563 PDMDEV_ASSERT_DEVINS(pDevIns);
1564 RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pVMR3->hTraceBufR3;
1565 LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, hTraceBuf));
1566 return hTraceBuf;
1567}
1568
1569
1570/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFReportBugCheck} */
1571static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_DBGFReportBugCheck(PPDMDEVINS pDevIns, DBGFEVENTTYPE enmEvent, uint64_t uBugCheck,
1572 uint64_t uP1, uint64_t uP2, uint64_t uP3, uint64_t uP4)
1573{
1574 PDMDEV_ASSERT_DEVINS(pDevIns);
1575 LogFlow(("pdmR3DevHlp_DBGFReportBugCheck: caller='%s'/%d: enmEvent=%u uBugCheck=%#x uP1=%#x uP2=%#x uP3=%#x uP4=%#x\n",
1576 pDevIns->pReg->szName, pDevIns->iInstance, enmEvent, uBugCheck, uP1, uP2, uP3, uP4));
1577
1578 PVM pVM = pDevIns->Internal.s.pVMR3;
1579 VM_ASSERT_EMT(pVM);
1580 VBOXSTRICTRC rcStrict = DBGFR3ReportBugCheck(pVM, VMMGetCpu(pVM), enmEvent, uBugCheck, uP1, uP2, uP3, uP4);
1581
1582 LogFlow(("pdmR3DevHlp_DBGFReportBugCheck: caller='%s'/%d: returns %Rrc\n",
1583 pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict)));
1584 return rcStrict;
1585}
1586
1587
1588/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFCoreWrite} */
1589static DECLCALLBACK(int) pdmR3DevHlp_DBGFCoreWrite(PPDMDEVINS pDevIns, const char *pszFilename, bool fReplaceFile)
1590{
1591 PDMDEV_ASSERT_DEVINS(pDevIns);
1592 LogFlow(("pdmR3DevHlp_DBGFCoreWrite: caller='%s'/%d: pszFilename=%p:{%s} fReplaceFile=%RTbool\n",
1593 pDevIns->pReg->szName, pDevIns->iInstance, pszFilename, pszFilename, fReplaceFile));
1594
1595 int rc = DBGFR3CoreWrite(pDevIns->Internal.s.pVMR3->pUVM, pszFilename, fReplaceFile);
1596
1597 LogFlow(("pdmR3DevHlp_DBGFCoreWrite: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1598 return rc;
1599}
1600
1601
1602/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFInfoLogHlp} */
1603static DECLCALLBACK(PCDBGFINFOHLP) pdmR3DevHlp_DBGFInfoLogHlp(PPDMDEVINS pDevIns)
1604{
1605 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF(pDevIns);
1606 LogFlow(("pdmR3DevHlp_DBGFInfoLogHlp: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
1607
1608 PCDBGFINFOHLP pHlp = DBGFR3InfoLogHlp();
1609
1610 LogFlow(("pdmR3DevHlp_DBGFInfoLogHlp: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pHlp));
1611 return pHlp;
1612}
1613
1614
1615/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFRegNmQueryU64} */
1616static DECLCALLBACK(int) pdmR3DevHlp_DBGFRegNmQueryU64(PPDMDEVINS pDevIns, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64)
1617{
1618 PDMDEV_ASSERT_DEVINS(pDevIns);
1619 LogFlow(("pdmR3DevHlp_DBGFRegNmQueryU64: caller='%s'/%d: idDefCpu=%u pszReg=%p:{%s} pu64=%p\n",
1620 pDevIns->pReg->szName, pDevIns->iInstance, idDefCpu, pszReg, pszReg, pu64));
1621
1622 int rc = DBGFR3RegNmQueryU64(pDevIns->Internal.s.pVMR3->pUVM, idDefCpu, pszReg, pu64);
1623
1624 LogFlow(("pdmR3DevHlp_DBGFRegNmQueryU64: caller='%s'/%d: returns %Rrc *pu64=%#RX64\n",
1625 pDevIns->pReg->szName, pDevIns->iInstance, rc, *pu64));
1626 return rc;
1627}
1628
1629
1630/** @interface_method_impl{PDMDEVHLPR3,pfnDBGFRegPrintfV} */
1631static DECLCALLBACK(int) pdmR3DevHlp_DBGFRegPrintfV(PPDMDEVINS pDevIns, VMCPUID idCpu, char *pszBuf, size_t cbBuf,
1632 const char *pszFormat, va_list va)
1633{
1634 PDMDEV_ASSERT_DEVINS(pDevIns);
1635 LogFlow(("pdmR3DevHlp_DBGFRegPrintfV: caller='%s'/%d: idCpu=%u pszBuf=%p cbBuf=%u pszFormat=%p:{%s}\n",
1636 pDevIns->pReg->szName, pDevIns->iInstance, idCpu, pszBuf, cbBuf, pszFormat, pszFormat));
1637
1638 int rc = DBGFR3RegPrintfV(pDevIns->Internal.s.pVMR3->pUVM, idCpu, pszBuf, cbBuf, pszFormat, va);
1639
1640 LogFlow(("pdmR3DevHlp_DBGFRegPrintfV: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1641 return rc;
1642}
1643
1644
1645/** @interface_method_impl{PDMDEVHLPR3,pfnSTAMRegister} */
1646static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName,
1647 STAMUNIT enmUnit, const char *pszDesc)
1648{
1649 PDMDEV_ASSERT_DEVINS(pDevIns);
1650 PVM pVM = pDevIns->Internal.s.pVMR3;
1651 VM_ASSERT_EMT(pVM);
1652
1653 int rc;
1654 if (*pszName == '/')
1655 rc = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_ALWAYS, pszName, enmUnit, pszDesc);
1656 /* Provide default device statistics prefix: */
1657 else if (pDevIns->pReg->cMaxInstances == 1)
1658 rc = STAMR3RegisterF(pVM, pvSample, enmType, STAMVISIBILITY_ALWAYS, enmUnit, pszDesc,
1659 "/Devices/%s/%s", pDevIns->pReg->szName, pszName);
1660 else
1661 rc = STAMR3RegisterF(pVM, pvSample, enmType, STAMVISIBILITY_ALWAYS, enmUnit, pszDesc,
1662 "/Devices/%s#%u/%s", pDevIns->pReg->szName, pDevIns->iInstance, pszName);
1663 AssertRC(rc);
1664}
1665
1666
1667/** @interface_method_impl{PDMDEVHLPR3,pfnSTAMRegisterV} */
1668static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
1669 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args)
1670{
1671 PDMDEV_ASSERT_DEVINS(pDevIns);
1672 PVM pVM = pDevIns->Internal.s.pVMR3;
1673 VM_ASSERT_EMT(pVM);
1674
1675 int rc;
1676 if (*pszName == '/')
1677 rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
1678 else
1679 {
1680 /* Provide default device statistics prefix: */
1681 va_list vaCopy;
1682 va_copy(vaCopy, args);
1683 if (pDevIns->pReg->cMaxInstances == 1)
1684 rc = STAMR3RegisterF(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc,
1685 "/Devices/%s/%N", pDevIns->pReg->szName, pszName, &vaCopy);
1686 else
1687 rc = STAMR3RegisterF(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc,
1688 "/Devices/%s#%u/%N", pDevIns->pReg->szName, pDevIns->iInstance, pszName, &vaCopy);
1689 va_end(vaCopy);
1690 }
1691 AssertRC(rc);
1692}
1693
1694
1695/**
1696 * @interface_method_impl{PDMDEVHLPR3,pfnSTAMDeregisterByPrefix}
1697 */
1698static DECLCALLBACK(int) pdmR3DevHlp_STAMDeregisterByPrefix(PPDMDEVINS pDevIns, const char *pszPrefix)
1699{
1700 PDMDEV_ASSERT_DEVINS(pDevIns);
1701 PVM pVM = pDevIns->Internal.s.pVMR3;
1702 VM_ASSERT_EMT(pVM);
1703
1704 int rc;
1705 if (*pszPrefix == '/')
1706 rc = STAMR3DeregisterByPrefix(pVM->pUVM, pszPrefix);
1707 else
1708 {
1709 char szQualifiedPrefix[1024];
1710 ssize_t cch;
1711 if (pDevIns->pReg->cMaxInstances == 1)
1712 cch = RTStrPrintf2(szQualifiedPrefix, sizeof(szQualifiedPrefix), "/Devices/%s/%s", pDevIns->pReg->szName, pszPrefix);
1713 else
1714 cch = RTStrPrintf2(szQualifiedPrefix, sizeof(szQualifiedPrefix), "/Devices/%s#%u/%s",
1715 pDevIns->pReg->szName, pDevIns->iInstance, pszPrefix);
1716 AssertReturn(cch > 0, VERR_OUT_OF_RANGE);
1717 rc = STAMR3DeregisterByPrefix(pVM->pUVM, szQualifiedPrefix);
1718 }
1719 AssertRC(rc);
1720 return rc;
1721}
1722
1723
1724/**
1725 * @interface_method_impl{PDMDEVHLPR3,pfnPCIRegister}
1726 */
1727static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
1728 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName)
1729{
1730 PDMDEV_ASSERT_DEVINS(pDevIns);
1731 PVM pVM = pDevIns->Internal.s.pVMR3;
1732 VM_ASSERT_EMT(pVM);
1733 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Rhxs} fFlags=%#x uPciDevNo=%#x uPciFunNo=%#x pszName=%p:{%s}\n",
1734 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->abConfig, fFlags, uPciDevNo, uPciFunNo, pszName, pszName ? pszName : ""));
1735
1736 /*
1737 * Validate input.
1738 */
1739 AssertLogRelMsgReturn(pDevIns->pReg->cMaxPciDevices > 0,
1740 ("'%s'/%d: cMaxPciDevices is 0\n", pDevIns->pReg->szName, pDevIns->iInstance),
1741 VERR_WRONG_ORDER);
1742 AssertLogRelMsgReturn(RT_VALID_PTR(pPciDev),
1743 ("'%s'/%d: Invalid pPciDev value: %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pPciDev),
1744 VERR_INVALID_POINTER);
1745 AssertLogRelMsgReturn(PDMPciDevGetVendorId(pPciDev),
1746 ("'%s'/%d: Vendor ID is not set!\n", pDevIns->pReg->szName, pDevIns->iInstance),
1747 VERR_INVALID_POINTER);
1748 AssertLogRelMsgReturn( uPciDevNo < 32
1749 || uPciDevNo == PDMPCIDEVREG_DEV_NO_FIRST_UNUSED
1750 || uPciDevNo == PDMPCIDEVREG_DEV_NO_SAME_AS_PREV,
1751 ("'%s'/%d: Invalid PCI device number: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, uPciDevNo),
1752 VERR_INVALID_PARAMETER);
1753 AssertLogRelMsgReturn( uPciFunNo < 8
1754 || uPciFunNo == PDMPCIDEVREG_FUN_NO_FIRST_UNUSED,
1755 ("'%s'/%d: Invalid PCI funcion number: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, uPciFunNo),
1756 VERR_INVALID_PARAMETER);
1757 AssertLogRelMsgReturn(!(fFlags & ~PDMPCIDEVREG_F_VALID_MASK),
1758 ("'%s'/%d: Invalid flags: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, fFlags),
1759 VERR_INVALID_FLAGS);
1760 if (!pszName)
1761 pszName = pDevIns->pReg->szName;
1762 AssertLogRelReturn(RT_VALID_PTR(pszName), VERR_INVALID_POINTER);
1763 AssertLogRelReturn(!pPciDev->Int.s.fRegistered, VERR_PDM_NOT_PCI_DEVICE);
1764 AssertLogRelReturn(pPciDev == PDMDEV_GET_PPCIDEV(pDevIns, pPciDev->Int.s.idxSubDev), VERR_PDM_NOT_PCI_DEVICE);
1765 AssertLogRelReturn(pPciDev == PDMDEV_CALC_PPCIDEV(pDevIns, pPciDev->Int.s.idxSubDev), VERR_PDM_NOT_PCI_DEVICE);
1766 AssertMsgReturn(pPciDev->u32Magic == PDMPCIDEV_MAGIC, ("%#x\n", pPciDev->u32Magic), VERR_PDM_NOT_PCI_DEVICE);
1767
1768 /*
1769 * Check the registration order - must be following PDMDEVINSR3::apPciDevs.
1770 */
1771 PPDMPCIDEV const pPrevPciDev = pPciDev->Int.s.idxSubDev == 0 ? NULL
1772 : PDMDEV_GET_PPCIDEV(pDevIns, pPciDev->Int.s.idxSubDev - 1);
1773 if (pPrevPciDev)
1774 {
1775 AssertLogRelReturn(pPrevPciDev->u32Magic == PDMPCIDEV_MAGIC, VERR_INVALID_MAGIC);
1776 AssertLogRelReturn(pPrevPciDev->Int.s.fRegistered, VERR_WRONG_ORDER);
1777 }
1778
1779 /*
1780 * Resolve the PCI configuration node for the device. The default (zero'th)
1781 * is the same as the PDM device, the rest are "PciCfg1..255" CFGM sub-nodes.
1782 */
1783 PCFGMNODE pCfg = pDevIns->Internal.s.pCfgHandle;
1784 if (pPciDev->Int.s.idxSubDev > 0)
1785 pCfg = CFGMR3GetChildF(pDevIns->Internal.s.pCfgHandle, "PciCfg%u", pPciDev->Int.s.idxSubDev);
1786
1787 /*
1788 * We resolve PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, the PCI bus handles
1789 * PDMPCIDEVREG_DEV_NO_FIRST_UNUSED and PDMPCIDEVREG_FUN_NO_FIRST_UNUSED.
1790 */
1791 uint8_t const uPciDevNoRaw = uPciDevNo;
1792 uint32_t uDefPciBusNo = 0;
1793 if (uPciDevNo == PDMPCIDEVREG_DEV_NO_SAME_AS_PREV)
1794 {
1795 if (pPrevPciDev)
1796 {
1797 uPciDevNo = pPrevPciDev->uDevFn >> 3;
1798 uDefPciBusNo = pPrevPciDev->Int.s.idxPdmBus;
1799 }
1800 else
1801 {
1802 /* Look for PCI device registered with an earlier device instance so we can more
1803 easily have multiple functions spanning multiple PDM device instances. */
1804 PPDMDEVINS pPrevIns = pDevIns->Internal.s.pDevR3->pInstances;
1805 for (;;)
1806 {
1807 AssertLogRelMsgReturn(pPrevIns && pPrevIns != pDevIns,
1808 ("'%s'/%d: Can't use PDMPCIDEVREG_DEV_NO_SAME_AS_PREV without a previously registered PCI device by the same or earlier PDM device instance!\n",
1809 pDevIns->pReg->szName, pDevIns->iInstance), VERR_WRONG_ORDER);
1810 if (pPrevIns->Internal.s.pNextR3 == pDevIns)
1811 break;
1812 pPrevIns = pPrevIns->Internal.s.pNextR3;
1813 }
1814
1815 PPDMPCIDEV pOtherPciDev = PDMDEV_GET_PPCIDEV(pPrevIns, 0);
1816 AssertLogRelMsgReturn(pOtherPciDev && pOtherPciDev->Int.s.fRegistered,
1817 ("'%s'/%d: Can't use PDMPCIDEVREG_DEV_NO_SAME_AS_PREV without a previously registered PCI device by the same or earlier PDM device instance!\n",
1818 pDevIns->pReg->szName, pDevIns->iInstance),
1819 VERR_WRONG_ORDER);
1820 for (uint32_t iPrevPciDev = 1; iPrevPciDev < pDevIns->cPciDevs; iPrevPciDev++)
1821 {
1822 PPDMPCIDEV pCur = PDMDEV_GET_PPCIDEV(pPrevIns, iPrevPciDev);
1823 AssertBreak(pCur);
1824 if (!pCur->Int.s.fRegistered)
1825 break;
1826 pOtherPciDev = pCur;
1827 }
1828
1829 uPciDevNo = pOtherPciDev->uDevFn >> 3;
1830 uDefPciBusNo = pOtherPciDev->Int.s.idxPdmBus;
1831 }
1832 }
1833
1834 /*
1835 * Choose the PCI bus for the device.
1836 *
1837 * This is simple. If the device was configured for a particular bus, the PCIBusNo
1838 * configuration value will be set. If not the default bus is 0.
1839 */
1840 /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIBusNo, uint8_t, 0, 7, 0}
1841 * Selects the PCI bus number of a device. The default value isn't necessarily
1842 * zero if the device is registered using PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, it
1843 * will then also inherit the bus number from the previously registered device.
1844 */
1845 uint8_t u8Bus;
1846 int rc = CFGMR3QueryU8Def(pCfg, "PCIBusNo", &u8Bus, (uint8_t)uDefPciBusNo);
1847 AssertLogRelMsgRCReturn(rc, ("Configuration error: PCIBusNo query failed with rc=%Rrc (%s/%d)\n",
1848 rc, pDevIns->pReg->szName, pDevIns->iInstance), rc);
1849 AssertLogRelMsgReturn(u8Bus < RT_ELEMENTS(pVM->pdm.s.aPciBuses),
1850 ("Configuration error: PCIBusNo=%d, max is %d. (%s/%d)\n", u8Bus,
1851 RT_ELEMENTS(pVM->pdm.s.aPciBuses), pDevIns->pReg->szName, pDevIns->iInstance),
1852 VERR_PDM_NO_PCI_BUS);
1853 pPciDev->Int.s.idxPdmBus = u8Bus;
1854 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[u8Bus];
1855 if (pBus->pDevInsR3)
1856 {
1857 /*
1858 * Check the configuration for PCI device and function assignment.
1859 */
1860 /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIDeviceNo, uint8_t, 0, 31}
1861 * Overrides the default PCI device number of a device.
1862 */
1863 uint8_t uCfgDevice;
1864 rc = CFGMR3QueryU8(pCfg, "PCIDeviceNo", &uCfgDevice);
1865 if (RT_SUCCESS(rc))
1866 {
1867 AssertMsgReturn(uCfgDevice <= 31,
1868 ("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d/%d)\n",
1869 uCfgDevice, pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->Int.s.idxSubDev),
1870 VERR_PDM_BAD_PCI_CONFIG);
1871 uPciDevNo = uCfgDevice;
1872 }
1873 else
1874 AssertMsgReturn(rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT,
1875 ("Configuration error: PCIDeviceNo query failed with rc=%Rrc (%s/%d/%d)\n",
1876 rc, pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->Int.s.idxSubDev),
1877 rc);
1878
1879 /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIFunctionNo, uint8_t, 0, 7}
1880 * Overrides the default PCI function number of a device.
1881 */
1882 uint8_t uCfgFunction;
1883 rc = CFGMR3QueryU8(pCfg, "PCIFunctionNo", &uCfgFunction);
1884 if (RT_SUCCESS(rc))
1885 {
1886 AssertMsgReturn(uCfgFunction <= 7,
1887 ("Configuration error: PCIFunctionNo=%#x, max is 7. (%s/%d/%d)\n",
1888 uCfgFunction, pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->Int.s.idxSubDev),
1889 VERR_PDM_BAD_PCI_CONFIG);
1890 uPciFunNo = uCfgFunction;
1891 }
1892 else
1893 AssertMsgReturn(rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT,
1894 ("Configuration error: PCIFunctionNo query failed with rc=%Rrc (%s/%d/%d)\n",
1895 rc, pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->Int.s.idxSubDev),
1896 rc);
1897
1898#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
1899 PPDMIOMMUR3 pIommu = &pVM->pdm.s.aIommus[0];
1900 PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
1901 if (pDevInsIommu)
1902 {
1903 /*
1904 * If the PCI device/function number has been explicitly specified via CFGM,
1905 * ensure it's not the BDF reserved for the southbridge I/O APIC expected
1906 * by linux guests when using an AMD IOMMU, see @bugref{9654#c23}.
1907 *
1908 * In the Intel IOMMU case, we re-use the same I/O APIC address to reserve a
1909 * PCI slot so the same check below is sufficient, see @bugref{9967#c13}.
1910 */
1911 uint16_t const uDevFn = VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo);
1912 uint16_t const uBusDevFn = PCIBDF_MAKE(u8Bus, uDevFn);
1913 if (uBusDevFn == VBOX_PCI_BDF_SB_IOAPIC)
1914 {
1915 LogRel(("Configuration error: PCI BDF (%u:%u:%u) conflicts with SB I/O APIC (%s/%d/%d)\n", u8Bus,
1916 uCfgDevice, uCfgFunction, pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->Int.s.idxSubDev));
1917 return VERR_NOT_AVAILABLE;
1918 }
1919 }
1920#endif
1921
1922 /*
1923 * Initialize the internal data. We only do the wipe and the members
1924 * owned by PDM, the PCI bus does the rest in the registration call.
1925 */
1926 RT_ZERO(pPciDev->Int);
1927
1928 pPciDev->Int.s.idxDevCfg = pPciDev->Int.s.idxSubDev;
1929 pPciDev->Int.s.fReassignableDevNo = uPciDevNoRaw >= VBOX_PCI_MAX_DEVICES;
1930 pPciDev->Int.s.fReassignableFunNo = uPciFunNo >= VBOX_PCI_MAX_FUNCTIONS;
1931 pPciDev->Int.s.pDevInsR3 = pDevIns;
1932 pPciDev->Int.s.idxPdmBus = u8Bus;
1933 pPciDev->Int.s.fRegistered = true;
1934
1935 /* Set some of the public members too. */
1936 pPciDev->pszNameR3 = pszName;
1937
1938 /*
1939 * Call the pci bus device to do the actual registration.
1940 */
1941 pdmLock(pVM);
1942 rc = pBus->pfnRegister(pBus->pDevInsR3, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName);
1943 pdmUnlock(pVM);
1944 if (RT_SUCCESS(rc))
1945 Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n",
1946 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->uDevFn, pBus->iBus));
1947 else
1948 pPciDev->Int.s.fRegistered = false;
1949 }
1950 else
1951 {
1952 AssertLogRelMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n"));
1953 rc = VERR_PDM_NO_PCI_BUS;
1954 }
1955
1956 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1957 return rc;
1958}
1959
1960
1961/** @interface_method_impl{PDMDEVHLPR3,pfnPCIRegisterMsi} */
1962static DECLCALLBACK(int) pdmR3DevHlp_PCIRegisterMsi(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg)
1963{
1964 PDMDEV_ASSERT_DEVINS(pDevIns);
1965 if (!pPciDev) /* NULL is an alias for the default PCI device. */
1966 pPciDev = pDevIns->apPciDevs[0];
1967 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
1968 LogFlow(("pdmR3DevHlp_PCIRegisterMsi: caller='%s'/%d: pPciDev=%p:{%#x} pMsgReg=%p:{cMsiVectors=%d, cMsixVectors=%d}\n",
1969 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, pMsiReg, pMsiReg->cMsiVectors, pMsiReg->cMsixVectors));
1970 PDMPCIDEV_ASSERT_VALID_RET(pDevIns, pPciDev);
1971
1972 AssertLogRelMsgReturn(pDevIns->pReg->cMaxPciDevices > 0,
1973 ("'%s'/%d: cMaxPciDevices is 0\n", pDevIns->pReg->szName, pDevIns->iInstance),
1974 VERR_WRONG_ORDER);
1975 AssertLogRelMsgReturn(pMsiReg->cMsixVectors <= pDevIns->pReg->cMaxMsixVectors,
1976 ("'%s'/%d: cMsixVectors=%u cMaxMsixVectors=%u\n",
1977 pDevIns->pReg->szName, pDevIns->iInstance, pMsiReg->cMsixVectors, pDevIns->pReg->cMaxMsixVectors),
1978 VERR_INVALID_FLAGS);
1979
1980 PVM pVM = pDevIns->Internal.s.pVMR3;
1981 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
1982 AssertReturn(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses), VERR_WRONG_ORDER);
1983 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
1984
1985 pdmLock(pVM);
1986 int rc;
1987 if (pBus->pfnRegisterMsi)
1988 rc = pBus->pfnRegisterMsi(pBus->pDevInsR3, pPciDev, pMsiReg);
1989 else
1990 rc = VERR_NOT_IMPLEMENTED;
1991 pdmUnlock(pVM);
1992
1993 LogFlow(("pdmR3DevHlp_PCIRegisterMsi: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
1994 return rc;
1995}
1996
1997
1998/** @interface_method_impl{PDMDEVHLPR3,pfnPCIIORegionRegister} */
1999static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
2000 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, uint32_t fFlags,
2001 uint64_t hHandle, PFNPCIIOREGIONMAP pfnMapUnmap)
2002{
2003 PDMDEV_ASSERT_DEVINS(pDevIns);
2004 PVM pVM = pDevIns->Internal.s.pVMR3;
2005 VM_ASSERT_EMT(pVM);
2006 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2007 pPciDev = pDevIns->apPciDevs[0];
2008 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2009 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%d cbRegion=%RGp enmType=%d fFlags=%#x, hHandle=%#RX64 pfnMapUnmap=%p\n",
2010 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iRegion, cbRegion, enmType, fFlags, hHandle, pfnMapUnmap));
2011 PDMPCIDEV_ASSERT_VALID_RET(pDevIns, pPciDev);
2012
2013 /*
2014 * Validate input.
2015 */
2016 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
2017 AssertLogRelMsgReturn(VMR3GetState(pVM) == VMSTATE_CREATING,
2018 ("caller='%s'/%d: %s\n", pDevIns->pReg->szName, pDevIns->iInstance, VMR3GetStateName(VMR3GetState(pVM))),
2019 VERR_WRONG_ORDER);
2020
2021 if (iRegion >= VBOX_PCI_NUM_REGIONS)
2022 {
2023 Assert(iRegion < VBOX_PCI_NUM_REGIONS);
2024 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc (iRegion)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
2025 return VERR_INVALID_PARAMETER;
2026 }
2027
2028 switch ((int)enmType)
2029 {
2030 case PCI_ADDRESS_SPACE_IO:
2031 /*
2032 * Sanity check: don't allow to register more than 32K of the PCI I/O space.
2033 */
2034 AssertLogRelMsgReturn(cbRegion <= _32K,
2035 ("caller='%s'/%d: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, cbRegion),
2036 VERR_INVALID_PARAMETER);
2037 break;
2038
2039 case PCI_ADDRESS_SPACE_MEM:
2040 case PCI_ADDRESS_SPACE_MEM_PREFETCH:
2041 /*
2042 * Sanity check: Don't allow to register more than 2GB of the PCI MMIO space.
2043 */
2044 AssertLogRelMsgReturn(cbRegion <= MM_MMIO_32_MAX,
2045 ("caller='%s'/%d: %RGp (max %RGp)\n",
2046 pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, (RTGCPHYS)MM_MMIO_32_MAX),
2047 VERR_OUT_OF_RANGE);
2048 break;
2049
2050 case PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM:
2051 case PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH:
2052 /*
2053 * Sanity check: Don't allow to register more than 64GB of the 64-bit PCI MMIO space.
2054 */
2055 AssertLogRelMsgReturn(cbRegion <= MM_MMIO_64_MAX,
2056 ("caller='%s'/%d: %RGp (max %RGp)\n",
2057 pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, MM_MMIO_64_MAX),
2058 VERR_OUT_OF_RANGE);
2059 break;
2060
2061 default:
2062 AssertMsgFailed(("enmType=%#x is unknown\n", enmType));
2063 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc (enmType)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
2064 return VERR_INVALID_PARAMETER;
2065 }
2066
2067 AssertMsgReturn( pfnMapUnmap
2068 || ( hHandle != UINT64_MAX
2069 && (fFlags & PDMPCIDEV_IORGN_F_HANDLE_MASK) != PDMPCIDEV_IORGN_F_NO_HANDLE),
2070 ("caller='%s'/%d: fFlags=%#x hHandle=%#RX64\n", pDevIns->pReg->szName, pDevIns->iInstance, fFlags, hHandle),
2071 VERR_INVALID_PARAMETER);
2072
2073 AssertMsgReturn(!(fFlags & ~PDMPCIDEV_IORGN_F_VALID_MASK), ("fFlags=%#x\n", fFlags), VERR_INVALID_FLAGS);
2074 int rc;
2075 switch (fFlags & PDMPCIDEV_IORGN_F_HANDLE_MASK)
2076 {
2077 case PDMPCIDEV_IORGN_F_NO_HANDLE:
2078 break;
2079 case PDMPCIDEV_IORGN_F_IOPORT_HANDLE:
2080 AssertReturn(enmType == PCI_ADDRESS_SPACE_IO, VERR_INVALID_FLAGS);
2081 rc = IOMR3IoPortValidateHandle(pVM, pDevIns, (IOMIOPORTHANDLE)hHandle);
2082 AssertRCReturn(rc, rc);
2083 break;
2084 case PDMPCIDEV_IORGN_F_MMIO_HANDLE:
2085 AssertReturn( (enmType & ~PCI_ADDRESS_SPACE_BAR64) == PCI_ADDRESS_SPACE_MEM
2086 || (enmType & ~PCI_ADDRESS_SPACE_BAR64) == PCI_ADDRESS_SPACE_MEM_PREFETCH,
2087 VERR_INVALID_FLAGS);
2088 rc = IOMR3MmioValidateHandle(pVM, pDevIns, (IOMMMIOHANDLE)hHandle);
2089 AssertRCReturn(rc, rc);
2090 break;
2091 case PDMPCIDEV_IORGN_F_MMIO2_HANDLE:
2092 AssertReturn( (enmType & ~PCI_ADDRESS_SPACE_BAR64) == PCI_ADDRESS_SPACE_MEM
2093 || (enmType & ~PCI_ADDRESS_SPACE_BAR64) == PCI_ADDRESS_SPACE_MEM_PREFETCH,
2094 VERR_INVALID_FLAGS);
2095 rc = PGMR3PhysMmio2ValidateHandle(pVM, pDevIns, (PGMMMIO2HANDLE)hHandle);
2096 AssertRCReturn(rc, rc);
2097 break;
2098 default:
2099 AssertFailedReturn(VERR_IPE_NOT_REACHED_DEFAULT_CASE);
2100 break;
2101 }
2102
2103 /* This flag is required now. */
2104 AssertLogRelMsgReturn(fFlags & PDMPCIDEV_IORGN_F_NEW_STYLE,
2105 ("'%s'/%d: Invalid flags: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, fFlags),
2106 VERR_INVALID_FLAGS);
2107
2108 /*
2109 * We're currently restricted to page aligned MMIO regions.
2110 */
2111 if ( ((enmType & ~(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH)) == PCI_ADDRESS_SPACE_MEM)
2112 && cbRegion != RT_ALIGN_64(cbRegion, GUEST_PAGE_SIZE))
2113 {
2114 Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %RGp -> %RGp\n",
2115 pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, RT_ALIGN_64(cbRegion, GUEST_PAGE_SIZE)));
2116 cbRegion = RT_ALIGN_64(cbRegion, GUEST_PAGE_SIZE);
2117 }
2118
2119 /*
2120 * For registering PCI MMIO memory or PCI I/O memory, the size of the region must be a power of 2!
2121 */
2122 int iLastSet = ASMBitLastSetU64(cbRegion);
2123 Assert(iLastSet > 0);
2124 uint64_t cbRegionAligned = RT_BIT_64(iLastSet - 1);
2125 if (cbRegion > cbRegionAligned)
2126 cbRegion = cbRegionAligned * 2; /* round up */
2127
2128 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
2129 AssertReturn(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses), VERR_WRONG_ORDER);
2130 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
2131
2132 pdmLock(pVM);
2133 rc = pBus->pfnIORegionRegister(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, fFlags, hHandle, pfnMapUnmap);
2134 pdmUnlock(pVM);
2135
2136 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2137 return rc;
2138}
2139
2140
2141/** @interface_method_impl{PDMDEVHLPR3,pfnPCIInterceptConfigAccesses} */
2142static DECLCALLBACK(int) pdmR3DevHlp_PCIInterceptConfigAccesses(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
2143 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite)
2144{
2145 PDMDEV_ASSERT_DEVINS(pDevIns);
2146 PVM pVM = pDevIns->Internal.s.pVMR3;
2147 VM_ASSERT_EMT(pVM);
2148 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2149 pPciDev = pDevIns->apPciDevs[0];
2150 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2151 LogFlow(("pdmR3DevHlp_PCIInterceptConfigAccesses: caller='%s'/%d: pPciDev=%p pfnRead=%p pfnWrite=%p\n",
2152 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pfnRead, pfnWrite));
2153 PDMPCIDEV_ASSERT_VALID_RET(pDevIns, pPciDev);
2154
2155 /*
2156 * Validate input.
2157 */
2158 AssertPtr(pfnRead);
2159 AssertPtr(pfnWrite);
2160 AssertPtr(pPciDev);
2161
2162 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
2163 AssertReturn(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses), VERR_INTERNAL_ERROR_2);
2164 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
2165 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
2166
2167 /*
2168 * Do the job.
2169 */
2170 pdmLock(pVM);
2171 pBus->pfnInterceptConfigAccesses(pBus->pDevInsR3, pPciDev, pfnRead, pfnWrite);
2172 pdmUnlock(pVM);
2173
2174 LogFlow(("pdmR3DevHlp_PCIInterceptConfigAccesses: caller='%s'/%d: returns VINF_SUCCESS\n",
2175 pDevIns->pReg->szName, pDevIns->iInstance));
2176 return VINF_SUCCESS;
2177}
2178
2179
2180/** @interface_method_impl{PDMDEVHLPR3,pfnPCIConfigWrite} */
2181static DECLCALLBACK(VBOXSTRICTRC)
2182pdmR3DevHlp_PCIConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress, unsigned cb, uint32_t u32Value)
2183{
2184 PDMDEV_ASSERT_DEVINS(pDevIns);
2185 PVM pVM = pDevIns->Internal.s.pVMR3;
2186 AssertPtrReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2187 LogFlow(("pdmR3DevHlp_PCIConfigWrite: caller='%s'/%d: pPciDev=%p uAddress=%#x cd=%d u32Value=%#x\n",
2188 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, uAddress, cb, u32Value));
2189
2190 /*
2191 * Resolve the bus.
2192 */
2193 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
2194 AssertReturn(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses), VERR_INTERNAL_ERROR_2);
2195 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
2196
2197 /*
2198 * Do the job.
2199 */
2200 VBOXSTRICTRC rcStrict = pBus->pfnConfigWrite(pBus->pDevInsR3, pPciDev, uAddress, cb, u32Value);
2201
2202 LogFlow(("pdmR3DevHlp_PCIConfigWrite: caller='%s'/%d: returns %Rrc\n",
2203 pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict)));
2204 return rcStrict;
2205}
2206
2207
2208/** @interface_method_impl{PDMDEVHLPR3,pfnPCIConfigRead} */
2209static DECLCALLBACK(VBOXSTRICTRC)
2210pdmR3DevHlp_PCIConfigRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress, unsigned cb, uint32_t *pu32Value)
2211{
2212 PDMDEV_ASSERT_DEVINS(pDevIns);
2213 PVM pVM = pDevIns->Internal.s.pVMR3;
2214 AssertPtrReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2215 LogFlow(("pdmR3DevHlp_PCIConfigRead: caller='%s'/%d: pPciDev=%p uAddress=%#x cd=%d pu32Value=%p:{%#x}\n",
2216 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, uAddress, cb, pu32Value, *pu32Value));
2217
2218 /*
2219 * Resolve the bus.
2220 */
2221 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
2222 AssertReturn(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses), VERR_INTERNAL_ERROR_2);
2223 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
2224
2225 /*
2226 * Do the job.
2227 */
2228 VBOXSTRICTRC rcStrict = pBus->pfnConfigRead(pBus->pDevInsR3, pPciDev, uAddress, cb, pu32Value);
2229
2230 LogFlow(("pdmR3DevHlp_PCIConfigRead: caller='%s'/%d: returns %Rrc (*pu32Value=%#x)\n",
2231 pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict), *pu32Value));
2232 return rcStrict;
2233}
2234
2235
2236/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysRead} */
2237static DECLCALLBACK(int)
2238pdmR3DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags)
2239{
2240 PDMDEV_ASSERT_DEVINS(pDevIns);
2241 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2242 pPciDev = pDevIns->apPciDevs[0];
2243 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2244 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
2245
2246#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
2247 /*
2248 * Just check the busmaster setting here and forward the request to the generic read helper.
2249 */
2250 if (PCIDevIsBusmaster(pPciDev))
2251 { /* likely */ }
2252 else
2253 {
2254 Log(("pdmR3DevHlp_PCIPhysRead: caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n",
2255 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbRead));
2256 memset(pvBuf, 0xff, cbRead);
2257 return VERR_PDM_NOT_PCI_BUS_MASTER;
2258 }
2259#endif
2260
2261#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
2262 int rc = pdmIommuMemAccessRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead, fFlags);
2263 if ( rc == VERR_IOMMU_NOT_PRESENT
2264 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
2265 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
2266 else
2267 return rc;
2268#endif
2269
2270 return pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead, fFlags);
2271}
2272
2273
2274/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysWrite} */
2275static DECLCALLBACK(int)
2276pdmR3DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags)
2277{
2278 PDMDEV_ASSERT_DEVINS(pDevIns);
2279 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2280 pPciDev = pDevIns->apPciDevs[0];
2281 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2282 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
2283
2284#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
2285 /*
2286 * Just check the busmaster setting here and forward the request to the generic read helper.
2287 */
2288 if (PCIDevIsBusmaster(pPciDev))
2289 { /* likely */ }
2290 else
2291 {
2292 Log(("pdmR3DevHlp_PCIPhysWrite: caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
2293 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbWrite));
2294 return VERR_PDM_NOT_PCI_BUS_MASTER;
2295 }
2296#endif
2297
2298#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
2299 int rc = pdmIommuMemAccessWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite, fFlags);
2300 if ( rc == VERR_IOMMU_NOT_PRESENT
2301 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
2302 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
2303 else
2304 return rc;
2305#endif
2306
2307 return pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite, fFlags);
2308}
2309
2310
2311/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysGCPhys2CCPtr} */
2312static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
2313 uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
2314{
2315 PDMDEV_ASSERT_DEVINS(pDevIns);
2316 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2317 pPciDev = pDevIns->apPciDevs[0];
2318 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2319 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
2320
2321#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
2322 if (PCIDevIsBusmaster(pPciDev))
2323 { /* likely */ }
2324 else
2325 {
2326 LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp fFlags=%#RX32\n",
2327 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, fFlags));
2328 return VERR_PDM_NOT_PCI_BUS_MASTER;
2329 }
2330#endif
2331
2332#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
2333 int rc = pdmR3IommuMemAccessWriteCCPtr(pDevIns, pPciDev, GCPhys, fFlags, ppv, pLock);
2334 if ( rc == VERR_IOMMU_NOT_PRESENT
2335 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
2336 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
2337 else
2338 return rc;
2339#endif
2340
2341 return pDevIns->pHlpR3->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
2342}
2343
2344
2345/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysGCPhys2CCPtrReadOnly} */
2346static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
2347 uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock)
2348{
2349 PDMDEV_ASSERT_DEVINS(pDevIns);
2350 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2351 pPciDev = pDevIns->apPciDevs[0];
2352 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2353 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
2354
2355#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
2356 if (PCIDevIsBusmaster(pPciDev))
2357 { /* likely */ }
2358 else
2359 {
2360 LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp fFlags=%#RX32\n",
2361 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, fFlags));
2362 return VERR_PDM_NOT_PCI_BUS_MASTER;
2363 }
2364#endif
2365
2366#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
2367 int rc = pdmR3IommuMemAccessReadCCPtr(pDevIns, pPciDev, GCPhys, fFlags, ppv, pLock);
2368 if ( rc == VERR_IOMMU_NOT_PRESENT
2369 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
2370 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
2371 else
2372 return rc;
2373#endif
2374
2375 return pDevIns->pHlpR3->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
2376}
2377
2378
2379/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysBulkGCPhys2CCPtr} */
2380static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
2381 PCRTGCPHYS paGCPhysPages, uint32_t fFlags, void **papvPages,
2382 PPGMPAGEMAPLOCK paLocks)
2383{
2384 PDMDEV_ASSERT_DEVINS(pDevIns);
2385 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2386 pPciDev = pDevIns->apPciDevs[0];
2387 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2388 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
2389
2390#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
2391 if (PCIDevIsBusmaster(pPciDev))
2392 { /* likely */ }
2393 else
2394 {
2395 LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! cPages=%zu fFlags=%#RX32\n",
2396 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, cPages, fFlags));
2397 return VERR_PDM_NOT_PCI_BUS_MASTER;
2398 }
2399#endif
2400
2401#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
2402 int rc = pdmR3IommuMemAccessBulkWriteCCPtr(pDevIns, pPciDev, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
2403 if ( rc == VERR_IOMMU_NOT_PRESENT
2404 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
2405 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
2406 else
2407 return rc;
2408#endif
2409
2410 return pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtr(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
2411}
2412
2413
2414/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysBulkGCPhys2CCPtrReadOnly} */
2415static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
2416 PCRTGCPHYS paGCPhysPages, uint32_t fFlags,
2417 const void **papvPages, PPGMPAGEMAPLOCK paLocks)
2418{
2419 PDMDEV_ASSERT_DEVINS(pDevIns);
2420 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2421 pPciDev = pDevIns->apPciDevs[0];
2422 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
2423 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
2424
2425#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
2426 if (PCIDevIsBusmaster(pPciDev))
2427 { /* likely */ }
2428 else
2429 {
2430 LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! cPages=%zu fFlags=%#RX32\n",
2431 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, cPages, fFlags));
2432 return VERR_PDM_NOT_PCI_BUS_MASTER;
2433 }
2434#endif
2435
2436#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
2437 int rc = pdmR3IommuMemAccessBulkReadCCPtr(pDevIns, pPciDev, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
2438 if ( rc == VERR_IOMMU_NOT_PRESENT
2439 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
2440 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
2441 else
2442 return rc;
2443#endif
2444
2445 return pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtrReadOnly(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
2446}
2447
2448
2449/** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrq} */
2450static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
2451{
2452 PDMDEV_ASSERT_DEVINS(pDevIns);
2453 if (!pPciDev) /* NULL is an alias for the default PCI device. */
2454 pPciDev = pDevIns->apPciDevs[0];
2455 AssertReturnVoid(pPciDev);
2456 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
2457 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iIrq, iLevel));
2458 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
2459
2460 /*
2461 * Validate input.
2462 */
2463 Assert(iIrq == 0);
2464 Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
2465
2466 /*
2467 * Must have a PCI device registered!
2468 */
2469 PVM pVM = pDevIns->Internal.s.pVMR3;
2470 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
2471 AssertReturnVoid(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
2472 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
2473
2474 pdmLock(pVM);
2475 uint32_t uTagSrc;
2476 if (iLevel & PDM_IRQ_LEVEL_HIGH)
2477 {
2478 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
2479 if (iLevel == PDM_IRQ_LEVEL_HIGH)
2480 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2481 else
2482 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2483 }
2484 else
2485 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
2486
2487 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel, uTagSrc);
2488
2489 if (iLevel == PDM_IRQ_LEVEL_LOW)
2490 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2491 pdmUnlock(pVM);
2492
2493 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
2494}
2495
2496
2497/** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrqNoWait} */
2498static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
2499{
2500 pdmR3DevHlp_PCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
2501}
2502
2503
2504/** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrq} */
2505static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
2506{
2507 PDMDEV_ASSERT_DEVINS(pDevIns);
2508 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
2509
2510 /*
2511 * Validate input.
2512 */
2513 Assert(iIrq < 16);
2514 Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
2515
2516 PVM pVM = pDevIns->Internal.s.pVMR3;
2517
2518 /*
2519 * Do the job.
2520 */
2521 pdmLock(pVM);
2522 uint32_t uTagSrc;
2523 if (iLevel & PDM_IRQ_LEVEL_HIGH)
2524 {
2525 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
2526 if (iLevel == PDM_IRQ_LEVEL_HIGH)
2527 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2528 else
2529 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2530 }
2531 else
2532 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
2533
2534 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
2535
2536 if (iLevel == PDM_IRQ_LEVEL_LOW)
2537 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2538 pdmUnlock(pVM);
2539
2540 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
2541}
2542
2543
2544/** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrqNoWait} */
2545static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
2546{
2547 pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel);
2548}
2549
2550
2551/** @interface_method_impl{PDMDEVHLPR3,pfnDriverAttach} */
2552static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
2553{
2554 PDMDEV_ASSERT_DEVINS(pDevIns);
2555 PVM pVM = pDevIns->Internal.s.pVMR3;
2556 VM_ASSERT_EMT(pVM);
2557 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n",
2558 pDevIns->pReg->szName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc));
2559
2560 /*
2561 * Lookup the LUN, it might already be registered.
2562 */
2563 PPDMLUN pLunPrev = NULL;
2564 PPDMLUN pLun = pDevIns->Internal.s.pLunsR3;
2565 for (; pLun; pLunPrev = pLun, pLun = pLun->pNext)
2566 if (pLun->iLun == iLun)
2567 break;
2568
2569 /*
2570 * Create the LUN if if wasn't found, else check if driver is already attached to it.
2571 */
2572 if (!pLun)
2573 {
2574 if ( !pBaseInterface
2575 || !pszDesc
2576 || !*pszDesc)
2577 {
2578 Assert(pBaseInterface);
2579 Assert(pszDesc || *pszDesc);
2580 return VERR_INVALID_PARAMETER;
2581 }
2582
2583 pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun));
2584 if (!pLun)
2585 return VERR_NO_MEMORY;
2586
2587 pLun->iLun = iLun;
2588 pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL;
2589 pLun->pTop = NULL;
2590 pLun->pBottom = NULL;
2591 pLun->pDevIns = pDevIns;
2592 pLun->pUsbIns = NULL;
2593 pLun->pszDesc = pszDesc;
2594 pLun->pBase = pBaseInterface;
2595 if (!pLunPrev)
2596 pDevIns->Internal.s.pLunsR3 = pLun;
2597 else
2598 pLunPrev->pNext = pLun;
2599 Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n",
2600 iLun, pszDesc, pDevIns->pReg->szName, pDevIns->iInstance));
2601 }
2602 else if (pLun->pTop)
2603 {
2604 AssertMsgFailed(("Already attached! The device should keep track of such things!\n"));
2605 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED));
2606 return VERR_PDM_DRIVER_ALREADY_ATTACHED;
2607 }
2608 Assert(pLun->pBase == pBaseInterface);
2609
2610
2611 /*
2612 * Get the attached driver configuration.
2613 */
2614 int rc;
2615 PCFGMNODE pNode = CFGMR3GetChildF(pDevIns->Internal.s.pCfgHandle, "LUN#%u", iLun);
2616 if (pNode)
2617 rc = pdmR3DrvInstantiate(pVM, pNode, pBaseInterface, NULL /*pDrvAbove*/, pLun, ppBaseInterface);
2618 else
2619 rc = VERR_PDM_NO_ATTACHED_DRIVER;
2620
2621 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2622 return rc;
2623}
2624
2625
2626/** @interface_method_impl{PDMDEVHLPR3,pfnDriverDetach} */
2627static DECLCALLBACK(int) pdmR3DevHlp_DriverDetach(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags)
2628{
2629 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
2630 LogFlow(("pdmR3DevHlp_DriverDetach: caller='%s'/%d: pDrvIns=%p\n",
2631 pDevIns->pReg->szName, pDevIns->iInstance, pDrvIns));
2632
2633#ifdef VBOX_STRICT
2634 PVM pVM = pDevIns->Internal.s.pVMR3;
2635 VM_ASSERT_EMT(pVM);
2636#endif
2637
2638 int rc = pdmR3DrvDetach(pDrvIns, fFlags);
2639
2640 LogFlow(("pdmR3DevHlp_DriverDetach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2641 return rc;
2642}
2643
2644
2645/** @interface_method_impl{PDMDEVHLPR3,pfnDriverReconfigure} */
2646static DECLCALLBACK(int) pdmR3DevHlp_DriverReconfigure(PPDMDEVINS pDevIns, uint32_t iLun, uint32_t cDepth,
2647 const char * const *papszDrivers, PCFGMNODE *papConfigs, uint32_t fFlags)
2648{
2649 PDMDEV_ASSERT_DEVINS(pDevIns);
2650 PVM pVM = pDevIns->Internal.s.pVMR3;
2651 VM_ASSERT_EMT(pVM);
2652 LogFlow(("pdmR3DevHlp_DriverReconfigure: caller='%s'/%d: iLun=%u cDepth=%u fFlags=%#x\n",
2653 pDevIns->pReg->szName, pDevIns->iInstance, iLun, cDepth, fFlags));
2654
2655 /*
2656 * Validate input.
2657 */
2658 AssertReturn(cDepth <= 8, VERR_INVALID_PARAMETER);
2659 AssertPtrReturn(papszDrivers, VERR_INVALID_POINTER);
2660 AssertPtrNullReturn(papConfigs, VERR_INVALID_POINTER);
2661 for (uint32_t i = 0; i < cDepth; i++)
2662 {
2663 AssertPtrReturn(papszDrivers[i], VERR_INVALID_POINTER);
2664 size_t cchDriver = strlen(papszDrivers[i]);
2665 AssertReturn(cchDriver > 0 && cchDriver < RT_SIZEOFMEMB(PDMDRVREG, szName), VERR_OUT_OF_RANGE);
2666
2667 if (papConfigs)
2668 AssertPtrNullReturn(papConfigs[i], VERR_INVALID_POINTER);
2669 }
2670 AssertReturn(fFlags == 0, VERR_INVALID_FLAGS);
2671
2672 /*
2673 * Do we have to detach an existing driver first?
2674 */
2675 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)
2676 if (pLun->iLun == iLun)
2677 {
2678 if (pLun->pTop)
2679 {
2680 int rc = pdmR3DrvDetach(pLun->pTop, 0);
2681 AssertRCReturn(rc, rc);
2682 }
2683 break;
2684 }
2685
2686 /*
2687 * Remove the old tree.
2688 */
2689 PCFGMNODE pCfgDev = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/", pDevIns->pReg->szName, pDevIns->iInstance);
2690 AssertReturn(pCfgDev, VERR_INTERNAL_ERROR_2);
2691 PCFGMNODE pCfgLun = CFGMR3GetChildF(pCfgDev, "LUN#%u", iLun);
2692 if (pCfgLun)
2693 CFGMR3RemoveNode(pCfgLun);
2694
2695 /*
2696 * Construct a new tree.
2697 */
2698 int rc = CFGMR3InsertNodeF(pCfgDev, &pCfgLun, "LUN#%u", iLun);
2699 AssertRCReturn(rc, rc);
2700 PCFGMNODE pCfgDrv = pCfgLun;
2701 for (uint32_t i = 0; i < cDepth; i++)
2702 {
2703 rc = CFGMR3InsertString(pCfgDrv, "Driver", papszDrivers[i]);
2704 AssertRCReturn(rc, rc);
2705 if (papConfigs && papConfigs[i])
2706 {
2707 rc = CFGMR3InsertSubTree(pCfgDrv, "Config", papConfigs[i], NULL);
2708 AssertRCReturn(rc, rc);
2709 papConfigs[i] = NULL;
2710 }
2711 else
2712 {
2713 rc = CFGMR3InsertNode(pCfgDrv, "Config", NULL);
2714 AssertRCReturn(rc, rc);
2715 }
2716
2717 if (i + 1 >= cDepth)
2718 break;
2719 rc = CFGMR3InsertNode(pCfgDrv, "AttachedDriver", &pCfgDrv);
2720 AssertRCReturn(rc, rc);
2721 }
2722
2723 LogFlow(("pdmR3DevHlp_DriverReconfigure: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2724 return rc;
2725}
2726
2727
2728/** @interface_method_impl{PDMDEVHLPR3,pfnQueueCreate} */
2729static DECLCALLBACK(int) pdmR3DevHlp_QueueCreate(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
2730 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName,
2731 PDMQUEUEHANDLE *phQueue)
2732{
2733 PDMDEV_ASSERT_DEVINS(pDevIns);
2734 LogFlow(("pdmR3DevHlp_QueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fRZEnabled=%RTbool pszName=%p:{%s} phQueue=%p\n",
2735 pDevIns->pReg->szName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, pszName, phQueue));
2736
2737 PVM pVM = pDevIns->Internal.s.pVMR3;
2738 VM_ASSERT_EMT(pVM);
2739
2740 if (pDevIns->iInstance > 0)
2741 {
2742 pszName = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s_%u", pszName, pDevIns->iInstance);
2743 AssertLogRelReturn(pszName, VERR_NO_MEMORY);
2744 }
2745
2746 int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, phQueue);
2747
2748 LogFlow(("pdmR3DevHlp_QueueCreate: caller='%s'/%d: returns %Rrc *phQueue=%p\n",
2749 pDevIns->pReg->szName, pDevIns->iInstance, rc, *phQueue));
2750 return rc;
2751}
2752
2753
2754/** @interface_method_impl{PDMDEVHLPR3,pfnQueueAlloc} */
2755static DECLCALLBACK(PPDMQUEUEITEMCORE) pdmR3DevHlp_QueueAlloc(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
2756{
2757 PDMDEV_ASSERT_DEVINS(pDevIns);
2758 return PDMQueueAlloc(pDevIns->Internal.s.pVMR3, hQueue, pDevIns);
2759}
2760
2761
2762/** @interface_method_impl{PDMDEVHLPR3,pfnQueueInsert} */
2763static DECLCALLBACK(int) pdmR3DevHlp_QueueInsert(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue, PPDMQUEUEITEMCORE pItem)
2764{
2765 return PDMQueueInsert(pDevIns->Internal.s.pVMR3, hQueue, pDevIns, pItem);
2766}
2767
2768
2769/** @interface_method_impl{PDMDEVHLPR3,pfnQueueFlushIfNecessary} */
2770static DECLCALLBACK(bool) pdmR3DevHlp_QueueFlushIfNecessary(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
2771{
2772 return PDMQueueFlushIfNecessary(pDevIns->Internal.s.pVMR3, hQueue, pDevIns) == VINF_SUCCESS;
2773}
2774
2775
2776/** @interface_method_impl{PDMDEVHLPR3,pfnTaskCreate} */
2777static DECLCALLBACK(int) pdmR3DevHlp_TaskCreate(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszName,
2778 PFNPDMTASKDEV pfnCallback, void *pvUser, PDMTASKHANDLE *phTask)
2779{
2780 PDMDEV_ASSERT_DEVINS(pDevIns);
2781 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: pfnCallback=%p fFlags=%#x pszName=%p:{%s} phTask=%p\n",
2782 pDevIns->pReg->szName, pDevIns->iInstance, pfnCallback, fFlags, pszName, pszName, phTask));
2783 PVM pVM = pDevIns->Internal.s.pVMR3;
2784 VM_ASSERT_EMT(pVM);
2785
2786 int rc = PDMR3TaskCreate(pVM, fFlags, pszName, PDMTASKTYPE_DEV, pDevIns, (PFNRT)pfnCallback, pvUser, phTask);
2787
2788 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2789 return rc;
2790}
2791
2792
2793/** @interface_method_impl{PDMDEVHLPR3,pfnTaskTrigger} */
2794static DECLCALLBACK(int) pdmR3DevHlp_TaskTrigger(PPDMDEVINS pDevIns, PDMTASKHANDLE hTask)
2795{
2796 PDMDEV_ASSERT_DEVINS(pDevIns);
2797 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: hTask=%RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, hTask));
2798
2799 int rc = PDMTaskTrigger(pDevIns->Internal.s.pVMR3, PDMTASKTYPE_DEV, pDevIns, hTask);
2800
2801 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2802 return rc;
2803}
2804
2805
2806/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventCreate} */
2807static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventCreate(PPDMDEVINS pDevIns, PSUPSEMEVENT phEvent)
2808{
2809 PDMDEV_ASSERT_DEVINS(pDevIns);
2810 LogFlow(("pdmR3DevHlp_SUPSemEventCreate: caller='%s'/%d: phEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, phEvent));
2811 PVM pVM = pDevIns->Internal.s.pVMR3;
2812 VM_ASSERT_EMT(pVM);
2813
2814 int rc = SUPSemEventCreate(pVM->pSession, phEvent);
2815
2816 LogFlow(("pdmR3DevHlp_SUPSemEventCreate: caller='%s'/%d: returns %Rrc *phEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *phEvent));
2817 return rc;
2818}
2819
2820
2821/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventClose} */
2822static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventClose(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent)
2823{
2824 PDMDEV_ASSERT_DEVINS(pDevIns);
2825 LogFlow(("pdmR3DevHlp_SUPSemEventClose: caller='%s'/%d: hEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEvent));
2826
2827 int rc = SUPSemEventClose(pDevIns->Internal.s.pVMR3->pSession, hEvent);
2828
2829 LogFlow(("pdmR3DevHlp_SUPSemEventClose: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2830 return rc;
2831}
2832
2833
2834/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventSignal} */
2835static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventSignal(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent)
2836{
2837 PDMDEV_ASSERT_DEVINS(pDevIns);
2838 LogFlow(("pdmR3DevHlp_SUPSemEventSignal: caller='%s'/%d: hEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEvent));
2839
2840 int rc = SUPSemEventSignal(pDevIns->Internal.s.pVMR3->pSession, hEvent);
2841
2842 LogFlow(("pdmR3DevHlp_SUPSemEventSignal: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2843 return rc;
2844}
2845
2846
2847/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventWaitNoResume} */
2848static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint32_t cMillies)
2849{
2850 PDMDEV_ASSERT_DEVINS(pDevIns);
2851 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNoResume: caller='%s'/%d: hEvent=%p cNsTimeout=%RU32\n",
2852 pDevIns->pReg->szName, pDevIns->iInstance, hEvent, cMillies));
2853
2854 int rc = SUPSemEventWaitNoResume(pDevIns->Internal.s.pVMR3->pSession, hEvent, cMillies);
2855
2856 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNoResume: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2857 return rc;
2858}
2859
2860
2861/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventWaitNsAbsIntr} */
2862static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t uNsTimeout)
2863{
2864 PDMDEV_ASSERT_DEVINS(pDevIns);
2865 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsAbsIntr: caller='%s'/%d: hEvent=%p uNsTimeout=%RU64\n",
2866 pDevIns->pReg->szName, pDevIns->iInstance, hEvent, uNsTimeout));
2867
2868 int rc = SUPSemEventWaitNsAbsIntr(pDevIns->Internal.s.pVMR3->pSession, hEvent, uNsTimeout);
2869
2870 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsAbsIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2871 return rc;
2872}
2873
2874
2875/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventWaitNsRelIntr} */
2876static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t cNsTimeout)
2877{
2878 PDMDEV_ASSERT_DEVINS(pDevIns);
2879 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsRelIntr: caller='%s'/%d: hEvent=%p cNsTimeout=%RU64\n",
2880 pDevIns->pReg->szName, pDevIns->iInstance, hEvent, cNsTimeout));
2881
2882 int rc = SUPSemEventWaitNsRelIntr(pDevIns->Internal.s.pVMR3->pSession, hEvent, cNsTimeout);
2883
2884 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsRelIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2885 return rc;
2886}
2887
2888
2889/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventGetResolution} */
2890static DECLCALLBACK(uint32_t) pdmR3DevHlp_SUPSemEventGetResolution(PPDMDEVINS pDevIns)
2891{
2892 PDMDEV_ASSERT_DEVINS(pDevIns);
2893 LogFlow(("pdmR3DevHlp_SUPSemEventGetResolution: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
2894
2895 uint32_t cNsResolution = SUPSemEventGetResolution(pDevIns->Internal.s.pVMR3->pSession);
2896
2897 LogFlow(("pdmR3DevHlp_SUPSemEventGetResolution: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, cNsResolution));
2898 return cNsResolution;
2899}
2900
2901
2902/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiCreate} */
2903static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiCreate(PPDMDEVINS pDevIns, PSUPSEMEVENTMULTI phEventMulti)
2904{
2905 PDMDEV_ASSERT_DEVINS(pDevIns);
2906 LogFlow(("pdmR3DevHlp_SUPSemEventMultiCreate: caller='%s'/%d: phEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, phEventMulti));
2907 PVM pVM = pDevIns->Internal.s.pVMR3;
2908 VM_ASSERT_EMT(pVM);
2909
2910 int rc = SUPSemEventMultiCreate(pVM->pSession, phEventMulti);
2911
2912 LogFlow(("pdmR3DevHlp_SUPSemEventMultiCreate: caller='%s'/%d: returns %Rrc *phEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *phEventMulti));
2913 return rc;
2914}
2915
2916
2917/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiClose} */
2918static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiClose(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
2919{
2920 PDMDEV_ASSERT_DEVINS(pDevIns);
2921 LogFlow(("pdmR3DevHlp_SUPSemEventMultiClose: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
2922
2923 int rc = SUPSemEventMultiClose(pDevIns->Internal.s.pVMR3->pSession, hEventMulti);
2924
2925 LogFlow(("pdmR3DevHlp_SUPSemEventMultiClose: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2926 return rc;
2927}
2928
2929
2930/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiSignal} */
2931static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiSignal(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
2932{
2933 PDMDEV_ASSERT_DEVINS(pDevIns);
2934 LogFlow(("pdmR3DevHlp_SUPSemEventMultiSignal: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
2935
2936 int rc = SUPSemEventMultiSignal(pDevIns->Internal.s.pVMR3->pSession, hEventMulti);
2937
2938 LogFlow(("pdmR3DevHlp_SUPSemEventMultiSignal: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2939 return rc;
2940}
2941
2942
2943/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiReset} */
2944static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiReset(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
2945{
2946 PDMDEV_ASSERT_DEVINS(pDevIns);
2947 LogFlow(("pdmR3DevHlp_SUPSemEventMultiReset: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
2948
2949 int rc = SUPSemEventMultiReset(pDevIns->Internal.s.pVMR3->pSession, hEventMulti);
2950
2951 LogFlow(("pdmR3DevHlp_SUPSemEventMultiReset: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2952 return rc;
2953}
2954
2955
2956/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiWaitNoResume} */
2957static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
2958 uint32_t cMillies)
2959{
2960 PDMDEV_ASSERT_DEVINS(pDevIns);
2961 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNoResume: caller='%s'/%d: hEventMulti=%p cMillies=%RU32\n",
2962 pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, cMillies));
2963
2964 int rc = SUPSemEventMultiWaitNoResume(pDevIns->Internal.s.pVMR3->pSession, hEventMulti, cMillies);
2965
2966 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNoResume: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2967 return rc;
2968}
2969
2970
2971/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiWaitNsAbsIntr} */
2972static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
2973 uint64_t uNsTimeout)
2974{
2975 PDMDEV_ASSERT_DEVINS(pDevIns);
2976 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr: caller='%s'/%d: hEventMulti=%p uNsTimeout=%RU64\n",
2977 pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, uNsTimeout));
2978
2979 int rc = SUPSemEventMultiWaitNsAbsIntr(pDevIns->Internal.s.pVMR3->pSession, hEventMulti, uNsTimeout);
2980
2981 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2982 return rc;
2983}
2984
2985
2986/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiWaitNsRelIntr} */
2987static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
2988 uint64_t cNsTimeout)
2989{
2990 PDMDEV_ASSERT_DEVINS(pDevIns);
2991 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr: caller='%s'/%d: hEventMulti=%p cNsTimeout=%RU64\n",
2992 pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, cNsTimeout));
2993
2994 int rc = SUPSemEventMultiWaitNsRelIntr(pDevIns->Internal.s.pVMR3->pSession, hEventMulti, cNsTimeout);
2995
2996 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2997 return rc;
2998}
2999
3000
3001/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiGetResolution} */
3002static DECLCALLBACK(uint32_t) pdmR3DevHlp_SUPSemEventMultiGetResolution(PPDMDEVINS pDevIns)
3003{
3004 PDMDEV_ASSERT_DEVINS(pDevIns);
3005 LogFlow(("pdmR3DevHlp_SUPSemEventMultiGetResolution: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
3006
3007 uint32_t cNsResolution = SUPSemEventMultiGetResolution(pDevIns->Internal.s.pVMR3->pSession);
3008
3009 LogFlow(("pdmR3DevHlp_SUPSemEventMultiGetResolution: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, cNsResolution));
3010 return cNsResolution;
3011}
3012
3013
3014/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectInit} */
3015static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
3016 const char *pszNameFmt, va_list va)
3017{
3018 PDMDEV_ASSERT_DEVINS(pDevIns);
3019 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszNameFmt=%p:{%s}\n",
3020 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pszNameFmt, pszNameFmt));
3021
3022 PVM pVM = pDevIns->Internal.s.pVMR3;
3023 VM_ASSERT_EMT(pVM);
3024 int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
3025
3026 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3027 return rc;
3028}
3029
3030
3031/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNop} */
3032static DECLCALLBACK(PPDMCRITSECT) pdmR3DevHlp_CritSectGetNop(PPDMDEVINS pDevIns)
3033{
3034 PDMDEV_ASSERT_DEVINS(pDevIns);
3035 PVM pVM = pDevIns->Internal.s.pVMR3;
3036 VM_ASSERT_EMT(pVM);
3037
3038 PPDMCRITSECT pCritSect = PDMR3CritSectGetNop(pVM);
3039 LogFlow(("pdmR3DevHlp_CritSectGetNop: caller='%s'/%d: return %p\n",
3040 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
3041 return pCritSect;
3042}
3043
3044
3045/** @interface_method_impl{PDMDEVHLPR3,pfnSetDeviceCritSect} */
3046static DECLCALLBACK(int) pdmR3DevHlp_SetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3047{
3048 /*
3049 * Validate input.
3050 *
3051 * Note! We only allow the automatically created default critical section
3052 * to be replaced by this API.
3053 */
3054 PDMDEV_ASSERT_DEVINS(pDevIns);
3055 AssertPtrReturn(pCritSect, VERR_INVALID_POINTER);
3056 LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: pCritSect=%p (%s)\n",
3057 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pCritSect->s.pszName));
3058 AssertReturn(PDMCritSectIsInitialized(pCritSect), VERR_INVALID_PARAMETER);
3059 PVM pVM = pDevIns->Internal.s.pVMR3;
3060
3061 VM_ASSERT_EMT(pVM);
3062 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
3063
3064 AssertReturn(pDevIns->pCritSectRoR3, VERR_PDM_DEV_IPE_1);
3065 AssertReturn(pDevIns->pCritSectRoR3->s.fAutomaticDefaultCritsect, VERR_WRONG_ORDER);
3066 AssertReturn(!pDevIns->pCritSectRoR3->s.fUsedByTimerOrSimilar, VERR_WRONG_ORDER);
3067 AssertReturn(pDevIns->pCritSectRoR3 != pCritSect, VERR_INVALID_PARAMETER);
3068
3069 /*
3070 * Replace the critical section and destroy the automatic default section.
3071 */
3072 PPDMCRITSECT pOldCritSect = pDevIns->pCritSectRoR3;
3073 pDevIns->pCritSectRoR3 = pCritSect;
3074 pDevIns->Internal.s.fIntFlags |= PDMDEVINSINT_FLAGS_CHANGED_CRITSECT;
3075
3076 Assert(RT_BOOL(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED) == pDevIns->fR0Enabled);
3077 if ( (pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED)
3078 && !(pDevIns->Internal.s.pDevR3->pReg->fFlags & PDM_DEVREG_FLAGS_NEW_STYLE))
3079 {
3080 PDMDEVICECOMPATSETCRITSECTREQ Req;
3081 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
3082 Req.Hdr.cbReq = sizeof(Req);
3083 Req.idxR0Device = pDevIns->Internal.s.idxR0Device;
3084 Req.pDevInsR3 = pDevIns;
3085 Req.pCritSectR3 = pCritSect;
3086 int rc = VMMR3CallR0(pVM, VMMR0_DO_PDM_DEVICE_COMPAT_SET_CRITSECT, 0, &Req.Hdr);
3087 AssertLogRelRCReturn(rc, rc);
3088 }
3089
3090 PDMR3CritSectDelete(pVM, pOldCritSect);
3091 Assert((uintptr_t)pOldCritSect - (uintptr_t)pDevIns < pDevIns->cbRing3);
3092
3093 LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
3094 return VINF_SUCCESS;
3095}
3096
3097
3098/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectYield} */
3099static DECLCALLBACK(bool) pdmR3DevHlp_CritSectYield(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3100{
3101 PDMDEV_ASSERT_DEVINS(pDevIns);
3102 return PDMR3CritSectYield(pDevIns->Internal.s.pVMR3, pCritSect);
3103}
3104
3105
3106/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectEnter} */
3107static DECLCALLBACK(int) pdmR3DevHlp_CritSectEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy)
3108{
3109 PDMDEV_ASSERT_DEVINS(pDevIns);
3110 return PDMCritSectEnter(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy);
3111}
3112
3113
3114/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectEnterDebug} */
3115static DECLCALLBACK(int) pdmR3DevHlp_CritSectEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
3116{
3117 PDMDEV_ASSERT_DEVINS(pDevIns);
3118 return PDMCritSectEnterDebug(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
3119}
3120
3121
3122/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectTryEnter} */
3123static DECLCALLBACK(int) pdmR3DevHlp_CritSectTryEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3124{
3125 PDMDEV_ASSERT_DEVINS(pDevIns);
3126 return PDMCritSectTryEnter(pDevIns->Internal.s.pVMR3, pCritSect);
3127}
3128
3129
3130/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectTryEnterDebug} */
3131static DECLCALLBACK(int) pdmR3DevHlp_CritSectTryEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
3132{
3133 PDMDEV_ASSERT_DEVINS(pDevIns);
3134 return PDMCritSectTryEnterDebug(pDevIns->Internal.s.pVMR3, pCritSect, uId, RT_SRC_POS_ARGS);
3135}
3136
3137
3138/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectLeave} */
3139static DECLCALLBACK(int) pdmR3DevHlp_CritSectLeave(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3140{
3141 PDMDEV_ASSERT_DEVINS(pDevIns);
3142 return PDMCritSectLeave(pDevIns->Internal.s.pVMR3, pCritSect);
3143}
3144
3145
3146/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectIsOwner} */
3147static DECLCALLBACK(bool) pdmR3DevHlp_CritSectIsOwner(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3148{
3149 PDMDEV_ASSERT_DEVINS(pDevIns);
3150 return PDMCritSectIsOwner(pDevIns->Internal.s.pVMR3, pCritSect);
3151}
3152
3153
3154/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectIsInitialized} */
3155static DECLCALLBACK(bool) pdmR3DevHlp_CritSectIsInitialized(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3156{
3157 PDMDEV_ASSERT_DEVINS(pDevIns);
3158 RT_NOREF(pDevIns);
3159 return PDMCritSectIsInitialized(pCritSect);
3160}
3161
3162
3163/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectHasWaiters} */
3164static DECLCALLBACK(bool) pdmR3DevHlp_CritSectHasWaiters(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3165{
3166 PDMDEV_ASSERT_DEVINS(pDevIns);
3167 return PDMCritSectHasWaiters(pDevIns->Internal.s.pVMR3, pCritSect);
3168}
3169
3170
3171/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetRecursion} */
3172static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectGetRecursion(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3173{
3174 PDMDEV_ASSERT_DEVINS(pDevIns);
3175 RT_NOREF(pDevIns);
3176 return PDMCritSectGetRecursion(pCritSect);
3177}
3178
3179
3180/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectScheduleExitEvent} */
3181static DECLCALLBACK(int) pdmR3DevHlp_CritSectScheduleExitEvent(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect,
3182 SUPSEMEVENT hEventToSignal)
3183{
3184 PDMDEV_ASSERT_DEVINS(pDevIns);
3185 RT_NOREF(pDevIns);
3186 return PDMHCCritSectScheduleExitEvent(pCritSect, hEventToSignal);
3187}
3188
3189
3190/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectDelete} */
3191static DECLCALLBACK(int) pdmR3DevHlp_CritSectDelete(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3192{
3193 PDMDEV_ASSERT_DEVINS(pDevIns);
3194 return PDMR3CritSectDelete(pDevIns->Internal.s.pVMR3, pCritSect);
3195}
3196
3197
3198/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwInit} */
3199static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwInit(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
3200 const char *pszNameFmt, va_list va)
3201{
3202 PDMDEV_ASSERT_DEVINS(pDevIns);
3203 LogFlow(("pdmR3DevHlp_CritSectRwInit: caller='%s'/%d: pCritSect=%p pszNameFmt=%p:{%s}\n",
3204 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pszNameFmt, pszNameFmt));
3205
3206 PVM pVM = pDevIns->Internal.s.pVMR3;
3207 VM_ASSERT_EMT(pVM);
3208 int rc = pdmR3CritSectRwInitDevice(pVM, pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
3209
3210 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3211 return rc;
3212}
3213
3214
3215/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwDelete} */
3216static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwDelete(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3217{
3218 PDMDEV_ASSERT_DEVINS(pDevIns);
3219 return PDMR3CritSectRwDelete(pDevIns->Internal.s.pVMR3, pCritSect);
3220}
3221
3222
3223/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterShared} */
3224static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy)
3225{
3226 PDMDEV_ASSERT_DEVINS(pDevIns);
3227 return PDMCritSectRwEnterShared(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy);
3228}
3229
3230
3231/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterSharedDebug} */
3232static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterSharedDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy,
3233 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3234{
3235 PDMDEV_ASSERT_DEVINS(pDevIns);
3236 return PDMCritSectRwEnterSharedDebug(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
3237}
3238
3239
3240/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterShared} */
3241static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3242{
3243 PDMDEV_ASSERT_DEVINS(pDevIns);
3244 return PDMCritSectRwTryEnterShared(pDevIns->Internal.s.pVMR3, pCritSect);
3245}
3246
3247
3248/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterSharedDebug} */
3249static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterSharedDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect,
3250 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3251{
3252 PDMDEV_ASSERT_DEVINS(pDevIns);
3253 return PDMCritSectRwTryEnterSharedDebug(pDevIns->Internal.s.pVMR3, pCritSect, uId, RT_SRC_POS_ARGS);
3254}
3255
3256
3257/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwLeaveShared} */
3258static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwLeaveShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3259{
3260 PDMDEV_ASSERT_DEVINS(pDevIns);
3261 return PDMCritSectRwLeaveShared(pDevIns->Internal.s.pVMR3, pCritSect);
3262}
3263
3264
3265/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterExcl} */
3266static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy)
3267{
3268 PDMDEV_ASSERT_DEVINS(pDevIns);
3269 return PDMCritSectRwEnterExcl(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy);
3270}
3271
3272
3273/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterExclDebug} */
3274static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterExclDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy,
3275 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3276{
3277 PDMDEV_ASSERT_DEVINS(pDevIns);
3278 return PDMCritSectRwEnterExclDebug(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
3279}
3280
3281
3282/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterExcl} */
3283static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3284{
3285 PDMDEV_ASSERT_DEVINS(pDevIns);
3286 return PDMCritSectRwTryEnterExcl(pDevIns->Internal.s.pVMR3, pCritSect);
3287}
3288
3289
3290/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterExclDebug} */
3291static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterExclDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect,
3292 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3293{
3294 PDMDEV_ASSERT_DEVINS(pDevIns);
3295 return PDMCritSectRwTryEnterExclDebug(pDevIns->Internal.s.pVMR3, pCritSect, uId, RT_SRC_POS_ARGS);
3296}
3297
3298
3299/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwLeaveExcl} */
3300static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwLeaveExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3301{
3302 PDMDEV_ASSERT_DEVINS(pDevIns);
3303 return PDMCritSectRwLeaveExcl(pDevIns->Internal.s.pVMR3, pCritSect);
3304}
3305
3306
3307/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwIsWriteOwner} */
3308static DECLCALLBACK(bool) pdmR3DevHlp_CritSectRwIsWriteOwner(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3309{
3310 PDMDEV_ASSERT_DEVINS(pDevIns);
3311 return PDMCritSectRwIsWriteOwner(pDevIns->Internal.s.pVMR3, pCritSect);
3312}
3313
3314
3315/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwIsReadOwner} */
3316static DECLCALLBACK(bool) pdmR3DevHlp_CritSectRwIsReadOwner(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, bool fWannaHear)
3317{
3318 PDMDEV_ASSERT_DEVINS(pDevIns);
3319 return PDMCritSectRwIsReadOwner(pDevIns->Internal.s.pVMR3, pCritSect, fWannaHear);
3320}
3321
3322
3323/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwGetWriteRecursion} */
3324static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectRwGetWriteRecursion(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3325{
3326 PDMDEV_ASSERT_DEVINS(pDevIns);
3327 RT_NOREF(pDevIns);
3328 return PDMCritSectRwGetWriteRecursion(pCritSect);
3329}
3330
3331
3332/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwGetWriterReadRecursion} */
3333static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectRwGetWriterReadRecursion(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3334{
3335 PDMDEV_ASSERT_DEVINS(pDevIns);
3336 RT_NOREF(pDevIns);
3337 return PDMCritSectRwGetWriterReadRecursion(pCritSect);
3338}
3339
3340
3341/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwGetReadCount} */
3342static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectRwGetReadCount(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3343{
3344 PDMDEV_ASSERT_DEVINS(pDevIns);
3345 RT_NOREF(pDevIns);
3346 return PDMCritSectRwGetReadCount(pCritSect);
3347}
3348
3349
3350/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwIsInitialized} */
3351static DECLCALLBACK(bool) pdmR3DevHlp_CritSectRwIsInitialized(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3352{
3353 PDMDEV_ASSERT_DEVINS(pDevIns);
3354 RT_NOREF(pDevIns);
3355 return PDMCritSectRwIsInitialized(pCritSect);
3356}
3357
3358
3359/** @interface_method_impl{PDMDEVHLPR3,pfnThreadCreate} */
3360static DECLCALLBACK(int) pdmR3DevHlp_ThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
3361 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
3362{
3363 PDMDEV_ASSERT_DEVINS(pDevIns);
3364 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3365 LogFlow(("pdmR3DevHlp_ThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",
3366 pDevIns->pReg->szName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));
3367
3368 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
3369
3370 LogFlow(("pdmR3DevHlp_ThreadCreate: caller='%s'/%d: returns %Rrc *ppThread=%RTthrd\n", pDevIns->pReg->szName, pDevIns->iInstance,
3371 rc, *ppThread));
3372 return rc;
3373}
3374
3375
3376/** @interface_method_impl{PDMDEVHLPR3,pfnSetAsyncNotification} */
3377static DECLCALLBACK(int) pdmR3DevHlp_SetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
3378{
3379 PDMDEV_ASSERT_DEVINS(pDevIns);
3380 VM_ASSERT_EMT0(pDevIns->Internal.s.pVMR3);
3381 LogFlow(("pdmR3DevHlp_SetAsyncNotification: caller='%s'/%d: pfnAsyncNotify=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pfnAsyncNotify));
3382
3383 int rc = VINF_SUCCESS;
3384 AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER);
3385 AssertStmt(!pDevIns->Internal.s.pfnAsyncNotify, rc = VERR_WRONG_ORDER);
3386 AssertStmt(pDevIns->Internal.s.fIntFlags & (PDMDEVINSINT_FLAGS_SUSPENDED | PDMDEVINSINT_FLAGS_RESET), rc = VERR_WRONG_ORDER);
3387 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);
3388 AssertStmt( enmVMState == VMSTATE_SUSPENDING
3389 || enmVMState == VMSTATE_SUSPENDING_EXT_LS
3390 || enmVMState == VMSTATE_SUSPENDING_LS
3391 || enmVMState == VMSTATE_RESETTING
3392 || enmVMState == VMSTATE_RESETTING_LS
3393 || enmVMState == VMSTATE_POWERING_OFF
3394 || enmVMState == VMSTATE_POWERING_OFF_LS,
3395 rc = VERR_INVALID_STATE);
3396
3397 if (RT_SUCCESS(rc))
3398 pDevIns->Internal.s.pfnAsyncNotify = pfnAsyncNotify;
3399
3400 LogFlow(("pdmR3DevHlp_SetAsyncNotification: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3401 return rc;
3402}
3403
3404
3405/** @interface_method_impl{PDMDEVHLPR3,pfnAsyncNotificationCompleted} */
3406static DECLCALLBACK(void) pdmR3DevHlp_AsyncNotificationCompleted(PPDMDEVINS pDevIns)
3407{
3408 PDMDEV_ASSERT_DEVINS(pDevIns);
3409 PVM pVM = pDevIns->Internal.s.pVMR3;
3410
3411 VMSTATE enmVMState = VMR3GetState(pVM);
3412 if ( enmVMState == VMSTATE_SUSPENDING
3413 || enmVMState == VMSTATE_SUSPENDING_EXT_LS
3414 || enmVMState == VMSTATE_SUSPENDING_LS
3415 || enmVMState == VMSTATE_RESETTING
3416 || enmVMState == VMSTATE_RESETTING_LS
3417 || enmVMState == VMSTATE_POWERING_OFF
3418 || enmVMState == VMSTATE_POWERING_OFF_LS)
3419 {
3420 LogFlow(("pdmR3DevHlp_AsyncNotificationCompleted: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
3421 VMR3AsyncPdmNotificationWakeupU(pVM->pUVM);
3422 }
3423 else
3424 LogFlow(("pdmR3DevHlp_AsyncNotificationCompleted: caller='%s'/%d: enmVMState=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, enmVMState));
3425}
3426
3427
3428/** @interface_method_impl{PDMDEVHLPR3,pfnRTCRegister} */
3429static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
3430{
3431 PDMDEV_ASSERT_DEVINS(pDevIns);
3432 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3433 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n",
3434 pDevIns->pReg->szName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite,
3435 pRtcReg->pfnWrite, ppRtcHlp));
3436
3437 /*
3438 * Validate input.
3439 */
3440 if (pRtcReg->u32Version != PDM_RTCREG_VERSION)
3441 {
3442 AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version,
3443 PDM_RTCREG_VERSION));
3444 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (version)\n",
3445 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3446 return VERR_INVALID_PARAMETER;
3447 }
3448 if ( !pRtcReg->pfnWrite
3449 || !pRtcReg->pfnRead)
3450 {
3451 Assert(pRtcReg->pfnWrite);
3452 Assert(pRtcReg->pfnRead);
3453 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
3454 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3455 return VERR_INVALID_PARAMETER;
3456 }
3457
3458 if (!ppRtcHlp)
3459 {
3460 Assert(ppRtcHlp);
3461 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (ppRtcHlp)\n",
3462 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3463 return VERR_INVALID_PARAMETER;
3464 }
3465
3466 /*
3467 * Only one DMA device.
3468 */
3469 PVM pVM = pDevIns->Internal.s.pVMR3;
3470 if (pVM->pdm.s.pRtc)
3471 {
3472 AssertMsgFailed(("Only one RTC device is supported!\n"));
3473 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc\n",
3474 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3475 return VERR_INVALID_PARAMETER;
3476 }
3477
3478 /*
3479 * Allocate and initialize pci bus structure.
3480 */
3481 int rc = VINF_SUCCESS;
3482 PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc));
3483 if (pRtc)
3484 {
3485 pRtc->pDevIns = pDevIns;
3486 pRtc->Reg = *pRtcReg;
3487 pVM->pdm.s.pRtc = pRtc;
3488
3489 /* set the helper pointer. */
3490 *ppRtcHlp = &g_pdmR3DevRtcHlp;
3491 Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n",
3492 pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
3493 }
3494 else
3495 rc = VERR_NO_MEMORY;
3496
3497 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc\n",
3498 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3499 return rc;
3500}
3501
3502
3503/** @interface_method_impl{PDMDEVHLPR3,pfnDMARegister} */
3504static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
3505{
3506 PDMDEV_ASSERT_DEVINS(pDevIns);
3507 PVM pVM = pDevIns->Internal.s.pVMR3;
3508 VM_ASSERT_EMT(pVM);
3509 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n",
3510 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser));
3511 int rc = VINF_SUCCESS;
3512 if (pVM->pdm.s.pDmac)
3513 pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pDevIns, pfnTransferHandler, pvUser);
3514 else
3515 {
3516 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3517 rc = VERR_PDM_NO_DMAC_INSTANCE;
3518 }
3519 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Rrc\n",
3520 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3521 return rc;
3522}
3523
3524
3525/** @interface_method_impl{PDMDEVHLPR3,pfnDMAReadMemory} */
3526static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
3527{
3528 PDMDEV_ASSERT_DEVINS(pDevIns);
3529 PVM pVM = pDevIns->Internal.s.pVMR3;
3530 VM_ASSERT_EMT(pVM);
3531 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n",
3532 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead));
3533 int rc = VINF_SUCCESS;
3534 if (pVM->pdm.s.pDmac)
3535 {
3536 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
3537 if (pcbRead)
3538 *pcbRead = cb;
3539 }
3540 else
3541 {
3542 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3543 rc = VERR_PDM_NO_DMAC_INSTANCE;
3544 }
3545 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Rrc\n",
3546 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3547 return rc;
3548}
3549
3550
3551/** @interface_method_impl{PDMDEVHLPR3,pfnDMAWriteMemory} */
3552static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
3553{
3554 PDMDEV_ASSERT_DEVINS(pDevIns);
3555 PVM pVM = pDevIns->Internal.s.pVMR3;
3556 VM_ASSERT_EMT(pVM);
3557 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n",
3558 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten));
3559 int rc = VINF_SUCCESS;
3560 if (pVM->pdm.s.pDmac)
3561 {
3562 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
3563 if (pcbWritten)
3564 *pcbWritten = cb;
3565 }
3566 else
3567 {
3568 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3569 rc = VERR_PDM_NO_DMAC_INSTANCE;
3570 }
3571 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Rrc\n",
3572 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3573 return rc;
3574}
3575
3576
3577/** @interface_method_impl{PDMDEVHLPR3,pfnDMASetDREQ} */
3578static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
3579{
3580 PDMDEV_ASSERT_DEVINS(pDevIns);
3581 PVM pVM = pDevIns->Internal.s.pVMR3;
3582 VM_ASSERT_EMT(pVM);
3583 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n",
3584 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, uLevel));
3585 int rc = VINF_SUCCESS;
3586 if (pVM->pdm.s.pDmac)
3587 pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel);
3588 else
3589 {
3590 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3591 rc = VERR_PDM_NO_DMAC_INSTANCE;
3592 }
3593 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Rrc\n",
3594 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3595 return rc;
3596}
3597
3598/** @interface_method_impl{PDMDEVHLPR3,pfnDMAGetChannelMode} */
3599static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
3600{
3601 PDMDEV_ASSERT_DEVINS(pDevIns);
3602 PVM pVM = pDevIns->Internal.s.pVMR3;
3603 VM_ASSERT_EMT(pVM);
3604 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n",
3605 pDevIns->pReg->szName, pDevIns->iInstance, uChannel));
3606 uint8_t u8Mode;
3607 if (pVM->pdm.s.pDmac)
3608 u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel);
3609 else
3610 {
3611 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3612 u8Mode = 3 << 2 /* illegal mode type */;
3613 }
3614 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n",
3615 pDevIns->pReg->szName, pDevIns->iInstance, u8Mode));
3616 return u8Mode;
3617}
3618
3619/** @interface_method_impl{PDMDEVHLPR3,pfnDMASchedule} */
3620static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns)
3621{
3622 PDMDEV_ASSERT_DEVINS(pDevIns);
3623 PVM pVM = pDevIns->Internal.s.pVMR3;
3624 VM_ASSERT_EMT(pVM);
3625 LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n",
3626 pDevIns->pReg->szName, pDevIns->iInstance, VM_FF_IS_SET(pVM, VM_FF_PDM_DMA)));
3627
3628 AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3629 VM_FF_SET(pVM, VM_FF_PDM_DMA);
3630 VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
3631}
3632
3633
3634/** @interface_method_impl{PDMDEVHLPR3,pfnCMOSWrite} */
3635static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
3636{
3637 PDMDEV_ASSERT_DEVINS(pDevIns);
3638 PVM pVM = pDevIns->Internal.s.pVMR3;
3639 VM_ASSERT_EMT(pVM);
3640
3641 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n",
3642 pDevIns->pReg->szName, pDevIns->iInstance, iReg, u8Value));
3643 int rc;
3644 if (pVM->pdm.s.pRtc)
3645 {
3646 PPDMDEVINS pDevInsRtc = pVM->pdm.s.pRtc->pDevIns;
3647 rc = PDMCritSectEnter(pVM, pDevInsRtc->pCritSectRoR3, VERR_IGNORED);
3648 if (RT_SUCCESS(rc))
3649 {
3650 rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pDevInsRtc, iReg, u8Value);
3651 PDMCritSectLeave(pVM, pDevInsRtc->pCritSectRoR3);
3652 }
3653 }
3654 else
3655 rc = VERR_PDM_NO_RTC_INSTANCE;
3656
3657 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Rrc\n",
3658 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3659 return rc;
3660}
3661
3662
3663/** @interface_method_impl{PDMDEVHLPR3,pfnCMOSRead} */
3664static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
3665{
3666 PDMDEV_ASSERT_DEVINS(pDevIns);
3667 PVM pVM = pDevIns->Internal.s.pVMR3;
3668 VM_ASSERT_EMT(pVM);
3669
3670 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n",
3671 pDevIns->pReg->szName, pDevIns->iInstance, iReg, pu8Value));
3672 int rc;
3673 if (pVM->pdm.s.pRtc)
3674 {
3675 PPDMDEVINS pDevInsRtc = pVM->pdm.s.pRtc->pDevIns;
3676 rc = PDMCritSectEnter(pVM, pDevInsRtc->pCritSectRoR3, VERR_IGNORED);
3677 if (RT_SUCCESS(rc))
3678 {
3679 rc = pVM->pdm.s.pRtc->Reg.pfnRead(pDevInsRtc, iReg, pu8Value);
3680 PDMCritSectLeave(pVM, pDevInsRtc->pCritSectRoR3);
3681 }
3682 }
3683 else
3684 rc = VERR_PDM_NO_RTC_INSTANCE;
3685
3686 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Rrc\n",
3687 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3688 return rc;
3689}
3690
3691
3692/** @interface_method_impl{PDMDEVHLPR3,pfnAssertEMT} */
3693static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
3694{
3695 PDMDEV_ASSERT_DEVINS(pDevIns);
3696 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3))
3697 return true;
3698
3699 char szMsg[100];
3700 RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance);
3701 RTAssertMsg1Weak(szMsg, iLine, pszFile, pszFunction);
3702 AssertBreakpoint();
3703 return false;
3704}
3705
3706
3707/** @interface_method_impl{PDMDEVHLPR3,pfnAssertOther} */
3708static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
3709{
3710 PDMDEV_ASSERT_DEVINS(pDevIns);
3711 if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3))
3712 return true;
3713
3714 char szMsg[100];
3715 RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance);
3716 RTAssertMsg1Weak(szMsg, iLine, pszFile, pszFunction);
3717 AssertBreakpoint();
3718 return false;
3719}
3720
3721
3722/** @interface_method_impl{PDMDEVHLPR3,pfnLdrGetRCInterfaceSymbols} */
3723static DECLCALLBACK(int) pdmR3DevHlp_LdrGetRCInterfaceSymbols(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3724 const char *pszSymPrefix, const char *pszSymList)
3725{
3726 PDMDEV_ASSERT_DEVINS(pDevIns);
3727 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3728 LogFlow(("pdmR3DevHlp_PDMLdrGetRCInterfaceSymbols: caller='%s'/%d: pvInterface=%p cbInterface=%zu pszSymPrefix=%p:{%s} pszSymList=%p:{%s}\n",
3729 pDevIns->pReg->szName, pDevIns->iInstance, pvInterface, cbInterface, pszSymPrefix, pszSymPrefix, pszSymList, pszSymList));
3730
3731 int rc;
3732 if ( strncmp(pszSymPrefix, "dev", 3) == 0
3733 && RTStrIStr(pszSymPrefix + 3, pDevIns->pReg->szName) != NULL)
3734 {
3735 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
3736 rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
3737 pvInterface, cbInterface,
3738 pDevIns->pReg->pszRCMod, pDevIns->Internal.s.pDevR3->pszRCSearchPath,
3739 pszSymPrefix, pszSymList,
3740 false /*fRing0OrRC*/);
3741 else
3742 {
3743 AssertMsgFailed(("Not a raw-mode enabled driver\n"));
3744 rc = VERR_PERMISSION_DENIED;
3745 }
3746 }
3747 else
3748 {
3749 AssertMsgFailed(("Invalid prefix '%s' for '%s'; must start with 'dev' and contain the driver name!\n",
3750 pszSymPrefix, pDevIns->pReg->szName));
3751 rc = VERR_INVALID_NAME;
3752 }
3753
3754 LogFlow(("pdmR3DevHlp_PDMLdrGetRCInterfaceSymbols: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
3755 pDevIns->iInstance, rc));
3756 return rc;
3757}
3758
3759
3760/** @interface_method_impl{PDMDEVHLPR3,pfnLdrGetR0InterfaceSymbols} */
3761static DECLCALLBACK(int) pdmR3DevHlp_LdrGetR0InterfaceSymbols(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3762 const char *pszSymPrefix, const char *pszSymList)
3763{
3764 PDMDEV_ASSERT_DEVINS(pDevIns);
3765 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3766 LogFlow(("pdmR3DevHlp_PDMLdrGetR0InterfaceSymbols: caller='%s'/%d: pvInterface=%p cbInterface=%zu pszSymPrefix=%p:{%s} pszSymList=%p:{%s}\n",
3767 pDevIns->pReg->szName, pDevIns->iInstance, pvInterface, cbInterface, pszSymPrefix, pszSymPrefix, pszSymList, pszSymList));
3768
3769 int rc;
3770 if ( strncmp(pszSymPrefix, "dev", 3) == 0
3771 && RTStrIStr(pszSymPrefix + 3, pDevIns->pReg->szName) != NULL)
3772 {
3773 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
3774 rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
3775 pvInterface, cbInterface,
3776 pDevIns->pReg->pszR0Mod, pDevIns->Internal.s.pDevR3->pszR0SearchPath,
3777 pszSymPrefix, pszSymList,
3778 true /*fRing0OrRC*/);
3779 else
3780 {
3781 AssertMsgFailed(("Not a ring-0 enabled driver\n"));
3782 rc = VERR_PERMISSION_DENIED;
3783 }
3784 }
3785 else
3786 {
3787 AssertMsgFailed(("Invalid prefix '%s' for '%s'; must start with 'dev' and contain the driver name!\n",
3788 pszSymPrefix, pDevIns->pReg->szName));
3789 rc = VERR_INVALID_NAME;
3790 }
3791
3792 LogFlow(("pdmR3DevHlp_PDMLdrGetR0InterfaceSymbols: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
3793 pDevIns->iInstance, rc));
3794 return rc;
3795}
3796
3797
3798/** @interface_method_impl{PDMDEVHLPR3,pfnCallR0} */
3799static DECLCALLBACK(int) pdmR3DevHlp_CallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
3800{
3801 PDMDEV_ASSERT_DEVINS(pDevIns);
3802 PVM pVM = pDevIns->Internal.s.pVMR3;
3803 PVMCPU pVCpu = VMMGetCpu(pVM);
3804 AssertReturn(pVCpu, VERR_VM_THREAD_IS_EMT);
3805 LogFlow(("pdmR3DevHlp_CallR0: caller='%s'/%d: uOperation=%#x u64Arg=%#RX64\n",
3806 pDevIns->pReg->szName, pDevIns->iInstance, uOperation, u64Arg));
3807
3808 /*
3809 * Resolve the ring-0 entry point. There is not need to remember this like
3810 * we do for drivers since this is mainly for construction time hacks and
3811 * other things that aren't performance critical.
3812 */
3813 int rc;
3814 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
3815 {
3816 /*
3817 * Make the ring-0 call.
3818 */
3819 PDMDEVICEGENCALLREQ Req;
3820 RT_ZERO(Req.Params);
3821 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
3822 Req.Hdr.cbReq = sizeof(Req);
3823 Req.pDevInsR3 = pDevIns;
3824 Req.idxR0Device = pDevIns->Internal.s.idxR0Device;
3825 Req.enmCall = PDMDEVICEGENCALL_REQUEST;
3826 Req.Params.Req.uReq = uOperation;
3827 Req.Params.Req.uArg = u64Arg;
3828 rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_PDM_DEVICE_GEN_CALL, 0, &Req.Hdr);
3829 }
3830 else
3831 rc = VERR_ACCESS_DENIED;
3832 LogFlow(("pdmR3DevHlp_CallR0: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
3833 pDevIns->iInstance, rc));
3834 return rc;
3835}
3836
3837
3838/** @interface_method_impl{PDMDEVHLPR3,pfnVMGetSuspendReason} */
3839static DECLCALLBACK(VMSUSPENDREASON) pdmR3DevHlp_VMGetSuspendReason(PPDMDEVINS pDevIns)
3840{
3841 PDMDEV_ASSERT_DEVINS(pDevIns);
3842 PVM pVM = pDevIns->Internal.s.pVMR3;
3843 VM_ASSERT_EMT(pVM);
3844 VMSUSPENDREASON enmReason = VMR3GetSuspendReason(pVM->pUVM);
3845 LogFlow(("pdmR3DevHlp_VMGetSuspendReason: caller='%s'/%d: returns %d\n",
3846 pDevIns->pReg->szName, pDevIns->iInstance, enmReason));
3847 return enmReason;
3848}
3849
3850
3851/** @interface_method_impl{PDMDEVHLPR3,pfnVMGetResumeReason} */
3852static DECLCALLBACK(VMRESUMEREASON) pdmR3DevHlp_VMGetResumeReason(PPDMDEVINS pDevIns)
3853{
3854 PDMDEV_ASSERT_DEVINS(pDevIns);
3855 PVM pVM = pDevIns->Internal.s.pVMR3;
3856 VM_ASSERT_EMT(pVM);
3857 VMRESUMEREASON enmReason = VMR3GetResumeReason(pVM->pUVM);
3858 LogFlow(("pdmR3DevHlp_VMGetResumeReason: caller='%s'/%d: returns %d\n",
3859 pDevIns->pReg->szName, pDevIns->iInstance, enmReason));
3860 return enmReason;
3861}
3862
3863
3864/** @interface_method_impl{PDMDEVHLPR3,pfnGetUVM} */
3865static DECLCALLBACK(PUVM) pdmR3DevHlp_GetUVM(PPDMDEVINS pDevIns)
3866{
3867 PDMDEV_ASSERT_DEVINS(pDevIns);
3868 LogFlow(("pdmR3DevHlp_GetUVM: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));
3869 return pDevIns->Internal.s.pVMR3->pUVM;
3870}
3871
3872
3873/** @interface_method_impl{PDMDEVHLPR3,pfnGetVM} */
3874static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns)
3875{
3876 PDMDEV_ASSERT_DEVINS(pDevIns);
3877 LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));
3878 return pDevIns->Internal.s.pVMR3;
3879}
3880
3881
3882/** @interface_method_impl{PDMDEVHLPR3,pfnGetVMCPU} */
3883static DECLCALLBACK(PVMCPU) pdmR3DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
3884{
3885 PDMDEV_ASSERT_DEVINS(pDevIns);
3886 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3887 LogFlow(("pdmR3DevHlp_GetVMCPU: caller='%s'/%d for CPU %u\n", pDevIns->pReg->szName, pDevIns->iInstance, VMMGetCpuId(pDevIns->Internal.s.pVMR3)));
3888 return VMMGetCpu(pDevIns->Internal.s.pVMR3);
3889}
3890
3891
3892/** @interface_method_impl{PDMDEVHLPR3,pfnGetCurrentCpuId} */
3893static DECLCALLBACK(VMCPUID) pdmR3DevHlp_GetCurrentCpuId(PPDMDEVINS pDevIns)
3894{
3895 PDMDEV_ASSERT_DEVINS(pDevIns);
3896 VMCPUID idCpu = VMMGetCpuId(pDevIns->Internal.s.pVMR3);
3897 LogFlow(("pdmR3DevHlp_GetCurrentCpuId: caller='%s'/%d for CPU %u\n", pDevIns->pReg->szName, pDevIns->iInstance, idCpu));
3898 return idCpu;
3899}
3900
3901
3902/** @interface_method_impl{PDMDEVHLPR3,pfnPCIBusRegister} */
3903static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREGR3 pPciBusReg,
3904 PCPDMPCIHLPR3 *ppPciHlp, uint32_t *piBus)
3905{
3906 PDMDEV_ASSERT_DEVINS(pDevIns);
3907 PVM pVM = pDevIns->Internal.s.pVMR3;
3908 VM_ASSERT_EMT(pVM);
3909 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, "
3910 ".pfnInterceptConfigAccesses=%p, pfnConfigRead=%p, pfnConfigWrite=%p, .pfnSetIrqR3=%p, .u32EndVersion=%#x} ppPciHlpR3=%p piBus=%p\n",
3911 pDevIns->pReg->szName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3,
3912 pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnInterceptConfigAccesses, pPciBusReg->pfnConfigRead,
3913 pPciBusReg->pfnConfigWrite, pPciBusReg->pfnSetIrqR3, pPciBusReg->u32EndVersion, ppPciHlp, piBus));
3914
3915 /*
3916 * Validate the structure and output parameters.
3917 */
3918 AssertLogRelMsgReturn(pPciBusReg->u32Version == PDM_PCIBUSREGR3_VERSION,
3919 ("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREGR3_VERSION),
3920 VERR_INVALID_PARAMETER);
3921 AssertPtrReturn(pPciBusReg->pfnRegisterR3, VERR_INVALID_PARAMETER);
3922 AssertPtrNullReturn(pPciBusReg->pfnRegisterMsiR3, VERR_INVALID_POINTER);
3923 AssertPtrReturn(pPciBusReg->pfnIORegionRegisterR3, VERR_INVALID_POINTER);
3924 AssertPtrReturn(pPciBusReg->pfnInterceptConfigAccesses, VERR_INVALID_POINTER);
3925 AssertPtrReturn(pPciBusReg->pfnConfigWrite, VERR_INVALID_POINTER);
3926 AssertPtrReturn(pPciBusReg->pfnConfigRead, VERR_INVALID_POINTER);
3927 AssertPtrReturn(pPciBusReg->pfnSetIrqR3, VERR_INVALID_POINTER);
3928 AssertLogRelMsgReturn(pPciBusReg->u32EndVersion == PDM_PCIBUSREGR3_VERSION,
3929 ("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREGR3_VERSION),
3930 VERR_INVALID_PARAMETER);
3931 AssertPtrReturn(ppPciHlp, VERR_INVALID_POINTER);
3932 AssertPtrNullReturn(piBus, VERR_INVALID_POINTER);
3933 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
3934
3935 /*
3936 * Find free PCI bus entry.
3937 */
3938 unsigned iBus = 0;
3939 for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++)
3940 if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3)
3941 break;
3942 AssertLogRelMsgReturn(iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses),
3943 ("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses)),
3944 VERR_OUT_OF_RESOURCES);
3945 PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus];
3946
3947 /*
3948 * Init the R3 bits.
3949 */
3950 pPciBus->iBus = iBus;
3951 pPciBus->pDevInsR3 = pDevIns;
3952 pPciBus->pfnRegister = pPciBusReg->pfnRegisterR3;
3953 pPciBus->pfnRegisterMsi = pPciBusReg->pfnRegisterMsiR3;
3954 pPciBus->pfnIORegionRegister = pPciBusReg->pfnIORegionRegisterR3;
3955 pPciBus->pfnInterceptConfigAccesses = pPciBusReg->pfnInterceptConfigAccesses;
3956 pPciBus->pfnConfigRead = pPciBusReg->pfnConfigRead;
3957 pPciBus->pfnConfigWrite = pPciBusReg->pfnConfigWrite;
3958 pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3;
3959
3960 Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
3961
3962 /* set the helper pointer and return. */
3963 *ppPciHlp = &g_pdmR3DevPciHlp;
3964 if (piBus)
3965 *piBus = iBus;
3966 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc *piBus=%u\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS, iBus));
3967 return VINF_SUCCESS;
3968}
3969
3970
3971/** @interface_method_impl{PDMDEVHLPR3,pfnIommuRegister} */
3972static DECLCALLBACK(int) pdmR3DevHlp_IommuRegister(PPDMDEVINS pDevIns, PPDMIOMMUREGR3 pIommuReg, PCPDMIOMMUHLPR3 *ppIommuHlp,
3973 uint32_t *pidxIommu)
3974{
3975 PDMDEV_ASSERT_DEVINS(pDevIns);
3976 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3977 LogFlow(("pdmR3DevHlp_IommuRegister: caller='%s'/%d: pIommuReg=%p:{.u32Version=%#x, .u32TheEnd=%#x } ppIommuHlp=%p\n",
3978 pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg, pIommuReg->u32Version, pIommuReg->u32TheEnd, ppIommuHlp));
3979 PVM pVM = pDevIns->Internal.s.pVMR3;
3980
3981 /*
3982 * Validate input.
3983 */
3984 AssertMsgReturn(pIommuReg->u32Version == PDM_IOMMUREGR3_VERSION,
3985 ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg->u32Version, PDM_IOMMUREGR3_VERSION),
3986 VERR_INVALID_PARAMETER);
3987 AssertPtrReturn(pIommuReg->pfnMemAccess, VERR_INVALID_POINTER);
3988 AssertPtrReturn(pIommuReg->pfnMemBulkAccess, VERR_INVALID_POINTER);
3989 AssertPtrReturn(pIommuReg->pfnMsiRemap, VERR_INVALID_POINTER);
3990 AssertMsgReturn(pIommuReg->u32TheEnd == PDM_IOMMUREGR3_VERSION,
3991 ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg->u32TheEnd, PDM_IOMMUREGR3_VERSION),
3992 VERR_INVALID_PARAMETER);
3993 AssertPtrReturn(ppIommuHlp, VERR_INVALID_POINTER);
3994
3995 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
3996 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
3997
3998 /*
3999 * Find free IOMMU slot.
4000 * The IOMMU at the root complex is the one at 0.
4001 */
4002 unsigned idxIommu = 0;
4003#if 0
4004 for (idxIommu = 0; idxIommu < RT_ELEMENTS(pVM->pdm.s.aIommus); idxIommu++)
4005 if (!pVM->pdm.s.aIommus[idxIommu].pDevInsR3)
4006 break;
4007 AssertLogRelMsgReturn(idxIommu < RT_ELEMENTS(pVM->pdm.s.aIommus),
4008 ("Too many IOMMUs. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aIommus)),
4009 VERR_OUT_OF_RESOURCES);
4010#else
4011 /* Currently we support only a single IOMMU. */
4012 AssertMsgReturn(!pVM->pdm.s.aIommus[0].pDevInsR3,
4013 ("%s/%u: Only one IOMMU device is supported!\n", pDevIns->pReg->szName, pDevIns->iInstance),
4014 VERR_ALREADY_EXISTS);
4015#endif
4016 PPDMIOMMUR3 pIommu = &pVM->pdm.s.aIommus[idxIommu];
4017
4018 /*
4019 * Init the R3 bits.
4020 */
4021 pIommu->idxIommu = idxIommu;
4022 pIommu->pDevInsR3 = pDevIns;
4023 pIommu->pfnMemAccess = pIommuReg->pfnMemAccess;
4024 pIommu->pfnMemBulkAccess = pIommuReg->pfnMemBulkAccess;
4025 pIommu->pfnMsiRemap = pIommuReg->pfnMsiRemap;
4026 Log(("PDM: Registered IOMMU device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4027
4028 /* Set the helper pointer and return. */
4029 *ppIommuHlp = &g_pdmR3DevIommuHlp;
4030 if (pidxIommu)
4031 *pidxIommu = idxIommu;
4032 LogFlow(("pdmR3DevHlp_IommuRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4033 return VINF_SUCCESS;
4034}
4035
4036
4037
4038/** @interface_method_impl{PDMDEVHLPR3,pfnPICRegister} */
4039static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
4040{
4041 PDMDEV_ASSERT_DEVINS(pDevIns);
4042 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4043 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnGetInterrupt=%p, .u32TheEnd=%#x } ppPicHlp=%p\n",
4044 pDevIns->pReg->szName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrq, pPicReg->pfnGetInterrupt, pPicReg->u32TheEnd, ppPicHlp));
4045 PVM pVM = pDevIns->Internal.s.pVMR3;
4046
4047 /*
4048 * Validate input.
4049 */
4050 AssertMsgReturn(pPicReg->u32Version == PDM_PICREG_VERSION,
4051 ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32Version, PDM_PICREG_VERSION),
4052 VERR_INVALID_PARAMETER);
4053 AssertPtrReturn(pPicReg->pfnSetIrq, VERR_INVALID_POINTER);
4054 AssertPtrReturn(pPicReg->pfnGetInterrupt, VERR_INVALID_POINTER);
4055 AssertMsgReturn(pPicReg->u32TheEnd == PDM_PICREG_VERSION,
4056 ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32TheEnd, PDM_PICREG_VERSION),
4057 VERR_INVALID_PARAMETER);
4058 AssertPtrReturn(ppPicHlp, VERR_INVALID_POINTER);
4059
4060 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4061 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4062
4063 /*
4064 * Only one PIC device.
4065 */
4066 AssertMsgReturn(pVM->pdm.s.Pic.pDevInsR3 == NULL, ("%s/%d: Only one PIC!\n", pDevIns->pReg->szName, pDevIns->iInstance),
4067 VERR_ALREADY_EXISTS);
4068
4069 /*
4070 * Take down the callbacks and instance.
4071 */
4072 pVM->pdm.s.Pic.pDevInsR3 = pDevIns;
4073 pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrq;
4074 pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterrupt;
4075 Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4076
4077 /* set the helper pointer and return. */
4078 *ppPicHlp = &g_pdmR3DevPicHlp;
4079 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4080 return VINF_SUCCESS;
4081}
4082
4083
4084/** @interface_method_impl{PDMDEVHLPR3,pfnApicRegister} */
4085static DECLCALLBACK(int) pdmR3DevHlp_ApicRegister(PPDMDEVINS pDevIns)
4086{
4087 PDMDEV_ASSERT_DEVINS(pDevIns);
4088
4089 /*
4090 * Validate caller context.
4091 */
4092 PVM pVM = pDevIns->Internal.s.pVMR3;
4093 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4094 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4095
4096 /*
4097 * Only one APIC device. On SMP we have single logical device covering all LAPICs,
4098 * as they need to communicate and share state easily.
4099 */
4100 AssertMsgReturn(pVM->pdm.s.Apic.pDevInsR3 == NULL,
4101 ("%s/%u: Only one APIC device is supported!\n", pDevIns->pReg->szName, pDevIns->iInstance),
4102 VERR_ALREADY_EXISTS);
4103
4104 /*
4105 * Set the ring-3 and raw-mode bits, leave the ring-0 to ring-0 setup.
4106 */
4107 pVM->pdm.s.Apic.pDevInsR3 = pDevIns;
4108#ifdef VBOX_WITH_RAW_MODE_KEEP
4109 pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
4110 Assert(pVM->pdm.s.Apic.pDevInsRC || !VM_IS_RAW_MODE_ENABLED(pVM));
4111#endif
4112
4113 LogFlow(("pdmR3DevHlp_ApicRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4114 return VINF_SUCCESS;
4115}
4116
4117
4118/** @interface_method_impl{PDMDEVHLPR3,pfnIoApicRegister} */
4119static DECLCALLBACK(int) pdmR3DevHlp_IoApicRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
4120{
4121 PDMDEV_ASSERT_DEVINS(pDevIns);
4122 LogFlow(("pdmR3DevHlp_IoApicRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnSendMsi=%p, .pfnSetEoi=%p, .u32TheEnd=%#x } ppIoApicHlp=%p\n",
4123 pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrq, pIoApicReg->pfnSendMsi, pIoApicReg->pfnSetEoi, pIoApicReg->u32TheEnd, ppIoApicHlp));
4124 PVM pVM = pDevIns->Internal.s.pVMR3;
4125
4126 /*
4127 * Validate input.
4128 */
4129 AssertMsgReturn(pIoApicReg->u32Version == PDM_IOAPICREG_VERSION,
4130 ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32Version, PDM_IOAPICREG_VERSION),
4131 VERR_VERSION_MISMATCH);
4132 AssertPtrReturn(pIoApicReg->pfnSetIrq, VERR_INVALID_POINTER);
4133 AssertPtrReturn(pIoApicReg->pfnSendMsi, VERR_INVALID_POINTER);
4134 AssertPtrReturn(pIoApicReg->pfnSetEoi, VERR_INVALID_POINTER);
4135 AssertMsgReturn(pIoApicReg->u32TheEnd == PDM_IOAPICREG_VERSION,
4136 ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32TheEnd, PDM_IOAPICREG_VERSION),
4137 VERR_VERSION_MISMATCH);
4138 AssertPtrReturn(ppIoApicHlp, VERR_INVALID_POINTER);
4139 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4140 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4141
4142 /*
4143 * The I/O APIC requires the APIC to be present (hacks++).
4144 * If the I/O APIC does GC stuff so must the APIC.
4145 */
4146 AssertMsgReturn(pVM->pdm.s.Apic.pDevInsR3 != NULL, ("Configuration error / Init order error! No APIC!\n"), VERR_WRONG_ORDER);
4147
4148 /*
4149 * Only one I/O APIC device.
4150 */
4151 AssertMsgReturn(pVM->pdm.s.IoApic.pDevInsR3 == NULL,
4152 ("Only one IOAPIC device is supported! (caller %s/%d)\n", pDevIns->pReg->szName, pDevIns->iInstance),
4153 VERR_ALREADY_EXISTS);
4154
4155 /*
4156 * Initialize the R3 bits.
4157 */
4158 pVM->pdm.s.IoApic.pDevInsR3 = pDevIns;
4159 pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrq;
4160 pVM->pdm.s.IoApic.pfnSendMsiR3 = pIoApicReg->pfnSendMsi;
4161 pVM->pdm.s.IoApic.pfnSetEoiR3 = pIoApicReg->pfnSetEoi;
4162 Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4163
4164 /* set the helper pointer and return. */
4165 *ppIoApicHlp = &g_pdmR3DevIoApicHlp;
4166 LogFlow(("pdmR3DevHlp_IoApicRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4167 return VINF_SUCCESS;
4168}
4169
4170
4171/** @interface_method_impl{PDMDEVHLPR3,pfnHpetRegister} */
4172static DECLCALLBACK(int) pdmR3DevHlp_HpetRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
4173{
4174 PDMDEV_ASSERT_DEVINS(pDevIns);
4175 LogFlow(("pdmR3DevHlp_HpetRegister: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4176 PVM pVM = pDevIns->Internal.s.pVMR3;
4177
4178 /*
4179 * Validate input.
4180 */
4181 AssertMsgReturn(pHpetReg->u32Version == PDM_HPETREG_VERSION,
4182 ("%s/%u: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pHpetReg->u32Version, PDM_HPETREG_VERSION),
4183 VERR_VERSION_MISMATCH);
4184 AssertPtrReturn(ppHpetHlpR3, VERR_INVALID_POINTER);
4185 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4186 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4187
4188 /*
4189 * Only one HPET device.
4190 */
4191 AssertMsgReturn(pVM->pdm.s.pHpet == NULL,
4192 ("Only one HPET device is supported! (caller %s/%d)\n", pDevIns->pReg->szName, pDevIns->iInstance),
4193 VERR_ALREADY_EXISTS);
4194
4195 /*
4196 * Do the job (what there is of it).
4197 */
4198 pVM->pdm.s.pHpet = pDevIns;
4199 *ppHpetHlpR3 = &g_pdmR3DevHpetHlp;
4200
4201 LogFlow(("pdmR3DevHlp_HpetRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4202 return VINF_SUCCESS;
4203}
4204
4205
4206/** @interface_method_impl{PDMDEVHLPR3,pfnPciRawRegister} */
4207static DECLCALLBACK(int) pdmR3DevHlp_PciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
4208{
4209 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
4210 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4211 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4212
4213 /*
4214 * Validate input.
4215 */
4216 if (pPciRawReg->u32Version != PDM_PCIRAWREG_VERSION)
4217 {
4218 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciRawReg->u32Version, PDM_PCIRAWREG_VERSION));
4219 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4220 return VERR_INVALID_PARAMETER;
4221 }
4222
4223 if (!ppPciRawHlpR3)
4224 {
4225 Assert(ppPciRawHlpR3);
4226 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (ppPciRawHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4227 return VERR_INVALID_PARAMETER;
4228 }
4229
4230 /* set the helper pointer and return. */
4231 *ppPciRawHlpR3 = &g_pdmR3DevPciRawHlp;
4232 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4233 return VINF_SUCCESS;
4234}
4235
4236
4237/** @interface_method_impl{PDMDEVHLPR3,pfnDMACRegister} */
4238static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
4239{
4240 PDMDEV_ASSERT_DEVINS(pDevIns);
4241 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4242 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: pDmacReg=%p:{.u32Version=%#x, .pfnRun=%p, .pfnRegister=%p, .pfnReadMemory=%p, .pfnWriteMemory=%p, .pfnSetDREQ=%p, .pfnGetChannelMode=%p} ppDmacHlp=%p\n",
4243 pDevIns->pReg->szName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister,
4244 pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp));
4245
4246 /*
4247 * Validate input.
4248 */
4249 if (pDmacReg->u32Version != PDM_DMACREG_VERSION)
4250 {
4251 AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version,
4252 PDM_DMACREG_VERSION));
4253 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (version)\n",
4254 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4255 return VERR_INVALID_PARAMETER;
4256 }
4257 if ( !pDmacReg->pfnRun
4258 || !pDmacReg->pfnRegister
4259 || !pDmacReg->pfnReadMemory
4260 || !pDmacReg->pfnWriteMemory
4261 || !pDmacReg->pfnSetDREQ
4262 || !pDmacReg->pfnGetChannelMode)
4263 {
4264 Assert(pDmacReg->pfnRun);
4265 Assert(pDmacReg->pfnRegister);
4266 Assert(pDmacReg->pfnReadMemory);
4267 Assert(pDmacReg->pfnWriteMemory);
4268 Assert(pDmacReg->pfnSetDREQ);
4269 Assert(pDmacReg->pfnGetChannelMode);
4270 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
4271 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4272 return VERR_INVALID_PARAMETER;
4273 }
4274
4275 if (!ppDmacHlp)
4276 {
4277 Assert(ppDmacHlp);
4278 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (ppDmacHlp)\n",
4279 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4280 return VERR_INVALID_PARAMETER;
4281 }
4282
4283 /*
4284 * Only one DMA device.
4285 */
4286 PVM pVM = pDevIns->Internal.s.pVMR3;
4287 if (pVM->pdm.s.pDmac)
4288 {
4289 AssertMsgFailed(("Only one DMA device is supported!\n"));
4290 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc\n",
4291 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4292 return VERR_INVALID_PARAMETER;
4293 }
4294
4295 /*
4296 * Allocate and initialize pci bus structure.
4297 */
4298 int rc = VINF_SUCCESS;
4299 PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac));
4300 if (pDmac)
4301 {
4302 pDmac->pDevIns = pDevIns;
4303 pDmac->Reg = *pDmacReg;
4304 pVM->pdm.s.pDmac = pDmac;
4305
4306 /* set the helper pointer. */
4307 *ppDmacHlp = &g_pdmR3DevDmacHlp;
4308 Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n",
4309 pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4310 }
4311 else
4312 rc = VERR_NO_MEMORY;
4313
4314 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc\n",
4315 pDevIns->pReg->szName, pDevIns->iInstance, rc));
4316 return rc;
4317}
4318
4319
4320/**
4321 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
4322 */
4323static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbHeap)
4324{
4325 PDMDEV_ASSERT_DEVINS(pDevIns);
4326 PVM pVM = pDevIns->Internal.s.pVMR3;
4327 VM_ASSERT_EMT(pVM);
4328 LogFlow(("pdmR3DevHlp_RegisterVMMDevHeap: caller='%s'/%d: GCPhys=%RGp pvHeap=%p cbHeap=%#x\n",
4329 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvHeap, cbHeap));
4330
4331 if (pVM->pdm.s.pvVMMDevHeap == NULL)
4332 {
4333 pVM->pdm.s.pvVMMDevHeap = pvHeap;
4334 pVM->pdm.s.GCPhysVMMDevHeap = GCPhys;
4335 pVM->pdm.s.cbVMMDevHeap = cbHeap;
4336 pVM->pdm.s.cbVMMDevHeapLeft = cbHeap;
4337 }
4338 else
4339 {
4340 Assert(pVM->pdm.s.pvVMMDevHeap == pvHeap);
4341 Assert(pVM->pdm.s.cbVMMDevHeap == cbHeap);
4342 Assert(pVM->pdm.s.GCPhysVMMDevHeap != GCPhys || GCPhys == NIL_RTGCPHYS);
4343 if (pVM->pdm.s.GCPhysVMMDevHeap != GCPhys)
4344 {
4345 pVM->pdm.s.GCPhysVMMDevHeap = GCPhys;
4346 if (pVM->pdm.s.pfnVMMDevHeapNotify)
4347 pVM->pdm.s.pfnVMMDevHeapNotify(pVM, pvHeap, GCPhys);
4348 }
4349 }
4350
4351 LogFlow(("pdmR3DevHlp_RegisterVMMDevHeap: caller='%s'/%d: returns %Rrc\n",
4352 pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4353 return VINF_SUCCESS;
4354}
4355
4356
4357/**
4358 * @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister}
4359 */
4360static DECLCALLBACK(int) pdmR3DevHlp_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
4361{
4362 PDMDEV_ASSERT_DEVINS(pDevIns);
4363 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4364 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: pFWReg=%p:{.u32Version=%#x, .pfnIsHardReset=%p, .u32TheEnd=%#x} ppFwHlp=%p\n",
4365 pDevIns->pReg->szName, pDevIns->iInstance, pFwReg, pFwReg->u32Version, pFwReg->pfnIsHardReset, pFwReg->u32TheEnd, ppFwHlp));
4366
4367 /*
4368 * Validate input.
4369 */
4370 if (pFwReg->u32Version != PDM_FWREG_VERSION)
4371 {
4372 AssertMsgFailed(("u32Version=%#x expected %#x\n", pFwReg->u32Version, PDM_FWREG_VERSION));
4373 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (version)\n",
4374 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4375 return VERR_INVALID_PARAMETER;
4376 }
4377 if (!pFwReg->pfnIsHardReset)
4378 {
4379 Assert(pFwReg->pfnIsHardReset);
4380 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
4381 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4382 return VERR_INVALID_PARAMETER;
4383 }
4384
4385 if (!ppFwHlp)
4386 {
4387 Assert(ppFwHlp);
4388 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (ppFwHlp)\n",
4389 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4390 return VERR_INVALID_PARAMETER;
4391 }
4392
4393 /*
4394 * Only one DMA device.
4395 */
4396 PVM pVM = pDevIns->Internal.s.pVMR3;
4397 if (pVM->pdm.s.pFirmware)
4398 {
4399 AssertMsgFailed(("Only one firmware device is supported!\n"));
4400 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
4401 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4402 return VERR_INVALID_PARAMETER;
4403 }
4404
4405 /*
4406 * Allocate and initialize pci bus structure.
4407 */
4408 int rc = VINF_SUCCESS;
4409 PPDMFW pFirmware = (PPDMFW)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pFirmware));
4410 if (pFirmware)
4411 {
4412 pFirmware->pDevIns = pDevIns;
4413 pFirmware->Reg = *pFwReg;
4414 pVM->pdm.s.pFirmware = pFirmware;
4415
4416 /* set the helper pointer. */
4417 *ppFwHlp = &g_pdmR3DevFirmwareHlp;
4418 Log(("PDM: Registered firmware device '%s'/%d pDevIns=%p\n",
4419 pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4420 }
4421 else
4422 rc = VERR_NO_MEMORY;
4423
4424 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
4425 pDevIns->pReg->szName, pDevIns->iInstance, rc));
4426 return rc;
4427}
4428
4429
4430/** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
4431static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
4432{
4433 PDMDEV_ASSERT_DEVINS(pDevIns);
4434 PVM pVM = pDevIns->Internal.s.pVMR3;
4435 VM_ASSERT_EMT(pVM);
4436 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: fFlags=%#x VM_FF_RESET %d -> 1\n",
4437 pDevIns->pReg->szName, pDevIns->iInstance, fFlags, VM_FF_IS_SET(pVM, VM_FF_RESET)));
4438
4439 /*
4440 * We postpone this operation because we're likely to be inside a I/O instruction
4441 * and the EIP will be updated when we return.
4442 * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation.
4443 */
4444 bool fHaltOnReset;
4445 int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset);
4446 if (RT_SUCCESS(rc) && fHaltOnReset)
4447 {
4448 Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n"));
4449 rc = VINF_EM_HALT;
4450 }
4451 else
4452 {
4453 pVM->pdm.s.fResetFlags = fFlags;
4454 VM_FF_SET(pVM, VM_FF_RESET);
4455 rc = VINF_EM_RESET;
4456 }
4457
4458 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4459 return rc;
4460}
4461
4462
4463/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspend} */
4464static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns)
4465{
4466 int rc;
4467 PDMDEV_ASSERT_DEVINS(pDevIns);
4468 PVM pVM = pDevIns->Internal.s.pVMR3;
4469 VM_ASSERT_EMT(pVM);
4470 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n",
4471 pDevIns->pReg->szName, pDevIns->iInstance));
4472
4473 /** @todo Always take the SMP path - fewer code paths. */
4474 if (pVM->cCpus > 1)
4475 {
4476 /* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
4477 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)VMR3Suspend, 2, pVM->pUVM, VMSUSPENDREASON_VM);
4478 AssertRC(rc);
4479 rc = VINF_EM_SUSPEND;
4480 }
4481 else
4482 rc = VMR3Suspend(pVM->pUVM, VMSUSPENDREASON_VM);
4483
4484 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4485 return rc;
4486}
4487
4488
4489/**
4490 * Worker for pdmR3DevHlp_VMSuspendSaveAndPowerOff that is invoked via a queued
4491 * EMT request to avoid deadlocks.
4492 *
4493 * @returns VBox status code fit for scheduling.
4494 * @param pVM The cross context VM structure.
4495 * @param pDevIns The device that triggered this action.
4496 */
4497static DECLCALLBACK(int) pdmR3DevHlp_VMSuspendSaveAndPowerOffWorker(PVM pVM, PPDMDEVINS pDevIns)
4498{
4499 /*
4500 * Suspend the VM first then do the saving.
4501 */
4502 int rc = VMR3Suspend(pVM->pUVM, VMSUSPENDREASON_VM);
4503 if (RT_SUCCESS(rc))
4504 {
4505 PUVM pUVM = pVM->pUVM;
4506 rc = pUVM->pVmm2UserMethods->pfnSaveState(pVM->pUVM->pVmm2UserMethods, pUVM);
4507
4508 /*
4509 * On success, power off the VM, on failure we'll leave it suspended.
4510 */
4511 if (RT_SUCCESS(rc))
4512 {
4513 rc = VMR3PowerOff(pVM->pUVM);
4514 if (RT_FAILURE(rc))
4515 LogRel(("%s/SSP: VMR3PowerOff failed: %Rrc\n", pDevIns->pReg->szName, rc));
4516 }
4517 else
4518 LogRel(("%s/SSP: pfnSaveState failed: %Rrc\n", pDevIns->pReg->szName, rc));
4519 }
4520 else
4521 LogRel(("%s/SSP: Suspend failed: %Rrc\n", pDevIns->pReg->szName, rc));
4522 return rc;
4523}
4524
4525
4526/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspendSaveAndPowerOff} */
4527static DECLCALLBACK(int) pdmR3DevHlp_VMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
4528{
4529 PDMDEV_ASSERT_DEVINS(pDevIns);
4530 PVM pVM = pDevIns->Internal.s.pVMR3;
4531 VM_ASSERT_EMT(pVM);
4532 LogFlow(("pdmR3DevHlp_VMSuspendSaveAndPowerOff: caller='%s'/%d:\n",
4533 pDevIns->pReg->szName, pDevIns->iInstance));
4534
4535 int rc;
4536 if ( pVM->pUVM->pVmm2UserMethods
4537 && pVM->pUVM->pVmm2UserMethods->pfnSaveState)
4538 {
4539 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pdmR3DevHlp_VMSuspendSaveAndPowerOffWorker, 2, pVM, pDevIns);
4540 if (RT_SUCCESS(rc))
4541 {
4542 LogRel(("%s: Suspending, Saving and Powering Off the VM\n", pDevIns->pReg->szName));
4543 rc = VINF_EM_SUSPEND;
4544 }
4545 }
4546 else
4547 rc = VERR_NOT_SUPPORTED;
4548
4549 LogFlow(("pdmR3DevHlp_VMSuspendSaveAndPowerOff: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4550 return rc;
4551}
4552
4553
4554/** @interface_method_impl{PDMDEVHLPR3,pfnVMPowerOff} */
4555static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns)
4556{
4557 int rc;
4558 PDMDEV_ASSERT_DEVINS(pDevIns);
4559 PVM pVM = pDevIns->Internal.s.pVMR3;
4560 VM_ASSERT_EMT(pVM);
4561 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n",
4562 pDevIns->pReg->szName, pDevIns->iInstance));
4563
4564 /** @todo Always take the SMP path - fewer code paths. */
4565 if (pVM->cCpus > 1)
4566 {
4567 /* We might be holding locks here and could cause a deadlock since
4568 VMR3PowerOff rendezvous with the other CPUs. */
4569 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)VMR3PowerOff, 1, pVM->pUVM);
4570 AssertRC(rc);
4571 /* Set the VCPU state to stopped here as well to make sure no
4572 inconsistency with the EM state occurs. */
4573 VMCPU_SET_STATE(VMMGetCpu(pVM), VMCPUSTATE_STOPPED);
4574 rc = VINF_EM_OFF;
4575 }
4576 else
4577 rc = VMR3PowerOff(pVM->pUVM);
4578
4579 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4580 return rc;
4581}
4582
4583
4584/** @interface_method_impl{PDMDEVHLPR3,pfnA20IsEnabled} */
4585static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
4586{
4587 PDMDEV_ASSERT_DEVINS(pDevIns);
4588 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4589
4590 bool fRc = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR3));
4591
4592 LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pReg->szName, pDevIns->iInstance, fRc));
4593 return fRc;
4594}
4595
4596
4597/** @interface_method_impl{PDMDEVHLPR3,pfnA20Set} */
4598static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable)
4599{
4600 PDMDEV_ASSERT_DEVINS(pDevIns);
4601 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4602 LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, fEnable));
4603 PGMR3PhysSetA20(VMMGetCpu(pDevIns->Internal.s.pVMR3), fEnable);
4604}
4605
4606
4607/** @interface_method_impl{PDMDEVHLPR3,pfnGetCpuId} */
4608static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
4609 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
4610{
4611 PDMDEV_ASSERT_DEVINS(pDevIns);
4612 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4613
4614 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n",
4615 pDevIns->pReg->szName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx));
4616 AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx);
4617
4618 CPUMGetGuestCpuId(VMMGetCpu(pDevIns->Internal.s.pVMR3), iLeaf, 0 /*iSubLeaf*/, -1 /*f64BitMode*/, pEax, pEbx, pEcx, pEdx);
4619
4620 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n",
4621 pDevIns->pReg->szName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx));
4622}
4623
4624
4625/** @interface_method_impl{PDMDEVHLPR3,pfnGetMainExecutionEngine} */
4626static DECLCALLBACK(uint8_t) pdmR3DevHlp_GetMainExecutionEngine(PPDMDEVINS pDevIns)
4627{
4628 PDMDEV_ASSERT_DEVINS(pDevIns);
4629 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4630 LogFlow(("pdmR3DevHlp_GetMainExecutionEngine: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4631 return pDevIns->Internal.s.pVMR3->bMainExecutionEngine;
4632}
4633
4634
4635/** @interface_method_impl{PDMDEVHLPR3,pfnVMMRegisterPatchMemory} */
4636static DECLCALLBACK(int) pdmR3DevHlp_VMMRegisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
4637{
4638 PDMDEV_ASSERT_DEVINS(pDevIns);
4639
4640 LogFlow(("pdmR3DevHlp_VMMRegisterPatchMemory: caller='%s'/%d: GCPtrPatchMem=%RGv cbPatchMem=%RU32\n",
4641 pDevIns->pReg->szName, pDevIns->iInstance, GCPtrPatchMem, cbPatchMem));
4642
4643 int rc = VMMR3RegisterPatchMemory(pDevIns->Internal.s.pVMR3, GCPtrPatchMem, cbPatchMem);
4644
4645 LogFlow(("pdmR3DevHlp_VMMRegisterPatchMemory: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4646 return rc;
4647}
4648
4649
4650/** @interface_method_impl{PDMDEVHLPR3,pfnVMMDeregisterPatchMemory} */
4651static DECLCALLBACK(int) pdmR3DevHlp_VMMDeregisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
4652{
4653 PDMDEV_ASSERT_DEVINS(pDevIns);
4654
4655 LogFlow(("pdmR3DevHlp_VMMDeregisterPatchMemory: caller='%s'/%d: GCPtrPatchMem=%RGv cbPatchMem=%RU32\n",
4656 pDevIns->pReg->szName, pDevIns->iInstance, GCPtrPatchMem, cbPatchMem));
4657
4658 int rc = VMMR3DeregisterPatchMemory(pDevIns->Internal.s.pVMR3, GCPtrPatchMem, cbPatchMem);
4659
4660 LogFlow(("pdmR3DevHlp_VMMDeregisterPatchMemory: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4661 return rc;
4662}
4663
4664
4665/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleRegister} */
4666static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleRegister(PPDMDEVINS pDevIns, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
4667 RTGCPTR GCBaseAddr, uint32_t cbModule,
4668 uint32_t cRegions, VMMDEVSHAREDREGIONDESC const *paRegions)
4669{
4670 PDMDEV_ASSERT_DEVINS(pDevIns);
4671
4672 LogFlow(("pdmR3DevHlp_SharedModuleRegister: caller='%s'/%d: enmGuestOS=%u pszModuleName=%p:{%s} pszVersion=%p:{%s} GCBaseAddr=%RGv cbModule=%#x cRegions=%u paRegions=%p\n",
4673 pDevIns->pReg->szName, pDevIns->iInstance, enmGuestOS, pszModuleName, pszModuleName, pszVersion, pszVersion, GCBaseAddr, cbModule, cRegions, paRegions));
4674
4675#ifdef VBOX_WITH_PAGE_SHARING
4676 int rc = PGMR3SharedModuleRegister(pDevIns->Internal.s.pVMR3, enmGuestOS, pszModuleName, pszVersion,
4677 GCBaseAddr, cbModule, cRegions, paRegions);
4678#else
4679 RT_NOREF(pDevIns, enmGuestOS, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions, paRegions);
4680 int rc = VERR_NOT_SUPPORTED;
4681#endif
4682
4683 LogFlow(("pdmR3DevHlp_SharedModuleRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4684 return rc;
4685}
4686
4687
4688/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleUnregister} */
4689static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleUnregister(PPDMDEVINS pDevIns, char *pszModuleName, char *pszVersion,
4690 RTGCPTR GCBaseAddr, uint32_t cbModule)
4691{
4692 PDMDEV_ASSERT_DEVINS(pDevIns);
4693
4694 LogFlow(("pdmR3DevHlp_SharedModuleUnregister: caller='%s'/%d: pszModuleName=%p:{%s} pszVersion=%p:{%s} GCBaseAddr=%RGv cbModule=%#x\n",
4695 pDevIns->pReg->szName, pDevIns->iInstance, pszModuleName, pszModuleName, pszVersion, pszVersion, GCBaseAddr, cbModule));
4696
4697#ifdef VBOX_WITH_PAGE_SHARING
4698 int rc = PGMR3SharedModuleUnregister(pDevIns->Internal.s.pVMR3, pszModuleName, pszVersion, GCBaseAddr, cbModule);
4699#else
4700 RT_NOREF(pDevIns, pszModuleName, pszVersion, GCBaseAddr, cbModule);
4701 int rc = VERR_NOT_SUPPORTED;
4702#endif
4703
4704 LogFlow(("pdmR3DevHlp_SharedModuleUnregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4705 return rc;
4706}
4707
4708
4709/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleGetPageState} */
4710static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleGetPageState(PPDMDEVINS pDevIns, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags)
4711{
4712 PDMDEV_ASSERT_DEVINS(pDevIns);
4713
4714 LogFlow(("pdmR3DevHlp_SharedModuleGetPageState: caller='%s'/%d: GCPtrPage=%RGv pfShared=%p pfPageFlags=%p\n",
4715 pDevIns->pReg->szName, pDevIns->iInstance, GCPtrPage, pfShared, pfPageFlags));
4716
4717#if defined(VBOX_WITH_PAGE_SHARING) && defined(DEBUG)
4718 int rc = PGMR3SharedModuleGetPageState(pDevIns->Internal.s.pVMR3, GCPtrPage, pfShared, pfPageFlags);
4719#else
4720 RT_NOREF(pDevIns, GCPtrPage, pfShared, pfPageFlags);
4721 int rc = VERR_NOT_IMPLEMENTED;
4722#endif
4723
4724 LogFlow(("pdmR3DevHlp_SharedModuleGetPageState: caller='%s'/%d: returns %Rrc *pfShared=%RTbool *pfPageFlags=%#RX64\n",
4725 pDevIns->pReg->szName, pDevIns->iInstance, rc, *pfShared, *pfPageFlags));
4726 return rc;
4727}
4728
4729
4730/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleCheckAll} */
4731static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleCheckAll(PPDMDEVINS pDevIns)
4732{
4733 PDMDEV_ASSERT_DEVINS(pDevIns);
4734
4735 LogFlow(("pdmR3DevHlp_SharedModuleCheckAll: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4736
4737#ifdef VBOX_WITH_PAGE_SHARING
4738 int rc = PGMR3SharedModuleCheckAll(pDevIns->Internal.s.pVMR3);
4739#else
4740 RT_NOREF(pDevIns);
4741 int rc = VERR_NOT_SUPPORTED;
4742#endif
4743
4744 LogFlow(("pdmR3DevHlp_SharedModuleCheckAll: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4745 return rc;
4746}
4747
4748
4749/** @interface_method_impl{PDMDEVHLPR3,pfnQueryLun} */
4750static DECLCALLBACK(int) pdmR3DevHlp_QueryLun(PPDMDEVINS pDevIns, const char *pszDevice,
4751 unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase)
4752{
4753 PDMDEV_ASSERT_DEVINS(pDevIns);
4754
4755 LogFlow(("pdmR3DevHlp_QueryLun: caller='%s'/%d: pszDevice=%p:{%s} iInstance=%u iLun=%u ppBase=%p\n",
4756 pDevIns->pReg->szName, pDevIns->iInstance, pszDevice, pszDevice, iInstance, iLun, ppBase));
4757
4758 int rc = PDMR3QueryLun(pDevIns->Internal.s.pVMR3->pUVM, pszDevice, iInstance, iLun, ppBase);
4759
4760 LogFlow(("pdmR3DevHlp_QueryLun: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4761 return rc;
4762}
4763
4764
4765/** @interface_method_impl{PDMDEVHLPR3,pfnGIMDeviceRegister} */
4766static DECLCALLBACK(void) pdmR3DevHlp_GIMDeviceRegister(PPDMDEVINS pDevIns, PGIMDEBUG pDbg)
4767{
4768 PDMDEV_ASSERT_DEVINS(pDevIns);
4769
4770 LogFlow(("pdmR3DevHlp_GIMDeviceRegister: caller='%s'/%d: pDbg=%p\n",
4771 pDevIns->pReg->szName, pDevIns->iInstance, pDbg));
4772
4773 GIMR3GimDeviceRegister(pDevIns->Internal.s.pVMR3, pDevIns, pDbg);
4774
4775 LogFlow(("pdmR3DevHlp_GIMDeviceRegister: caller='%s'/%d: returns\n", pDevIns->pReg->szName, pDevIns->iInstance));
4776}
4777
4778
4779/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetDebugSetup} */
4780static DECLCALLBACK(int) pdmR3DevHlp_GIMGetDebugSetup(PPDMDEVINS pDevIns, PGIMDEBUGSETUP pDbgSetup)
4781{
4782 PDMDEV_ASSERT_DEVINS(pDevIns);
4783
4784 LogFlow(("pdmR3DevHlp_GIMGetDebugSetup: caller='%s'/%d: pDbgSetup=%p\n",
4785 pDevIns->pReg->szName, pDevIns->iInstance, pDbgSetup));
4786
4787 int rc = GIMR3GetDebugSetup(pDevIns->Internal.s.pVMR3, pDbgSetup);
4788
4789 LogFlow(("pdmR3DevHlp_GIMGetDebugSetup: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4790 return rc;
4791}
4792
4793
4794/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetMmio2Regions} */
4795static DECLCALLBACK(PGIMMMIO2REGION) pdmR3DevHlp_GIMGetMmio2Regions(PPDMDEVINS pDevIns, uint32_t *pcRegions)
4796{
4797 PDMDEV_ASSERT_DEVINS(pDevIns);
4798
4799 LogFlow(("pdmR3DevHlp_GIMGetMmio2Regions: caller='%s'/%d: pcRegions=%p\n",
4800 pDevIns->pReg->szName, pDevIns->iInstance, pcRegions));
4801
4802 PGIMMMIO2REGION pRegion = GIMGetMmio2Regions(pDevIns->Internal.s.pVMR3, pcRegions);
4803
4804 LogFlow(("pdmR3DevHlp_GIMGetMmio2Regions: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pRegion));
4805 return pRegion;
4806}
4807
4808
4809/**
4810 * The device helper structure for trusted devices.
4811 */
4812const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =
4813{
4814 PDM_DEVHLPR3_VERSION,
4815 pdmR3DevHlp_IoPortCreateEx,
4816 pdmR3DevHlp_IoPortMap,
4817 pdmR3DevHlp_IoPortUnmap,
4818 pdmR3DevHlp_IoPortGetMappingAddress,
4819 pdmR3DevHlp_IoPortWrite,
4820 pdmR3DevHlp_MmioCreateEx,
4821 pdmR3DevHlp_MmioMap,
4822 pdmR3DevHlp_MmioUnmap,
4823 pdmR3DevHlp_MmioReduce,
4824 pdmR3DevHlp_MmioGetMappingAddress,
4825 pdmR3DevHlp_Mmio2Create,
4826 pdmR3DevHlp_Mmio2Destroy,
4827 pdmR3DevHlp_Mmio2Map,
4828 pdmR3DevHlp_Mmio2Unmap,
4829 pdmR3DevHlp_Mmio2Reduce,
4830 pdmR3DevHlp_Mmio2GetMappingAddress,
4831 pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap,
4832 pdmR3DevHlp_Mmio2ControlDirtyPageTracking,
4833 pdmR3DevHlp_Mmio2ChangeRegionNo,
4834 pdmR3DevHlp_MmioMapMmio2Page,
4835 pdmR3DevHlp_MmioResetRegion,
4836 pdmR3DevHlp_ROMRegister,
4837 pdmR3DevHlp_ROMProtectShadow,
4838 pdmR3DevHlp_SSMRegister,
4839 pdmR3DevHlp_SSMRegisterLegacy,
4840 SSMR3PutStruct,
4841 SSMR3PutStructEx,
4842 SSMR3PutBool,
4843 SSMR3PutU8,
4844 SSMR3PutS8,
4845 SSMR3PutU16,
4846 SSMR3PutS16,
4847 SSMR3PutU32,
4848 SSMR3PutS32,
4849 SSMR3PutU64,
4850 SSMR3PutS64,
4851 SSMR3PutU128,
4852 SSMR3PutS128,
4853 SSMR3PutUInt,
4854 SSMR3PutSInt,
4855 SSMR3PutGCUInt,
4856 SSMR3PutGCUIntReg,
4857 SSMR3PutGCPhys32,
4858 SSMR3PutGCPhys64,
4859 SSMR3PutGCPhys,
4860 SSMR3PutGCPtr,
4861 SSMR3PutGCUIntPtr,
4862 SSMR3PutRCPtr,
4863 SSMR3PutIOPort,
4864 SSMR3PutSel,
4865 SSMR3PutMem,
4866 SSMR3PutStrZ,
4867 SSMR3GetStruct,
4868 SSMR3GetStructEx,
4869 SSMR3GetBool,
4870 SSMR3GetBoolV,
4871 SSMR3GetU8,
4872 SSMR3GetU8V,
4873 SSMR3GetS8,
4874 SSMR3GetS8V,
4875 SSMR3GetU16,
4876 SSMR3GetU16V,
4877 SSMR3GetS16,
4878 SSMR3GetS16V,
4879 SSMR3GetU32,
4880 SSMR3GetU32V,
4881 SSMR3GetS32,
4882 SSMR3GetS32V,
4883 SSMR3GetU64,
4884 SSMR3GetU64V,
4885 SSMR3GetS64,
4886 SSMR3GetS64V,
4887 SSMR3GetU128,
4888 SSMR3GetU128V,
4889 SSMR3GetS128,
4890 SSMR3GetS128V,
4891 SSMR3GetGCPhys32,
4892 SSMR3GetGCPhys32V,
4893 SSMR3GetGCPhys64,
4894 SSMR3GetGCPhys64V,
4895 SSMR3GetGCPhys,
4896 SSMR3GetGCPhysV,
4897 SSMR3GetUInt,
4898 SSMR3GetSInt,
4899 SSMR3GetGCUInt,
4900 SSMR3GetGCUIntReg,
4901 SSMR3GetGCPtr,
4902 SSMR3GetGCUIntPtr,
4903 SSMR3GetRCPtr,
4904 SSMR3GetIOPort,
4905 SSMR3GetSel,
4906 SSMR3GetMem,
4907 SSMR3GetStrZ,
4908 SSMR3GetStrZEx,
4909 SSMR3Skip,
4910 SSMR3SkipToEndOfUnit,
4911 SSMR3SetLoadError,
4912 SSMR3SetLoadErrorV,
4913 SSMR3SetCfgError,
4914 SSMR3SetCfgErrorV,
4915 SSMR3HandleGetStatus,
4916 SSMR3HandleGetAfter,
4917 SSMR3HandleIsLiveSave,
4918 SSMR3HandleMaxDowntime,
4919 SSMR3HandleHostBits,
4920 SSMR3HandleRevision,
4921 SSMR3HandleVersion,
4922 SSMR3HandleHostOSAndArch,
4923 pdmR3DevHlp_TimerCreate,
4924 pdmR3DevHlp_TimerFromMicro,
4925 pdmR3DevHlp_TimerFromMilli,
4926 pdmR3DevHlp_TimerFromNano,
4927 pdmR3DevHlp_TimerGet,
4928 pdmR3DevHlp_TimerGetFreq,
4929 pdmR3DevHlp_TimerGetNano,
4930 pdmR3DevHlp_TimerIsActive,
4931 pdmR3DevHlp_TimerIsLockOwner,
4932 pdmR3DevHlp_TimerLockClock,
4933 pdmR3DevHlp_TimerLockClock2,
4934 pdmR3DevHlp_TimerSet,
4935 pdmR3DevHlp_TimerSetFrequencyHint,
4936 pdmR3DevHlp_TimerSetMicro,
4937 pdmR3DevHlp_TimerSetMillies,
4938 pdmR3DevHlp_TimerSetNano,
4939 pdmR3DevHlp_TimerSetRelative,
4940 pdmR3DevHlp_TimerStop,
4941 pdmR3DevHlp_TimerUnlockClock,
4942 pdmR3DevHlp_TimerUnlockClock2,
4943 pdmR3DevHlp_TimerSetCritSect,
4944 pdmR3DevHlp_TimerSave,
4945 pdmR3DevHlp_TimerLoad,
4946 pdmR3DevHlp_TimerDestroy,
4947 TMR3TimerSkip,
4948 pdmR3DevHlp_TMUtcNow,
4949 CFGMR3Exists,
4950 CFGMR3QueryType,
4951 CFGMR3QuerySize,
4952 CFGMR3QueryInteger,
4953 CFGMR3QueryIntegerDef,
4954 CFGMR3QueryString,
4955 CFGMR3QueryStringDef,
4956 CFGMR3QueryPassword,
4957 CFGMR3QueryPasswordDef,
4958 CFGMR3QueryBytes,
4959 CFGMR3QueryU64,
4960 CFGMR3QueryU64Def,
4961 CFGMR3QueryS64,
4962 CFGMR3QueryS64Def,
4963 CFGMR3QueryU32,
4964 CFGMR3QueryU32Def,
4965 CFGMR3QueryS32,
4966 CFGMR3QueryS32Def,
4967 CFGMR3QueryU16,
4968 CFGMR3QueryU16Def,
4969 CFGMR3QueryS16,
4970 CFGMR3QueryS16Def,
4971 CFGMR3QueryU8,
4972 CFGMR3QueryU8Def,
4973 CFGMR3QueryS8,
4974 CFGMR3QueryS8Def,
4975 CFGMR3QueryBool,
4976 CFGMR3QueryBoolDef,
4977 CFGMR3QueryPort,
4978 CFGMR3QueryPortDef,
4979 CFGMR3QueryUInt,
4980 CFGMR3QueryUIntDef,
4981 CFGMR3QuerySInt,
4982 CFGMR3QuerySIntDef,
4983 CFGMR3QueryGCPtr,
4984 CFGMR3QueryGCPtrDef,
4985 CFGMR3QueryGCPtrU,
4986 CFGMR3QueryGCPtrUDef,
4987 CFGMR3QueryGCPtrS,
4988 CFGMR3QueryGCPtrSDef,
4989 CFGMR3QueryStringAlloc,
4990 CFGMR3QueryStringAllocDef,
4991 CFGMR3GetParent,
4992 CFGMR3GetChild,
4993 CFGMR3GetChildF,
4994 CFGMR3GetChildFV,
4995 CFGMR3GetFirstChild,
4996 CFGMR3GetNextChild,
4997 CFGMR3GetName,
4998 CFGMR3GetNameLen,
4999 CFGMR3AreChildrenValid,
5000 CFGMR3GetFirstValue,
5001 CFGMR3GetNextValue,
5002 CFGMR3GetValueName,
5003 CFGMR3GetValueNameLen,
5004 CFGMR3GetValueType,
5005 CFGMR3AreValuesValid,
5006 CFGMR3ValidateConfig,
5007 pdmR3DevHlp_PhysRead,
5008 pdmR3DevHlp_PhysWrite,
5009 pdmR3DevHlp_PhysGCPhys2CCPtr,
5010 pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
5011 pdmR3DevHlp_PhysReleasePageMappingLock,
5012 pdmR3DevHlp_PhysReadGCVirt,
5013 pdmR3DevHlp_PhysWriteGCVirt,
5014 pdmR3DevHlp_PhysGCPtr2GCPhys,
5015 pdmR3DevHlp_PhysIsGCPhysNormal,
5016 pdmR3DevHlp_PhysChangeMemBalloon,
5017 pdmR3DevHlp_MMHeapAlloc,
5018 pdmR3DevHlp_MMHeapAllocZ,
5019 pdmR3DevHlp_MMHeapAPrintfV,
5020 pdmR3DevHlp_MMHeapFree,
5021 pdmR3DevHlp_MMPhysGetRamSize,
5022 pdmR3DevHlp_MMPhysGetRamSizeBelow4GB,
5023 pdmR3DevHlp_MMPhysGetRamSizeAbove4GB,
5024 pdmR3DevHlp_VMState,
5025 pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
5026 pdmR3DevHlp_VMSetErrorV,
5027 pdmR3DevHlp_VMSetRuntimeErrorV,
5028 pdmR3DevHlp_VMWaitForDeviceReady,
5029 pdmR3DevHlp_VMNotifyCpuDeviceReady,
5030 pdmR3DevHlp_VMReqCallNoWaitV,
5031 pdmR3DevHlp_VMReqPriorityCallWaitV,
5032 pdmR3DevHlp_DBGFStopV,
5033 pdmR3DevHlp_DBGFInfoRegister,
5034 pdmR3DevHlp_DBGFInfoRegisterArgv,
5035 pdmR3DevHlp_DBGFRegRegister,
5036 pdmR3DevHlp_DBGFTraceBuf,
5037 pdmR3DevHlp_DBGFReportBugCheck,
5038 pdmR3DevHlp_DBGFCoreWrite,
5039 pdmR3DevHlp_DBGFInfoLogHlp,
5040 pdmR3DevHlp_DBGFRegNmQueryU64,
5041 pdmR3DevHlp_DBGFRegPrintfV,
5042 pdmR3DevHlp_STAMRegister,
5043 pdmR3DevHlp_STAMRegisterV,
5044 pdmR3DevHlp_PCIRegister,
5045 pdmR3DevHlp_PCIRegisterMsi,
5046 pdmR3DevHlp_PCIIORegionRegister,
5047 pdmR3DevHlp_PCIInterceptConfigAccesses,
5048 pdmR3DevHlp_PCIConfigWrite,
5049 pdmR3DevHlp_PCIConfigRead,
5050 pdmR3DevHlp_PCIPhysRead,
5051 pdmR3DevHlp_PCIPhysWrite,
5052 pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
5053 pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
5054 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
5055 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
5056 pdmR3DevHlp_PCISetIrq,
5057 pdmR3DevHlp_PCISetIrqNoWait,
5058 pdmR3DevHlp_ISASetIrq,
5059 pdmR3DevHlp_ISASetIrqNoWait,
5060 pdmR3DevHlp_DriverAttach,
5061 pdmR3DevHlp_DriverDetach,
5062 pdmR3DevHlp_DriverReconfigure,
5063 pdmR3DevHlp_QueueCreate,
5064 pdmR3DevHlp_QueueAlloc,
5065 pdmR3DevHlp_QueueInsert,
5066 pdmR3DevHlp_QueueFlushIfNecessary,
5067 pdmR3DevHlp_TaskCreate,
5068 pdmR3DevHlp_TaskTrigger,
5069 pdmR3DevHlp_SUPSemEventCreate,
5070 pdmR3DevHlp_SUPSemEventClose,
5071 pdmR3DevHlp_SUPSemEventSignal,
5072 pdmR3DevHlp_SUPSemEventWaitNoResume,
5073 pdmR3DevHlp_SUPSemEventWaitNsAbsIntr,
5074 pdmR3DevHlp_SUPSemEventWaitNsRelIntr,
5075 pdmR3DevHlp_SUPSemEventGetResolution,
5076 pdmR3DevHlp_SUPSemEventMultiCreate,
5077 pdmR3DevHlp_SUPSemEventMultiClose,
5078 pdmR3DevHlp_SUPSemEventMultiSignal,
5079 pdmR3DevHlp_SUPSemEventMultiReset,
5080 pdmR3DevHlp_SUPSemEventMultiWaitNoResume,
5081 pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr,
5082 pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr,
5083 pdmR3DevHlp_SUPSemEventMultiGetResolution,
5084 pdmR3DevHlp_CritSectInit,
5085 pdmR3DevHlp_CritSectGetNop,
5086 pdmR3DevHlp_SetDeviceCritSect,
5087 pdmR3DevHlp_CritSectYield,
5088 pdmR3DevHlp_CritSectEnter,
5089 pdmR3DevHlp_CritSectEnterDebug,
5090 pdmR3DevHlp_CritSectTryEnter,
5091 pdmR3DevHlp_CritSectTryEnterDebug,
5092 pdmR3DevHlp_CritSectLeave,
5093 pdmR3DevHlp_CritSectIsOwner,
5094 pdmR3DevHlp_CritSectIsInitialized,
5095 pdmR3DevHlp_CritSectHasWaiters,
5096 pdmR3DevHlp_CritSectGetRecursion,
5097 pdmR3DevHlp_CritSectScheduleExitEvent,
5098 pdmR3DevHlp_CritSectDelete,
5099 pdmR3DevHlp_CritSectRwInit,
5100 pdmR3DevHlp_CritSectRwDelete,
5101 pdmR3DevHlp_CritSectRwEnterShared,
5102 pdmR3DevHlp_CritSectRwEnterSharedDebug,
5103 pdmR3DevHlp_CritSectRwTryEnterShared,
5104 pdmR3DevHlp_CritSectRwTryEnterSharedDebug,
5105 pdmR3DevHlp_CritSectRwLeaveShared,
5106 pdmR3DevHlp_CritSectRwEnterExcl,
5107 pdmR3DevHlp_CritSectRwEnterExclDebug,
5108 pdmR3DevHlp_CritSectRwTryEnterExcl,
5109 pdmR3DevHlp_CritSectRwTryEnterExclDebug,
5110 pdmR3DevHlp_CritSectRwLeaveExcl,
5111 pdmR3DevHlp_CritSectRwIsWriteOwner,
5112 pdmR3DevHlp_CritSectRwIsReadOwner,
5113 pdmR3DevHlp_CritSectRwGetWriteRecursion,
5114 pdmR3DevHlp_CritSectRwGetWriterReadRecursion,
5115 pdmR3DevHlp_CritSectRwGetReadCount,
5116 pdmR3DevHlp_CritSectRwIsInitialized,
5117 pdmR3DevHlp_ThreadCreate,
5118 PDMR3ThreadDestroy,
5119 PDMR3ThreadIAmSuspending,
5120 PDMR3ThreadIAmRunning,
5121 PDMR3ThreadSleep,
5122 PDMR3ThreadSuspend,
5123 PDMR3ThreadResume,
5124 pdmR3DevHlp_SetAsyncNotification,
5125 pdmR3DevHlp_AsyncNotificationCompleted,
5126 pdmR3DevHlp_RTCRegister,
5127 pdmR3DevHlp_PCIBusRegister,
5128 pdmR3DevHlp_IommuRegister,
5129 pdmR3DevHlp_PICRegister,
5130 pdmR3DevHlp_ApicRegister,
5131 pdmR3DevHlp_IoApicRegister,
5132 pdmR3DevHlp_HpetRegister,
5133 pdmR3DevHlp_PciRawRegister,
5134 pdmR3DevHlp_DMACRegister,
5135 pdmR3DevHlp_DMARegister,
5136 pdmR3DevHlp_DMAReadMemory,
5137 pdmR3DevHlp_DMAWriteMemory,
5138 pdmR3DevHlp_DMASetDREQ,
5139 pdmR3DevHlp_DMAGetChannelMode,
5140 pdmR3DevHlp_DMASchedule,
5141 pdmR3DevHlp_CMOSWrite,
5142 pdmR3DevHlp_CMOSRead,
5143 pdmR3DevHlp_AssertEMT,
5144 pdmR3DevHlp_AssertOther,
5145 pdmR3DevHlp_LdrGetRCInterfaceSymbols,
5146 pdmR3DevHlp_LdrGetR0InterfaceSymbols,
5147 pdmR3DevHlp_CallR0,
5148 pdmR3DevHlp_VMGetSuspendReason,
5149 pdmR3DevHlp_VMGetResumeReason,
5150 pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
5151 pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
5152 pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
5153 pdmR3DevHlp_CpuGetGuestMicroarch,
5154 pdmR3DevHlp_CpuGetGuestAddrWidths,
5155 pdmR3DevHlp_CpuGetGuestScalableBusFrequency,
5156 pdmR3DevHlp_STAMDeregisterByPrefix,
5157 0,
5158 0,
5159 0,
5160 0,
5161 0,
5162 0,
5163 0,
5164 0,
5165 0,
5166 pdmR3DevHlp_GetUVM,
5167 pdmR3DevHlp_GetVM,
5168 pdmR3DevHlp_GetVMCPU,
5169 pdmR3DevHlp_GetCurrentCpuId,
5170 pdmR3DevHlp_RegisterVMMDevHeap,
5171 pdmR3DevHlp_FirmwareRegister,
5172 pdmR3DevHlp_VMReset,
5173 pdmR3DevHlp_VMSuspend,
5174 pdmR3DevHlp_VMSuspendSaveAndPowerOff,
5175 pdmR3DevHlp_VMPowerOff,
5176 pdmR3DevHlp_A20IsEnabled,
5177 pdmR3DevHlp_A20Set,
5178 pdmR3DevHlp_GetCpuId,
5179 pdmR3DevHlp_GetMainExecutionEngine,
5180 pdmR3DevHlp_TMTimeVirtGet,
5181 pdmR3DevHlp_TMTimeVirtGetFreq,
5182 pdmR3DevHlp_TMTimeVirtGetNano,
5183 pdmR3DevHlp_TMCpuTicksPerSecond,
5184 pdmR3DevHlp_GetSupDrvSession,
5185 pdmR3DevHlp_QueryGenericUserObject,
5186 pdmR3DevHlp_PGMHandlerPhysicalTypeRegister,
5187 pdmR3DevHlp_PGMHandlerPhysicalRegister,
5188 pdmR3DevHlp_PGMHandlerPhysicalDeregister,
5189 pdmR3DevHlp_PGMHandlerPhysicalPageTempOff,
5190 pdmR3DevHlp_PGMHandlerPhysicalReset,
5191 pdmR3DevHlp_VMMRegisterPatchMemory,
5192 pdmR3DevHlp_VMMDeregisterPatchMemory,
5193 pdmR3DevHlp_SharedModuleRegister,
5194 pdmR3DevHlp_SharedModuleUnregister,
5195 pdmR3DevHlp_SharedModuleGetPageState,
5196 pdmR3DevHlp_SharedModuleCheckAll,
5197 pdmR3DevHlp_QueryLun,
5198 pdmR3DevHlp_GIMDeviceRegister,
5199 pdmR3DevHlp_GIMGetDebugSetup,
5200 pdmR3DevHlp_GIMGetMmio2Regions,
5201 PDM_DEVHLPR3_VERSION /* the end */
5202};
5203
5204
5205#ifdef VBOX_WITH_DBGF_TRACING
5206/**
5207 * The device helper structure for trusted devices - tracing variant.
5208 */
5209const PDMDEVHLPR3 g_pdmR3DevHlpTracing =
5210{
5211 PDM_DEVHLPR3_VERSION,
5212 pdmR3DevHlpTracing_IoPortCreateEx,
5213 pdmR3DevHlpTracing_IoPortMap,
5214 pdmR3DevHlpTracing_IoPortUnmap,
5215 pdmR3DevHlp_IoPortGetMappingAddress,
5216 pdmR3DevHlp_IoPortWrite,
5217 pdmR3DevHlpTracing_MmioCreateEx,
5218 pdmR3DevHlpTracing_MmioMap,
5219 pdmR3DevHlpTracing_MmioUnmap,
5220 pdmR3DevHlp_MmioReduce,
5221 pdmR3DevHlp_MmioGetMappingAddress,
5222 pdmR3DevHlp_Mmio2Create,
5223 pdmR3DevHlp_Mmio2Destroy,
5224 pdmR3DevHlp_Mmio2Map,
5225 pdmR3DevHlp_Mmio2Unmap,
5226 pdmR3DevHlp_Mmio2Reduce,
5227 pdmR3DevHlp_Mmio2GetMappingAddress,
5228 pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap,
5229 pdmR3DevHlp_Mmio2ControlDirtyPageTracking,
5230 pdmR3DevHlp_Mmio2ChangeRegionNo,
5231 pdmR3DevHlp_MmioMapMmio2Page,
5232 pdmR3DevHlp_MmioResetRegion,
5233 pdmR3DevHlp_ROMRegister,
5234 pdmR3DevHlp_ROMProtectShadow,
5235 pdmR3DevHlp_SSMRegister,
5236 pdmR3DevHlp_SSMRegisterLegacy,
5237 SSMR3PutStruct,
5238 SSMR3PutStructEx,
5239 SSMR3PutBool,
5240 SSMR3PutU8,
5241 SSMR3PutS8,
5242 SSMR3PutU16,
5243 SSMR3PutS16,
5244 SSMR3PutU32,
5245 SSMR3PutS32,
5246 SSMR3PutU64,
5247 SSMR3PutS64,
5248 SSMR3PutU128,
5249 SSMR3PutS128,
5250 SSMR3PutUInt,
5251 SSMR3PutSInt,
5252 SSMR3PutGCUInt,
5253 SSMR3PutGCUIntReg,
5254 SSMR3PutGCPhys32,
5255 SSMR3PutGCPhys64,
5256 SSMR3PutGCPhys,
5257 SSMR3PutGCPtr,
5258 SSMR3PutGCUIntPtr,
5259 SSMR3PutRCPtr,
5260 SSMR3PutIOPort,
5261 SSMR3PutSel,
5262 SSMR3PutMem,
5263 SSMR3PutStrZ,
5264 SSMR3GetStruct,
5265 SSMR3GetStructEx,
5266 SSMR3GetBool,
5267 SSMR3GetBoolV,
5268 SSMR3GetU8,
5269 SSMR3GetU8V,
5270 SSMR3GetS8,
5271 SSMR3GetS8V,
5272 SSMR3GetU16,
5273 SSMR3GetU16V,
5274 SSMR3GetS16,
5275 SSMR3GetS16V,
5276 SSMR3GetU32,
5277 SSMR3GetU32V,
5278 SSMR3GetS32,
5279 SSMR3GetS32V,
5280 SSMR3GetU64,
5281 SSMR3GetU64V,
5282 SSMR3GetS64,
5283 SSMR3GetS64V,
5284 SSMR3GetU128,
5285 SSMR3GetU128V,
5286 SSMR3GetS128,
5287 SSMR3GetS128V,
5288 SSMR3GetGCPhys32,
5289 SSMR3GetGCPhys32V,
5290 SSMR3GetGCPhys64,
5291 SSMR3GetGCPhys64V,
5292 SSMR3GetGCPhys,
5293 SSMR3GetGCPhysV,
5294 SSMR3GetUInt,
5295 SSMR3GetSInt,
5296 SSMR3GetGCUInt,
5297 SSMR3GetGCUIntReg,
5298 SSMR3GetGCPtr,
5299 SSMR3GetGCUIntPtr,
5300 SSMR3GetRCPtr,
5301 SSMR3GetIOPort,
5302 SSMR3GetSel,
5303 SSMR3GetMem,
5304 SSMR3GetStrZ,
5305 SSMR3GetStrZEx,
5306 SSMR3Skip,
5307 SSMR3SkipToEndOfUnit,
5308 SSMR3SetLoadError,
5309 SSMR3SetLoadErrorV,
5310 SSMR3SetCfgError,
5311 SSMR3SetCfgErrorV,
5312 SSMR3HandleGetStatus,
5313 SSMR3HandleGetAfter,
5314 SSMR3HandleIsLiveSave,
5315 SSMR3HandleMaxDowntime,
5316 SSMR3HandleHostBits,
5317 SSMR3HandleRevision,
5318 SSMR3HandleVersion,
5319 SSMR3HandleHostOSAndArch,
5320 pdmR3DevHlp_TimerCreate,
5321 pdmR3DevHlp_TimerFromMicro,
5322 pdmR3DevHlp_TimerFromMilli,
5323 pdmR3DevHlp_TimerFromNano,
5324 pdmR3DevHlp_TimerGet,
5325 pdmR3DevHlp_TimerGetFreq,
5326 pdmR3DevHlp_TimerGetNano,
5327 pdmR3DevHlp_TimerIsActive,
5328 pdmR3DevHlp_TimerIsLockOwner,
5329 pdmR3DevHlp_TimerLockClock,
5330 pdmR3DevHlp_TimerLockClock2,
5331 pdmR3DevHlp_TimerSet,
5332 pdmR3DevHlp_TimerSetFrequencyHint,
5333 pdmR3DevHlp_TimerSetMicro,
5334 pdmR3DevHlp_TimerSetMillies,
5335 pdmR3DevHlp_TimerSetNano,
5336 pdmR3DevHlp_TimerSetRelative,
5337 pdmR3DevHlp_TimerStop,
5338 pdmR3DevHlp_TimerUnlockClock,
5339 pdmR3DevHlp_TimerUnlockClock2,
5340 pdmR3DevHlp_TimerSetCritSect,
5341 pdmR3DevHlp_TimerSave,
5342 pdmR3DevHlp_TimerLoad,
5343 pdmR3DevHlp_TimerDestroy,
5344 TMR3TimerSkip,
5345 pdmR3DevHlp_TMUtcNow,
5346 CFGMR3Exists,
5347 CFGMR3QueryType,
5348 CFGMR3QuerySize,
5349 CFGMR3QueryInteger,
5350 CFGMR3QueryIntegerDef,
5351 CFGMR3QueryString,
5352 CFGMR3QueryStringDef,
5353 CFGMR3QueryPassword,
5354 CFGMR3QueryPasswordDef,
5355 CFGMR3QueryBytes,
5356 CFGMR3QueryU64,
5357 CFGMR3QueryU64Def,
5358 CFGMR3QueryS64,
5359 CFGMR3QueryS64Def,
5360 CFGMR3QueryU32,
5361 CFGMR3QueryU32Def,
5362 CFGMR3QueryS32,
5363 CFGMR3QueryS32Def,
5364 CFGMR3QueryU16,
5365 CFGMR3QueryU16Def,
5366 CFGMR3QueryS16,
5367 CFGMR3QueryS16Def,
5368 CFGMR3QueryU8,
5369 CFGMR3QueryU8Def,
5370 CFGMR3QueryS8,
5371 CFGMR3QueryS8Def,
5372 CFGMR3QueryBool,
5373 CFGMR3QueryBoolDef,
5374 CFGMR3QueryPort,
5375 CFGMR3QueryPortDef,
5376 CFGMR3QueryUInt,
5377 CFGMR3QueryUIntDef,
5378 CFGMR3QuerySInt,
5379 CFGMR3QuerySIntDef,
5380 CFGMR3QueryGCPtr,
5381 CFGMR3QueryGCPtrDef,
5382 CFGMR3QueryGCPtrU,
5383 CFGMR3QueryGCPtrUDef,
5384 CFGMR3QueryGCPtrS,
5385 CFGMR3QueryGCPtrSDef,
5386 CFGMR3QueryStringAlloc,
5387 CFGMR3QueryStringAllocDef,
5388 CFGMR3GetParent,
5389 CFGMR3GetChild,
5390 CFGMR3GetChildF,
5391 CFGMR3GetChildFV,
5392 CFGMR3GetFirstChild,
5393 CFGMR3GetNextChild,
5394 CFGMR3GetName,
5395 CFGMR3GetNameLen,
5396 CFGMR3AreChildrenValid,
5397 CFGMR3GetFirstValue,
5398 CFGMR3GetNextValue,
5399 CFGMR3GetValueName,
5400 CFGMR3GetValueNameLen,
5401 CFGMR3GetValueType,
5402 CFGMR3AreValuesValid,
5403 CFGMR3ValidateConfig,
5404 pdmR3DevHlpTracing_PhysRead,
5405 pdmR3DevHlpTracing_PhysWrite,
5406 pdmR3DevHlp_PhysGCPhys2CCPtr,
5407 pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
5408 pdmR3DevHlp_PhysReleasePageMappingLock,
5409 pdmR3DevHlp_PhysReadGCVirt,
5410 pdmR3DevHlp_PhysWriteGCVirt,
5411 pdmR3DevHlp_PhysGCPtr2GCPhys,
5412 pdmR3DevHlp_PhysIsGCPhysNormal,
5413 pdmR3DevHlp_PhysChangeMemBalloon,
5414 pdmR3DevHlp_MMHeapAlloc,
5415 pdmR3DevHlp_MMHeapAllocZ,
5416 pdmR3DevHlp_MMHeapAPrintfV,
5417 pdmR3DevHlp_MMHeapFree,
5418 pdmR3DevHlp_MMPhysGetRamSize,
5419 pdmR3DevHlp_MMPhysGetRamSizeBelow4GB,
5420 pdmR3DevHlp_MMPhysGetRamSizeAbove4GB,
5421 pdmR3DevHlp_VMState,
5422 pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
5423 pdmR3DevHlp_VMSetErrorV,
5424 pdmR3DevHlp_VMSetRuntimeErrorV,
5425 pdmR3DevHlp_VMWaitForDeviceReady,
5426 pdmR3DevHlp_VMNotifyCpuDeviceReady,
5427 pdmR3DevHlp_VMReqCallNoWaitV,
5428 pdmR3DevHlp_VMReqPriorityCallWaitV,
5429 pdmR3DevHlp_DBGFStopV,
5430 pdmR3DevHlp_DBGFInfoRegister,
5431 pdmR3DevHlp_DBGFInfoRegisterArgv,
5432 pdmR3DevHlp_DBGFRegRegister,
5433 pdmR3DevHlp_DBGFTraceBuf,
5434 pdmR3DevHlp_DBGFReportBugCheck,
5435 pdmR3DevHlp_DBGFCoreWrite,
5436 pdmR3DevHlp_DBGFInfoLogHlp,
5437 pdmR3DevHlp_DBGFRegNmQueryU64,
5438 pdmR3DevHlp_DBGFRegPrintfV,
5439 pdmR3DevHlp_STAMRegister,
5440 pdmR3DevHlp_STAMRegisterV,
5441 pdmR3DevHlp_PCIRegister,
5442 pdmR3DevHlp_PCIRegisterMsi,
5443 pdmR3DevHlp_PCIIORegionRegister,
5444 pdmR3DevHlp_PCIInterceptConfigAccesses,
5445 pdmR3DevHlp_PCIConfigWrite,
5446 pdmR3DevHlp_PCIConfigRead,
5447 pdmR3DevHlpTracing_PCIPhysRead,
5448 pdmR3DevHlpTracing_PCIPhysWrite,
5449 pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
5450 pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
5451 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
5452 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
5453 pdmR3DevHlpTracing_PCISetIrq,
5454 pdmR3DevHlpTracing_PCISetIrqNoWait,
5455 pdmR3DevHlpTracing_ISASetIrq,
5456 pdmR3DevHlpTracing_ISASetIrqNoWait,
5457 pdmR3DevHlp_DriverAttach,
5458 pdmR3DevHlp_DriverDetach,
5459 pdmR3DevHlp_DriverReconfigure,
5460 pdmR3DevHlp_QueueCreate,
5461 pdmR3DevHlp_QueueAlloc,
5462 pdmR3DevHlp_QueueInsert,
5463 pdmR3DevHlp_QueueFlushIfNecessary,
5464 pdmR3DevHlp_TaskCreate,
5465 pdmR3DevHlp_TaskTrigger,
5466 pdmR3DevHlp_SUPSemEventCreate,
5467 pdmR3DevHlp_SUPSemEventClose,
5468 pdmR3DevHlp_SUPSemEventSignal,
5469 pdmR3DevHlp_SUPSemEventWaitNoResume,
5470 pdmR3DevHlp_SUPSemEventWaitNsAbsIntr,
5471 pdmR3DevHlp_SUPSemEventWaitNsRelIntr,
5472 pdmR3DevHlp_SUPSemEventGetResolution,
5473 pdmR3DevHlp_SUPSemEventMultiCreate,
5474 pdmR3DevHlp_SUPSemEventMultiClose,
5475 pdmR3DevHlp_SUPSemEventMultiSignal,
5476 pdmR3DevHlp_SUPSemEventMultiReset,
5477 pdmR3DevHlp_SUPSemEventMultiWaitNoResume,
5478 pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr,
5479 pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr,
5480 pdmR3DevHlp_SUPSemEventMultiGetResolution,
5481 pdmR3DevHlp_CritSectInit,
5482 pdmR3DevHlp_CritSectGetNop,
5483 pdmR3DevHlp_SetDeviceCritSect,
5484 pdmR3DevHlp_CritSectYield,
5485 pdmR3DevHlp_CritSectEnter,
5486 pdmR3DevHlp_CritSectEnterDebug,
5487 pdmR3DevHlp_CritSectTryEnter,
5488 pdmR3DevHlp_CritSectTryEnterDebug,
5489 pdmR3DevHlp_CritSectLeave,
5490 pdmR3DevHlp_CritSectIsOwner,
5491 pdmR3DevHlp_CritSectIsInitialized,
5492 pdmR3DevHlp_CritSectHasWaiters,
5493 pdmR3DevHlp_CritSectGetRecursion,
5494 pdmR3DevHlp_CritSectScheduleExitEvent,
5495 pdmR3DevHlp_CritSectDelete,
5496 pdmR3DevHlp_CritSectRwInit,
5497 pdmR3DevHlp_CritSectRwDelete,
5498 pdmR3DevHlp_CritSectRwEnterShared,
5499 pdmR3DevHlp_CritSectRwEnterSharedDebug,
5500 pdmR3DevHlp_CritSectRwTryEnterShared,
5501 pdmR3DevHlp_CritSectRwTryEnterSharedDebug,
5502 pdmR3DevHlp_CritSectRwLeaveShared,
5503 pdmR3DevHlp_CritSectRwEnterExcl,
5504 pdmR3DevHlp_CritSectRwEnterExclDebug,
5505 pdmR3DevHlp_CritSectRwTryEnterExcl,
5506 pdmR3DevHlp_CritSectRwTryEnterExclDebug,
5507 pdmR3DevHlp_CritSectRwLeaveExcl,
5508 pdmR3DevHlp_CritSectRwIsWriteOwner,
5509 pdmR3DevHlp_CritSectRwIsReadOwner,
5510 pdmR3DevHlp_CritSectRwGetWriteRecursion,
5511 pdmR3DevHlp_CritSectRwGetWriterReadRecursion,
5512 pdmR3DevHlp_CritSectRwGetReadCount,
5513 pdmR3DevHlp_CritSectRwIsInitialized,
5514 pdmR3DevHlp_ThreadCreate,
5515 PDMR3ThreadDestroy,
5516 PDMR3ThreadIAmSuspending,
5517 PDMR3ThreadIAmRunning,
5518 PDMR3ThreadSleep,
5519 PDMR3ThreadSuspend,
5520 PDMR3ThreadResume,
5521 pdmR3DevHlp_SetAsyncNotification,
5522 pdmR3DevHlp_AsyncNotificationCompleted,
5523 pdmR3DevHlp_RTCRegister,
5524 pdmR3DevHlp_PCIBusRegister,
5525 pdmR3DevHlp_IommuRegister,
5526 pdmR3DevHlp_PICRegister,
5527 pdmR3DevHlp_ApicRegister,
5528 pdmR3DevHlp_IoApicRegister,
5529 pdmR3DevHlp_HpetRegister,
5530 pdmR3DevHlp_PciRawRegister,
5531 pdmR3DevHlp_DMACRegister,
5532 pdmR3DevHlp_DMARegister,
5533 pdmR3DevHlp_DMAReadMemory,
5534 pdmR3DevHlp_DMAWriteMemory,
5535 pdmR3DevHlp_DMASetDREQ,
5536 pdmR3DevHlp_DMAGetChannelMode,
5537 pdmR3DevHlp_DMASchedule,
5538 pdmR3DevHlp_CMOSWrite,
5539 pdmR3DevHlp_CMOSRead,
5540 pdmR3DevHlp_AssertEMT,
5541 pdmR3DevHlp_AssertOther,
5542 pdmR3DevHlp_LdrGetRCInterfaceSymbols,
5543 pdmR3DevHlp_LdrGetR0InterfaceSymbols,
5544 pdmR3DevHlp_CallR0,
5545 pdmR3DevHlp_VMGetSuspendReason,
5546 pdmR3DevHlp_VMGetResumeReason,
5547 pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
5548 pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
5549 pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
5550 pdmR3DevHlp_CpuGetGuestMicroarch,
5551 pdmR3DevHlp_CpuGetGuestAddrWidths,
5552 pdmR3DevHlp_CpuGetGuestScalableBusFrequency,
5553 pdmR3DevHlp_STAMDeregisterByPrefix,
5554 0,
5555 0,
5556 0,
5557 0,
5558 0,
5559 0,
5560 0,
5561 0,
5562 0,
5563 pdmR3DevHlp_GetUVM,
5564 pdmR3DevHlp_GetVM,
5565 pdmR3DevHlp_GetVMCPU,
5566 pdmR3DevHlp_GetCurrentCpuId,
5567 pdmR3DevHlp_RegisterVMMDevHeap,
5568 pdmR3DevHlp_FirmwareRegister,
5569 pdmR3DevHlp_VMReset,
5570 pdmR3DevHlp_VMSuspend,
5571 pdmR3DevHlp_VMSuspendSaveAndPowerOff,
5572 pdmR3DevHlp_VMPowerOff,
5573 pdmR3DevHlp_A20IsEnabled,
5574 pdmR3DevHlp_A20Set,
5575 pdmR3DevHlp_GetCpuId,
5576 pdmR3DevHlp_GetMainExecutionEngine,
5577 pdmR3DevHlp_TMTimeVirtGet,
5578 pdmR3DevHlp_TMTimeVirtGetFreq,
5579 pdmR3DevHlp_TMTimeVirtGetNano,
5580 pdmR3DevHlp_TMCpuTicksPerSecond,
5581 pdmR3DevHlp_GetSupDrvSession,
5582 pdmR3DevHlp_QueryGenericUserObject,
5583 pdmR3DevHlp_PGMHandlerPhysicalTypeRegister,
5584 pdmR3DevHlp_PGMHandlerPhysicalRegister,
5585 pdmR3DevHlp_PGMHandlerPhysicalDeregister,
5586 pdmR3DevHlp_PGMHandlerPhysicalPageTempOff,
5587 pdmR3DevHlp_PGMHandlerPhysicalReset,
5588 pdmR3DevHlp_VMMRegisterPatchMemory,
5589 pdmR3DevHlp_VMMDeregisterPatchMemory,
5590 pdmR3DevHlp_SharedModuleRegister,
5591 pdmR3DevHlp_SharedModuleUnregister,
5592 pdmR3DevHlp_SharedModuleGetPageState,
5593 pdmR3DevHlp_SharedModuleCheckAll,
5594 pdmR3DevHlp_QueryLun,
5595 pdmR3DevHlp_GIMDeviceRegister,
5596 pdmR3DevHlp_GIMGetDebugSetup,
5597 pdmR3DevHlp_GIMGetMmio2Regions,
5598 PDM_DEVHLPR3_VERSION /* the end */
5599};
5600#endif /* VBOX_WITH_DBGF_TRACING */
5601
5602
5603
5604
5605/** @interface_method_impl{PDMDEVHLPR3,pfnGetUVM} */
5606static DECLCALLBACK(PUVM) pdmR3DevHlp_Untrusted_GetUVM(PPDMDEVINS pDevIns)
5607{
5608 PDMDEV_ASSERT_DEVINS(pDevIns);
5609 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5610 return NULL;
5611}
5612
5613
5614/** @interface_method_impl{PDMDEVHLPR3,pfnGetVM} */
5615static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns)
5616{
5617 PDMDEV_ASSERT_DEVINS(pDevIns);
5618 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5619 return NULL;
5620}
5621
5622
5623/** @interface_method_impl{PDMDEVHLPR3,pfnGetVMCPU} */
5624static DECLCALLBACK(PVMCPU) pdmR3DevHlp_Untrusted_GetVMCPU(PPDMDEVINS pDevIns)
5625{
5626 PDMDEV_ASSERT_DEVINS(pDevIns);
5627 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5628 return NULL;
5629}
5630
5631
5632/** @interface_method_impl{PDMDEVHLPR3,pfnGetCurrentCpuId} */
5633static DECLCALLBACK(VMCPUID) pdmR3DevHlp_Untrusted_GetCurrentCpuId(PPDMDEVINS pDevIns)
5634{
5635 PDMDEV_ASSERT_DEVINS(pDevIns);
5636 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5637 return NIL_VMCPUID;
5638}
5639
5640
5641/** @interface_method_impl{PDMDEVHLPR3,pfnRegisterVMMDevHeap} */
5642static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys,
5643 RTR3PTR pvHeap, unsigned cbHeap)
5644{
5645 PDMDEV_ASSERT_DEVINS(pDevIns);
5646 NOREF(GCPhys); NOREF(pvHeap); NOREF(cbHeap);
5647 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5648 return VERR_ACCESS_DENIED;
5649}
5650
5651
5652/** @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister} */
5653static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
5654{
5655 PDMDEV_ASSERT_DEVINS(pDevIns);
5656 NOREF(pFwReg); NOREF(ppFwHlp);
5657 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5658 return VERR_ACCESS_DENIED;
5659}
5660
5661
5662/** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
5663static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
5664{
5665 PDMDEV_ASSERT_DEVINS(pDevIns); NOREF(fFlags);
5666 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5667 return VERR_ACCESS_DENIED;
5668}
5669
5670
5671/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspend} */
5672static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns)
5673{
5674 PDMDEV_ASSERT_DEVINS(pDevIns);
5675 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5676 return VERR_ACCESS_DENIED;
5677}
5678
5679
5680/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspendSaveAndPowerOff} */
5681static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
5682{
5683 PDMDEV_ASSERT_DEVINS(pDevIns);
5684 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5685 return VERR_ACCESS_DENIED;
5686}
5687
5688
5689/** @interface_method_impl{PDMDEVHLPR3,pfnVMPowerOff} */
5690static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns)
5691{
5692 PDMDEV_ASSERT_DEVINS(pDevIns);
5693 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5694 return VERR_ACCESS_DENIED;
5695}
5696
5697
5698/** @interface_method_impl{PDMDEVHLPR3,pfnA20IsEnabled} */
5699static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns)
5700{
5701 PDMDEV_ASSERT_DEVINS(pDevIns);
5702 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5703 return false;
5704}
5705
5706
5707/** @interface_method_impl{PDMDEVHLPR3,pfnA20Set} */
5708static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable)
5709{
5710 PDMDEV_ASSERT_DEVINS(pDevIns);
5711 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5712 NOREF(fEnable);
5713}
5714
5715
5716/** @interface_method_impl{PDMDEVHLPR3,pfnGetCpuId} */
5717static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
5718 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
5719{
5720 PDMDEV_ASSERT_DEVINS(pDevIns);
5721 NOREF(iLeaf); NOREF(pEax); NOREF(pEbx); NOREF(pEcx); NOREF(pEdx);
5722 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5723}
5724
5725
5726/** @interface_method_impl{PDMDEVHLPR3,pfnGetMainExecutionEngine} */
5727static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_GetMainExecutionEngine(PPDMDEVINS pDevIns)
5728{
5729 PDMDEV_ASSERT_DEVINS(pDevIns);
5730 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5731 return VM_EXEC_ENGINE_NOT_SET;
5732}
5733
5734
5735/** @interface_method_impl{PDMDEVHLPR3,pfnGetSupDrvSession} */
5736static DECLCALLBACK(PSUPDRVSESSION) pdmR3DevHlp_Untrusted_GetSupDrvSession(PPDMDEVINS pDevIns)
5737{
5738 PDMDEV_ASSERT_DEVINS(pDevIns);
5739 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5740 return (PSUPDRVSESSION)0;
5741}
5742
5743
5744/** @interface_method_impl{PDMDEVHLPR3,pfnQueryGenericUserObject} */
5745static DECLCALLBACK(void *) pdmR3DevHlp_Untrusted_QueryGenericUserObject(PPDMDEVINS pDevIns, PCRTUUID pUuid)
5746{
5747 PDMDEV_ASSERT_DEVINS(pDevIns);
5748 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d %RTuuid\n",
5749 pDevIns->pReg->szName, pDevIns->iInstance, pUuid));
5750 return NULL;
5751}
5752
5753
5754/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalTypeRegister} */
5755static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalTypeRegister(PPDMDEVINS pDevIns, PGMPHYSHANDLERKIND enmKind,
5756 PFNPGMPHYSHANDLER pfnHandler,
5757 const char *pszDesc, PPGMPHYSHANDLERTYPE phType)
5758{
5759 PDMDEV_ASSERT_DEVINS(pDevIns);
5760 RT_NOREF(pDevIns, enmKind, pfnHandler, pszDesc);
5761 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5762 pDevIns->pReg->szName, pDevIns->iInstance));
5763 *phType = NIL_PGMPHYSHANDLERTYPE;
5764 return VERR_ACCESS_DENIED;
5765}
5766
5767
5768/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalRegister} */
5769static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
5770 PGMPHYSHANDLERTYPE hType, R3PTRTYPE(const char *) pszDesc)
5771{
5772 PDMDEV_ASSERT_DEVINS(pDevIns);
5773 RT_NOREF(GCPhys, GCPhysLast, hType, pszDesc);
5774 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5775 return VERR_ACCESS_DENIED;
5776}
5777
5778
5779/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalDeregister} */
5780static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalDeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
5781{
5782 PDMDEV_ASSERT_DEVINS(pDevIns);
5783 RT_NOREF(GCPhys);
5784 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5785 pDevIns->pReg->szName, pDevIns->iInstance));
5786 return VERR_ACCESS_DENIED;
5787}
5788
5789
5790/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalPageTempOff} */
5791static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalPageTempOff(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage)
5792{
5793 PDMDEV_ASSERT_DEVINS(pDevIns);
5794 RT_NOREF(GCPhys, GCPhysPage);
5795 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5796 pDevIns->pReg->szName, pDevIns->iInstance));
5797 return VERR_ACCESS_DENIED;
5798}
5799
5800
5801/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalReset} */
5802static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalReset(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
5803{
5804 PDMDEV_ASSERT_DEVINS(pDevIns);
5805 RT_NOREF(GCPhys);
5806 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5807 pDevIns->pReg->szName, pDevIns->iInstance));
5808 return VERR_ACCESS_DENIED;
5809}
5810
5811
5812/** @interface_method_impl{PDMDEVHLPR3,pfnVMMRegisterPatchMemory} */
5813static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMMRegisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
5814{
5815 PDMDEV_ASSERT_DEVINS(pDevIns);
5816 RT_NOREF(GCPtrPatchMem, cbPatchMem);
5817 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5818 pDevIns->pReg->szName, pDevIns->iInstance));
5819 return VERR_ACCESS_DENIED;
5820}
5821
5822
5823/** @interface_method_impl{PDMDEVHLPR3,pfnVMMDeregisterPatchMemory} */
5824static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMMDeregisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
5825{
5826 PDMDEV_ASSERT_DEVINS(pDevIns);
5827 RT_NOREF(GCPtrPatchMem, cbPatchMem);
5828 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5829 pDevIns->pReg->szName, pDevIns->iInstance));
5830 return VERR_ACCESS_DENIED;
5831}
5832
5833
5834/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleRegister} */
5835static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleRegister(PPDMDEVINS pDevIns, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
5836 RTGCPTR GCBaseAddr, uint32_t cbModule,
5837 uint32_t cRegions, VMMDEVSHAREDREGIONDESC const *paRegions)
5838{
5839 PDMDEV_ASSERT_DEVINS(pDevIns);
5840 RT_NOREF(enmGuestOS, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions, paRegions);
5841 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5842 pDevIns->pReg->szName, pDevIns->iInstance));
5843 return VERR_ACCESS_DENIED;
5844}
5845
5846
5847/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleUnregister} */
5848static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleUnregister(PPDMDEVINS pDevIns, char *pszModuleName, char *pszVersion,
5849 RTGCPTR GCBaseAddr, uint32_t cbModule)
5850{
5851 PDMDEV_ASSERT_DEVINS(pDevIns);
5852 RT_NOREF(pszModuleName, pszVersion, GCBaseAddr, cbModule);
5853 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5854 pDevIns->pReg->szName, pDevIns->iInstance));
5855 return VERR_ACCESS_DENIED;
5856}
5857
5858
5859/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleGetPageState} */
5860static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleGetPageState(PPDMDEVINS pDevIns, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags)
5861{
5862 PDMDEV_ASSERT_DEVINS(pDevIns);
5863 RT_NOREF(GCPtrPage, pfShared, pfPageFlags);
5864 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5865 pDevIns->pReg->szName, pDevIns->iInstance));
5866 return VERR_ACCESS_DENIED;
5867}
5868
5869
5870/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleCheckAll} */
5871static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleCheckAll(PPDMDEVINS pDevIns)
5872{
5873 PDMDEV_ASSERT_DEVINS(pDevIns);
5874 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5875 pDevIns->pReg->szName, pDevIns->iInstance));
5876 return VERR_ACCESS_DENIED;
5877}
5878
5879
5880/** @interface_method_impl{PDMDEVHLPR3,pfnQueryLun} */
5881static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_QueryLun(PPDMDEVINS pDevIns, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase)
5882{
5883 PDMDEV_ASSERT_DEVINS(pDevIns);
5884 RT_NOREF(pszDevice, iInstance, iLun, ppBase);
5885 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5886 pDevIns->pReg->szName, pDevIns->iInstance));
5887 return VERR_ACCESS_DENIED;
5888}
5889
5890
5891/** @interface_method_impl{PDMDEVHLPR3,pfnGIMDeviceRegister} */
5892static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GIMDeviceRegister(PPDMDEVINS pDevIns, PGIMDEBUG pDbg)
5893{
5894 PDMDEV_ASSERT_DEVINS(pDevIns);
5895 RT_NOREF(pDbg);
5896 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5897 pDevIns->pReg->szName, pDevIns->iInstance));
5898}
5899
5900
5901/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetDebugSetup} */
5902static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_GIMGetDebugSetup(PPDMDEVINS pDevIns, PGIMDEBUGSETUP pDbgSetup)
5903{
5904 PDMDEV_ASSERT_DEVINS(pDevIns);
5905 RT_NOREF(pDbgSetup);
5906 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5907 pDevIns->pReg->szName, pDevIns->iInstance));
5908 return VERR_ACCESS_DENIED;
5909}
5910
5911
5912/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetMmio2Regions} */
5913static DECLCALLBACK(PGIMMMIO2REGION) pdmR3DevHlp_Untrusted_GIMGetMmio2Regions(PPDMDEVINS pDevIns, uint32_t *pcRegions)
5914{
5915 PDMDEV_ASSERT_DEVINS(pDevIns);
5916 RT_NOREF(pcRegions);
5917 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5918 pDevIns->pReg->szName, pDevIns->iInstance));
5919 return NULL;
5920}
5921
5922
5923/**
5924 * The device helper structure for non-trusted devices.
5925 */
5926const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =
5927{
5928 PDM_DEVHLPR3_VERSION,
5929 pdmR3DevHlp_IoPortCreateEx,
5930 pdmR3DevHlp_IoPortMap,
5931 pdmR3DevHlp_IoPortUnmap,
5932 pdmR3DevHlp_IoPortGetMappingAddress,
5933 pdmR3DevHlp_IoPortWrite,
5934 pdmR3DevHlp_MmioCreateEx,
5935 pdmR3DevHlp_MmioMap,
5936 pdmR3DevHlp_MmioUnmap,
5937 pdmR3DevHlp_MmioReduce,
5938 pdmR3DevHlp_MmioGetMappingAddress,
5939 pdmR3DevHlp_Mmio2Create,
5940 pdmR3DevHlp_Mmio2Destroy,
5941 pdmR3DevHlp_Mmio2Map,
5942 pdmR3DevHlp_Mmio2Unmap,
5943 pdmR3DevHlp_Mmio2Reduce,
5944 pdmR3DevHlp_Mmio2GetMappingAddress,
5945 pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap,
5946 pdmR3DevHlp_Mmio2ControlDirtyPageTracking,
5947 pdmR3DevHlp_Mmio2ChangeRegionNo,
5948 pdmR3DevHlp_MmioMapMmio2Page,
5949 pdmR3DevHlp_MmioResetRegion,
5950 pdmR3DevHlp_ROMRegister,
5951 pdmR3DevHlp_ROMProtectShadow,
5952 pdmR3DevHlp_SSMRegister,
5953 pdmR3DevHlp_SSMRegisterLegacy,
5954 SSMR3PutStruct,
5955 SSMR3PutStructEx,
5956 SSMR3PutBool,
5957 SSMR3PutU8,
5958 SSMR3PutS8,
5959 SSMR3PutU16,
5960 SSMR3PutS16,
5961 SSMR3PutU32,
5962 SSMR3PutS32,
5963 SSMR3PutU64,
5964 SSMR3PutS64,
5965 SSMR3PutU128,
5966 SSMR3PutS128,
5967 SSMR3PutUInt,
5968 SSMR3PutSInt,
5969 SSMR3PutGCUInt,
5970 SSMR3PutGCUIntReg,
5971 SSMR3PutGCPhys32,
5972 SSMR3PutGCPhys64,
5973 SSMR3PutGCPhys,
5974 SSMR3PutGCPtr,
5975 SSMR3PutGCUIntPtr,
5976 SSMR3PutRCPtr,
5977 SSMR3PutIOPort,
5978 SSMR3PutSel,
5979 SSMR3PutMem,
5980 SSMR3PutStrZ,
5981 SSMR3GetStruct,
5982 SSMR3GetStructEx,
5983 SSMR3GetBool,
5984 SSMR3GetBoolV,
5985 SSMR3GetU8,
5986 SSMR3GetU8V,
5987 SSMR3GetS8,
5988 SSMR3GetS8V,
5989 SSMR3GetU16,
5990 SSMR3GetU16V,
5991 SSMR3GetS16,
5992 SSMR3GetS16V,
5993 SSMR3GetU32,
5994 SSMR3GetU32V,
5995 SSMR3GetS32,
5996 SSMR3GetS32V,
5997 SSMR3GetU64,
5998 SSMR3GetU64V,
5999 SSMR3GetS64,
6000 SSMR3GetS64V,
6001 SSMR3GetU128,
6002 SSMR3GetU128V,
6003 SSMR3GetS128,
6004 SSMR3GetS128V,
6005 SSMR3GetGCPhys32,
6006 SSMR3GetGCPhys32V,
6007 SSMR3GetGCPhys64,
6008 SSMR3GetGCPhys64V,
6009 SSMR3GetGCPhys,
6010 SSMR3GetGCPhysV,
6011 SSMR3GetUInt,
6012 SSMR3GetSInt,
6013 SSMR3GetGCUInt,
6014 SSMR3GetGCUIntReg,
6015 SSMR3GetGCPtr,
6016 SSMR3GetGCUIntPtr,
6017 SSMR3GetRCPtr,
6018 SSMR3GetIOPort,
6019 SSMR3GetSel,
6020 SSMR3GetMem,
6021 SSMR3GetStrZ,
6022 SSMR3GetStrZEx,
6023 SSMR3Skip,
6024 SSMR3SkipToEndOfUnit,
6025 SSMR3SetLoadError,
6026 SSMR3SetLoadErrorV,
6027 SSMR3SetCfgError,
6028 SSMR3SetCfgErrorV,
6029 SSMR3HandleGetStatus,
6030 SSMR3HandleGetAfter,
6031 SSMR3HandleIsLiveSave,
6032 SSMR3HandleMaxDowntime,
6033 SSMR3HandleHostBits,
6034 SSMR3HandleRevision,
6035 SSMR3HandleVersion,
6036 SSMR3HandleHostOSAndArch,
6037 pdmR3DevHlp_TimerCreate,
6038 pdmR3DevHlp_TimerFromMicro,
6039 pdmR3DevHlp_TimerFromMilli,
6040 pdmR3DevHlp_TimerFromNano,
6041 pdmR3DevHlp_TimerGet,
6042 pdmR3DevHlp_TimerGetFreq,
6043 pdmR3DevHlp_TimerGetNano,
6044 pdmR3DevHlp_TimerIsActive,
6045 pdmR3DevHlp_TimerIsLockOwner,
6046 pdmR3DevHlp_TimerLockClock,
6047 pdmR3DevHlp_TimerLockClock2,
6048 pdmR3DevHlp_TimerSet,
6049 pdmR3DevHlp_TimerSetFrequencyHint,
6050 pdmR3DevHlp_TimerSetMicro,
6051 pdmR3DevHlp_TimerSetMillies,
6052 pdmR3DevHlp_TimerSetNano,
6053 pdmR3DevHlp_TimerSetRelative,
6054 pdmR3DevHlp_TimerStop,
6055 pdmR3DevHlp_TimerUnlockClock,
6056 pdmR3DevHlp_TimerUnlockClock2,
6057 pdmR3DevHlp_TimerSetCritSect,
6058 pdmR3DevHlp_TimerSave,
6059 pdmR3DevHlp_TimerLoad,
6060 pdmR3DevHlp_TimerDestroy,
6061 TMR3TimerSkip,
6062 pdmR3DevHlp_TMUtcNow,
6063 CFGMR3Exists,
6064 CFGMR3QueryType,
6065 CFGMR3QuerySize,
6066 CFGMR3QueryInteger,
6067 CFGMR3QueryIntegerDef,
6068 CFGMR3QueryString,
6069 CFGMR3QueryStringDef,
6070 CFGMR3QueryPassword,
6071 CFGMR3QueryPasswordDef,
6072 CFGMR3QueryBytes,
6073 CFGMR3QueryU64,
6074 CFGMR3QueryU64Def,
6075 CFGMR3QueryS64,
6076 CFGMR3QueryS64Def,
6077 CFGMR3QueryU32,
6078 CFGMR3QueryU32Def,
6079 CFGMR3QueryS32,
6080 CFGMR3QueryS32Def,
6081 CFGMR3QueryU16,
6082 CFGMR3QueryU16Def,
6083 CFGMR3QueryS16,
6084 CFGMR3QueryS16Def,
6085 CFGMR3QueryU8,
6086 CFGMR3QueryU8Def,
6087 CFGMR3QueryS8,
6088 CFGMR3QueryS8Def,
6089 CFGMR3QueryBool,
6090 CFGMR3QueryBoolDef,
6091 CFGMR3QueryPort,
6092 CFGMR3QueryPortDef,
6093 CFGMR3QueryUInt,
6094 CFGMR3QueryUIntDef,
6095 CFGMR3QuerySInt,
6096 CFGMR3QuerySIntDef,
6097 CFGMR3QueryGCPtr,
6098 CFGMR3QueryGCPtrDef,
6099 CFGMR3QueryGCPtrU,
6100 CFGMR3QueryGCPtrUDef,
6101 CFGMR3QueryGCPtrS,
6102 CFGMR3QueryGCPtrSDef,
6103 CFGMR3QueryStringAlloc,
6104 CFGMR3QueryStringAllocDef,
6105 CFGMR3GetParent,
6106 CFGMR3GetChild,
6107 CFGMR3GetChildF,
6108 CFGMR3GetChildFV,
6109 CFGMR3GetFirstChild,
6110 CFGMR3GetNextChild,
6111 CFGMR3GetName,
6112 CFGMR3GetNameLen,
6113 CFGMR3AreChildrenValid,
6114 CFGMR3GetFirstValue,
6115 CFGMR3GetNextValue,
6116 CFGMR3GetValueName,
6117 CFGMR3GetValueNameLen,
6118 CFGMR3GetValueType,
6119 CFGMR3AreValuesValid,
6120 CFGMR3ValidateConfig,
6121 pdmR3DevHlp_PhysRead,
6122 pdmR3DevHlp_PhysWrite,
6123 pdmR3DevHlp_PhysGCPhys2CCPtr,
6124 pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
6125 pdmR3DevHlp_PhysReleasePageMappingLock,
6126 pdmR3DevHlp_PhysReadGCVirt,
6127 pdmR3DevHlp_PhysWriteGCVirt,
6128 pdmR3DevHlp_PhysGCPtr2GCPhys,
6129 pdmR3DevHlp_PhysIsGCPhysNormal,
6130 pdmR3DevHlp_PhysChangeMemBalloon,
6131 pdmR3DevHlp_MMHeapAlloc,
6132 pdmR3DevHlp_MMHeapAllocZ,
6133 pdmR3DevHlp_MMHeapAPrintfV,
6134 pdmR3DevHlp_MMHeapFree,
6135 pdmR3DevHlp_MMPhysGetRamSize,
6136 pdmR3DevHlp_MMPhysGetRamSizeBelow4GB,
6137 pdmR3DevHlp_MMPhysGetRamSizeAbove4GB,
6138 pdmR3DevHlp_VMState,
6139 pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
6140 pdmR3DevHlp_VMSetErrorV,
6141 pdmR3DevHlp_VMSetRuntimeErrorV,
6142 pdmR3DevHlp_VMWaitForDeviceReady,
6143 pdmR3DevHlp_VMNotifyCpuDeviceReady,
6144 pdmR3DevHlp_VMReqCallNoWaitV,
6145 pdmR3DevHlp_VMReqPriorityCallWaitV,
6146 pdmR3DevHlp_DBGFStopV,
6147 pdmR3DevHlp_DBGFInfoRegister,
6148 pdmR3DevHlp_DBGFInfoRegisterArgv,
6149 pdmR3DevHlp_DBGFRegRegister,
6150 pdmR3DevHlp_DBGFTraceBuf,
6151 pdmR3DevHlp_DBGFReportBugCheck,
6152 pdmR3DevHlp_DBGFCoreWrite,
6153 pdmR3DevHlp_DBGFInfoLogHlp,
6154 pdmR3DevHlp_DBGFRegNmQueryU64,
6155 pdmR3DevHlp_DBGFRegPrintfV,
6156 pdmR3DevHlp_STAMRegister,
6157 pdmR3DevHlp_STAMRegisterV,
6158 pdmR3DevHlp_PCIRegister,
6159 pdmR3DevHlp_PCIRegisterMsi,
6160 pdmR3DevHlp_PCIIORegionRegister,
6161 pdmR3DevHlp_PCIInterceptConfigAccesses,
6162 pdmR3DevHlp_PCIConfigWrite,
6163 pdmR3DevHlp_PCIConfigRead,
6164 pdmR3DevHlp_PCIPhysRead,
6165 pdmR3DevHlp_PCIPhysWrite,
6166 pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
6167 pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
6168 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
6169 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
6170 pdmR3DevHlp_PCISetIrq,
6171 pdmR3DevHlp_PCISetIrqNoWait,
6172 pdmR3DevHlp_ISASetIrq,
6173 pdmR3DevHlp_ISASetIrqNoWait,
6174 pdmR3DevHlp_DriverAttach,
6175 pdmR3DevHlp_DriverDetach,
6176 pdmR3DevHlp_DriverReconfigure,
6177 pdmR3DevHlp_QueueCreate,
6178 pdmR3DevHlp_QueueAlloc,
6179 pdmR3DevHlp_QueueInsert,
6180 pdmR3DevHlp_QueueFlushIfNecessary,
6181 pdmR3DevHlp_TaskCreate,
6182 pdmR3DevHlp_TaskTrigger,
6183 pdmR3DevHlp_SUPSemEventCreate,
6184 pdmR3DevHlp_SUPSemEventClose,
6185 pdmR3DevHlp_SUPSemEventSignal,
6186 pdmR3DevHlp_SUPSemEventWaitNoResume,
6187 pdmR3DevHlp_SUPSemEventWaitNsAbsIntr,
6188 pdmR3DevHlp_SUPSemEventWaitNsRelIntr,
6189 pdmR3DevHlp_SUPSemEventGetResolution,
6190 pdmR3DevHlp_SUPSemEventMultiCreate,
6191 pdmR3DevHlp_SUPSemEventMultiClose,
6192 pdmR3DevHlp_SUPSemEventMultiSignal,
6193 pdmR3DevHlp_SUPSemEventMultiReset,
6194 pdmR3DevHlp_SUPSemEventMultiWaitNoResume,
6195 pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr,
6196 pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr,
6197 pdmR3DevHlp_SUPSemEventMultiGetResolution,
6198 pdmR3DevHlp_CritSectInit,
6199 pdmR3DevHlp_CritSectGetNop,
6200 pdmR3DevHlp_SetDeviceCritSect,
6201 pdmR3DevHlp_CritSectYield,
6202 pdmR3DevHlp_CritSectEnter,
6203 pdmR3DevHlp_CritSectEnterDebug,
6204 pdmR3DevHlp_CritSectTryEnter,
6205 pdmR3DevHlp_CritSectTryEnterDebug,
6206 pdmR3DevHlp_CritSectLeave,
6207 pdmR3DevHlp_CritSectIsOwner,
6208 pdmR3DevHlp_CritSectIsInitialized,
6209 pdmR3DevHlp_CritSectHasWaiters,
6210 pdmR3DevHlp_CritSectGetRecursion,
6211 pdmR3DevHlp_CritSectScheduleExitEvent,
6212 pdmR3DevHlp_CritSectDelete,
6213 pdmR3DevHlp_CritSectRwInit,
6214 pdmR3DevHlp_CritSectRwDelete,
6215 pdmR3DevHlp_CritSectRwEnterShared,
6216 pdmR3DevHlp_CritSectRwEnterSharedDebug,
6217 pdmR3DevHlp_CritSectRwTryEnterShared,
6218 pdmR3DevHlp_CritSectRwTryEnterSharedDebug,
6219 pdmR3DevHlp_CritSectRwLeaveShared,
6220 pdmR3DevHlp_CritSectRwEnterExcl,
6221 pdmR3DevHlp_CritSectRwEnterExclDebug,
6222 pdmR3DevHlp_CritSectRwTryEnterExcl,
6223 pdmR3DevHlp_CritSectRwTryEnterExclDebug,
6224 pdmR3DevHlp_CritSectRwLeaveExcl,
6225 pdmR3DevHlp_CritSectRwIsWriteOwner,
6226 pdmR3DevHlp_CritSectRwIsReadOwner,
6227 pdmR3DevHlp_CritSectRwGetWriteRecursion,
6228 pdmR3DevHlp_CritSectRwGetWriterReadRecursion,
6229 pdmR3DevHlp_CritSectRwGetReadCount,
6230 pdmR3DevHlp_CritSectRwIsInitialized,
6231 pdmR3DevHlp_ThreadCreate,
6232 PDMR3ThreadDestroy,
6233 PDMR3ThreadIAmSuspending,
6234 PDMR3ThreadIAmRunning,
6235 PDMR3ThreadSleep,
6236 PDMR3ThreadSuspend,
6237 PDMR3ThreadResume,
6238 pdmR3DevHlp_SetAsyncNotification,
6239 pdmR3DevHlp_AsyncNotificationCompleted,
6240 pdmR3DevHlp_RTCRegister,
6241 pdmR3DevHlp_PCIBusRegister,
6242 pdmR3DevHlp_IommuRegister,
6243 pdmR3DevHlp_PICRegister,
6244 pdmR3DevHlp_ApicRegister,
6245 pdmR3DevHlp_IoApicRegister,
6246 pdmR3DevHlp_HpetRegister,
6247 pdmR3DevHlp_PciRawRegister,
6248 pdmR3DevHlp_DMACRegister,
6249 pdmR3DevHlp_DMARegister,
6250 pdmR3DevHlp_DMAReadMemory,
6251 pdmR3DevHlp_DMAWriteMemory,
6252 pdmR3DevHlp_DMASetDREQ,
6253 pdmR3DevHlp_DMAGetChannelMode,
6254 pdmR3DevHlp_DMASchedule,
6255 pdmR3DevHlp_CMOSWrite,
6256 pdmR3DevHlp_CMOSRead,
6257 pdmR3DevHlp_AssertEMT,
6258 pdmR3DevHlp_AssertOther,
6259 pdmR3DevHlp_LdrGetRCInterfaceSymbols,
6260 pdmR3DevHlp_LdrGetR0InterfaceSymbols,
6261 pdmR3DevHlp_CallR0,
6262 pdmR3DevHlp_VMGetSuspendReason,
6263 pdmR3DevHlp_VMGetResumeReason,
6264 pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
6265 pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
6266 pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
6267 pdmR3DevHlp_CpuGetGuestMicroarch,
6268 pdmR3DevHlp_CpuGetGuestAddrWidths,
6269 pdmR3DevHlp_CpuGetGuestScalableBusFrequency,
6270 pdmR3DevHlp_STAMDeregisterByPrefix,
6271 0,
6272 0,
6273 0,
6274 0,
6275 0,
6276 0,
6277 0,
6278 0,
6279 0,
6280 pdmR3DevHlp_Untrusted_GetUVM,
6281 pdmR3DevHlp_Untrusted_GetVM,
6282 pdmR3DevHlp_Untrusted_GetVMCPU,
6283 pdmR3DevHlp_Untrusted_GetCurrentCpuId,
6284 pdmR3DevHlp_Untrusted_RegisterVMMDevHeap,
6285 pdmR3DevHlp_Untrusted_FirmwareRegister,
6286 pdmR3DevHlp_Untrusted_VMReset,
6287 pdmR3DevHlp_Untrusted_VMSuspend,
6288 pdmR3DevHlp_Untrusted_VMSuspendSaveAndPowerOff,
6289 pdmR3DevHlp_Untrusted_VMPowerOff,
6290 pdmR3DevHlp_Untrusted_A20IsEnabled,
6291 pdmR3DevHlp_Untrusted_A20Set,
6292 pdmR3DevHlp_Untrusted_GetCpuId,
6293 pdmR3DevHlp_Untrusted_GetMainExecutionEngine,
6294 pdmR3DevHlp_TMTimeVirtGet,
6295 pdmR3DevHlp_TMTimeVirtGetFreq,
6296 pdmR3DevHlp_TMTimeVirtGetNano,
6297 pdmR3DevHlp_TMCpuTicksPerSecond,
6298 pdmR3DevHlp_Untrusted_GetSupDrvSession,
6299 pdmR3DevHlp_Untrusted_QueryGenericUserObject,
6300 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalTypeRegister,
6301 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalRegister,
6302 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalDeregister,
6303 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalPageTempOff,
6304 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalReset,
6305 pdmR3DevHlp_Untrusted_VMMRegisterPatchMemory,
6306 pdmR3DevHlp_Untrusted_VMMDeregisterPatchMemory,
6307 pdmR3DevHlp_Untrusted_SharedModuleRegister,
6308 pdmR3DevHlp_Untrusted_SharedModuleUnregister,
6309 pdmR3DevHlp_Untrusted_SharedModuleGetPageState,
6310 pdmR3DevHlp_Untrusted_SharedModuleCheckAll,
6311 pdmR3DevHlp_Untrusted_QueryLun,
6312 pdmR3DevHlp_Untrusted_GIMDeviceRegister,
6313 pdmR3DevHlp_Untrusted_GIMGetDebugSetup,
6314 pdmR3DevHlp_Untrusted_GIMGetMmio2Regions,
6315 PDM_DEVHLPR3_VERSION /* the end */
6316};
6317
6318
6319
6320/**
6321 * Queue consumer callback for internal component.
6322 *
6323 * @returns Success indicator.
6324 * If false the item will not be removed and the flushing will stop.
6325 * @param pVM The cross context VM structure.
6326 * @param pItem The item to consume. Upon return this item will be freed.
6327 */
6328DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem)
6329{
6330 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem;
6331 LogFlow(("pdmR3DevHlpQueueConsumer: enmOp=%d pDevIns=%p\n", pTask->enmOp, pTask->pDevInsR3));
6332 switch (pTask->enmOp)
6333 {
6334 case PDMDEVHLPTASKOP_ISA_SET_IRQ:
6335 PDMIsaSetIrq(pVM, pTask->u.IsaSetIrq.iIrq, pTask->u.IsaSetIrq.iLevel, pTask->u.IsaSetIrq.uTagSrc);
6336 break;
6337
6338 case PDMDEVHLPTASKOP_PCI_SET_IRQ:
6339 {
6340 /* Same as pdmR3DevHlp_PCISetIrq, except we've got a tag already. */
6341 PPDMDEVINSR3 pDevIns = pTask->pDevInsR3;
6342 PPDMPCIDEV pPciDev = pTask->u.PciSetIrq.idxPciDev < RT_ELEMENTS(pDevIns->apPciDevs)
6343 ? pDevIns->apPciDevs[pTask->u.PciSetIrq.idxPciDev] : NULL;
6344 if (pPciDev)
6345 {
6346 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
6347 AssertBreak(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
6348 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
6349
6350 pdmLock(pVM);
6351 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, pTask->u.PciSetIrq.iIrq,
6352 pTask->u.PciSetIrq.iLevel, pTask->u.PciSetIrq.uTagSrc);
6353 pdmUnlock(pVM);
6354 }
6355 else
6356 AssertReleaseMsgFailed(("No PCI device given! (%#x)\n", pPciDev->Int.s.idxSubDev));
6357 break;
6358 }
6359
6360 case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:
6361 {
6362 PDMIoApicSetIrq(pVM, pTask->u.IoApicSetIrq.uBusDevFn, pTask->u.IoApicSetIrq.iIrq, pTask->u.IoApicSetIrq.iLevel,
6363 pTask->u.IoApicSetIrq.uTagSrc);
6364 break;
6365 }
6366
6367 case PDMDEVHLPTASKOP_IOAPIC_SEND_MSI:
6368 {
6369 PDMIoApicSendMsi(pVM, pTask->u.IoApicSendMsi.uBusDevFn, &pTask->u.IoApicSendMsi.Msi, pTask->u.IoApicSendMsi.uTagSrc);
6370 break;
6371 }
6372
6373 case PDMDEVHLPTASKOP_IOAPIC_SET_EOI:
6374 {
6375 PDMIoApicBroadcastEoi(pVM, pTask->u.IoApicSetEoi.uVector);
6376 break;
6377 }
6378
6379 default:
6380 AssertReleaseMsgFailed(("Invalid operation %d\n", pTask->enmOp));
6381 break;
6382 }
6383 return true;
6384}
6385
6386/** @} */
6387
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