VirtualBox

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

Last change on this file since 99377 was 99051, checked in by vboxsync, 21 months ago

VMM: More ARMv8 x86/amd64 separation work, VBoxVMMArm compiles and links now, bugref:10385

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