VirtualBox

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

Last change on this file since 100139 was 100108, checked in by vboxsync, 22 months ago

*: Fix build issues when setting VBOX_WITH_WARNINGS_AS_ERRORS=1 on darwin.arm64 and make it a default, bugref:10469

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette