VirtualBox

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

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

VMM,Devices: Eliminate direct calls to IOMMmioResetRegion and IOMMmioMapMmio2Page APIs and introduce callbacks in the device helper callback table, bugref:10074

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