VirtualBox

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

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

VMM/PDMQueue: Removed unused function. bugref:10093

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