VirtualBox

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

Last change on this file since 107464 was 107308, checked in by vboxsync, 3 months ago

VMM: bugref:10759 Refactor GIC for use with different backends.

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

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