VirtualBox

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

Last change on this file since 104933 was 104840, checked in by vboxsync, 6 months ago

VMM/PGM: Refactored RAM ranges, MMIO2 ranges and ROM ranges and added MMIO ranges (to PGM) so we can safely access RAM ranges at runtime w/o fear of them ever being freed up. It is now only possible to create these during VM creation and loading, and they will live till VM destruction (except for MMIO2 which could be destroyed during loading (PCNet fun)). The lookup handling is by table instead of pointer tree. No more ring-0 pointers in shared data. bugref:10687 bugref:10093

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