VirtualBox

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

Last change on this file since 102468 was 100399, checked in by vboxsync, 18 months ago

VMM/PDMDevHlp: Allow IRQ numbers >= 16 for ARMv8 (we are kind of abusing the ISA interrupt helper on ARM right now to forward interrupts to the GIC, bugref:10404

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

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