VirtualBox

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

Last change on this file since 99863 was 99743, checked in by vboxsync, 19 months ago

VMM: Add full support for reading/writing I/O ports on ARMv8 in order to emulate PIO accesses to PCI devices through a dedicated MMIO region by the host to PCI bridge, bugref:10445

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

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