VirtualBox

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

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

VMM: Add a CPUMGetGuestArch() method and PDM device helper to make it easier to determine the guest architecture and not having to deal with the massive CPUMMICROARCH enum, bugref:10385

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 252.2 KB
Line 
1/* $Id: PDMDevHlp.cpp 100184 2023-06-16 06:51:39Z 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 Assert(iIrq < 16);
2564 Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
2565
2566 PVM pVM = pDevIns->Internal.s.pVMR3;
2567
2568 /*
2569 * Do the job.
2570 */
2571 pdmLock(pVM);
2572 uint32_t uTagSrc;
2573 if (iLevel & PDM_IRQ_LEVEL_HIGH)
2574 {
2575 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
2576 if (iLevel == PDM_IRQ_LEVEL_HIGH)
2577 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2578 else
2579 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2580 }
2581 else
2582 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
2583
2584 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
2585
2586 if (iLevel == PDM_IRQ_LEVEL_LOW)
2587 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
2588 pdmUnlock(pVM);
2589
2590 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
2591}
2592
2593
2594/** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrqNoWait} */
2595static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
2596{
2597 pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel);
2598}
2599
2600
2601/** @interface_method_impl{PDMDEVHLPR3,pfnDriverAttach} */
2602static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
2603{
2604 PDMDEV_ASSERT_DEVINS(pDevIns);
2605 PVM pVM = pDevIns->Internal.s.pVMR3;
2606 VM_ASSERT_EMT(pVM);
2607 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n",
2608 pDevIns->pReg->szName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc));
2609
2610 /*
2611 * Lookup the LUN, it might already be registered.
2612 */
2613 PPDMLUN pLunPrev = NULL;
2614 PPDMLUN pLun = pDevIns->Internal.s.pLunsR3;
2615 for (; pLun; pLunPrev = pLun, pLun = pLun->pNext)
2616 if (pLun->iLun == iLun)
2617 break;
2618
2619 /*
2620 * Create the LUN if if wasn't found, else check if driver is already attached to it.
2621 */
2622 if (!pLun)
2623 {
2624 if ( !pBaseInterface
2625 || !pszDesc
2626 || !*pszDesc)
2627 {
2628 Assert(pBaseInterface);
2629 Assert(pszDesc || *pszDesc);
2630 return VERR_INVALID_PARAMETER;
2631 }
2632
2633 pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun));
2634 if (!pLun)
2635 return VERR_NO_MEMORY;
2636
2637 pLun->iLun = iLun;
2638 pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL;
2639 pLun->pTop = NULL;
2640 pLun->pBottom = NULL;
2641 pLun->pDevIns = pDevIns;
2642 pLun->pUsbIns = NULL;
2643 pLun->pszDesc = pszDesc;
2644 pLun->pBase = pBaseInterface;
2645 if (!pLunPrev)
2646 pDevIns->Internal.s.pLunsR3 = pLun;
2647 else
2648 pLunPrev->pNext = pLun;
2649 Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n",
2650 iLun, pszDesc, pDevIns->pReg->szName, pDevIns->iInstance));
2651 }
2652 else if (pLun->pTop)
2653 {
2654 AssertMsgFailed(("Already attached! The device should keep track of such things!\n"));
2655 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED));
2656 return VERR_PDM_DRIVER_ALREADY_ATTACHED;
2657 }
2658 Assert(pLun->pBase == pBaseInterface);
2659
2660
2661 /*
2662 * Get the attached driver configuration.
2663 */
2664 int rc;
2665 PCFGMNODE pNode = CFGMR3GetChildF(pDevIns->Internal.s.pCfgHandle, "LUN#%u", iLun);
2666 if (pNode)
2667 rc = pdmR3DrvInstantiate(pVM, pNode, pBaseInterface, NULL /*pDrvAbove*/, pLun, ppBaseInterface);
2668 else
2669 rc = VERR_PDM_NO_ATTACHED_DRIVER;
2670
2671 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2672 return rc;
2673}
2674
2675
2676/** @interface_method_impl{PDMDEVHLPR3,pfnDriverDetach} */
2677static DECLCALLBACK(int) pdmR3DevHlp_DriverDetach(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags)
2678{
2679 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
2680 LogFlow(("pdmR3DevHlp_DriverDetach: caller='%s'/%d: pDrvIns=%p\n",
2681 pDevIns->pReg->szName, pDevIns->iInstance, pDrvIns));
2682
2683#ifdef VBOX_STRICT
2684 PVM pVM = pDevIns->Internal.s.pVMR3;
2685 VM_ASSERT_EMT(pVM);
2686#endif
2687
2688 int rc = pdmR3DrvDetach(pDrvIns, fFlags);
2689
2690 LogFlow(("pdmR3DevHlp_DriverDetach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2691 return rc;
2692}
2693
2694
2695/** @interface_method_impl{PDMDEVHLPR3,pfnDriverReconfigure} */
2696static DECLCALLBACK(int) pdmR3DevHlp_DriverReconfigure(PPDMDEVINS pDevIns, uint32_t iLun, uint32_t cDepth,
2697 const char * const *papszDrivers, PCFGMNODE *papConfigs, uint32_t fFlags)
2698{
2699 PDMDEV_ASSERT_DEVINS(pDevIns);
2700 PVM pVM = pDevIns->Internal.s.pVMR3;
2701 VM_ASSERT_EMT(pVM);
2702 LogFlow(("pdmR3DevHlp_DriverReconfigure: caller='%s'/%d: iLun=%u cDepth=%u fFlags=%#x\n",
2703 pDevIns->pReg->szName, pDevIns->iInstance, iLun, cDepth, fFlags));
2704
2705 /*
2706 * Validate input.
2707 */
2708 AssertReturn(cDepth <= 8, VERR_INVALID_PARAMETER);
2709 AssertPtrReturn(papszDrivers, VERR_INVALID_POINTER);
2710 AssertPtrNullReturn(papConfigs, VERR_INVALID_POINTER);
2711 for (uint32_t i = 0; i < cDepth; i++)
2712 {
2713 AssertPtrReturn(papszDrivers[i], VERR_INVALID_POINTER);
2714 size_t cchDriver = strlen(papszDrivers[i]);
2715 AssertReturn(cchDriver > 0 && cchDriver < RT_SIZEOFMEMB(PDMDRVREG, szName), VERR_OUT_OF_RANGE);
2716
2717 if (papConfigs)
2718 AssertPtrNullReturn(papConfigs[i], VERR_INVALID_POINTER);
2719 }
2720 AssertReturn(fFlags == 0, VERR_INVALID_FLAGS);
2721
2722 /*
2723 * Do we have to detach an existing driver first?
2724 */
2725 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)
2726 if (pLun->iLun == iLun)
2727 {
2728 if (pLun->pTop)
2729 {
2730 int rc = pdmR3DrvDetach(pLun->pTop, 0);
2731 AssertRCReturn(rc, rc);
2732 }
2733 break;
2734 }
2735
2736 /*
2737 * Remove the old tree.
2738 */
2739 PCFGMNODE pCfgDev = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/", pDevIns->pReg->szName, pDevIns->iInstance);
2740 AssertReturn(pCfgDev, VERR_INTERNAL_ERROR_2);
2741 PCFGMNODE pCfgLun = CFGMR3GetChildF(pCfgDev, "LUN#%u", iLun);
2742 if (pCfgLun)
2743 CFGMR3RemoveNode(pCfgLun);
2744
2745 /*
2746 * Construct a new tree.
2747 */
2748 int rc = CFGMR3InsertNodeF(pCfgDev, &pCfgLun, "LUN#%u", iLun);
2749 AssertRCReturn(rc, rc);
2750 PCFGMNODE pCfgDrv = pCfgLun;
2751 for (uint32_t i = 0; i < cDepth; i++)
2752 {
2753 rc = CFGMR3InsertString(pCfgDrv, "Driver", papszDrivers[i]);
2754 AssertRCReturn(rc, rc);
2755 if (papConfigs && papConfigs[i])
2756 {
2757 rc = CFGMR3InsertSubTree(pCfgDrv, "Config", papConfigs[i], NULL);
2758 AssertRCReturn(rc, rc);
2759 papConfigs[i] = NULL;
2760 }
2761 else
2762 {
2763 rc = CFGMR3InsertNode(pCfgDrv, "Config", NULL);
2764 AssertRCReturn(rc, rc);
2765 }
2766
2767 if (i + 1 >= cDepth)
2768 break;
2769 rc = CFGMR3InsertNode(pCfgDrv, "AttachedDriver", &pCfgDrv);
2770 AssertRCReturn(rc, rc);
2771 }
2772
2773 LogFlow(("pdmR3DevHlp_DriverReconfigure: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2774 return rc;
2775}
2776
2777
2778/** @interface_method_impl{PDMDEVHLPR3,pfnQueueCreate} */
2779static DECLCALLBACK(int) pdmR3DevHlp_QueueCreate(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
2780 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName,
2781 PDMQUEUEHANDLE *phQueue)
2782{
2783 PDMDEV_ASSERT_DEVINS(pDevIns);
2784 LogFlow(("pdmR3DevHlp_QueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fRZEnabled=%RTbool pszName=%p:{%s} phQueue=%p\n",
2785 pDevIns->pReg->szName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, pszName, phQueue));
2786
2787 PVM pVM = pDevIns->Internal.s.pVMR3;
2788 VM_ASSERT_EMT(pVM);
2789
2790 if (pDevIns->iInstance > 0)
2791 {
2792 pszName = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s_%u", pszName, pDevIns->iInstance);
2793 AssertLogRelReturn(pszName, VERR_NO_MEMORY);
2794 }
2795
2796 int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, phQueue);
2797
2798 LogFlow(("pdmR3DevHlp_QueueCreate: caller='%s'/%d: returns %Rrc *phQueue=%p\n",
2799 pDevIns->pReg->szName, pDevIns->iInstance, rc, *phQueue));
2800 return rc;
2801}
2802
2803
2804/** @interface_method_impl{PDMDEVHLPR3,pfnQueueAlloc} */
2805static DECLCALLBACK(PPDMQUEUEITEMCORE) pdmR3DevHlp_QueueAlloc(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
2806{
2807 PDMDEV_ASSERT_DEVINS(pDevIns);
2808 return PDMQueueAlloc(pDevIns->Internal.s.pVMR3, hQueue, pDevIns);
2809}
2810
2811
2812/** @interface_method_impl{PDMDEVHLPR3,pfnQueueInsert} */
2813static DECLCALLBACK(int) pdmR3DevHlp_QueueInsert(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue, PPDMQUEUEITEMCORE pItem)
2814{
2815 return PDMQueueInsert(pDevIns->Internal.s.pVMR3, hQueue, pDevIns, pItem);
2816}
2817
2818
2819/** @interface_method_impl{PDMDEVHLPR3,pfnQueueFlushIfNecessary} */
2820static DECLCALLBACK(bool) pdmR3DevHlp_QueueFlushIfNecessary(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
2821{
2822 return PDMQueueFlushIfNecessary(pDevIns->Internal.s.pVMR3, hQueue, pDevIns) == VINF_SUCCESS;
2823}
2824
2825
2826/** @interface_method_impl{PDMDEVHLPR3,pfnTaskCreate} */
2827static DECLCALLBACK(int) pdmR3DevHlp_TaskCreate(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszName,
2828 PFNPDMTASKDEV pfnCallback, void *pvUser, PDMTASKHANDLE *phTask)
2829{
2830 PDMDEV_ASSERT_DEVINS(pDevIns);
2831 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: pfnCallback=%p fFlags=%#x pszName=%p:{%s} phTask=%p\n",
2832 pDevIns->pReg->szName, pDevIns->iInstance, pfnCallback, fFlags, pszName, pszName, phTask));
2833 PVM pVM = pDevIns->Internal.s.pVMR3;
2834 VM_ASSERT_EMT(pVM);
2835
2836 int rc = PDMR3TaskCreate(pVM, fFlags, pszName, PDMTASKTYPE_DEV, pDevIns, (PFNRT)pfnCallback, pvUser, phTask);
2837
2838 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2839 return rc;
2840}
2841
2842
2843/** @interface_method_impl{PDMDEVHLPR3,pfnTaskTrigger} */
2844static DECLCALLBACK(int) pdmR3DevHlp_TaskTrigger(PPDMDEVINS pDevIns, PDMTASKHANDLE hTask)
2845{
2846 PDMDEV_ASSERT_DEVINS(pDevIns);
2847 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: hTask=%RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, hTask));
2848
2849 int rc = PDMTaskTrigger(pDevIns->Internal.s.pVMR3, PDMTASKTYPE_DEV, pDevIns, hTask);
2850
2851 LogFlow(("pdmR3DevHlp_TaskTrigger: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2852 return rc;
2853}
2854
2855
2856/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventCreate} */
2857static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventCreate(PPDMDEVINS pDevIns, PSUPSEMEVENT phEvent)
2858{
2859 PDMDEV_ASSERT_DEVINS(pDevIns);
2860 LogFlow(("pdmR3DevHlp_SUPSemEventCreate: caller='%s'/%d: phEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, phEvent));
2861 PVM pVM = pDevIns->Internal.s.pVMR3;
2862 VM_ASSERT_EMT(pVM);
2863
2864 int rc = SUPSemEventCreate(pVM->pSession, phEvent);
2865
2866 LogFlow(("pdmR3DevHlp_SUPSemEventCreate: caller='%s'/%d: returns %Rrc *phEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *phEvent));
2867 return rc;
2868}
2869
2870
2871/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventClose} */
2872static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventClose(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent)
2873{
2874 PDMDEV_ASSERT_DEVINS(pDevIns);
2875 LogFlow(("pdmR3DevHlp_SUPSemEventClose: caller='%s'/%d: hEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEvent));
2876
2877 int rc = SUPSemEventClose(pDevIns->Internal.s.pVMR3->pSession, hEvent);
2878
2879 LogFlow(("pdmR3DevHlp_SUPSemEventClose: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2880 return rc;
2881}
2882
2883
2884/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventSignal} */
2885static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventSignal(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent)
2886{
2887 PDMDEV_ASSERT_DEVINS(pDevIns);
2888 LogFlow(("pdmR3DevHlp_SUPSemEventSignal: caller='%s'/%d: hEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEvent));
2889
2890 int rc = SUPSemEventSignal(pDevIns->Internal.s.pVMR3->pSession, hEvent);
2891
2892 LogFlow(("pdmR3DevHlp_SUPSemEventSignal: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2893 return rc;
2894}
2895
2896
2897/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventWaitNoResume} */
2898static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint32_t cMillies)
2899{
2900 PDMDEV_ASSERT_DEVINS(pDevIns);
2901 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNoResume: caller='%s'/%d: hEvent=%p cNsTimeout=%RU32\n",
2902 pDevIns->pReg->szName, pDevIns->iInstance, hEvent, cMillies));
2903
2904 int rc = SUPSemEventWaitNoResume(pDevIns->Internal.s.pVMR3->pSession, hEvent, cMillies);
2905
2906 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNoResume: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2907 return rc;
2908}
2909
2910
2911/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventWaitNsAbsIntr} */
2912static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t uNsTimeout)
2913{
2914 PDMDEV_ASSERT_DEVINS(pDevIns);
2915 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsAbsIntr: caller='%s'/%d: hEvent=%p uNsTimeout=%RU64\n",
2916 pDevIns->pReg->szName, pDevIns->iInstance, hEvent, uNsTimeout));
2917
2918 int rc = SUPSemEventWaitNsAbsIntr(pDevIns->Internal.s.pVMR3->pSession, hEvent, uNsTimeout);
2919
2920 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsAbsIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2921 return rc;
2922}
2923
2924
2925/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventWaitNsRelIntr} */
2926static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t cNsTimeout)
2927{
2928 PDMDEV_ASSERT_DEVINS(pDevIns);
2929 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsRelIntr: caller='%s'/%d: hEvent=%p cNsTimeout=%RU64\n",
2930 pDevIns->pReg->szName, pDevIns->iInstance, hEvent, cNsTimeout));
2931
2932 int rc = SUPSemEventWaitNsRelIntr(pDevIns->Internal.s.pVMR3->pSession, hEvent, cNsTimeout);
2933
2934 LogFlow(("pdmR3DevHlp_SUPSemEventWaitNsRelIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2935 return rc;
2936}
2937
2938
2939/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventGetResolution} */
2940static DECLCALLBACK(uint32_t) pdmR3DevHlp_SUPSemEventGetResolution(PPDMDEVINS pDevIns)
2941{
2942 PDMDEV_ASSERT_DEVINS(pDevIns);
2943 LogFlow(("pdmR3DevHlp_SUPSemEventGetResolution: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
2944
2945 uint32_t cNsResolution = SUPSemEventGetResolution(pDevIns->Internal.s.pVMR3->pSession);
2946
2947 LogFlow(("pdmR3DevHlp_SUPSemEventGetResolution: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, cNsResolution));
2948 return cNsResolution;
2949}
2950
2951
2952/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiCreate} */
2953static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiCreate(PPDMDEVINS pDevIns, PSUPSEMEVENTMULTI phEventMulti)
2954{
2955 PDMDEV_ASSERT_DEVINS(pDevIns);
2956 LogFlow(("pdmR3DevHlp_SUPSemEventMultiCreate: caller='%s'/%d: phEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, phEventMulti));
2957 PVM pVM = pDevIns->Internal.s.pVMR3;
2958 VM_ASSERT_EMT(pVM);
2959
2960 int rc = SUPSemEventMultiCreate(pVM->pSession, phEventMulti);
2961
2962 LogFlow(("pdmR3DevHlp_SUPSemEventMultiCreate: caller='%s'/%d: returns %Rrc *phEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *phEventMulti));
2963 return rc;
2964}
2965
2966
2967/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiClose} */
2968static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiClose(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
2969{
2970 PDMDEV_ASSERT_DEVINS(pDevIns);
2971 LogFlow(("pdmR3DevHlp_SUPSemEventMultiClose: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
2972
2973 int rc = SUPSemEventMultiClose(pDevIns->Internal.s.pVMR3->pSession, hEventMulti);
2974
2975 LogFlow(("pdmR3DevHlp_SUPSemEventMultiClose: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2976 return rc;
2977}
2978
2979
2980/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiSignal} */
2981static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiSignal(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
2982{
2983 PDMDEV_ASSERT_DEVINS(pDevIns);
2984 LogFlow(("pdmR3DevHlp_SUPSemEventMultiSignal: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
2985
2986 int rc = SUPSemEventMultiSignal(pDevIns->Internal.s.pVMR3->pSession, hEventMulti);
2987
2988 LogFlow(("pdmR3DevHlp_SUPSemEventMultiSignal: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
2989 return rc;
2990}
2991
2992
2993/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiReset} */
2994static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiReset(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
2995{
2996 PDMDEV_ASSERT_DEVINS(pDevIns);
2997 LogFlow(("pdmR3DevHlp_SUPSemEventMultiReset: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
2998
2999 int rc = SUPSemEventMultiReset(pDevIns->Internal.s.pVMR3->pSession, hEventMulti);
3000
3001 LogFlow(("pdmR3DevHlp_SUPSemEventMultiReset: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3002 return rc;
3003}
3004
3005
3006/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiWaitNoResume} */
3007static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
3008 uint32_t cMillies)
3009{
3010 PDMDEV_ASSERT_DEVINS(pDevIns);
3011 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNoResume: caller='%s'/%d: hEventMulti=%p cMillies=%RU32\n",
3012 pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, cMillies));
3013
3014 int rc = SUPSemEventMultiWaitNoResume(pDevIns->Internal.s.pVMR3->pSession, hEventMulti, cMillies);
3015
3016 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNoResume: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3017 return rc;
3018}
3019
3020
3021/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiWaitNsAbsIntr} */
3022static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
3023 uint64_t uNsTimeout)
3024{
3025 PDMDEV_ASSERT_DEVINS(pDevIns);
3026 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr: caller='%s'/%d: hEventMulti=%p uNsTimeout=%RU64\n",
3027 pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, uNsTimeout));
3028
3029 int rc = SUPSemEventMultiWaitNsAbsIntr(pDevIns->Internal.s.pVMR3->pSession, hEventMulti, uNsTimeout);
3030
3031 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3032 return rc;
3033}
3034
3035
3036/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiWaitNsRelIntr} */
3037static DECLCALLBACK(int) pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
3038 uint64_t cNsTimeout)
3039{
3040 PDMDEV_ASSERT_DEVINS(pDevIns);
3041 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr: caller='%s'/%d: hEventMulti=%p cNsTimeout=%RU64\n",
3042 pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, cNsTimeout));
3043
3044 int rc = SUPSemEventMultiWaitNsRelIntr(pDevIns->Internal.s.pVMR3->pSession, hEventMulti, cNsTimeout);
3045
3046 LogFlow(("pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3047 return rc;
3048}
3049
3050
3051/** @interface_method_impl{PDMDEVHLPR3,pfnSUPSemEventMultiGetResolution} */
3052static DECLCALLBACK(uint32_t) pdmR3DevHlp_SUPSemEventMultiGetResolution(PPDMDEVINS pDevIns)
3053{
3054 PDMDEV_ASSERT_DEVINS(pDevIns);
3055 LogFlow(("pdmR3DevHlp_SUPSemEventMultiGetResolution: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
3056
3057 uint32_t cNsResolution = SUPSemEventMultiGetResolution(pDevIns->Internal.s.pVMR3->pSession);
3058
3059 LogFlow(("pdmR3DevHlp_SUPSemEventMultiGetResolution: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, cNsResolution));
3060 return cNsResolution;
3061}
3062
3063
3064/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectInit} */
3065static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
3066 const char *pszNameFmt, va_list va)
3067{
3068 PDMDEV_ASSERT_DEVINS(pDevIns);
3069 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszNameFmt=%p:{%s}\n",
3070 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pszNameFmt, pszNameFmt));
3071
3072 PVM pVM = pDevIns->Internal.s.pVMR3;
3073 VM_ASSERT_EMT(pVM);
3074 int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
3075
3076 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3077 return rc;
3078}
3079
3080
3081/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNop} */
3082static DECLCALLBACK(PPDMCRITSECT) pdmR3DevHlp_CritSectGetNop(PPDMDEVINS pDevIns)
3083{
3084 PDMDEV_ASSERT_DEVINS(pDevIns);
3085 PVM pVM = pDevIns->Internal.s.pVMR3;
3086 VM_ASSERT_EMT(pVM);
3087
3088 PPDMCRITSECT pCritSect = PDMR3CritSectGetNop(pVM);
3089 LogFlow(("pdmR3DevHlp_CritSectGetNop: caller='%s'/%d: return %p\n",
3090 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
3091 return pCritSect;
3092}
3093
3094
3095/** @interface_method_impl{PDMDEVHLPR3,pfnSetDeviceCritSect} */
3096static DECLCALLBACK(int) pdmR3DevHlp_SetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3097{
3098 /*
3099 * Validate input.
3100 *
3101 * Note! We only allow the automatically created default critical section
3102 * to be replaced by this API.
3103 */
3104 PDMDEV_ASSERT_DEVINS(pDevIns);
3105 AssertPtrReturn(pCritSect, VERR_INVALID_POINTER);
3106 LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: pCritSect=%p (%s)\n",
3107 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pCritSect->s.pszName));
3108 AssertReturn(PDMCritSectIsInitialized(pCritSect), VERR_INVALID_PARAMETER);
3109 PVM pVM = pDevIns->Internal.s.pVMR3;
3110
3111 VM_ASSERT_EMT(pVM);
3112 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
3113
3114 AssertReturn(pDevIns->pCritSectRoR3, VERR_PDM_DEV_IPE_1);
3115 AssertReturn(pDevIns->pCritSectRoR3->s.fAutomaticDefaultCritsect, VERR_WRONG_ORDER);
3116 AssertReturn(!pDevIns->pCritSectRoR3->s.fUsedByTimerOrSimilar, VERR_WRONG_ORDER);
3117 AssertReturn(pDevIns->pCritSectRoR3 != pCritSect, VERR_INVALID_PARAMETER);
3118
3119 /*
3120 * Replace the critical section and destroy the automatic default section.
3121 */
3122 PPDMCRITSECT pOldCritSect = pDevIns->pCritSectRoR3;
3123 pDevIns->pCritSectRoR3 = pCritSect;
3124 pDevIns->Internal.s.fIntFlags |= PDMDEVINSINT_FLAGS_CHANGED_CRITSECT;
3125
3126 Assert(RT_BOOL(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED) == pDevIns->fR0Enabled);
3127 if ( (pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED)
3128 && !(pDevIns->Internal.s.pDevR3->pReg->fFlags & PDM_DEVREG_FLAGS_NEW_STYLE))
3129 {
3130 PDMDEVICECOMPATSETCRITSECTREQ Req;
3131 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
3132 Req.Hdr.cbReq = sizeof(Req);
3133 Req.idxR0Device = pDevIns->Internal.s.idxR0Device;
3134 Req.pDevInsR3 = pDevIns;
3135 Req.pCritSectR3 = pCritSect;
3136 int rc = VMMR3CallR0(pVM, VMMR0_DO_PDM_DEVICE_COMPAT_SET_CRITSECT, 0, &Req.Hdr);
3137 AssertLogRelRCReturn(rc, rc);
3138 }
3139
3140 PDMR3CritSectDelete(pVM, pOldCritSect);
3141 Assert((uintptr_t)pOldCritSect - (uintptr_t)pDevIns < pDevIns->cbRing3);
3142
3143 LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
3144 return VINF_SUCCESS;
3145}
3146
3147
3148/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectYield} */
3149static DECLCALLBACK(bool) pdmR3DevHlp_CritSectYield(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3150{
3151 PDMDEV_ASSERT_DEVINS(pDevIns);
3152 return PDMR3CritSectYield(pDevIns->Internal.s.pVMR3, pCritSect);
3153}
3154
3155
3156/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectEnter} */
3157static DECLCALLBACK(int) pdmR3DevHlp_CritSectEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy)
3158{
3159 PDMDEV_ASSERT_DEVINS(pDevIns);
3160 return PDMCritSectEnter(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy);
3161}
3162
3163
3164/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectEnterDebug} */
3165static DECLCALLBACK(int) pdmR3DevHlp_CritSectEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
3166{
3167 PDMDEV_ASSERT_DEVINS(pDevIns);
3168 return PDMCritSectEnterDebug(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
3169}
3170
3171
3172/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectTryEnter} */
3173static DECLCALLBACK(int) pdmR3DevHlp_CritSectTryEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3174{
3175 PDMDEV_ASSERT_DEVINS(pDevIns);
3176 return PDMCritSectTryEnter(pDevIns->Internal.s.pVMR3, pCritSect);
3177}
3178
3179
3180/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectTryEnterDebug} */
3181static DECLCALLBACK(int) pdmR3DevHlp_CritSectTryEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
3182{
3183 PDMDEV_ASSERT_DEVINS(pDevIns);
3184 return PDMCritSectTryEnterDebug(pDevIns->Internal.s.pVMR3, pCritSect, uId, RT_SRC_POS_ARGS);
3185}
3186
3187
3188/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectLeave} */
3189static DECLCALLBACK(int) pdmR3DevHlp_CritSectLeave(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3190{
3191 PDMDEV_ASSERT_DEVINS(pDevIns);
3192 return PDMCritSectLeave(pDevIns->Internal.s.pVMR3, pCritSect);
3193}
3194
3195
3196/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectIsOwner} */
3197static DECLCALLBACK(bool) pdmR3DevHlp_CritSectIsOwner(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3198{
3199 PDMDEV_ASSERT_DEVINS(pDevIns);
3200 return PDMCritSectIsOwner(pDevIns->Internal.s.pVMR3, pCritSect);
3201}
3202
3203
3204/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectIsInitialized} */
3205static DECLCALLBACK(bool) pdmR3DevHlp_CritSectIsInitialized(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3206{
3207 PDMDEV_ASSERT_DEVINS(pDevIns);
3208 RT_NOREF(pDevIns);
3209 return PDMCritSectIsInitialized(pCritSect);
3210}
3211
3212
3213/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectHasWaiters} */
3214static DECLCALLBACK(bool) pdmR3DevHlp_CritSectHasWaiters(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3215{
3216 PDMDEV_ASSERT_DEVINS(pDevIns);
3217 return PDMCritSectHasWaiters(pDevIns->Internal.s.pVMR3, pCritSect);
3218}
3219
3220
3221/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetRecursion} */
3222static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectGetRecursion(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
3223{
3224 PDMDEV_ASSERT_DEVINS(pDevIns);
3225 RT_NOREF(pDevIns);
3226 return PDMCritSectGetRecursion(pCritSect);
3227}
3228
3229
3230/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectScheduleExitEvent} */
3231static DECLCALLBACK(int) pdmR3DevHlp_CritSectScheduleExitEvent(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect,
3232 SUPSEMEVENT hEventToSignal)
3233{
3234 PDMDEV_ASSERT_DEVINS(pDevIns);
3235 RT_NOREF(pDevIns);
3236 return PDMHCCritSectScheduleExitEvent(pCritSect, hEventToSignal);
3237}
3238
3239
3240/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectDelete} */
3241static DECLCALLBACK(int) pdmR3DevHlp_CritSectDelete(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
3242{
3243 PDMDEV_ASSERT_DEVINS(pDevIns);
3244 return PDMR3CritSectDelete(pDevIns->Internal.s.pVMR3, pCritSect);
3245}
3246
3247
3248/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwInit} */
3249static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwInit(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
3250 const char *pszNameFmt, va_list va)
3251{
3252 PDMDEV_ASSERT_DEVINS(pDevIns);
3253 LogFlow(("pdmR3DevHlp_CritSectRwInit: caller='%s'/%d: pCritSect=%p pszNameFmt=%p:{%s}\n",
3254 pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pszNameFmt, pszNameFmt));
3255
3256 PVM pVM = pDevIns->Internal.s.pVMR3;
3257 VM_ASSERT_EMT(pVM);
3258 int rc = pdmR3CritSectRwInitDevice(pVM, pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
3259
3260 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3261 return rc;
3262}
3263
3264
3265/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwDelete} */
3266static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwDelete(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3267{
3268 PDMDEV_ASSERT_DEVINS(pDevIns);
3269 return PDMR3CritSectRwDelete(pDevIns->Internal.s.pVMR3, pCritSect);
3270}
3271
3272
3273/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterShared} */
3274static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy)
3275{
3276 PDMDEV_ASSERT_DEVINS(pDevIns);
3277 return PDMCritSectRwEnterShared(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy);
3278}
3279
3280
3281/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterSharedDebug} */
3282static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterSharedDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy,
3283 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3284{
3285 PDMDEV_ASSERT_DEVINS(pDevIns);
3286 return PDMCritSectRwEnterSharedDebug(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
3287}
3288
3289
3290/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterShared} */
3291static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3292{
3293 PDMDEV_ASSERT_DEVINS(pDevIns);
3294 return PDMCritSectRwTryEnterShared(pDevIns->Internal.s.pVMR3, pCritSect);
3295}
3296
3297
3298/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterSharedDebug} */
3299static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterSharedDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect,
3300 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3301{
3302 PDMDEV_ASSERT_DEVINS(pDevIns);
3303 return PDMCritSectRwTryEnterSharedDebug(pDevIns->Internal.s.pVMR3, pCritSect, uId, RT_SRC_POS_ARGS);
3304}
3305
3306
3307/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwLeaveShared} */
3308static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwLeaveShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3309{
3310 PDMDEV_ASSERT_DEVINS(pDevIns);
3311 return PDMCritSectRwLeaveShared(pDevIns->Internal.s.pVMR3, pCritSect);
3312}
3313
3314
3315/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterExcl} */
3316static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy)
3317{
3318 PDMDEV_ASSERT_DEVINS(pDevIns);
3319 return PDMCritSectRwEnterExcl(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy);
3320}
3321
3322
3323/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwEnterExclDebug} */
3324static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwEnterExclDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy,
3325 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3326{
3327 PDMDEV_ASSERT_DEVINS(pDevIns);
3328 return PDMCritSectRwEnterExclDebug(pDevIns->Internal.s.pVMR3, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
3329}
3330
3331
3332/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterExcl} */
3333static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3334{
3335 PDMDEV_ASSERT_DEVINS(pDevIns);
3336 return PDMCritSectRwTryEnterExcl(pDevIns->Internal.s.pVMR3, pCritSect);
3337}
3338
3339
3340/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwTryEnterExclDebug} */
3341static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwTryEnterExclDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect,
3342 RTHCUINTPTR uId, RT_SRC_POS_DECL)
3343{
3344 PDMDEV_ASSERT_DEVINS(pDevIns);
3345 return PDMCritSectRwTryEnterExclDebug(pDevIns->Internal.s.pVMR3, pCritSect, uId, RT_SRC_POS_ARGS);
3346}
3347
3348
3349/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwLeaveExcl} */
3350static DECLCALLBACK(int) pdmR3DevHlp_CritSectRwLeaveExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3351{
3352 PDMDEV_ASSERT_DEVINS(pDevIns);
3353 return PDMCritSectRwLeaveExcl(pDevIns->Internal.s.pVMR3, pCritSect);
3354}
3355
3356
3357/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwIsWriteOwner} */
3358static DECLCALLBACK(bool) pdmR3DevHlp_CritSectRwIsWriteOwner(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3359{
3360 PDMDEV_ASSERT_DEVINS(pDevIns);
3361 return PDMCritSectRwIsWriteOwner(pDevIns->Internal.s.pVMR3, pCritSect);
3362}
3363
3364
3365/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwIsReadOwner} */
3366static DECLCALLBACK(bool) pdmR3DevHlp_CritSectRwIsReadOwner(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, bool fWannaHear)
3367{
3368 PDMDEV_ASSERT_DEVINS(pDevIns);
3369 return PDMCritSectRwIsReadOwner(pDevIns->Internal.s.pVMR3, pCritSect, fWannaHear);
3370}
3371
3372
3373/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwGetWriteRecursion} */
3374static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectRwGetWriteRecursion(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3375{
3376 PDMDEV_ASSERT_DEVINS(pDevIns);
3377 RT_NOREF(pDevIns);
3378 return PDMCritSectRwGetWriteRecursion(pCritSect);
3379}
3380
3381
3382/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwGetWriterReadRecursion} */
3383static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectRwGetWriterReadRecursion(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3384{
3385 PDMDEV_ASSERT_DEVINS(pDevIns);
3386 RT_NOREF(pDevIns);
3387 return PDMCritSectRwGetWriterReadRecursion(pCritSect);
3388}
3389
3390
3391/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwGetReadCount} */
3392static DECLCALLBACK(uint32_t) pdmR3DevHlp_CritSectRwGetReadCount(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3393{
3394 PDMDEV_ASSERT_DEVINS(pDevIns);
3395 RT_NOREF(pDevIns);
3396 return PDMCritSectRwGetReadCount(pCritSect);
3397}
3398
3399
3400/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectRwIsInitialized} */
3401static DECLCALLBACK(bool) pdmR3DevHlp_CritSectRwIsInitialized(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
3402{
3403 PDMDEV_ASSERT_DEVINS(pDevIns);
3404 RT_NOREF(pDevIns);
3405 return PDMCritSectRwIsInitialized(pCritSect);
3406}
3407
3408
3409/** @interface_method_impl{PDMDEVHLPR3,pfnThreadCreate} */
3410static DECLCALLBACK(int) pdmR3DevHlp_ThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
3411 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
3412{
3413 PDMDEV_ASSERT_DEVINS(pDevIns);
3414 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3415 LogFlow(("pdmR3DevHlp_ThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",
3416 pDevIns->pReg->szName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));
3417
3418 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
3419
3420 LogFlow(("pdmR3DevHlp_ThreadCreate: caller='%s'/%d: returns %Rrc *ppThread=%RTthrd\n", pDevIns->pReg->szName, pDevIns->iInstance,
3421 rc, *ppThread));
3422 return rc;
3423}
3424
3425
3426/** @interface_method_impl{PDMDEVHLPR3,pfnSetAsyncNotification} */
3427static DECLCALLBACK(int) pdmR3DevHlp_SetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
3428{
3429 PDMDEV_ASSERT_DEVINS(pDevIns);
3430 VM_ASSERT_EMT0(pDevIns->Internal.s.pVMR3);
3431 LogFlow(("pdmR3DevHlp_SetAsyncNotification: caller='%s'/%d: pfnAsyncNotify=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pfnAsyncNotify));
3432
3433 int rc = VINF_SUCCESS;
3434 AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER);
3435 AssertStmt(!pDevIns->Internal.s.pfnAsyncNotify, rc = VERR_WRONG_ORDER);
3436 AssertStmt(pDevIns->Internal.s.fIntFlags & (PDMDEVINSINT_FLAGS_SUSPENDED | PDMDEVINSINT_FLAGS_RESET), rc = VERR_WRONG_ORDER);
3437 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);
3438 AssertStmt( enmVMState == VMSTATE_SUSPENDING
3439 || enmVMState == VMSTATE_SUSPENDING_EXT_LS
3440 || enmVMState == VMSTATE_SUSPENDING_LS
3441 || enmVMState == VMSTATE_RESETTING
3442 || enmVMState == VMSTATE_RESETTING_LS
3443 || enmVMState == VMSTATE_POWERING_OFF
3444 || enmVMState == VMSTATE_POWERING_OFF_LS,
3445 rc = VERR_INVALID_STATE);
3446
3447 if (RT_SUCCESS(rc))
3448 pDevIns->Internal.s.pfnAsyncNotify = pfnAsyncNotify;
3449
3450 LogFlow(("pdmR3DevHlp_SetAsyncNotification: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
3451 return rc;
3452}
3453
3454
3455/** @interface_method_impl{PDMDEVHLPR3,pfnAsyncNotificationCompleted} */
3456static DECLCALLBACK(void) pdmR3DevHlp_AsyncNotificationCompleted(PPDMDEVINS pDevIns)
3457{
3458 PDMDEV_ASSERT_DEVINS(pDevIns);
3459 PVM pVM = pDevIns->Internal.s.pVMR3;
3460
3461 VMSTATE enmVMState = VMR3GetState(pVM);
3462 if ( enmVMState == VMSTATE_SUSPENDING
3463 || enmVMState == VMSTATE_SUSPENDING_EXT_LS
3464 || enmVMState == VMSTATE_SUSPENDING_LS
3465 || enmVMState == VMSTATE_RESETTING
3466 || enmVMState == VMSTATE_RESETTING_LS
3467 || enmVMState == VMSTATE_POWERING_OFF
3468 || enmVMState == VMSTATE_POWERING_OFF_LS)
3469 {
3470 LogFlow(("pdmR3DevHlp_AsyncNotificationCompleted: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
3471 VMR3AsyncPdmNotificationWakeupU(pVM->pUVM);
3472 }
3473 else
3474 LogFlow(("pdmR3DevHlp_AsyncNotificationCompleted: caller='%s'/%d: enmVMState=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, enmVMState));
3475}
3476
3477
3478/** @interface_method_impl{PDMDEVHLPR3,pfnRTCRegister} */
3479static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
3480{
3481 PDMDEV_ASSERT_DEVINS(pDevIns);
3482 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3483 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n",
3484 pDevIns->pReg->szName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite,
3485 pRtcReg->pfnWrite, ppRtcHlp));
3486
3487 /*
3488 * Validate input.
3489 */
3490 if (pRtcReg->u32Version != PDM_RTCREG_VERSION)
3491 {
3492 AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version,
3493 PDM_RTCREG_VERSION));
3494 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (version)\n",
3495 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3496 return VERR_INVALID_PARAMETER;
3497 }
3498 if ( !pRtcReg->pfnWrite
3499 || !pRtcReg->pfnRead)
3500 {
3501 Assert(pRtcReg->pfnWrite);
3502 Assert(pRtcReg->pfnRead);
3503 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
3504 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3505 return VERR_INVALID_PARAMETER;
3506 }
3507
3508 if (!ppRtcHlp)
3509 {
3510 Assert(ppRtcHlp);
3511 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (ppRtcHlp)\n",
3512 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3513 return VERR_INVALID_PARAMETER;
3514 }
3515
3516 /*
3517 * Only one DMA device.
3518 */
3519 PVM pVM = pDevIns->Internal.s.pVMR3;
3520 if (pVM->pdm.s.pRtc)
3521 {
3522 AssertMsgFailed(("Only one RTC device is supported!\n"));
3523 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc\n",
3524 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
3525 return VERR_INVALID_PARAMETER;
3526 }
3527
3528 /*
3529 * Allocate and initialize pci bus structure.
3530 */
3531 int rc = VINF_SUCCESS;
3532 PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc));
3533 if (pRtc)
3534 {
3535 pRtc->pDevIns = pDevIns;
3536 pRtc->Reg = *pRtcReg;
3537 pVM->pdm.s.pRtc = pRtc;
3538
3539 /* set the helper pointer. */
3540 *ppRtcHlp = &g_pdmR3DevRtcHlp;
3541 Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n",
3542 pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
3543 }
3544 else
3545 rc = VERR_NO_MEMORY;
3546
3547 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc\n",
3548 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3549 return rc;
3550}
3551
3552
3553/** @interface_method_impl{PDMDEVHLPR3,pfnDMARegister} */
3554static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
3555{
3556 PDMDEV_ASSERT_DEVINS(pDevIns);
3557 PVM pVM = pDevIns->Internal.s.pVMR3;
3558 VM_ASSERT_EMT(pVM);
3559 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n",
3560 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser));
3561 int rc = VINF_SUCCESS;
3562 if (pVM->pdm.s.pDmac)
3563 pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pDevIns, pfnTransferHandler, pvUser);
3564 else
3565 {
3566 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3567 rc = VERR_PDM_NO_DMAC_INSTANCE;
3568 }
3569 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Rrc\n",
3570 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3571 return rc;
3572}
3573
3574
3575/** @interface_method_impl{PDMDEVHLPR3,pfnDMAReadMemory} */
3576static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
3577{
3578 PDMDEV_ASSERT_DEVINS(pDevIns);
3579 PVM pVM = pDevIns->Internal.s.pVMR3;
3580 VM_ASSERT_EMT(pVM);
3581 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n",
3582 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead));
3583 int rc = VINF_SUCCESS;
3584 if (pVM->pdm.s.pDmac)
3585 {
3586 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
3587 if (pcbRead)
3588 *pcbRead = cb;
3589 }
3590 else
3591 {
3592 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3593 rc = VERR_PDM_NO_DMAC_INSTANCE;
3594 }
3595 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Rrc\n",
3596 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3597 return rc;
3598}
3599
3600
3601/** @interface_method_impl{PDMDEVHLPR3,pfnDMAWriteMemory} */
3602static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
3603{
3604 PDMDEV_ASSERT_DEVINS(pDevIns);
3605 PVM pVM = pDevIns->Internal.s.pVMR3;
3606 VM_ASSERT_EMT(pVM);
3607 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n",
3608 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten));
3609 int rc = VINF_SUCCESS;
3610 if (pVM->pdm.s.pDmac)
3611 {
3612 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
3613 if (pcbWritten)
3614 *pcbWritten = cb;
3615 }
3616 else
3617 {
3618 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3619 rc = VERR_PDM_NO_DMAC_INSTANCE;
3620 }
3621 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Rrc\n",
3622 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3623 return rc;
3624}
3625
3626
3627/** @interface_method_impl{PDMDEVHLPR3,pfnDMASetDREQ} */
3628static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
3629{
3630 PDMDEV_ASSERT_DEVINS(pDevIns);
3631 PVM pVM = pDevIns->Internal.s.pVMR3;
3632 VM_ASSERT_EMT(pVM);
3633 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n",
3634 pDevIns->pReg->szName, pDevIns->iInstance, uChannel, uLevel));
3635 int rc = VINF_SUCCESS;
3636 if (pVM->pdm.s.pDmac)
3637 pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel);
3638 else
3639 {
3640 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3641 rc = VERR_PDM_NO_DMAC_INSTANCE;
3642 }
3643 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Rrc\n",
3644 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3645 return rc;
3646}
3647
3648/** @interface_method_impl{PDMDEVHLPR3,pfnDMAGetChannelMode} */
3649static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
3650{
3651 PDMDEV_ASSERT_DEVINS(pDevIns);
3652 PVM pVM = pDevIns->Internal.s.pVMR3;
3653 VM_ASSERT_EMT(pVM);
3654 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n",
3655 pDevIns->pReg->szName, pDevIns->iInstance, uChannel));
3656 uint8_t u8Mode;
3657 if (pVM->pdm.s.pDmac)
3658 u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel);
3659 else
3660 {
3661 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3662 u8Mode = 3 << 2 /* illegal mode type */;
3663 }
3664 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n",
3665 pDevIns->pReg->szName, pDevIns->iInstance, u8Mode));
3666 return u8Mode;
3667}
3668
3669/** @interface_method_impl{PDMDEVHLPR3,pfnDMASchedule} */
3670static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns)
3671{
3672 PDMDEV_ASSERT_DEVINS(pDevIns);
3673 PVM pVM = pDevIns->Internal.s.pVMR3;
3674 VM_ASSERT_EMT(pVM);
3675 LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n",
3676 pDevIns->pReg->szName, pDevIns->iInstance, VM_FF_IS_SET(pVM, VM_FF_PDM_DMA)));
3677
3678 AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
3679 VM_FF_SET(pVM, VM_FF_PDM_DMA);
3680 VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
3681}
3682
3683
3684/** @interface_method_impl{PDMDEVHLPR3,pfnCMOSWrite} */
3685static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
3686{
3687 PDMDEV_ASSERT_DEVINS(pDevIns);
3688 PVM pVM = pDevIns->Internal.s.pVMR3;
3689 VM_ASSERT_EMT(pVM);
3690
3691 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n",
3692 pDevIns->pReg->szName, pDevIns->iInstance, iReg, u8Value));
3693 int rc;
3694 if (pVM->pdm.s.pRtc)
3695 {
3696 PPDMDEVINS pDevInsRtc = pVM->pdm.s.pRtc->pDevIns;
3697 rc = PDMCritSectEnter(pVM, pDevInsRtc->pCritSectRoR3, VERR_IGNORED);
3698 if (RT_SUCCESS(rc))
3699 {
3700 rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pDevInsRtc, iReg, u8Value);
3701 PDMCritSectLeave(pVM, pDevInsRtc->pCritSectRoR3);
3702 }
3703 }
3704 else
3705 rc = VERR_PDM_NO_RTC_INSTANCE;
3706
3707 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Rrc\n",
3708 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3709 return rc;
3710}
3711
3712
3713/** @interface_method_impl{PDMDEVHLPR3,pfnCMOSRead} */
3714static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
3715{
3716 PDMDEV_ASSERT_DEVINS(pDevIns);
3717 PVM pVM = pDevIns->Internal.s.pVMR3;
3718 VM_ASSERT_EMT(pVM);
3719
3720 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n",
3721 pDevIns->pReg->szName, pDevIns->iInstance, iReg, pu8Value));
3722 int rc;
3723 if (pVM->pdm.s.pRtc)
3724 {
3725 PPDMDEVINS pDevInsRtc = pVM->pdm.s.pRtc->pDevIns;
3726 rc = PDMCritSectEnter(pVM, pDevInsRtc->pCritSectRoR3, VERR_IGNORED);
3727 if (RT_SUCCESS(rc))
3728 {
3729 rc = pVM->pdm.s.pRtc->Reg.pfnRead(pDevInsRtc, iReg, pu8Value);
3730 PDMCritSectLeave(pVM, pDevInsRtc->pCritSectRoR3);
3731 }
3732 }
3733 else
3734 rc = VERR_PDM_NO_RTC_INSTANCE;
3735
3736 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Rrc\n",
3737 pDevIns->pReg->szName, pDevIns->iInstance, rc));
3738 return rc;
3739}
3740
3741
3742/** @interface_method_impl{PDMDEVHLPR3,pfnAssertEMT} */
3743static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
3744{
3745 PDMDEV_ASSERT_DEVINS(pDevIns);
3746 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3))
3747 return true;
3748
3749 char szMsg[100];
3750 RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance);
3751 RTAssertMsg1Weak(szMsg, iLine, pszFile, pszFunction);
3752 AssertBreakpoint();
3753 return false;
3754}
3755
3756
3757/** @interface_method_impl{PDMDEVHLPR3,pfnAssertOther} */
3758static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
3759{
3760 PDMDEV_ASSERT_DEVINS(pDevIns);
3761 if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3))
3762 return true;
3763
3764 char szMsg[100];
3765 RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance);
3766 RTAssertMsg1Weak(szMsg, iLine, pszFile, pszFunction);
3767 AssertBreakpoint();
3768 return false;
3769}
3770
3771
3772/** @interface_method_impl{PDMDEVHLPR3,pfnLdrGetRCInterfaceSymbols} */
3773static DECLCALLBACK(int) pdmR3DevHlp_LdrGetRCInterfaceSymbols(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3774 const char *pszSymPrefix, const char *pszSymList)
3775{
3776 PDMDEV_ASSERT_DEVINS(pDevIns);
3777 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3778 LogFlow(("pdmR3DevHlp_PDMLdrGetRCInterfaceSymbols: caller='%s'/%d: pvInterface=%p cbInterface=%zu pszSymPrefix=%p:{%s} pszSymList=%p:{%s}\n",
3779 pDevIns->pReg->szName, pDevIns->iInstance, pvInterface, cbInterface, pszSymPrefix, pszSymPrefix, pszSymList, pszSymList));
3780
3781 int rc;
3782 if ( strncmp(pszSymPrefix, "dev", 3) == 0
3783 && RTStrIStr(pszSymPrefix + 3, pDevIns->pReg->szName) != NULL)
3784 {
3785 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
3786 rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
3787 pvInterface, cbInterface,
3788 pDevIns->pReg->pszRCMod, pDevIns->Internal.s.pDevR3->pszRCSearchPath,
3789 pszSymPrefix, pszSymList,
3790 false /*fRing0OrRC*/);
3791 else
3792 {
3793 AssertMsgFailed(("Not a raw-mode enabled driver\n"));
3794 rc = VERR_PERMISSION_DENIED;
3795 }
3796 }
3797 else
3798 {
3799 AssertMsgFailed(("Invalid prefix '%s' for '%s'; must start with 'dev' and contain the driver name!\n",
3800 pszSymPrefix, pDevIns->pReg->szName));
3801 rc = VERR_INVALID_NAME;
3802 }
3803
3804 LogFlow(("pdmR3DevHlp_PDMLdrGetRCInterfaceSymbols: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
3805 pDevIns->iInstance, rc));
3806 return rc;
3807}
3808
3809
3810/** @interface_method_impl{PDMDEVHLPR3,pfnLdrGetR0InterfaceSymbols} */
3811static DECLCALLBACK(int) pdmR3DevHlp_LdrGetR0InterfaceSymbols(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3812 const char *pszSymPrefix, const char *pszSymList)
3813{
3814 PDMDEV_ASSERT_DEVINS(pDevIns);
3815 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3816 LogFlow(("pdmR3DevHlp_PDMLdrGetR0InterfaceSymbols: caller='%s'/%d: pvInterface=%p cbInterface=%zu pszSymPrefix=%p:{%s} pszSymList=%p:{%s}\n",
3817 pDevIns->pReg->szName, pDevIns->iInstance, pvInterface, cbInterface, pszSymPrefix, pszSymPrefix, pszSymList, pszSymList));
3818
3819 int rc;
3820 if ( strncmp(pszSymPrefix, "dev", 3) == 0
3821 && RTStrIStr(pszSymPrefix + 3, pDevIns->pReg->szName) != NULL)
3822 {
3823 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
3824 rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
3825 pvInterface, cbInterface,
3826 pDevIns->pReg->pszR0Mod, pDevIns->Internal.s.pDevR3->pszR0SearchPath,
3827 pszSymPrefix, pszSymList,
3828 true /*fRing0OrRC*/);
3829 else
3830 {
3831 AssertMsgFailed(("Not a ring-0 enabled driver\n"));
3832 rc = VERR_PERMISSION_DENIED;
3833 }
3834 }
3835 else
3836 {
3837 AssertMsgFailed(("Invalid prefix '%s' for '%s'; must start with 'dev' and contain the driver name!\n",
3838 pszSymPrefix, pDevIns->pReg->szName));
3839 rc = VERR_INVALID_NAME;
3840 }
3841
3842 LogFlow(("pdmR3DevHlp_PDMLdrGetR0InterfaceSymbols: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
3843 pDevIns->iInstance, rc));
3844 return rc;
3845}
3846
3847
3848/** @interface_method_impl{PDMDEVHLPR3,pfnCallR0} */
3849static DECLCALLBACK(int) pdmR3DevHlp_CallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
3850{
3851 PDMDEV_ASSERT_DEVINS(pDevIns);
3852 PVM pVM = pDevIns->Internal.s.pVMR3;
3853 PVMCPU pVCpu = VMMGetCpu(pVM);
3854 AssertReturn(pVCpu, VERR_VM_THREAD_IS_EMT);
3855 LogFlow(("pdmR3DevHlp_CallR0: caller='%s'/%d: uOperation=%#x u64Arg=%#RX64\n",
3856 pDevIns->pReg->szName, pDevIns->iInstance, uOperation, u64Arg));
3857
3858 /*
3859 * Resolve the ring-0 entry point. There is not need to remember this like
3860 * we do for drivers since this is mainly for construction time hacks and
3861 * other things that aren't performance critical.
3862 */
3863 int rc;
3864 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
3865 {
3866 /*
3867 * Make the ring-0 call.
3868 */
3869 PDMDEVICEGENCALLREQ Req;
3870 RT_ZERO(Req.Params);
3871 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
3872 Req.Hdr.cbReq = sizeof(Req);
3873 Req.pDevInsR3 = pDevIns;
3874 Req.idxR0Device = pDevIns->Internal.s.idxR0Device;
3875 Req.enmCall = PDMDEVICEGENCALL_REQUEST;
3876 Req.Params.Req.uReq = uOperation;
3877 Req.Params.Req.uArg = u64Arg;
3878 rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_PDM_DEVICE_GEN_CALL, 0, &Req.Hdr);
3879 }
3880 else
3881 rc = VERR_ACCESS_DENIED;
3882 LogFlow(("pdmR3DevHlp_CallR0: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
3883 pDevIns->iInstance, rc));
3884 return rc;
3885}
3886
3887
3888/** @interface_method_impl{PDMDEVHLPR3,pfnVMGetSuspendReason} */
3889static DECLCALLBACK(VMSUSPENDREASON) pdmR3DevHlp_VMGetSuspendReason(PPDMDEVINS pDevIns)
3890{
3891 PDMDEV_ASSERT_DEVINS(pDevIns);
3892 PVM pVM = pDevIns->Internal.s.pVMR3;
3893 VM_ASSERT_EMT(pVM);
3894 VMSUSPENDREASON enmReason = VMR3GetSuspendReason(pVM->pUVM);
3895 LogFlow(("pdmR3DevHlp_VMGetSuspendReason: caller='%s'/%d: returns %d\n",
3896 pDevIns->pReg->szName, pDevIns->iInstance, enmReason));
3897 return enmReason;
3898}
3899
3900
3901/** @interface_method_impl{PDMDEVHLPR3,pfnVMGetResumeReason} */
3902static DECLCALLBACK(VMRESUMEREASON) pdmR3DevHlp_VMGetResumeReason(PPDMDEVINS pDevIns)
3903{
3904 PDMDEV_ASSERT_DEVINS(pDevIns);
3905 PVM pVM = pDevIns->Internal.s.pVMR3;
3906 VM_ASSERT_EMT(pVM);
3907 VMRESUMEREASON enmReason = VMR3GetResumeReason(pVM->pUVM);
3908 LogFlow(("pdmR3DevHlp_VMGetResumeReason: caller='%s'/%d: returns %d\n",
3909 pDevIns->pReg->szName, pDevIns->iInstance, enmReason));
3910 return enmReason;
3911}
3912
3913
3914/** @interface_method_impl{PDMDEVHLPR3,pfnGetUVM} */
3915static DECLCALLBACK(PUVM) pdmR3DevHlp_GetUVM(PPDMDEVINS pDevIns)
3916{
3917 PDMDEV_ASSERT_DEVINS(pDevIns);
3918 LogFlow(("pdmR3DevHlp_GetUVM: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));
3919 return pDevIns->Internal.s.pVMR3->pUVM;
3920}
3921
3922
3923/** @interface_method_impl{PDMDEVHLPR3,pfnGetVM} */
3924static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns)
3925{
3926 PDMDEV_ASSERT_DEVINS(pDevIns);
3927 LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));
3928 return pDevIns->Internal.s.pVMR3;
3929}
3930
3931
3932/** @interface_method_impl{PDMDEVHLPR3,pfnGetVMCPU} */
3933static DECLCALLBACK(PVMCPU) pdmR3DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
3934{
3935 PDMDEV_ASSERT_DEVINS(pDevIns);
3936 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
3937 LogFlow(("pdmR3DevHlp_GetVMCPU: caller='%s'/%d for CPU %u\n", pDevIns->pReg->szName, pDevIns->iInstance, VMMGetCpuId(pDevIns->Internal.s.pVMR3)));
3938 return VMMGetCpu(pDevIns->Internal.s.pVMR3);
3939}
3940
3941
3942/** @interface_method_impl{PDMDEVHLPR3,pfnGetCurrentCpuId} */
3943static DECLCALLBACK(VMCPUID) pdmR3DevHlp_GetCurrentCpuId(PPDMDEVINS pDevIns)
3944{
3945 PDMDEV_ASSERT_DEVINS(pDevIns);
3946 VMCPUID idCpu = VMMGetCpuId(pDevIns->Internal.s.pVMR3);
3947 LogFlow(("pdmR3DevHlp_GetCurrentCpuId: caller='%s'/%d for CPU %u\n", pDevIns->pReg->szName, pDevIns->iInstance, idCpu));
3948 return idCpu;
3949}
3950
3951
3952/** @interface_method_impl{PDMDEVHLPR3,pfnPCIBusRegister} */
3953static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREGR3 pPciBusReg,
3954 PCPDMPCIHLPR3 *ppPciHlp, uint32_t *piBus)
3955{
3956 PDMDEV_ASSERT_DEVINS(pDevIns);
3957 PVM pVM = pDevIns->Internal.s.pVMR3;
3958 VM_ASSERT_EMT(pVM);
3959 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, "
3960 ".pfnInterceptConfigAccesses=%p, pfnConfigRead=%p, pfnConfigWrite=%p, .pfnSetIrqR3=%p, .u32EndVersion=%#x} ppPciHlpR3=%p piBus=%p\n",
3961 pDevIns->pReg->szName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3,
3962 pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnInterceptConfigAccesses, pPciBusReg->pfnConfigRead,
3963 pPciBusReg->pfnConfigWrite, pPciBusReg->pfnSetIrqR3, pPciBusReg->u32EndVersion, ppPciHlp, piBus));
3964
3965 /*
3966 * Validate the structure and output parameters.
3967 */
3968 AssertLogRelMsgReturn(pPciBusReg->u32Version == PDM_PCIBUSREGR3_VERSION,
3969 ("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREGR3_VERSION),
3970 VERR_INVALID_PARAMETER);
3971 AssertPtrReturn(pPciBusReg->pfnRegisterR3, VERR_INVALID_PARAMETER);
3972 AssertPtrNullReturn(pPciBusReg->pfnRegisterMsiR3, VERR_INVALID_POINTER);
3973 AssertPtrReturn(pPciBusReg->pfnIORegionRegisterR3, VERR_INVALID_POINTER);
3974 AssertPtrReturn(pPciBusReg->pfnInterceptConfigAccesses, VERR_INVALID_POINTER);
3975 AssertPtrReturn(pPciBusReg->pfnConfigWrite, VERR_INVALID_POINTER);
3976 AssertPtrReturn(pPciBusReg->pfnConfigRead, VERR_INVALID_POINTER);
3977 AssertPtrReturn(pPciBusReg->pfnSetIrqR3, VERR_INVALID_POINTER);
3978 AssertLogRelMsgReturn(pPciBusReg->u32EndVersion == PDM_PCIBUSREGR3_VERSION,
3979 ("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREGR3_VERSION),
3980 VERR_INVALID_PARAMETER);
3981 AssertPtrReturn(ppPciHlp, VERR_INVALID_POINTER);
3982 AssertPtrNullReturn(piBus, VERR_INVALID_POINTER);
3983 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
3984
3985 /*
3986 * Find free PCI bus entry.
3987 */
3988 unsigned iBus = 0;
3989 for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++)
3990 if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3)
3991 break;
3992 AssertLogRelMsgReturn(iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses),
3993 ("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses)),
3994 VERR_OUT_OF_RESOURCES);
3995 PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus];
3996
3997 /*
3998 * Init the R3 bits.
3999 */
4000 pPciBus->iBus = iBus;
4001 pPciBus->pDevInsR3 = pDevIns;
4002 pPciBus->pfnRegister = pPciBusReg->pfnRegisterR3;
4003 pPciBus->pfnRegisterMsi = pPciBusReg->pfnRegisterMsiR3;
4004 pPciBus->pfnIORegionRegister = pPciBusReg->pfnIORegionRegisterR3;
4005 pPciBus->pfnInterceptConfigAccesses = pPciBusReg->pfnInterceptConfigAccesses;
4006 pPciBus->pfnConfigRead = pPciBusReg->pfnConfigRead;
4007 pPciBus->pfnConfigWrite = pPciBusReg->pfnConfigWrite;
4008 pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3;
4009
4010 Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4011
4012 /* set the helper pointer and return. */
4013 *ppPciHlp = &g_pdmR3DevPciHlp;
4014 if (piBus)
4015 *piBus = iBus;
4016 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc *piBus=%u\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS, iBus));
4017 return VINF_SUCCESS;
4018}
4019
4020
4021/** @interface_method_impl{PDMDEVHLPR3,pfnIommuRegister} */
4022static DECLCALLBACK(int) pdmR3DevHlp_IommuRegister(PPDMDEVINS pDevIns, PPDMIOMMUREGR3 pIommuReg, PCPDMIOMMUHLPR3 *ppIommuHlp,
4023 uint32_t *pidxIommu)
4024{
4025 PDMDEV_ASSERT_DEVINS(pDevIns);
4026 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4027 LogFlow(("pdmR3DevHlp_IommuRegister: caller='%s'/%d: pIommuReg=%p:{.u32Version=%#x, .u32TheEnd=%#x } ppIommuHlp=%p\n",
4028 pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg, pIommuReg->u32Version, pIommuReg->u32TheEnd, ppIommuHlp));
4029 PVM pVM = pDevIns->Internal.s.pVMR3;
4030
4031 /*
4032 * Validate input.
4033 */
4034 AssertMsgReturn(pIommuReg->u32Version == PDM_IOMMUREGR3_VERSION,
4035 ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg->u32Version, PDM_IOMMUREGR3_VERSION),
4036 VERR_INVALID_PARAMETER);
4037 AssertPtrReturn(pIommuReg->pfnMemAccess, VERR_INVALID_POINTER);
4038 AssertPtrReturn(pIommuReg->pfnMemBulkAccess, VERR_INVALID_POINTER);
4039 AssertPtrReturn(pIommuReg->pfnMsiRemap, VERR_INVALID_POINTER);
4040 AssertMsgReturn(pIommuReg->u32TheEnd == PDM_IOMMUREGR3_VERSION,
4041 ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg->u32TheEnd, PDM_IOMMUREGR3_VERSION),
4042 VERR_INVALID_PARAMETER);
4043 AssertPtrReturn(ppIommuHlp, VERR_INVALID_POINTER);
4044
4045 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4046 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4047
4048 /*
4049 * Find free IOMMU slot.
4050 * The IOMMU at the root complex is the one at 0.
4051 */
4052 unsigned idxIommu = 0;
4053#if 0
4054 for (idxIommu = 0; idxIommu < RT_ELEMENTS(pVM->pdm.s.aIommus); idxIommu++)
4055 if (!pVM->pdm.s.aIommus[idxIommu].pDevInsR3)
4056 break;
4057 AssertLogRelMsgReturn(idxIommu < RT_ELEMENTS(pVM->pdm.s.aIommus),
4058 ("Too many IOMMUs. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aIommus)),
4059 VERR_OUT_OF_RESOURCES);
4060#else
4061 /* Currently we support only a single IOMMU. */
4062 AssertMsgReturn(!pVM->pdm.s.aIommus[0].pDevInsR3,
4063 ("%s/%u: Only one IOMMU device is supported!\n", pDevIns->pReg->szName, pDevIns->iInstance),
4064 VERR_ALREADY_EXISTS);
4065#endif
4066 PPDMIOMMUR3 pIommu = &pVM->pdm.s.aIommus[idxIommu];
4067
4068 /*
4069 * Init the R3 bits.
4070 */
4071 pIommu->idxIommu = idxIommu;
4072 pIommu->pDevInsR3 = pDevIns;
4073 pIommu->pfnMemAccess = pIommuReg->pfnMemAccess;
4074 pIommu->pfnMemBulkAccess = pIommuReg->pfnMemBulkAccess;
4075 pIommu->pfnMsiRemap = pIommuReg->pfnMsiRemap;
4076 Log(("PDM: Registered IOMMU device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4077
4078 /* Set the helper pointer and return. */
4079 *ppIommuHlp = &g_pdmR3DevIommuHlp;
4080 if (pidxIommu)
4081 *pidxIommu = idxIommu;
4082 LogFlow(("pdmR3DevHlp_IommuRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4083 return VINF_SUCCESS;
4084}
4085
4086
4087
4088/** @interface_method_impl{PDMDEVHLPR3,pfnPICRegister} */
4089static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
4090{
4091 PDMDEV_ASSERT_DEVINS(pDevIns);
4092 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4093 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnGetInterrupt=%p, .u32TheEnd=%#x } ppPicHlp=%p\n",
4094 pDevIns->pReg->szName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrq, pPicReg->pfnGetInterrupt, pPicReg->u32TheEnd, ppPicHlp));
4095 PVM pVM = pDevIns->Internal.s.pVMR3;
4096
4097 /*
4098 * Validate input.
4099 */
4100 AssertMsgReturn(pPicReg->u32Version == PDM_PICREG_VERSION,
4101 ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32Version, PDM_PICREG_VERSION),
4102 VERR_INVALID_PARAMETER);
4103 AssertPtrReturn(pPicReg->pfnSetIrq, VERR_INVALID_POINTER);
4104 AssertPtrReturn(pPicReg->pfnGetInterrupt, VERR_INVALID_POINTER);
4105 AssertMsgReturn(pPicReg->u32TheEnd == PDM_PICREG_VERSION,
4106 ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32TheEnd, PDM_PICREG_VERSION),
4107 VERR_INVALID_PARAMETER);
4108 AssertPtrReturn(ppPicHlp, VERR_INVALID_POINTER);
4109
4110 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4111 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4112
4113 /*
4114 * Only one PIC device.
4115 */
4116 AssertMsgReturn(pVM->pdm.s.Pic.pDevInsR3 == NULL, ("%s/%d: Only one PIC!\n", pDevIns->pReg->szName, pDevIns->iInstance),
4117 VERR_ALREADY_EXISTS);
4118
4119 /*
4120 * Take down the callbacks and instance.
4121 */
4122 pVM->pdm.s.Pic.pDevInsR3 = pDevIns;
4123 pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrq;
4124 pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterrupt;
4125 Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4126
4127 /* set the helper pointer and return. */
4128 *ppPicHlp = &g_pdmR3DevPicHlp;
4129 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4130 return VINF_SUCCESS;
4131}
4132
4133
4134/** @interface_method_impl{PDMDEVHLPR3,pfnApicRegister} */
4135static DECLCALLBACK(int) pdmR3DevHlp_ApicRegister(PPDMDEVINS pDevIns)
4136{
4137 PDMDEV_ASSERT_DEVINS(pDevIns);
4138
4139 /*
4140 * Validate caller context.
4141 */
4142 PVM pVM = pDevIns->Internal.s.pVMR3;
4143 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4144 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4145
4146 /*
4147 * Only one APIC device. On SMP we have single logical device covering all LAPICs,
4148 * as they need to communicate and share state easily.
4149 */
4150 AssertMsgReturn(pVM->pdm.s.Apic.pDevInsR3 == NULL,
4151 ("%s/%u: Only one APIC device is supported!\n", pDevIns->pReg->szName, pDevIns->iInstance),
4152 VERR_ALREADY_EXISTS);
4153
4154 /*
4155 * Set the ring-3 and raw-mode bits, leave the ring-0 to ring-0 setup.
4156 */
4157 pVM->pdm.s.Apic.pDevInsR3 = pDevIns;
4158#ifdef VBOX_WITH_RAW_MODE_KEEP
4159 pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
4160 Assert(pVM->pdm.s.Apic.pDevInsRC || !VM_IS_RAW_MODE_ENABLED(pVM));
4161#endif
4162
4163 LogFlow(("pdmR3DevHlp_ApicRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4164 return VINF_SUCCESS;
4165}
4166
4167
4168/** @interface_method_impl{PDMDEVHLPR3,pfnIoApicRegister} */
4169static DECLCALLBACK(int) pdmR3DevHlp_IoApicRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
4170{
4171 PDMDEV_ASSERT_DEVINS(pDevIns);
4172 LogFlow(("pdmR3DevHlp_IoApicRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnSendMsi=%p, .pfnSetEoi=%p, .u32TheEnd=%#x } ppIoApicHlp=%p\n",
4173 pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrq, pIoApicReg->pfnSendMsi, pIoApicReg->pfnSetEoi, pIoApicReg->u32TheEnd, ppIoApicHlp));
4174 PVM pVM = pDevIns->Internal.s.pVMR3;
4175
4176 /*
4177 * Validate input.
4178 */
4179 AssertMsgReturn(pIoApicReg->u32Version == PDM_IOAPICREG_VERSION,
4180 ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32Version, PDM_IOAPICREG_VERSION),
4181 VERR_VERSION_MISMATCH);
4182 AssertPtrReturn(pIoApicReg->pfnSetIrq, VERR_INVALID_POINTER);
4183 AssertPtrReturn(pIoApicReg->pfnSendMsi, VERR_INVALID_POINTER);
4184 AssertPtrReturn(pIoApicReg->pfnSetEoi, VERR_INVALID_POINTER);
4185 AssertMsgReturn(pIoApicReg->u32TheEnd == PDM_IOAPICREG_VERSION,
4186 ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32TheEnd, PDM_IOAPICREG_VERSION),
4187 VERR_VERSION_MISMATCH);
4188 AssertPtrReturn(ppIoApicHlp, VERR_INVALID_POINTER);
4189 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4190 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4191
4192 /*
4193 * The I/O APIC requires the APIC to be present (hacks++).
4194 * If the I/O APIC does GC stuff so must the APIC.
4195 */
4196 AssertMsgReturn(pVM->pdm.s.Apic.pDevInsR3 != NULL, ("Configuration error / Init order error! No APIC!\n"), VERR_WRONG_ORDER);
4197
4198 /*
4199 * Only one I/O APIC device.
4200 */
4201 AssertMsgReturn(pVM->pdm.s.IoApic.pDevInsR3 == NULL,
4202 ("Only one IOAPIC device is supported! (caller %s/%d)\n", pDevIns->pReg->szName, pDevIns->iInstance),
4203 VERR_ALREADY_EXISTS);
4204
4205 /*
4206 * Initialize the R3 bits.
4207 */
4208 pVM->pdm.s.IoApic.pDevInsR3 = pDevIns;
4209 pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrq;
4210 pVM->pdm.s.IoApic.pfnSendMsiR3 = pIoApicReg->pfnSendMsi;
4211 pVM->pdm.s.IoApic.pfnSetEoiR3 = pIoApicReg->pfnSetEoi;
4212 Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4213
4214 /* set the helper pointer and return. */
4215 *ppIoApicHlp = &g_pdmR3DevIoApicHlp;
4216 LogFlow(("pdmR3DevHlp_IoApicRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4217 return VINF_SUCCESS;
4218}
4219
4220
4221/** @interface_method_impl{PDMDEVHLPR3,pfnHpetRegister} */
4222static DECLCALLBACK(int) pdmR3DevHlp_HpetRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
4223{
4224 PDMDEV_ASSERT_DEVINS(pDevIns);
4225 LogFlow(("pdmR3DevHlp_HpetRegister: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4226 PVM pVM = pDevIns->Internal.s.pVMR3;
4227
4228 /*
4229 * Validate input.
4230 */
4231 AssertMsgReturn(pHpetReg->u32Version == PDM_HPETREG_VERSION,
4232 ("%s/%u: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pHpetReg->u32Version, PDM_HPETREG_VERSION),
4233 VERR_VERSION_MISMATCH);
4234 AssertPtrReturn(ppHpetHlpR3, VERR_INVALID_POINTER);
4235 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
4236 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
4237
4238 /*
4239 * Only one HPET device.
4240 */
4241 AssertMsgReturn(pVM->pdm.s.pHpet == NULL,
4242 ("Only one HPET device is supported! (caller %s/%d)\n", pDevIns->pReg->szName, pDevIns->iInstance),
4243 VERR_ALREADY_EXISTS);
4244
4245 /*
4246 * Do the job (what there is of it).
4247 */
4248 pVM->pdm.s.pHpet = pDevIns;
4249 *ppHpetHlpR3 = &g_pdmR3DevHpetHlp;
4250
4251 LogFlow(("pdmR3DevHlp_HpetRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4252 return VINF_SUCCESS;
4253}
4254
4255
4256/** @interface_method_impl{PDMDEVHLPR3,pfnPciRawRegister} */
4257static DECLCALLBACK(int) pdmR3DevHlp_PciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
4258{
4259 PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
4260 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4261 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4262
4263 /*
4264 * Validate input.
4265 */
4266 if (pPciRawReg->u32Version != PDM_PCIRAWREG_VERSION)
4267 {
4268 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciRawReg->u32Version, PDM_PCIRAWREG_VERSION));
4269 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4270 return VERR_INVALID_PARAMETER;
4271 }
4272
4273 if (!ppPciRawHlpR3)
4274 {
4275 Assert(ppPciRawHlpR3);
4276 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (ppPciRawHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4277 return VERR_INVALID_PARAMETER;
4278 }
4279
4280 /* set the helper pointer and return. */
4281 *ppPciRawHlpR3 = &g_pdmR3DevPciRawHlp;
4282 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4283 return VINF_SUCCESS;
4284}
4285
4286
4287/** @interface_method_impl{PDMDEVHLPR3,pfnDMACRegister} */
4288static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
4289{
4290 PDMDEV_ASSERT_DEVINS(pDevIns);
4291 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4292 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",
4293 pDevIns->pReg->szName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister,
4294 pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp));
4295
4296 /*
4297 * Validate input.
4298 */
4299 if (pDmacReg->u32Version != PDM_DMACREG_VERSION)
4300 {
4301 AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version,
4302 PDM_DMACREG_VERSION));
4303 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (version)\n",
4304 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4305 return VERR_INVALID_PARAMETER;
4306 }
4307 if ( !pDmacReg->pfnRun
4308 || !pDmacReg->pfnRegister
4309 || !pDmacReg->pfnReadMemory
4310 || !pDmacReg->pfnWriteMemory
4311 || !pDmacReg->pfnSetDREQ
4312 || !pDmacReg->pfnGetChannelMode)
4313 {
4314 Assert(pDmacReg->pfnRun);
4315 Assert(pDmacReg->pfnRegister);
4316 Assert(pDmacReg->pfnReadMemory);
4317 Assert(pDmacReg->pfnWriteMemory);
4318 Assert(pDmacReg->pfnSetDREQ);
4319 Assert(pDmacReg->pfnGetChannelMode);
4320 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
4321 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4322 return VERR_INVALID_PARAMETER;
4323 }
4324
4325 if (!ppDmacHlp)
4326 {
4327 Assert(ppDmacHlp);
4328 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (ppDmacHlp)\n",
4329 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4330 return VERR_INVALID_PARAMETER;
4331 }
4332
4333 /*
4334 * Only one DMA device.
4335 */
4336 PVM pVM = pDevIns->Internal.s.pVMR3;
4337 if (pVM->pdm.s.pDmac)
4338 {
4339 AssertMsgFailed(("Only one DMA device is supported!\n"));
4340 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc\n",
4341 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4342 return VERR_INVALID_PARAMETER;
4343 }
4344
4345 /*
4346 * Allocate and initialize pci bus structure.
4347 */
4348 int rc = VINF_SUCCESS;
4349 PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac));
4350 if (pDmac)
4351 {
4352 pDmac->pDevIns = pDevIns;
4353 pDmac->Reg = *pDmacReg;
4354 pVM->pdm.s.pDmac = pDmac;
4355
4356 /* set the helper pointer. */
4357 *ppDmacHlp = &g_pdmR3DevDmacHlp;
4358 Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n",
4359 pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4360 }
4361 else
4362 rc = VERR_NO_MEMORY;
4363
4364 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc\n",
4365 pDevIns->pReg->szName, pDevIns->iInstance, rc));
4366 return rc;
4367}
4368
4369
4370/**
4371 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
4372 */
4373static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbHeap)
4374{
4375 PDMDEV_ASSERT_DEVINS(pDevIns);
4376 PVM pVM = pDevIns->Internal.s.pVMR3;
4377 VM_ASSERT_EMT(pVM);
4378 LogFlow(("pdmR3DevHlp_RegisterVMMDevHeap: caller='%s'/%d: GCPhys=%RGp pvHeap=%p cbHeap=%#x\n",
4379 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvHeap, cbHeap));
4380
4381 if (pVM->pdm.s.pvVMMDevHeap == NULL)
4382 {
4383 pVM->pdm.s.pvVMMDevHeap = pvHeap;
4384 pVM->pdm.s.GCPhysVMMDevHeap = GCPhys;
4385 pVM->pdm.s.cbVMMDevHeap = cbHeap;
4386 pVM->pdm.s.cbVMMDevHeapLeft = cbHeap;
4387 }
4388 else
4389 {
4390 Assert(pVM->pdm.s.pvVMMDevHeap == pvHeap);
4391 Assert(pVM->pdm.s.cbVMMDevHeap == cbHeap);
4392 Assert(pVM->pdm.s.GCPhysVMMDevHeap != GCPhys || GCPhys == NIL_RTGCPHYS);
4393 if (pVM->pdm.s.GCPhysVMMDevHeap != GCPhys)
4394 {
4395 pVM->pdm.s.GCPhysVMMDevHeap = GCPhys;
4396 if (pVM->pdm.s.pfnVMMDevHeapNotify)
4397 pVM->pdm.s.pfnVMMDevHeapNotify(pVM, pvHeap, GCPhys);
4398 }
4399 }
4400
4401 LogFlow(("pdmR3DevHlp_RegisterVMMDevHeap: caller='%s'/%d: returns %Rrc\n",
4402 pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
4403 return VINF_SUCCESS;
4404}
4405
4406
4407/**
4408 * @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister}
4409 */
4410static DECLCALLBACK(int) pdmR3DevHlp_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
4411{
4412 PDMDEV_ASSERT_DEVINS(pDevIns);
4413 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4414 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: pFWReg=%p:{.u32Version=%#x, .pfnIsHardReset=%p, .u32TheEnd=%#x} ppFwHlp=%p\n",
4415 pDevIns->pReg->szName, pDevIns->iInstance, pFwReg, pFwReg->u32Version, pFwReg->pfnIsHardReset, pFwReg->u32TheEnd, ppFwHlp));
4416
4417 /*
4418 * Validate input.
4419 */
4420 if (pFwReg->u32Version != PDM_FWREG_VERSION)
4421 {
4422 AssertMsgFailed(("u32Version=%#x expected %#x\n", pFwReg->u32Version, PDM_FWREG_VERSION));
4423 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (version)\n",
4424 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4425 return VERR_INVALID_PARAMETER;
4426 }
4427 if (!pFwReg->pfnIsHardReset)
4428 {
4429 Assert(pFwReg->pfnIsHardReset);
4430 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
4431 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4432 return VERR_INVALID_PARAMETER;
4433 }
4434
4435 if (!ppFwHlp)
4436 {
4437 Assert(ppFwHlp);
4438 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (ppFwHlp)\n",
4439 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4440 return VERR_INVALID_PARAMETER;
4441 }
4442
4443 /*
4444 * Only one DMA device.
4445 */
4446 PVM pVM = pDevIns->Internal.s.pVMR3;
4447 if (pVM->pdm.s.pFirmware)
4448 {
4449 AssertMsgFailed(("Only one firmware device is supported!\n"));
4450 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
4451 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
4452 return VERR_INVALID_PARAMETER;
4453 }
4454
4455 /*
4456 * Allocate and initialize pci bus structure.
4457 */
4458 int rc = VINF_SUCCESS;
4459 PPDMFW pFirmware = (PPDMFW)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pFirmware));
4460 if (pFirmware)
4461 {
4462 pFirmware->pDevIns = pDevIns;
4463 pFirmware->Reg = *pFwReg;
4464 pVM->pdm.s.pFirmware = pFirmware;
4465
4466 /* set the helper pointer. */
4467 *ppFwHlp = &g_pdmR3DevFirmwareHlp;
4468 Log(("PDM: Registered firmware device '%s'/%d pDevIns=%p\n",
4469 pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
4470 }
4471 else
4472 rc = VERR_NO_MEMORY;
4473
4474 LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
4475 pDevIns->pReg->szName, pDevIns->iInstance, rc));
4476 return rc;
4477}
4478
4479
4480/** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
4481static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
4482{
4483 PDMDEV_ASSERT_DEVINS(pDevIns);
4484 PVM pVM = pDevIns->Internal.s.pVMR3;
4485 VM_ASSERT_EMT(pVM);
4486 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: fFlags=%#x VM_FF_RESET %d -> 1\n",
4487 pDevIns->pReg->szName, pDevIns->iInstance, fFlags, VM_FF_IS_SET(pVM, VM_FF_RESET)));
4488
4489 /*
4490 * We postpone this operation because we're likely to be inside a I/O instruction
4491 * and the EIP will be updated when we return.
4492 * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation.
4493 */
4494 bool fHaltOnReset;
4495 int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset);
4496 if (RT_SUCCESS(rc) && fHaltOnReset)
4497 {
4498 Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n"));
4499 rc = VINF_EM_HALT;
4500 }
4501 else
4502 {
4503 pVM->pdm.s.fResetFlags = fFlags;
4504 VM_FF_SET(pVM, VM_FF_RESET);
4505 rc = VINF_EM_RESET;
4506 }
4507
4508 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4509 return rc;
4510}
4511
4512
4513/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspend} */
4514static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns)
4515{
4516 int rc;
4517 PDMDEV_ASSERT_DEVINS(pDevIns);
4518 PVM pVM = pDevIns->Internal.s.pVMR3;
4519 VM_ASSERT_EMT(pVM);
4520 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n",
4521 pDevIns->pReg->szName, pDevIns->iInstance));
4522
4523 /** @todo Always take the SMP path - fewer code paths. */
4524 if (pVM->cCpus > 1)
4525 {
4526 /* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
4527 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)VMR3Suspend, 2, pVM->pUVM, VMSUSPENDREASON_VM);
4528 AssertRC(rc);
4529 rc = VINF_EM_SUSPEND;
4530 }
4531 else
4532 rc = VMR3Suspend(pVM->pUVM, VMSUSPENDREASON_VM);
4533
4534 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4535 return rc;
4536}
4537
4538
4539/**
4540 * Worker for pdmR3DevHlp_VMSuspendSaveAndPowerOff that is invoked via a queued
4541 * EMT request to avoid deadlocks.
4542 *
4543 * @returns VBox status code fit for scheduling.
4544 * @param pVM The cross context VM structure.
4545 * @param pDevIns The device that triggered this action.
4546 */
4547static DECLCALLBACK(int) pdmR3DevHlp_VMSuspendSaveAndPowerOffWorker(PVM pVM, PPDMDEVINS pDevIns)
4548{
4549 /*
4550 * Suspend the VM first then do the saving.
4551 */
4552 int rc = VMR3Suspend(pVM->pUVM, VMSUSPENDREASON_VM);
4553 if (RT_SUCCESS(rc))
4554 {
4555 PUVM pUVM = pVM->pUVM;
4556 rc = pUVM->pVmm2UserMethods->pfnSaveState(pVM->pUVM->pVmm2UserMethods, pUVM);
4557
4558 /*
4559 * On success, power off the VM, on failure we'll leave it suspended.
4560 */
4561 if (RT_SUCCESS(rc))
4562 {
4563 rc = VMR3PowerOff(pVM->pUVM);
4564 if (RT_FAILURE(rc))
4565 LogRel(("%s/SSP: VMR3PowerOff failed: %Rrc\n", pDevIns->pReg->szName, rc));
4566 }
4567 else
4568 LogRel(("%s/SSP: pfnSaveState failed: %Rrc\n", pDevIns->pReg->szName, rc));
4569 }
4570 else
4571 LogRel(("%s/SSP: Suspend failed: %Rrc\n", pDevIns->pReg->szName, rc));
4572 return rc;
4573}
4574
4575
4576/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspendSaveAndPowerOff} */
4577static DECLCALLBACK(int) pdmR3DevHlp_VMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
4578{
4579 PDMDEV_ASSERT_DEVINS(pDevIns);
4580 PVM pVM = pDevIns->Internal.s.pVMR3;
4581 VM_ASSERT_EMT(pVM);
4582 LogFlow(("pdmR3DevHlp_VMSuspendSaveAndPowerOff: caller='%s'/%d:\n",
4583 pDevIns->pReg->szName, pDevIns->iInstance));
4584
4585 int rc;
4586 if ( pVM->pUVM->pVmm2UserMethods
4587 && pVM->pUVM->pVmm2UserMethods->pfnSaveState)
4588 {
4589 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pdmR3DevHlp_VMSuspendSaveAndPowerOffWorker, 2, pVM, pDevIns);
4590 if (RT_SUCCESS(rc))
4591 {
4592 LogRel(("%s: Suspending, Saving and Powering Off the VM\n", pDevIns->pReg->szName));
4593 rc = VINF_EM_SUSPEND;
4594 }
4595 }
4596 else
4597 rc = VERR_NOT_SUPPORTED;
4598
4599 LogFlow(("pdmR3DevHlp_VMSuspendSaveAndPowerOff: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4600 return rc;
4601}
4602
4603
4604/** @interface_method_impl{PDMDEVHLPR3,pfnVMPowerOff} */
4605static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns)
4606{
4607 int rc;
4608 PDMDEV_ASSERT_DEVINS(pDevIns);
4609 PVM pVM = pDevIns->Internal.s.pVMR3;
4610 VM_ASSERT_EMT(pVM);
4611 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n",
4612 pDevIns->pReg->szName, pDevIns->iInstance));
4613
4614 /** @todo Always take the SMP path - fewer code paths. */
4615 if (pVM->cCpus > 1)
4616 {
4617 /* We might be holding locks here and could cause a deadlock since
4618 VMR3PowerOff rendezvous with the other CPUs. */
4619 rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)VMR3PowerOff, 1, pVM->pUVM);
4620 AssertRC(rc);
4621 /* Set the VCPU state to stopped here as well to make sure no
4622 inconsistency with the EM state occurs. */
4623 VMCPU_SET_STATE(VMMGetCpu(pVM), VMCPUSTATE_STOPPED);
4624 rc = VINF_EM_OFF;
4625 }
4626 else
4627 rc = VMR3PowerOff(pVM->pUVM);
4628
4629 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4630 return rc;
4631}
4632
4633
4634/** @interface_method_impl{PDMDEVHLPR3,pfnA20IsEnabled} */
4635static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
4636{
4637 PDMDEV_ASSERT_DEVINS(pDevIns);
4638 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4639
4640 bool fRc = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR3));
4641
4642 LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pReg->szName, pDevIns->iInstance, fRc));
4643 return fRc;
4644}
4645
4646
4647/** @interface_method_impl{PDMDEVHLPR3,pfnA20Set} */
4648static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable)
4649{
4650 PDMDEV_ASSERT_DEVINS(pDevIns);
4651 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4652 LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, fEnable));
4653#ifdef VBOX_VMM_TARGET_ARMV8
4654 AssertReleaseFailed();
4655 RT_NOREF(pDevIns, fEnable);
4656#else
4657 PGMR3PhysSetA20(VMMGetCpu(pDevIns->Internal.s.pVMR3), fEnable);
4658#endif
4659}
4660
4661
4662/** @interface_method_impl{PDMDEVHLPR3,pfnGetCpuId} */
4663static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
4664 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
4665{
4666 PDMDEV_ASSERT_DEVINS(pDevIns);
4667 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4668
4669 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n",
4670 pDevIns->pReg->szName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx));
4671 AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx);
4672
4673#ifdef VBOX_VMM_TARGET_ARMV8
4674 RT_NOREF(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
4675 AssertReleaseFailed();
4676#else
4677 CPUMGetGuestCpuId(VMMGetCpu(pDevIns->Internal.s.pVMR3), iLeaf, 0 /*iSubLeaf*/, -1 /*f64BitMode*/, pEax, pEbx, pEcx, pEdx);
4678#endif
4679
4680 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n",
4681 pDevIns->pReg->szName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx));
4682}
4683
4684
4685/** @interface_method_impl{PDMDEVHLPR3,pfnGetMainExecutionEngine} */
4686static DECLCALLBACK(uint8_t) pdmR3DevHlp_GetMainExecutionEngine(PPDMDEVINS pDevIns)
4687{
4688 PDMDEV_ASSERT_DEVINS(pDevIns);
4689 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
4690 LogFlow(("pdmR3DevHlp_GetMainExecutionEngine: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4691 return pDevIns->Internal.s.pVMR3->bMainExecutionEngine;
4692}
4693
4694
4695/** @interface_method_impl{PDMDEVHLPR3,pfnVMMRegisterPatchMemory} */
4696static DECLCALLBACK(int) pdmR3DevHlp_VMMRegisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
4697{
4698 PDMDEV_ASSERT_DEVINS(pDevIns);
4699
4700 LogFlow(("pdmR3DevHlp_VMMRegisterPatchMemory: caller='%s'/%d: GCPtrPatchMem=%RGv cbPatchMem=%RU32\n",
4701 pDevIns->pReg->szName, pDevIns->iInstance, GCPtrPatchMem, cbPatchMem));
4702
4703 int rc = VMMR3RegisterPatchMemory(pDevIns->Internal.s.pVMR3, GCPtrPatchMem, cbPatchMem);
4704
4705 LogFlow(("pdmR3DevHlp_VMMRegisterPatchMemory: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4706 return rc;
4707}
4708
4709
4710/** @interface_method_impl{PDMDEVHLPR3,pfnVMMDeregisterPatchMemory} */
4711static DECLCALLBACK(int) pdmR3DevHlp_VMMDeregisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
4712{
4713 PDMDEV_ASSERT_DEVINS(pDevIns);
4714
4715 LogFlow(("pdmR3DevHlp_VMMDeregisterPatchMemory: caller='%s'/%d: GCPtrPatchMem=%RGv cbPatchMem=%RU32\n",
4716 pDevIns->pReg->szName, pDevIns->iInstance, GCPtrPatchMem, cbPatchMem));
4717
4718 int rc = VMMR3DeregisterPatchMemory(pDevIns->Internal.s.pVMR3, GCPtrPatchMem, cbPatchMem);
4719
4720 LogFlow(("pdmR3DevHlp_VMMDeregisterPatchMemory: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4721 return rc;
4722}
4723
4724
4725/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleRegister} */
4726static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleRegister(PPDMDEVINS pDevIns, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
4727 RTGCPTR GCBaseAddr, uint32_t cbModule,
4728 uint32_t cRegions, VMMDEVSHAREDREGIONDESC const *paRegions)
4729{
4730 PDMDEV_ASSERT_DEVINS(pDevIns);
4731
4732 LogFlow(("pdmR3DevHlp_SharedModuleRegister: caller='%s'/%d: enmGuestOS=%u pszModuleName=%p:{%s} pszVersion=%p:{%s} GCBaseAddr=%RGv cbModule=%#x cRegions=%u paRegions=%p\n",
4733 pDevIns->pReg->szName, pDevIns->iInstance, enmGuestOS, pszModuleName, pszModuleName, pszVersion, pszVersion, GCBaseAddr, cbModule, cRegions, paRegions));
4734
4735#ifdef VBOX_WITH_PAGE_SHARING
4736 int rc = PGMR3SharedModuleRegister(pDevIns->Internal.s.pVMR3, enmGuestOS, pszModuleName, pszVersion,
4737 GCBaseAddr, cbModule, cRegions, paRegions);
4738#else
4739 RT_NOREF(pDevIns, enmGuestOS, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions, paRegions);
4740 int rc = VERR_NOT_SUPPORTED;
4741#endif
4742
4743 LogFlow(("pdmR3DevHlp_SharedModuleRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4744 return rc;
4745}
4746
4747
4748/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleUnregister} */
4749static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleUnregister(PPDMDEVINS pDevIns, char *pszModuleName, char *pszVersion,
4750 RTGCPTR GCBaseAddr, uint32_t cbModule)
4751{
4752 PDMDEV_ASSERT_DEVINS(pDevIns);
4753
4754 LogFlow(("pdmR3DevHlp_SharedModuleUnregister: caller='%s'/%d: pszModuleName=%p:{%s} pszVersion=%p:{%s} GCBaseAddr=%RGv cbModule=%#x\n",
4755 pDevIns->pReg->szName, pDevIns->iInstance, pszModuleName, pszModuleName, pszVersion, pszVersion, GCBaseAddr, cbModule));
4756
4757#ifdef VBOX_WITH_PAGE_SHARING
4758 int rc = PGMR3SharedModuleUnregister(pDevIns->Internal.s.pVMR3, pszModuleName, pszVersion, GCBaseAddr, cbModule);
4759#else
4760 RT_NOREF(pDevIns, pszModuleName, pszVersion, GCBaseAddr, cbModule);
4761 int rc = VERR_NOT_SUPPORTED;
4762#endif
4763
4764 LogFlow(("pdmR3DevHlp_SharedModuleUnregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4765 return rc;
4766}
4767
4768
4769/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleGetPageState} */
4770static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleGetPageState(PPDMDEVINS pDevIns, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags)
4771{
4772 PDMDEV_ASSERT_DEVINS(pDevIns);
4773
4774 LogFlow(("pdmR3DevHlp_SharedModuleGetPageState: caller='%s'/%d: GCPtrPage=%RGv pfShared=%p pfPageFlags=%p\n",
4775 pDevIns->pReg->szName, pDevIns->iInstance, GCPtrPage, pfShared, pfPageFlags));
4776
4777#if defined(VBOX_WITH_PAGE_SHARING) && defined(DEBUG)
4778 int rc = PGMR3SharedModuleGetPageState(pDevIns->Internal.s.pVMR3, GCPtrPage, pfShared, pfPageFlags);
4779#else
4780 RT_NOREF(pDevIns, GCPtrPage, pfShared, pfPageFlags);
4781 int rc = VERR_NOT_IMPLEMENTED;
4782#endif
4783
4784 LogFlow(("pdmR3DevHlp_SharedModuleGetPageState: caller='%s'/%d: returns %Rrc *pfShared=%RTbool *pfPageFlags=%#RX64\n",
4785 pDevIns->pReg->szName, pDevIns->iInstance, rc, *pfShared, *pfPageFlags));
4786 return rc;
4787}
4788
4789
4790/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleCheckAll} */
4791static DECLCALLBACK(int) pdmR3DevHlp_SharedModuleCheckAll(PPDMDEVINS pDevIns)
4792{
4793 PDMDEV_ASSERT_DEVINS(pDevIns);
4794
4795 LogFlow(("pdmR3DevHlp_SharedModuleCheckAll: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
4796
4797#ifdef VBOX_WITH_PAGE_SHARING
4798 int rc = PGMR3SharedModuleCheckAll(pDevIns->Internal.s.pVMR3);
4799#else
4800 RT_NOREF(pDevIns);
4801 int rc = VERR_NOT_SUPPORTED;
4802#endif
4803
4804 LogFlow(("pdmR3DevHlp_SharedModuleCheckAll: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4805 return rc;
4806}
4807
4808
4809/** @interface_method_impl{PDMDEVHLPR3,pfnQueryLun} */
4810static DECLCALLBACK(int) pdmR3DevHlp_QueryLun(PPDMDEVINS pDevIns, const char *pszDevice,
4811 unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase)
4812{
4813 PDMDEV_ASSERT_DEVINS(pDevIns);
4814
4815 LogFlow(("pdmR3DevHlp_QueryLun: caller='%s'/%d: pszDevice=%p:{%s} iInstance=%u iLun=%u ppBase=%p\n",
4816 pDevIns->pReg->szName, pDevIns->iInstance, pszDevice, pszDevice, iInstance, iLun, ppBase));
4817
4818 int rc = PDMR3QueryLun(pDevIns->Internal.s.pVMR3->pUVM, pszDevice, iInstance, iLun, ppBase);
4819
4820 LogFlow(("pdmR3DevHlp_QueryLun: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4821 return rc;
4822}
4823
4824
4825/** @interface_method_impl{PDMDEVHLPR3,pfnGIMDeviceRegister} */
4826static DECLCALLBACK(void) pdmR3DevHlp_GIMDeviceRegister(PPDMDEVINS pDevIns, PGIMDEBUG pDbg)
4827{
4828 PDMDEV_ASSERT_DEVINS(pDevIns);
4829
4830 LogFlow(("pdmR3DevHlp_GIMDeviceRegister: caller='%s'/%d: pDbg=%p\n",
4831 pDevIns->pReg->szName, pDevIns->iInstance, pDbg));
4832
4833 GIMR3GimDeviceRegister(pDevIns->Internal.s.pVMR3, pDevIns, pDbg);
4834
4835 LogFlow(("pdmR3DevHlp_GIMDeviceRegister: caller='%s'/%d: returns\n", pDevIns->pReg->szName, pDevIns->iInstance));
4836}
4837
4838
4839/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetDebugSetup} */
4840static DECLCALLBACK(int) pdmR3DevHlp_GIMGetDebugSetup(PPDMDEVINS pDevIns, PGIMDEBUGSETUP pDbgSetup)
4841{
4842 PDMDEV_ASSERT_DEVINS(pDevIns);
4843
4844 LogFlow(("pdmR3DevHlp_GIMGetDebugSetup: caller='%s'/%d: pDbgSetup=%p\n",
4845 pDevIns->pReg->szName, pDevIns->iInstance, pDbgSetup));
4846
4847 int rc = GIMR3GetDebugSetup(pDevIns->Internal.s.pVMR3, pDbgSetup);
4848
4849 LogFlow(("pdmR3DevHlp_GIMGetDebugSetup: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
4850 return rc;
4851}
4852
4853
4854/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetMmio2Regions} */
4855static DECLCALLBACK(PGIMMMIO2REGION) pdmR3DevHlp_GIMGetMmio2Regions(PPDMDEVINS pDevIns, uint32_t *pcRegions)
4856{
4857 PDMDEV_ASSERT_DEVINS(pDevIns);
4858
4859 LogFlow(("pdmR3DevHlp_GIMGetMmio2Regions: caller='%s'/%d: pcRegions=%p\n",
4860 pDevIns->pReg->szName, pDevIns->iInstance, pcRegions));
4861
4862 PGIMMMIO2REGION pRegion = GIMGetMmio2Regions(pDevIns->Internal.s.pVMR3, pcRegions);
4863
4864 LogFlow(("pdmR3DevHlp_GIMGetMmio2Regions: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pRegion));
4865 return pRegion;
4866}
4867
4868
4869/**
4870 * The device helper structure for trusted devices.
4871 */
4872const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =
4873{
4874 PDM_DEVHLPR3_VERSION,
4875 pdmR3DevHlp_IoPortCreateEx,
4876 pdmR3DevHlp_IoPortMap,
4877 pdmR3DevHlp_IoPortUnmap,
4878 pdmR3DevHlp_IoPortGetMappingAddress,
4879 pdmR3DevHlp_IoPortRead,
4880 pdmR3DevHlp_IoPortWrite,
4881 pdmR3DevHlp_MmioCreateEx,
4882 pdmR3DevHlp_MmioMap,
4883 pdmR3DevHlp_MmioUnmap,
4884 pdmR3DevHlp_MmioReduce,
4885 pdmR3DevHlp_MmioGetMappingAddress,
4886 pdmR3DevHlp_Mmio2Create,
4887 pdmR3DevHlp_Mmio2Destroy,
4888 pdmR3DevHlp_Mmio2Map,
4889 pdmR3DevHlp_Mmio2Unmap,
4890 pdmR3DevHlp_Mmio2Reduce,
4891 pdmR3DevHlp_Mmio2GetMappingAddress,
4892 pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap,
4893 pdmR3DevHlp_Mmio2ControlDirtyPageTracking,
4894 pdmR3DevHlp_Mmio2ChangeRegionNo,
4895 pdmR3DevHlp_MmioMapMmio2Page,
4896 pdmR3DevHlp_MmioResetRegion,
4897 pdmR3DevHlp_ROMRegister,
4898 pdmR3DevHlp_ROMProtectShadow,
4899 pdmR3DevHlp_SSMRegister,
4900 pdmR3DevHlp_SSMRegisterLegacy,
4901 SSMR3PutStruct,
4902 SSMR3PutStructEx,
4903 SSMR3PutBool,
4904 SSMR3PutU8,
4905 SSMR3PutS8,
4906 SSMR3PutU16,
4907 SSMR3PutS16,
4908 SSMR3PutU32,
4909 SSMR3PutS32,
4910 SSMR3PutU64,
4911 SSMR3PutS64,
4912 SSMR3PutU128,
4913 SSMR3PutS128,
4914 SSMR3PutUInt,
4915 SSMR3PutSInt,
4916 SSMR3PutGCUInt,
4917 SSMR3PutGCUIntReg,
4918 SSMR3PutGCPhys32,
4919 SSMR3PutGCPhys64,
4920 SSMR3PutGCPhys,
4921 SSMR3PutGCPtr,
4922 SSMR3PutGCUIntPtr,
4923 SSMR3PutRCPtr,
4924 SSMR3PutIOPort,
4925 SSMR3PutSel,
4926 SSMR3PutMem,
4927 SSMR3PutStrZ,
4928 SSMR3GetStruct,
4929 SSMR3GetStructEx,
4930 SSMR3GetBool,
4931 SSMR3GetBoolV,
4932 SSMR3GetU8,
4933 SSMR3GetU8V,
4934 SSMR3GetS8,
4935 SSMR3GetS8V,
4936 SSMR3GetU16,
4937 SSMR3GetU16V,
4938 SSMR3GetS16,
4939 SSMR3GetS16V,
4940 SSMR3GetU32,
4941 SSMR3GetU32V,
4942 SSMR3GetS32,
4943 SSMR3GetS32V,
4944 SSMR3GetU64,
4945 SSMR3GetU64V,
4946 SSMR3GetS64,
4947 SSMR3GetS64V,
4948 SSMR3GetU128,
4949 SSMR3GetU128V,
4950 SSMR3GetS128,
4951 SSMR3GetS128V,
4952 SSMR3GetGCPhys32,
4953 SSMR3GetGCPhys32V,
4954 SSMR3GetGCPhys64,
4955 SSMR3GetGCPhys64V,
4956 SSMR3GetGCPhys,
4957 SSMR3GetGCPhysV,
4958 SSMR3GetUInt,
4959 SSMR3GetSInt,
4960 SSMR3GetGCUInt,
4961 SSMR3GetGCUIntReg,
4962 SSMR3GetGCPtr,
4963 SSMR3GetGCUIntPtr,
4964 SSMR3GetRCPtr,
4965 SSMR3GetIOPort,
4966 SSMR3GetSel,
4967 SSMR3GetMem,
4968 SSMR3GetStrZ,
4969 SSMR3GetStrZEx,
4970 SSMR3Skip,
4971 SSMR3SkipToEndOfUnit,
4972 SSMR3SetLoadError,
4973 SSMR3SetLoadErrorV,
4974 SSMR3SetCfgError,
4975 SSMR3SetCfgErrorV,
4976 SSMR3HandleGetStatus,
4977 SSMR3HandleGetAfter,
4978 SSMR3HandleIsLiveSave,
4979 SSMR3HandleMaxDowntime,
4980 SSMR3HandleHostBits,
4981 SSMR3HandleRevision,
4982 SSMR3HandleVersion,
4983 SSMR3HandleHostOSAndArch,
4984 pdmR3DevHlp_TimerCreate,
4985 pdmR3DevHlp_TimerFromMicro,
4986 pdmR3DevHlp_TimerFromMilli,
4987 pdmR3DevHlp_TimerFromNano,
4988 pdmR3DevHlp_TimerGet,
4989 pdmR3DevHlp_TimerGetFreq,
4990 pdmR3DevHlp_TimerGetNano,
4991 pdmR3DevHlp_TimerIsActive,
4992 pdmR3DevHlp_TimerIsLockOwner,
4993 pdmR3DevHlp_TimerLockClock,
4994 pdmR3DevHlp_TimerLockClock2,
4995 pdmR3DevHlp_TimerSet,
4996 pdmR3DevHlp_TimerSetFrequencyHint,
4997 pdmR3DevHlp_TimerSetMicro,
4998 pdmR3DevHlp_TimerSetMillies,
4999 pdmR3DevHlp_TimerSetNano,
5000 pdmR3DevHlp_TimerSetRelative,
5001 pdmR3DevHlp_TimerStop,
5002 pdmR3DevHlp_TimerUnlockClock,
5003 pdmR3DevHlp_TimerUnlockClock2,
5004 pdmR3DevHlp_TimerSetCritSect,
5005 pdmR3DevHlp_TimerSave,
5006 pdmR3DevHlp_TimerLoad,
5007 pdmR3DevHlp_TimerDestroy,
5008 TMR3TimerSkip,
5009 pdmR3DevHlp_TMUtcNow,
5010 CFGMR3Exists,
5011 CFGMR3QueryType,
5012 CFGMR3QuerySize,
5013 CFGMR3QueryInteger,
5014 CFGMR3QueryIntegerDef,
5015 CFGMR3QueryString,
5016 CFGMR3QueryStringDef,
5017 CFGMR3QueryPassword,
5018 CFGMR3QueryPasswordDef,
5019 CFGMR3QueryBytes,
5020 CFGMR3QueryU64,
5021 CFGMR3QueryU64Def,
5022 CFGMR3QueryS64,
5023 CFGMR3QueryS64Def,
5024 CFGMR3QueryU32,
5025 CFGMR3QueryU32Def,
5026 CFGMR3QueryS32,
5027 CFGMR3QueryS32Def,
5028 CFGMR3QueryU16,
5029 CFGMR3QueryU16Def,
5030 CFGMR3QueryS16,
5031 CFGMR3QueryS16Def,
5032 CFGMR3QueryU8,
5033 CFGMR3QueryU8Def,
5034 CFGMR3QueryS8,
5035 CFGMR3QueryS8Def,
5036 CFGMR3QueryBool,
5037 CFGMR3QueryBoolDef,
5038 CFGMR3QueryPort,
5039 CFGMR3QueryPortDef,
5040 CFGMR3QueryUInt,
5041 CFGMR3QueryUIntDef,
5042 CFGMR3QuerySInt,
5043 CFGMR3QuerySIntDef,
5044 CFGMR3QueryGCPtr,
5045 CFGMR3QueryGCPtrDef,
5046 CFGMR3QueryGCPtrU,
5047 CFGMR3QueryGCPtrUDef,
5048 CFGMR3QueryGCPtrS,
5049 CFGMR3QueryGCPtrSDef,
5050 CFGMR3QueryStringAlloc,
5051 CFGMR3QueryStringAllocDef,
5052 CFGMR3GetParent,
5053 CFGMR3GetChild,
5054 CFGMR3GetChildF,
5055 CFGMR3GetChildFV,
5056 CFGMR3GetFirstChild,
5057 CFGMR3GetNextChild,
5058 CFGMR3GetName,
5059 CFGMR3GetNameLen,
5060 CFGMR3AreChildrenValid,
5061 CFGMR3GetFirstValue,
5062 CFGMR3GetNextValue,
5063 CFGMR3GetValueName,
5064 CFGMR3GetValueNameLen,
5065 CFGMR3GetValueType,
5066 CFGMR3AreValuesValid,
5067 CFGMR3ValidateConfig,
5068 pdmR3DevHlp_PhysRead,
5069 pdmR3DevHlp_PhysWrite,
5070 pdmR3DevHlp_PhysGCPhys2CCPtr,
5071 pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
5072 pdmR3DevHlp_PhysReleasePageMappingLock,
5073 pdmR3DevHlp_PhysReadGCVirt,
5074 pdmR3DevHlp_PhysWriteGCVirt,
5075 pdmR3DevHlp_PhysGCPtr2GCPhys,
5076 pdmR3DevHlp_PhysIsGCPhysNormal,
5077 pdmR3DevHlp_PhysChangeMemBalloon,
5078 pdmR3DevHlp_MMHeapAlloc,
5079 pdmR3DevHlp_MMHeapAllocZ,
5080 pdmR3DevHlp_MMHeapAPrintfV,
5081 pdmR3DevHlp_MMHeapFree,
5082 pdmR3DevHlp_MMPhysGetRamSize,
5083 pdmR3DevHlp_MMPhysGetRamSizeBelow4GB,
5084 pdmR3DevHlp_MMPhysGetRamSizeAbove4GB,
5085 pdmR3DevHlp_VMState,
5086 pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
5087 pdmR3DevHlp_VMSetErrorV,
5088 pdmR3DevHlp_VMSetRuntimeErrorV,
5089 pdmR3DevHlp_VMWaitForDeviceReady,
5090 pdmR3DevHlp_VMNotifyCpuDeviceReady,
5091 pdmR3DevHlp_VMReqCallNoWaitV,
5092 pdmR3DevHlp_VMReqPriorityCallWaitV,
5093 pdmR3DevHlp_DBGFStopV,
5094 pdmR3DevHlp_DBGFInfoRegister,
5095 pdmR3DevHlp_DBGFInfoRegisterArgv,
5096 pdmR3DevHlp_DBGFRegRegister,
5097 pdmR3DevHlp_DBGFTraceBuf,
5098 pdmR3DevHlp_DBGFReportBugCheck,
5099 pdmR3DevHlp_DBGFCoreWrite,
5100 pdmR3DevHlp_DBGFInfoLogHlp,
5101 pdmR3DevHlp_DBGFRegNmQueryU64,
5102 pdmR3DevHlp_DBGFRegPrintfV,
5103 pdmR3DevHlp_STAMRegister,
5104 pdmR3DevHlp_STAMRegisterV,
5105 pdmR3DevHlp_PCIRegister,
5106 pdmR3DevHlp_PCIRegisterMsi,
5107 pdmR3DevHlp_PCIIORegionRegister,
5108 pdmR3DevHlp_PCIInterceptConfigAccesses,
5109 pdmR3DevHlp_PCIConfigWrite,
5110 pdmR3DevHlp_PCIConfigRead,
5111 pdmR3DevHlp_PCIPhysRead,
5112 pdmR3DevHlp_PCIPhysWrite,
5113 pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
5114 pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
5115 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
5116 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
5117 pdmR3DevHlp_PCISetIrq,
5118 pdmR3DevHlp_PCISetIrqNoWait,
5119 pdmR3DevHlp_ISASetIrq,
5120 pdmR3DevHlp_ISASetIrqNoWait,
5121 pdmR3DevHlp_DriverAttach,
5122 pdmR3DevHlp_DriverDetach,
5123 pdmR3DevHlp_DriverReconfigure,
5124 pdmR3DevHlp_QueueCreate,
5125 pdmR3DevHlp_QueueAlloc,
5126 pdmR3DevHlp_QueueInsert,
5127 pdmR3DevHlp_QueueFlushIfNecessary,
5128 pdmR3DevHlp_TaskCreate,
5129 pdmR3DevHlp_TaskTrigger,
5130 pdmR3DevHlp_SUPSemEventCreate,
5131 pdmR3DevHlp_SUPSemEventClose,
5132 pdmR3DevHlp_SUPSemEventSignal,
5133 pdmR3DevHlp_SUPSemEventWaitNoResume,
5134 pdmR3DevHlp_SUPSemEventWaitNsAbsIntr,
5135 pdmR3DevHlp_SUPSemEventWaitNsRelIntr,
5136 pdmR3DevHlp_SUPSemEventGetResolution,
5137 pdmR3DevHlp_SUPSemEventMultiCreate,
5138 pdmR3DevHlp_SUPSemEventMultiClose,
5139 pdmR3DevHlp_SUPSemEventMultiSignal,
5140 pdmR3DevHlp_SUPSemEventMultiReset,
5141 pdmR3DevHlp_SUPSemEventMultiWaitNoResume,
5142 pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr,
5143 pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr,
5144 pdmR3DevHlp_SUPSemEventMultiGetResolution,
5145 pdmR3DevHlp_CritSectInit,
5146 pdmR3DevHlp_CritSectGetNop,
5147 pdmR3DevHlp_SetDeviceCritSect,
5148 pdmR3DevHlp_CritSectYield,
5149 pdmR3DevHlp_CritSectEnter,
5150 pdmR3DevHlp_CritSectEnterDebug,
5151 pdmR3DevHlp_CritSectTryEnter,
5152 pdmR3DevHlp_CritSectTryEnterDebug,
5153 pdmR3DevHlp_CritSectLeave,
5154 pdmR3DevHlp_CritSectIsOwner,
5155 pdmR3DevHlp_CritSectIsInitialized,
5156 pdmR3DevHlp_CritSectHasWaiters,
5157 pdmR3DevHlp_CritSectGetRecursion,
5158 pdmR3DevHlp_CritSectScheduleExitEvent,
5159 pdmR3DevHlp_CritSectDelete,
5160 pdmR3DevHlp_CritSectRwInit,
5161 pdmR3DevHlp_CritSectRwDelete,
5162 pdmR3DevHlp_CritSectRwEnterShared,
5163 pdmR3DevHlp_CritSectRwEnterSharedDebug,
5164 pdmR3DevHlp_CritSectRwTryEnterShared,
5165 pdmR3DevHlp_CritSectRwTryEnterSharedDebug,
5166 pdmR3DevHlp_CritSectRwLeaveShared,
5167 pdmR3DevHlp_CritSectRwEnterExcl,
5168 pdmR3DevHlp_CritSectRwEnterExclDebug,
5169 pdmR3DevHlp_CritSectRwTryEnterExcl,
5170 pdmR3DevHlp_CritSectRwTryEnterExclDebug,
5171 pdmR3DevHlp_CritSectRwLeaveExcl,
5172 pdmR3DevHlp_CritSectRwIsWriteOwner,
5173 pdmR3DevHlp_CritSectRwIsReadOwner,
5174 pdmR3DevHlp_CritSectRwGetWriteRecursion,
5175 pdmR3DevHlp_CritSectRwGetWriterReadRecursion,
5176 pdmR3DevHlp_CritSectRwGetReadCount,
5177 pdmR3DevHlp_CritSectRwIsInitialized,
5178 pdmR3DevHlp_ThreadCreate,
5179 PDMR3ThreadDestroy,
5180 PDMR3ThreadIAmSuspending,
5181 PDMR3ThreadIAmRunning,
5182 PDMR3ThreadSleep,
5183 PDMR3ThreadSuspend,
5184 PDMR3ThreadResume,
5185 pdmR3DevHlp_SetAsyncNotification,
5186 pdmR3DevHlp_AsyncNotificationCompleted,
5187 pdmR3DevHlp_RTCRegister,
5188 pdmR3DevHlp_PCIBusRegister,
5189 pdmR3DevHlp_IommuRegister,
5190 pdmR3DevHlp_PICRegister,
5191 pdmR3DevHlp_ApicRegister,
5192 pdmR3DevHlp_IoApicRegister,
5193 pdmR3DevHlp_HpetRegister,
5194 pdmR3DevHlp_PciRawRegister,
5195 pdmR3DevHlp_DMACRegister,
5196 pdmR3DevHlp_DMARegister,
5197 pdmR3DevHlp_DMAReadMemory,
5198 pdmR3DevHlp_DMAWriteMemory,
5199 pdmR3DevHlp_DMASetDREQ,
5200 pdmR3DevHlp_DMAGetChannelMode,
5201 pdmR3DevHlp_DMASchedule,
5202 pdmR3DevHlp_CMOSWrite,
5203 pdmR3DevHlp_CMOSRead,
5204 pdmR3DevHlp_AssertEMT,
5205 pdmR3DevHlp_AssertOther,
5206 pdmR3DevHlp_LdrGetRCInterfaceSymbols,
5207 pdmR3DevHlp_LdrGetR0InterfaceSymbols,
5208 pdmR3DevHlp_CallR0,
5209 pdmR3DevHlp_VMGetSuspendReason,
5210 pdmR3DevHlp_VMGetResumeReason,
5211 pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
5212 pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
5213 pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
5214 pdmR3DevHlp_CpuGetGuestArch,
5215 pdmR3DevHlp_CpuGetGuestMicroarch,
5216 pdmR3DevHlp_CpuGetGuestAddrWidths,
5217 pdmR3DevHlp_CpuGetGuestScalableBusFrequency,
5218 pdmR3DevHlp_STAMDeregisterByPrefix,
5219 0,
5220 0,
5221 0,
5222 0,
5223 0,
5224 0,
5225 0,
5226 0,
5227 0,
5228 pdmR3DevHlp_GetUVM,
5229 pdmR3DevHlp_GetVM,
5230 pdmR3DevHlp_GetVMCPU,
5231 pdmR3DevHlp_GetCurrentCpuId,
5232 pdmR3DevHlp_RegisterVMMDevHeap,
5233 pdmR3DevHlp_FirmwareRegister,
5234 pdmR3DevHlp_VMReset,
5235 pdmR3DevHlp_VMSuspend,
5236 pdmR3DevHlp_VMSuspendSaveAndPowerOff,
5237 pdmR3DevHlp_VMPowerOff,
5238 pdmR3DevHlp_A20IsEnabled,
5239 pdmR3DevHlp_A20Set,
5240 pdmR3DevHlp_GetCpuId,
5241 pdmR3DevHlp_GetMainExecutionEngine,
5242 pdmR3DevHlp_TMTimeVirtGet,
5243 pdmR3DevHlp_TMTimeVirtGetFreq,
5244 pdmR3DevHlp_TMTimeVirtGetNano,
5245 pdmR3DevHlp_TMCpuTicksPerSecond,
5246 pdmR3DevHlp_GetSupDrvSession,
5247 pdmR3DevHlp_QueryGenericUserObject,
5248 pdmR3DevHlp_PGMHandlerPhysicalTypeRegister,
5249 pdmR3DevHlp_PGMHandlerPhysicalRegister,
5250 pdmR3DevHlp_PGMHandlerPhysicalDeregister,
5251 pdmR3DevHlp_PGMHandlerPhysicalPageTempOff,
5252 pdmR3DevHlp_PGMHandlerPhysicalReset,
5253 pdmR3DevHlp_VMMRegisterPatchMemory,
5254 pdmR3DevHlp_VMMDeregisterPatchMemory,
5255 pdmR3DevHlp_SharedModuleRegister,
5256 pdmR3DevHlp_SharedModuleUnregister,
5257 pdmR3DevHlp_SharedModuleGetPageState,
5258 pdmR3DevHlp_SharedModuleCheckAll,
5259 pdmR3DevHlp_QueryLun,
5260 pdmR3DevHlp_GIMDeviceRegister,
5261 pdmR3DevHlp_GIMGetDebugSetup,
5262 pdmR3DevHlp_GIMGetMmio2Regions,
5263 PDM_DEVHLPR3_VERSION /* the end */
5264};
5265
5266
5267#ifdef VBOX_WITH_DBGF_TRACING
5268/**
5269 * The device helper structure for trusted devices - tracing variant.
5270 */
5271const PDMDEVHLPR3 g_pdmR3DevHlpTracing =
5272{
5273 PDM_DEVHLPR3_VERSION,
5274 pdmR3DevHlpTracing_IoPortCreateEx,
5275 pdmR3DevHlpTracing_IoPortMap,
5276 pdmR3DevHlpTracing_IoPortUnmap,
5277 pdmR3DevHlp_IoPortGetMappingAddress,
5278 pdmR3DevHlp_IoPortRead, /** @todo Needs tracing variants for ARM now. */
5279 pdmR3DevHlp_IoPortWrite, /** @todo Needs tracing variants for ARM now. */
5280 pdmR3DevHlpTracing_MmioCreateEx,
5281 pdmR3DevHlpTracing_MmioMap,
5282 pdmR3DevHlpTracing_MmioUnmap,
5283 pdmR3DevHlp_MmioReduce,
5284 pdmR3DevHlp_MmioGetMappingAddress,
5285 pdmR3DevHlp_Mmio2Create,
5286 pdmR3DevHlp_Mmio2Destroy,
5287 pdmR3DevHlp_Mmio2Map,
5288 pdmR3DevHlp_Mmio2Unmap,
5289 pdmR3DevHlp_Mmio2Reduce,
5290 pdmR3DevHlp_Mmio2GetMappingAddress,
5291 pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap,
5292 pdmR3DevHlp_Mmio2ControlDirtyPageTracking,
5293 pdmR3DevHlp_Mmio2ChangeRegionNo,
5294 pdmR3DevHlp_MmioMapMmio2Page,
5295 pdmR3DevHlp_MmioResetRegion,
5296 pdmR3DevHlp_ROMRegister,
5297 pdmR3DevHlp_ROMProtectShadow,
5298 pdmR3DevHlp_SSMRegister,
5299 pdmR3DevHlp_SSMRegisterLegacy,
5300 SSMR3PutStruct,
5301 SSMR3PutStructEx,
5302 SSMR3PutBool,
5303 SSMR3PutU8,
5304 SSMR3PutS8,
5305 SSMR3PutU16,
5306 SSMR3PutS16,
5307 SSMR3PutU32,
5308 SSMR3PutS32,
5309 SSMR3PutU64,
5310 SSMR3PutS64,
5311 SSMR3PutU128,
5312 SSMR3PutS128,
5313 SSMR3PutUInt,
5314 SSMR3PutSInt,
5315 SSMR3PutGCUInt,
5316 SSMR3PutGCUIntReg,
5317 SSMR3PutGCPhys32,
5318 SSMR3PutGCPhys64,
5319 SSMR3PutGCPhys,
5320 SSMR3PutGCPtr,
5321 SSMR3PutGCUIntPtr,
5322 SSMR3PutRCPtr,
5323 SSMR3PutIOPort,
5324 SSMR3PutSel,
5325 SSMR3PutMem,
5326 SSMR3PutStrZ,
5327 SSMR3GetStruct,
5328 SSMR3GetStructEx,
5329 SSMR3GetBool,
5330 SSMR3GetBoolV,
5331 SSMR3GetU8,
5332 SSMR3GetU8V,
5333 SSMR3GetS8,
5334 SSMR3GetS8V,
5335 SSMR3GetU16,
5336 SSMR3GetU16V,
5337 SSMR3GetS16,
5338 SSMR3GetS16V,
5339 SSMR3GetU32,
5340 SSMR3GetU32V,
5341 SSMR3GetS32,
5342 SSMR3GetS32V,
5343 SSMR3GetU64,
5344 SSMR3GetU64V,
5345 SSMR3GetS64,
5346 SSMR3GetS64V,
5347 SSMR3GetU128,
5348 SSMR3GetU128V,
5349 SSMR3GetS128,
5350 SSMR3GetS128V,
5351 SSMR3GetGCPhys32,
5352 SSMR3GetGCPhys32V,
5353 SSMR3GetGCPhys64,
5354 SSMR3GetGCPhys64V,
5355 SSMR3GetGCPhys,
5356 SSMR3GetGCPhysV,
5357 SSMR3GetUInt,
5358 SSMR3GetSInt,
5359 SSMR3GetGCUInt,
5360 SSMR3GetGCUIntReg,
5361 SSMR3GetGCPtr,
5362 SSMR3GetGCUIntPtr,
5363 SSMR3GetRCPtr,
5364 SSMR3GetIOPort,
5365 SSMR3GetSel,
5366 SSMR3GetMem,
5367 SSMR3GetStrZ,
5368 SSMR3GetStrZEx,
5369 SSMR3Skip,
5370 SSMR3SkipToEndOfUnit,
5371 SSMR3SetLoadError,
5372 SSMR3SetLoadErrorV,
5373 SSMR3SetCfgError,
5374 SSMR3SetCfgErrorV,
5375 SSMR3HandleGetStatus,
5376 SSMR3HandleGetAfter,
5377 SSMR3HandleIsLiveSave,
5378 SSMR3HandleMaxDowntime,
5379 SSMR3HandleHostBits,
5380 SSMR3HandleRevision,
5381 SSMR3HandleVersion,
5382 SSMR3HandleHostOSAndArch,
5383 pdmR3DevHlp_TimerCreate,
5384 pdmR3DevHlp_TimerFromMicro,
5385 pdmR3DevHlp_TimerFromMilli,
5386 pdmR3DevHlp_TimerFromNano,
5387 pdmR3DevHlp_TimerGet,
5388 pdmR3DevHlp_TimerGetFreq,
5389 pdmR3DevHlp_TimerGetNano,
5390 pdmR3DevHlp_TimerIsActive,
5391 pdmR3DevHlp_TimerIsLockOwner,
5392 pdmR3DevHlp_TimerLockClock,
5393 pdmR3DevHlp_TimerLockClock2,
5394 pdmR3DevHlp_TimerSet,
5395 pdmR3DevHlp_TimerSetFrequencyHint,
5396 pdmR3DevHlp_TimerSetMicro,
5397 pdmR3DevHlp_TimerSetMillies,
5398 pdmR3DevHlp_TimerSetNano,
5399 pdmR3DevHlp_TimerSetRelative,
5400 pdmR3DevHlp_TimerStop,
5401 pdmR3DevHlp_TimerUnlockClock,
5402 pdmR3DevHlp_TimerUnlockClock2,
5403 pdmR3DevHlp_TimerSetCritSect,
5404 pdmR3DevHlp_TimerSave,
5405 pdmR3DevHlp_TimerLoad,
5406 pdmR3DevHlp_TimerDestroy,
5407 TMR3TimerSkip,
5408 pdmR3DevHlp_TMUtcNow,
5409 CFGMR3Exists,
5410 CFGMR3QueryType,
5411 CFGMR3QuerySize,
5412 CFGMR3QueryInteger,
5413 CFGMR3QueryIntegerDef,
5414 CFGMR3QueryString,
5415 CFGMR3QueryStringDef,
5416 CFGMR3QueryPassword,
5417 CFGMR3QueryPasswordDef,
5418 CFGMR3QueryBytes,
5419 CFGMR3QueryU64,
5420 CFGMR3QueryU64Def,
5421 CFGMR3QueryS64,
5422 CFGMR3QueryS64Def,
5423 CFGMR3QueryU32,
5424 CFGMR3QueryU32Def,
5425 CFGMR3QueryS32,
5426 CFGMR3QueryS32Def,
5427 CFGMR3QueryU16,
5428 CFGMR3QueryU16Def,
5429 CFGMR3QueryS16,
5430 CFGMR3QueryS16Def,
5431 CFGMR3QueryU8,
5432 CFGMR3QueryU8Def,
5433 CFGMR3QueryS8,
5434 CFGMR3QueryS8Def,
5435 CFGMR3QueryBool,
5436 CFGMR3QueryBoolDef,
5437 CFGMR3QueryPort,
5438 CFGMR3QueryPortDef,
5439 CFGMR3QueryUInt,
5440 CFGMR3QueryUIntDef,
5441 CFGMR3QuerySInt,
5442 CFGMR3QuerySIntDef,
5443 CFGMR3QueryGCPtr,
5444 CFGMR3QueryGCPtrDef,
5445 CFGMR3QueryGCPtrU,
5446 CFGMR3QueryGCPtrUDef,
5447 CFGMR3QueryGCPtrS,
5448 CFGMR3QueryGCPtrSDef,
5449 CFGMR3QueryStringAlloc,
5450 CFGMR3QueryStringAllocDef,
5451 CFGMR3GetParent,
5452 CFGMR3GetChild,
5453 CFGMR3GetChildF,
5454 CFGMR3GetChildFV,
5455 CFGMR3GetFirstChild,
5456 CFGMR3GetNextChild,
5457 CFGMR3GetName,
5458 CFGMR3GetNameLen,
5459 CFGMR3AreChildrenValid,
5460 CFGMR3GetFirstValue,
5461 CFGMR3GetNextValue,
5462 CFGMR3GetValueName,
5463 CFGMR3GetValueNameLen,
5464 CFGMR3GetValueType,
5465 CFGMR3AreValuesValid,
5466 CFGMR3ValidateConfig,
5467 pdmR3DevHlpTracing_PhysRead,
5468 pdmR3DevHlpTracing_PhysWrite,
5469 pdmR3DevHlp_PhysGCPhys2CCPtr,
5470 pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
5471 pdmR3DevHlp_PhysReleasePageMappingLock,
5472 pdmR3DevHlp_PhysReadGCVirt,
5473 pdmR3DevHlp_PhysWriteGCVirt,
5474 pdmR3DevHlp_PhysGCPtr2GCPhys,
5475 pdmR3DevHlp_PhysIsGCPhysNormal,
5476 pdmR3DevHlp_PhysChangeMemBalloon,
5477 pdmR3DevHlp_MMHeapAlloc,
5478 pdmR3DevHlp_MMHeapAllocZ,
5479 pdmR3DevHlp_MMHeapAPrintfV,
5480 pdmR3DevHlp_MMHeapFree,
5481 pdmR3DevHlp_MMPhysGetRamSize,
5482 pdmR3DevHlp_MMPhysGetRamSizeBelow4GB,
5483 pdmR3DevHlp_MMPhysGetRamSizeAbove4GB,
5484 pdmR3DevHlp_VMState,
5485 pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
5486 pdmR3DevHlp_VMSetErrorV,
5487 pdmR3DevHlp_VMSetRuntimeErrorV,
5488 pdmR3DevHlp_VMWaitForDeviceReady,
5489 pdmR3DevHlp_VMNotifyCpuDeviceReady,
5490 pdmR3DevHlp_VMReqCallNoWaitV,
5491 pdmR3DevHlp_VMReqPriorityCallWaitV,
5492 pdmR3DevHlp_DBGFStopV,
5493 pdmR3DevHlp_DBGFInfoRegister,
5494 pdmR3DevHlp_DBGFInfoRegisterArgv,
5495 pdmR3DevHlp_DBGFRegRegister,
5496 pdmR3DevHlp_DBGFTraceBuf,
5497 pdmR3DevHlp_DBGFReportBugCheck,
5498 pdmR3DevHlp_DBGFCoreWrite,
5499 pdmR3DevHlp_DBGFInfoLogHlp,
5500 pdmR3DevHlp_DBGFRegNmQueryU64,
5501 pdmR3DevHlp_DBGFRegPrintfV,
5502 pdmR3DevHlp_STAMRegister,
5503 pdmR3DevHlp_STAMRegisterV,
5504 pdmR3DevHlp_PCIRegister,
5505 pdmR3DevHlp_PCIRegisterMsi,
5506 pdmR3DevHlp_PCIIORegionRegister,
5507 pdmR3DevHlp_PCIInterceptConfigAccesses,
5508 pdmR3DevHlp_PCIConfigWrite,
5509 pdmR3DevHlp_PCIConfigRead,
5510 pdmR3DevHlpTracing_PCIPhysRead,
5511 pdmR3DevHlpTracing_PCIPhysWrite,
5512 pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
5513 pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
5514 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
5515 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
5516 pdmR3DevHlpTracing_PCISetIrq,
5517 pdmR3DevHlpTracing_PCISetIrqNoWait,
5518 pdmR3DevHlpTracing_ISASetIrq,
5519 pdmR3DevHlpTracing_ISASetIrqNoWait,
5520 pdmR3DevHlp_DriverAttach,
5521 pdmR3DevHlp_DriverDetach,
5522 pdmR3DevHlp_DriverReconfigure,
5523 pdmR3DevHlp_QueueCreate,
5524 pdmR3DevHlp_QueueAlloc,
5525 pdmR3DevHlp_QueueInsert,
5526 pdmR3DevHlp_QueueFlushIfNecessary,
5527 pdmR3DevHlp_TaskCreate,
5528 pdmR3DevHlp_TaskTrigger,
5529 pdmR3DevHlp_SUPSemEventCreate,
5530 pdmR3DevHlp_SUPSemEventClose,
5531 pdmR3DevHlp_SUPSemEventSignal,
5532 pdmR3DevHlp_SUPSemEventWaitNoResume,
5533 pdmR3DevHlp_SUPSemEventWaitNsAbsIntr,
5534 pdmR3DevHlp_SUPSemEventWaitNsRelIntr,
5535 pdmR3DevHlp_SUPSemEventGetResolution,
5536 pdmR3DevHlp_SUPSemEventMultiCreate,
5537 pdmR3DevHlp_SUPSemEventMultiClose,
5538 pdmR3DevHlp_SUPSemEventMultiSignal,
5539 pdmR3DevHlp_SUPSemEventMultiReset,
5540 pdmR3DevHlp_SUPSemEventMultiWaitNoResume,
5541 pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr,
5542 pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr,
5543 pdmR3DevHlp_SUPSemEventMultiGetResolution,
5544 pdmR3DevHlp_CritSectInit,
5545 pdmR3DevHlp_CritSectGetNop,
5546 pdmR3DevHlp_SetDeviceCritSect,
5547 pdmR3DevHlp_CritSectYield,
5548 pdmR3DevHlp_CritSectEnter,
5549 pdmR3DevHlp_CritSectEnterDebug,
5550 pdmR3DevHlp_CritSectTryEnter,
5551 pdmR3DevHlp_CritSectTryEnterDebug,
5552 pdmR3DevHlp_CritSectLeave,
5553 pdmR3DevHlp_CritSectIsOwner,
5554 pdmR3DevHlp_CritSectIsInitialized,
5555 pdmR3DevHlp_CritSectHasWaiters,
5556 pdmR3DevHlp_CritSectGetRecursion,
5557 pdmR3DevHlp_CritSectScheduleExitEvent,
5558 pdmR3DevHlp_CritSectDelete,
5559 pdmR3DevHlp_CritSectRwInit,
5560 pdmR3DevHlp_CritSectRwDelete,
5561 pdmR3DevHlp_CritSectRwEnterShared,
5562 pdmR3DevHlp_CritSectRwEnterSharedDebug,
5563 pdmR3DevHlp_CritSectRwTryEnterShared,
5564 pdmR3DevHlp_CritSectRwTryEnterSharedDebug,
5565 pdmR3DevHlp_CritSectRwLeaveShared,
5566 pdmR3DevHlp_CritSectRwEnterExcl,
5567 pdmR3DevHlp_CritSectRwEnterExclDebug,
5568 pdmR3DevHlp_CritSectRwTryEnterExcl,
5569 pdmR3DevHlp_CritSectRwTryEnterExclDebug,
5570 pdmR3DevHlp_CritSectRwLeaveExcl,
5571 pdmR3DevHlp_CritSectRwIsWriteOwner,
5572 pdmR3DevHlp_CritSectRwIsReadOwner,
5573 pdmR3DevHlp_CritSectRwGetWriteRecursion,
5574 pdmR3DevHlp_CritSectRwGetWriterReadRecursion,
5575 pdmR3DevHlp_CritSectRwGetReadCount,
5576 pdmR3DevHlp_CritSectRwIsInitialized,
5577 pdmR3DevHlp_ThreadCreate,
5578 PDMR3ThreadDestroy,
5579 PDMR3ThreadIAmSuspending,
5580 PDMR3ThreadIAmRunning,
5581 PDMR3ThreadSleep,
5582 PDMR3ThreadSuspend,
5583 PDMR3ThreadResume,
5584 pdmR3DevHlp_SetAsyncNotification,
5585 pdmR3DevHlp_AsyncNotificationCompleted,
5586 pdmR3DevHlp_RTCRegister,
5587 pdmR3DevHlp_PCIBusRegister,
5588 pdmR3DevHlp_IommuRegister,
5589 pdmR3DevHlp_PICRegister,
5590 pdmR3DevHlp_ApicRegister,
5591 pdmR3DevHlp_IoApicRegister,
5592 pdmR3DevHlp_HpetRegister,
5593 pdmR3DevHlp_PciRawRegister,
5594 pdmR3DevHlp_DMACRegister,
5595 pdmR3DevHlp_DMARegister,
5596 pdmR3DevHlp_DMAReadMemory,
5597 pdmR3DevHlp_DMAWriteMemory,
5598 pdmR3DevHlp_DMASetDREQ,
5599 pdmR3DevHlp_DMAGetChannelMode,
5600 pdmR3DevHlp_DMASchedule,
5601 pdmR3DevHlp_CMOSWrite,
5602 pdmR3DevHlp_CMOSRead,
5603 pdmR3DevHlp_AssertEMT,
5604 pdmR3DevHlp_AssertOther,
5605 pdmR3DevHlp_LdrGetRCInterfaceSymbols,
5606 pdmR3DevHlp_LdrGetR0InterfaceSymbols,
5607 pdmR3DevHlp_CallR0,
5608 pdmR3DevHlp_VMGetSuspendReason,
5609 pdmR3DevHlp_VMGetResumeReason,
5610 pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
5611 pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
5612 pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
5613 pdmR3DevHlp_CpuGetGuestArch,
5614 pdmR3DevHlp_CpuGetGuestMicroarch,
5615 pdmR3DevHlp_CpuGetGuestAddrWidths,
5616 pdmR3DevHlp_CpuGetGuestScalableBusFrequency,
5617 pdmR3DevHlp_STAMDeregisterByPrefix,
5618 0,
5619 0,
5620 0,
5621 0,
5622 0,
5623 0,
5624 0,
5625 0,
5626 0,
5627 pdmR3DevHlp_GetUVM,
5628 pdmR3DevHlp_GetVM,
5629 pdmR3DevHlp_GetVMCPU,
5630 pdmR3DevHlp_GetCurrentCpuId,
5631 pdmR3DevHlp_RegisterVMMDevHeap,
5632 pdmR3DevHlp_FirmwareRegister,
5633 pdmR3DevHlp_VMReset,
5634 pdmR3DevHlp_VMSuspend,
5635 pdmR3DevHlp_VMSuspendSaveAndPowerOff,
5636 pdmR3DevHlp_VMPowerOff,
5637 pdmR3DevHlp_A20IsEnabled,
5638 pdmR3DevHlp_A20Set,
5639 pdmR3DevHlp_GetCpuId,
5640 pdmR3DevHlp_GetMainExecutionEngine,
5641 pdmR3DevHlp_TMTimeVirtGet,
5642 pdmR3DevHlp_TMTimeVirtGetFreq,
5643 pdmR3DevHlp_TMTimeVirtGetNano,
5644 pdmR3DevHlp_TMCpuTicksPerSecond,
5645 pdmR3DevHlp_GetSupDrvSession,
5646 pdmR3DevHlp_QueryGenericUserObject,
5647 pdmR3DevHlp_PGMHandlerPhysicalTypeRegister,
5648 pdmR3DevHlp_PGMHandlerPhysicalRegister,
5649 pdmR3DevHlp_PGMHandlerPhysicalDeregister,
5650 pdmR3DevHlp_PGMHandlerPhysicalPageTempOff,
5651 pdmR3DevHlp_PGMHandlerPhysicalReset,
5652 pdmR3DevHlp_VMMRegisterPatchMemory,
5653 pdmR3DevHlp_VMMDeregisterPatchMemory,
5654 pdmR3DevHlp_SharedModuleRegister,
5655 pdmR3DevHlp_SharedModuleUnregister,
5656 pdmR3DevHlp_SharedModuleGetPageState,
5657 pdmR3DevHlp_SharedModuleCheckAll,
5658 pdmR3DevHlp_QueryLun,
5659 pdmR3DevHlp_GIMDeviceRegister,
5660 pdmR3DevHlp_GIMGetDebugSetup,
5661 pdmR3DevHlp_GIMGetMmio2Regions,
5662 PDM_DEVHLPR3_VERSION /* the end */
5663};
5664#endif /* VBOX_WITH_DBGF_TRACING */
5665
5666
5667
5668
5669/** @interface_method_impl{PDMDEVHLPR3,pfnGetUVM} */
5670static DECLCALLBACK(PUVM) pdmR3DevHlp_Untrusted_GetUVM(PPDMDEVINS pDevIns)
5671{
5672 PDMDEV_ASSERT_DEVINS(pDevIns);
5673 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5674 return NULL;
5675}
5676
5677
5678/** @interface_method_impl{PDMDEVHLPR3,pfnGetVM} */
5679static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns)
5680{
5681 PDMDEV_ASSERT_DEVINS(pDevIns);
5682 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5683 return NULL;
5684}
5685
5686
5687/** @interface_method_impl{PDMDEVHLPR3,pfnGetVMCPU} */
5688static DECLCALLBACK(PVMCPU) pdmR3DevHlp_Untrusted_GetVMCPU(PPDMDEVINS pDevIns)
5689{
5690 PDMDEV_ASSERT_DEVINS(pDevIns);
5691 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5692 return NULL;
5693}
5694
5695
5696/** @interface_method_impl{PDMDEVHLPR3,pfnGetCurrentCpuId} */
5697static DECLCALLBACK(VMCPUID) pdmR3DevHlp_Untrusted_GetCurrentCpuId(PPDMDEVINS pDevIns)
5698{
5699 PDMDEV_ASSERT_DEVINS(pDevIns);
5700 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5701 return NIL_VMCPUID;
5702}
5703
5704
5705/** @interface_method_impl{PDMDEVHLPR3,pfnRegisterVMMDevHeap} */
5706static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys,
5707 RTR3PTR pvHeap, unsigned cbHeap)
5708{
5709 PDMDEV_ASSERT_DEVINS(pDevIns);
5710 NOREF(GCPhys); NOREF(pvHeap); NOREF(cbHeap);
5711 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5712 return VERR_ACCESS_DENIED;
5713}
5714
5715
5716/** @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister} */
5717static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
5718{
5719 PDMDEV_ASSERT_DEVINS(pDevIns);
5720 NOREF(pFwReg); NOREF(ppFwHlp);
5721 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5722 return VERR_ACCESS_DENIED;
5723}
5724
5725
5726/** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
5727static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
5728{
5729 PDMDEV_ASSERT_DEVINS(pDevIns); NOREF(fFlags);
5730 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5731 return VERR_ACCESS_DENIED;
5732}
5733
5734
5735/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspend} */
5736static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns)
5737{
5738 PDMDEV_ASSERT_DEVINS(pDevIns);
5739 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5740 return VERR_ACCESS_DENIED;
5741}
5742
5743
5744/** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspendSaveAndPowerOff} */
5745static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
5746{
5747 PDMDEV_ASSERT_DEVINS(pDevIns);
5748 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5749 return VERR_ACCESS_DENIED;
5750}
5751
5752
5753/** @interface_method_impl{PDMDEVHLPR3,pfnVMPowerOff} */
5754static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns)
5755{
5756 PDMDEV_ASSERT_DEVINS(pDevIns);
5757 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5758 return VERR_ACCESS_DENIED;
5759}
5760
5761
5762/** @interface_method_impl{PDMDEVHLPR3,pfnA20IsEnabled} */
5763static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns)
5764{
5765 PDMDEV_ASSERT_DEVINS(pDevIns);
5766 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5767 return false;
5768}
5769
5770
5771/** @interface_method_impl{PDMDEVHLPR3,pfnA20Set} */
5772static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable)
5773{
5774 PDMDEV_ASSERT_DEVINS(pDevIns);
5775 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5776 NOREF(fEnable);
5777}
5778
5779
5780/** @interface_method_impl{PDMDEVHLPR3,pfnGetCpuId} */
5781static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
5782 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
5783{
5784 PDMDEV_ASSERT_DEVINS(pDevIns);
5785 NOREF(iLeaf); NOREF(pEax); NOREF(pEbx); NOREF(pEcx); NOREF(pEdx);
5786 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5787}
5788
5789
5790/** @interface_method_impl{PDMDEVHLPR3,pfnGetMainExecutionEngine} */
5791static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_GetMainExecutionEngine(PPDMDEVINS pDevIns)
5792{
5793 PDMDEV_ASSERT_DEVINS(pDevIns);
5794 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5795 return VM_EXEC_ENGINE_NOT_SET;
5796}
5797
5798
5799/** @interface_method_impl{PDMDEVHLPR3,pfnGetSupDrvSession} */
5800static DECLCALLBACK(PSUPDRVSESSION) pdmR3DevHlp_Untrusted_GetSupDrvSession(PPDMDEVINS pDevIns)
5801{
5802 PDMDEV_ASSERT_DEVINS(pDevIns);
5803 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5804 return (PSUPDRVSESSION)0;
5805}
5806
5807
5808/** @interface_method_impl{PDMDEVHLPR3,pfnQueryGenericUserObject} */
5809static DECLCALLBACK(void *) pdmR3DevHlp_Untrusted_QueryGenericUserObject(PPDMDEVINS pDevIns, PCRTUUID pUuid)
5810{
5811 PDMDEV_ASSERT_DEVINS(pDevIns);
5812 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d %RTuuid\n",
5813 pDevIns->pReg->szName, pDevIns->iInstance, pUuid));
5814 return NULL;
5815}
5816
5817
5818/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalTypeRegister} */
5819static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalTypeRegister(PPDMDEVINS pDevIns, PGMPHYSHANDLERKIND enmKind,
5820 PFNPGMPHYSHANDLER pfnHandler,
5821 const char *pszDesc, PPGMPHYSHANDLERTYPE phType)
5822{
5823 PDMDEV_ASSERT_DEVINS(pDevIns);
5824 RT_NOREF(pDevIns, enmKind, pfnHandler, pszDesc);
5825 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5826 pDevIns->pReg->szName, pDevIns->iInstance));
5827 *phType = NIL_PGMPHYSHANDLERTYPE;
5828 return VERR_ACCESS_DENIED;
5829}
5830
5831
5832/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalRegister} */
5833static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
5834 PGMPHYSHANDLERTYPE hType, R3PTRTYPE(const char *) pszDesc)
5835{
5836 PDMDEV_ASSERT_DEVINS(pDevIns);
5837 RT_NOREF(GCPhys, GCPhysLast, hType, pszDesc);
5838 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
5839 return VERR_ACCESS_DENIED;
5840}
5841
5842
5843/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalDeregister} */
5844static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalDeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
5845{
5846 PDMDEV_ASSERT_DEVINS(pDevIns);
5847 RT_NOREF(GCPhys);
5848 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5849 pDevIns->pReg->szName, pDevIns->iInstance));
5850 return VERR_ACCESS_DENIED;
5851}
5852
5853
5854/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalPageTempOff} */
5855static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalPageTempOff(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage)
5856{
5857 PDMDEV_ASSERT_DEVINS(pDevIns);
5858 RT_NOREF(GCPhys, GCPhysPage);
5859 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5860 pDevIns->pReg->szName, pDevIns->iInstance));
5861 return VERR_ACCESS_DENIED;
5862}
5863
5864
5865/** @interface_method_impl{PDMDEVHLPR3,pfnPGMHandlerPhysicalReset} */
5866static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PGMHandlerPhysicalReset(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
5867{
5868 PDMDEV_ASSERT_DEVINS(pDevIns);
5869 RT_NOREF(GCPhys);
5870 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5871 pDevIns->pReg->szName, pDevIns->iInstance));
5872 return VERR_ACCESS_DENIED;
5873}
5874
5875
5876/** @interface_method_impl{PDMDEVHLPR3,pfnVMMRegisterPatchMemory} */
5877static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMMRegisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
5878{
5879 PDMDEV_ASSERT_DEVINS(pDevIns);
5880 RT_NOREF(GCPtrPatchMem, cbPatchMem);
5881 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5882 pDevIns->pReg->szName, pDevIns->iInstance));
5883 return VERR_ACCESS_DENIED;
5884}
5885
5886
5887/** @interface_method_impl{PDMDEVHLPR3,pfnVMMDeregisterPatchMemory} */
5888static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMMDeregisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
5889{
5890 PDMDEV_ASSERT_DEVINS(pDevIns);
5891 RT_NOREF(GCPtrPatchMem, cbPatchMem);
5892 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5893 pDevIns->pReg->szName, pDevIns->iInstance));
5894 return VERR_ACCESS_DENIED;
5895}
5896
5897
5898/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleRegister} */
5899static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleRegister(PPDMDEVINS pDevIns, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
5900 RTGCPTR GCBaseAddr, uint32_t cbModule,
5901 uint32_t cRegions, VMMDEVSHAREDREGIONDESC const *paRegions)
5902{
5903 PDMDEV_ASSERT_DEVINS(pDevIns);
5904 RT_NOREF(enmGuestOS, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions, paRegions);
5905 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5906 pDevIns->pReg->szName, pDevIns->iInstance));
5907 return VERR_ACCESS_DENIED;
5908}
5909
5910
5911/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleUnregister} */
5912static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleUnregister(PPDMDEVINS pDevIns, char *pszModuleName, char *pszVersion,
5913 RTGCPTR GCBaseAddr, uint32_t cbModule)
5914{
5915 PDMDEV_ASSERT_DEVINS(pDevIns);
5916 RT_NOREF(pszModuleName, pszVersion, GCBaseAddr, cbModule);
5917 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5918 pDevIns->pReg->szName, pDevIns->iInstance));
5919 return VERR_ACCESS_DENIED;
5920}
5921
5922
5923/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleGetPageState} */
5924static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleGetPageState(PPDMDEVINS pDevIns, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags)
5925{
5926 PDMDEV_ASSERT_DEVINS(pDevIns);
5927 RT_NOREF(GCPtrPage, pfShared, pfPageFlags);
5928 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5929 pDevIns->pReg->szName, pDevIns->iInstance));
5930 return VERR_ACCESS_DENIED;
5931}
5932
5933
5934/** @interface_method_impl{PDMDEVHLPR3,pfnSharedModuleCheckAll} */
5935static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_SharedModuleCheckAll(PPDMDEVINS pDevIns)
5936{
5937 PDMDEV_ASSERT_DEVINS(pDevIns);
5938 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5939 pDevIns->pReg->szName, pDevIns->iInstance));
5940 return VERR_ACCESS_DENIED;
5941}
5942
5943
5944/** @interface_method_impl{PDMDEVHLPR3,pfnQueryLun} */
5945static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_QueryLun(PPDMDEVINS pDevIns, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase)
5946{
5947 PDMDEV_ASSERT_DEVINS(pDevIns);
5948 RT_NOREF(pszDevice, iInstance, iLun, ppBase);
5949 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5950 pDevIns->pReg->szName, pDevIns->iInstance));
5951 return VERR_ACCESS_DENIED;
5952}
5953
5954
5955/** @interface_method_impl{PDMDEVHLPR3,pfnGIMDeviceRegister} */
5956static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GIMDeviceRegister(PPDMDEVINS pDevIns, PGIMDEBUG pDbg)
5957{
5958 PDMDEV_ASSERT_DEVINS(pDevIns);
5959 RT_NOREF(pDbg);
5960 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5961 pDevIns->pReg->szName, pDevIns->iInstance));
5962}
5963
5964
5965/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetDebugSetup} */
5966static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_GIMGetDebugSetup(PPDMDEVINS pDevIns, PGIMDEBUGSETUP pDbgSetup)
5967{
5968 PDMDEV_ASSERT_DEVINS(pDevIns);
5969 RT_NOREF(pDbgSetup);
5970 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5971 pDevIns->pReg->szName, pDevIns->iInstance));
5972 return VERR_ACCESS_DENIED;
5973}
5974
5975
5976/** @interface_method_impl{PDMDEVHLPR3,pfnGIMGetMmio2Regions} */
5977static DECLCALLBACK(PGIMMMIO2REGION) pdmR3DevHlp_Untrusted_GIMGetMmio2Regions(PPDMDEVINS pDevIns, uint32_t *pcRegions)
5978{
5979 PDMDEV_ASSERT_DEVINS(pDevIns);
5980 RT_NOREF(pcRegions);
5981 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n",
5982 pDevIns->pReg->szName, pDevIns->iInstance));
5983 return NULL;
5984}
5985
5986
5987/**
5988 * The device helper structure for non-trusted devices.
5989 */
5990const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =
5991{
5992 PDM_DEVHLPR3_VERSION,
5993 pdmR3DevHlp_IoPortCreateEx,
5994 pdmR3DevHlp_IoPortMap,
5995 pdmR3DevHlp_IoPortUnmap,
5996 pdmR3DevHlp_IoPortGetMappingAddress,
5997 pdmR3DevHlp_IoPortRead,
5998 pdmR3DevHlp_IoPortWrite,
5999 pdmR3DevHlp_MmioCreateEx,
6000 pdmR3DevHlp_MmioMap,
6001 pdmR3DevHlp_MmioUnmap,
6002 pdmR3DevHlp_MmioReduce,
6003 pdmR3DevHlp_MmioGetMappingAddress,
6004 pdmR3DevHlp_Mmio2Create,
6005 pdmR3DevHlp_Mmio2Destroy,
6006 pdmR3DevHlp_Mmio2Map,
6007 pdmR3DevHlp_Mmio2Unmap,
6008 pdmR3DevHlp_Mmio2Reduce,
6009 pdmR3DevHlp_Mmio2GetMappingAddress,
6010 pdmR3DevHlp_Mmio2QueryAndResetDirtyBitmap,
6011 pdmR3DevHlp_Mmio2ControlDirtyPageTracking,
6012 pdmR3DevHlp_Mmio2ChangeRegionNo,
6013 pdmR3DevHlp_MmioMapMmio2Page,
6014 pdmR3DevHlp_MmioResetRegion,
6015 pdmR3DevHlp_ROMRegister,
6016 pdmR3DevHlp_ROMProtectShadow,
6017 pdmR3DevHlp_SSMRegister,
6018 pdmR3DevHlp_SSMRegisterLegacy,
6019 SSMR3PutStruct,
6020 SSMR3PutStructEx,
6021 SSMR3PutBool,
6022 SSMR3PutU8,
6023 SSMR3PutS8,
6024 SSMR3PutU16,
6025 SSMR3PutS16,
6026 SSMR3PutU32,
6027 SSMR3PutS32,
6028 SSMR3PutU64,
6029 SSMR3PutS64,
6030 SSMR3PutU128,
6031 SSMR3PutS128,
6032 SSMR3PutUInt,
6033 SSMR3PutSInt,
6034 SSMR3PutGCUInt,
6035 SSMR3PutGCUIntReg,
6036 SSMR3PutGCPhys32,
6037 SSMR3PutGCPhys64,
6038 SSMR3PutGCPhys,
6039 SSMR3PutGCPtr,
6040 SSMR3PutGCUIntPtr,
6041 SSMR3PutRCPtr,
6042 SSMR3PutIOPort,
6043 SSMR3PutSel,
6044 SSMR3PutMem,
6045 SSMR3PutStrZ,
6046 SSMR3GetStruct,
6047 SSMR3GetStructEx,
6048 SSMR3GetBool,
6049 SSMR3GetBoolV,
6050 SSMR3GetU8,
6051 SSMR3GetU8V,
6052 SSMR3GetS8,
6053 SSMR3GetS8V,
6054 SSMR3GetU16,
6055 SSMR3GetU16V,
6056 SSMR3GetS16,
6057 SSMR3GetS16V,
6058 SSMR3GetU32,
6059 SSMR3GetU32V,
6060 SSMR3GetS32,
6061 SSMR3GetS32V,
6062 SSMR3GetU64,
6063 SSMR3GetU64V,
6064 SSMR3GetS64,
6065 SSMR3GetS64V,
6066 SSMR3GetU128,
6067 SSMR3GetU128V,
6068 SSMR3GetS128,
6069 SSMR3GetS128V,
6070 SSMR3GetGCPhys32,
6071 SSMR3GetGCPhys32V,
6072 SSMR3GetGCPhys64,
6073 SSMR3GetGCPhys64V,
6074 SSMR3GetGCPhys,
6075 SSMR3GetGCPhysV,
6076 SSMR3GetUInt,
6077 SSMR3GetSInt,
6078 SSMR3GetGCUInt,
6079 SSMR3GetGCUIntReg,
6080 SSMR3GetGCPtr,
6081 SSMR3GetGCUIntPtr,
6082 SSMR3GetRCPtr,
6083 SSMR3GetIOPort,
6084 SSMR3GetSel,
6085 SSMR3GetMem,
6086 SSMR3GetStrZ,
6087 SSMR3GetStrZEx,
6088 SSMR3Skip,
6089 SSMR3SkipToEndOfUnit,
6090 SSMR3SetLoadError,
6091 SSMR3SetLoadErrorV,
6092 SSMR3SetCfgError,
6093 SSMR3SetCfgErrorV,
6094 SSMR3HandleGetStatus,
6095 SSMR3HandleGetAfter,
6096 SSMR3HandleIsLiveSave,
6097 SSMR3HandleMaxDowntime,
6098 SSMR3HandleHostBits,
6099 SSMR3HandleRevision,
6100 SSMR3HandleVersion,
6101 SSMR3HandleHostOSAndArch,
6102 pdmR3DevHlp_TimerCreate,
6103 pdmR3DevHlp_TimerFromMicro,
6104 pdmR3DevHlp_TimerFromMilli,
6105 pdmR3DevHlp_TimerFromNano,
6106 pdmR3DevHlp_TimerGet,
6107 pdmR3DevHlp_TimerGetFreq,
6108 pdmR3DevHlp_TimerGetNano,
6109 pdmR3DevHlp_TimerIsActive,
6110 pdmR3DevHlp_TimerIsLockOwner,
6111 pdmR3DevHlp_TimerLockClock,
6112 pdmR3DevHlp_TimerLockClock2,
6113 pdmR3DevHlp_TimerSet,
6114 pdmR3DevHlp_TimerSetFrequencyHint,
6115 pdmR3DevHlp_TimerSetMicro,
6116 pdmR3DevHlp_TimerSetMillies,
6117 pdmR3DevHlp_TimerSetNano,
6118 pdmR3DevHlp_TimerSetRelative,
6119 pdmR3DevHlp_TimerStop,
6120 pdmR3DevHlp_TimerUnlockClock,
6121 pdmR3DevHlp_TimerUnlockClock2,
6122 pdmR3DevHlp_TimerSetCritSect,
6123 pdmR3DevHlp_TimerSave,
6124 pdmR3DevHlp_TimerLoad,
6125 pdmR3DevHlp_TimerDestroy,
6126 TMR3TimerSkip,
6127 pdmR3DevHlp_TMUtcNow,
6128 CFGMR3Exists,
6129 CFGMR3QueryType,
6130 CFGMR3QuerySize,
6131 CFGMR3QueryInteger,
6132 CFGMR3QueryIntegerDef,
6133 CFGMR3QueryString,
6134 CFGMR3QueryStringDef,
6135 CFGMR3QueryPassword,
6136 CFGMR3QueryPasswordDef,
6137 CFGMR3QueryBytes,
6138 CFGMR3QueryU64,
6139 CFGMR3QueryU64Def,
6140 CFGMR3QueryS64,
6141 CFGMR3QueryS64Def,
6142 CFGMR3QueryU32,
6143 CFGMR3QueryU32Def,
6144 CFGMR3QueryS32,
6145 CFGMR3QueryS32Def,
6146 CFGMR3QueryU16,
6147 CFGMR3QueryU16Def,
6148 CFGMR3QueryS16,
6149 CFGMR3QueryS16Def,
6150 CFGMR3QueryU8,
6151 CFGMR3QueryU8Def,
6152 CFGMR3QueryS8,
6153 CFGMR3QueryS8Def,
6154 CFGMR3QueryBool,
6155 CFGMR3QueryBoolDef,
6156 CFGMR3QueryPort,
6157 CFGMR3QueryPortDef,
6158 CFGMR3QueryUInt,
6159 CFGMR3QueryUIntDef,
6160 CFGMR3QuerySInt,
6161 CFGMR3QuerySIntDef,
6162 CFGMR3QueryGCPtr,
6163 CFGMR3QueryGCPtrDef,
6164 CFGMR3QueryGCPtrU,
6165 CFGMR3QueryGCPtrUDef,
6166 CFGMR3QueryGCPtrS,
6167 CFGMR3QueryGCPtrSDef,
6168 CFGMR3QueryStringAlloc,
6169 CFGMR3QueryStringAllocDef,
6170 CFGMR3GetParent,
6171 CFGMR3GetChild,
6172 CFGMR3GetChildF,
6173 CFGMR3GetChildFV,
6174 CFGMR3GetFirstChild,
6175 CFGMR3GetNextChild,
6176 CFGMR3GetName,
6177 CFGMR3GetNameLen,
6178 CFGMR3AreChildrenValid,
6179 CFGMR3GetFirstValue,
6180 CFGMR3GetNextValue,
6181 CFGMR3GetValueName,
6182 CFGMR3GetValueNameLen,
6183 CFGMR3GetValueType,
6184 CFGMR3AreValuesValid,
6185 CFGMR3ValidateConfig,
6186 pdmR3DevHlp_PhysRead,
6187 pdmR3DevHlp_PhysWrite,
6188 pdmR3DevHlp_PhysGCPhys2CCPtr,
6189 pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
6190 pdmR3DevHlp_PhysReleasePageMappingLock,
6191 pdmR3DevHlp_PhysReadGCVirt,
6192 pdmR3DevHlp_PhysWriteGCVirt,
6193 pdmR3DevHlp_PhysGCPtr2GCPhys,
6194 pdmR3DevHlp_PhysIsGCPhysNormal,
6195 pdmR3DevHlp_PhysChangeMemBalloon,
6196 pdmR3DevHlp_MMHeapAlloc,
6197 pdmR3DevHlp_MMHeapAllocZ,
6198 pdmR3DevHlp_MMHeapAPrintfV,
6199 pdmR3DevHlp_MMHeapFree,
6200 pdmR3DevHlp_MMPhysGetRamSize,
6201 pdmR3DevHlp_MMPhysGetRamSizeBelow4GB,
6202 pdmR3DevHlp_MMPhysGetRamSizeAbove4GB,
6203 pdmR3DevHlp_VMState,
6204 pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
6205 pdmR3DevHlp_VMSetErrorV,
6206 pdmR3DevHlp_VMSetRuntimeErrorV,
6207 pdmR3DevHlp_VMWaitForDeviceReady,
6208 pdmR3DevHlp_VMNotifyCpuDeviceReady,
6209 pdmR3DevHlp_VMReqCallNoWaitV,
6210 pdmR3DevHlp_VMReqPriorityCallWaitV,
6211 pdmR3DevHlp_DBGFStopV,
6212 pdmR3DevHlp_DBGFInfoRegister,
6213 pdmR3DevHlp_DBGFInfoRegisterArgv,
6214 pdmR3DevHlp_DBGFRegRegister,
6215 pdmR3DevHlp_DBGFTraceBuf,
6216 pdmR3DevHlp_DBGFReportBugCheck,
6217 pdmR3DevHlp_DBGFCoreWrite,
6218 pdmR3DevHlp_DBGFInfoLogHlp,
6219 pdmR3DevHlp_DBGFRegNmQueryU64,
6220 pdmR3DevHlp_DBGFRegPrintfV,
6221 pdmR3DevHlp_STAMRegister,
6222 pdmR3DevHlp_STAMRegisterV,
6223 pdmR3DevHlp_PCIRegister,
6224 pdmR3DevHlp_PCIRegisterMsi,
6225 pdmR3DevHlp_PCIIORegionRegister,
6226 pdmR3DevHlp_PCIInterceptConfigAccesses,
6227 pdmR3DevHlp_PCIConfigWrite,
6228 pdmR3DevHlp_PCIConfigRead,
6229 pdmR3DevHlp_PCIPhysRead,
6230 pdmR3DevHlp_PCIPhysWrite,
6231 pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
6232 pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
6233 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
6234 pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
6235 pdmR3DevHlp_PCISetIrq,
6236 pdmR3DevHlp_PCISetIrqNoWait,
6237 pdmR3DevHlp_ISASetIrq,
6238 pdmR3DevHlp_ISASetIrqNoWait,
6239 pdmR3DevHlp_DriverAttach,
6240 pdmR3DevHlp_DriverDetach,
6241 pdmR3DevHlp_DriverReconfigure,
6242 pdmR3DevHlp_QueueCreate,
6243 pdmR3DevHlp_QueueAlloc,
6244 pdmR3DevHlp_QueueInsert,
6245 pdmR3DevHlp_QueueFlushIfNecessary,
6246 pdmR3DevHlp_TaskCreate,
6247 pdmR3DevHlp_TaskTrigger,
6248 pdmR3DevHlp_SUPSemEventCreate,
6249 pdmR3DevHlp_SUPSemEventClose,
6250 pdmR3DevHlp_SUPSemEventSignal,
6251 pdmR3DevHlp_SUPSemEventWaitNoResume,
6252 pdmR3DevHlp_SUPSemEventWaitNsAbsIntr,
6253 pdmR3DevHlp_SUPSemEventWaitNsRelIntr,
6254 pdmR3DevHlp_SUPSemEventGetResolution,
6255 pdmR3DevHlp_SUPSemEventMultiCreate,
6256 pdmR3DevHlp_SUPSemEventMultiClose,
6257 pdmR3DevHlp_SUPSemEventMultiSignal,
6258 pdmR3DevHlp_SUPSemEventMultiReset,
6259 pdmR3DevHlp_SUPSemEventMultiWaitNoResume,
6260 pdmR3DevHlp_SUPSemEventMultiWaitNsAbsIntr,
6261 pdmR3DevHlp_SUPSemEventMultiWaitNsRelIntr,
6262 pdmR3DevHlp_SUPSemEventMultiGetResolution,
6263 pdmR3DevHlp_CritSectInit,
6264 pdmR3DevHlp_CritSectGetNop,
6265 pdmR3DevHlp_SetDeviceCritSect,
6266 pdmR3DevHlp_CritSectYield,
6267 pdmR3DevHlp_CritSectEnter,
6268 pdmR3DevHlp_CritSectEnterDebug,
6269 pdmR3DevHlp_CritSectTryEnter,
6270 pdmR3DevHlp_CritSectTryEnterDebug,
6271 pdmR3DevHlp_CritSectLeave,
6272 pdmR3DevHlp_CritSectIsOwner,
6273 pdmR3DevHlp_CritSectIsInitialized,
6274 pdmR3DevHlp_CritSectHasWaiters,
6275 pdmR3DevHlp_CritSectGetRecursion,
6276 pdmR3DevHlp_CritSectScheduleExitEvent,
6277 pdmR3DevHlp_CritSectDelete,
6278 pdmR3DevHlp_CritSectRwInit,
6279 pdmR3DevHlp_CritSectRwDelete,
6280 pdmR3DevHlp_CritSectRwEnterShared,
6281 pdmR3DevHlp_CritSectRwEnterSharedDebug,
6282 pdmR3DevHlp_CritSectRwTryEnterShared,
6283 pdmR3DevHlp_CritSectRwTryEnterSharedDebug,
6284 pdmR3DevHlp_CritSectRwLeaveShared,
6285 pdmR3DevHlp_CritSectRwEnterExcl,
6286 pdmR3DevHlp_CritSectRwEnterExclDebug,
6287 pdmR3DevHlp_CritSectRwTryEnterExcl,
6288 pdmR3DevHlp_CritSectRwTryEnterExclDebug,
6289 pdmR3DevHlp_CritSectRwLeaveExcl,
6290 pdmR3DevHlp_CritSectRwIsWriteOwner,
6291 pdmR3DevHlp_CritSectRwIsReadOwner,
6292 pdmR3DevHlp_CritSectRwGetWriteRecursion,
6293 pdmR3DevHlp_CritSectRwGetWriterReadRecursion,
6294 pdmR3DevHlp_CritSectRwGetReadCount,
6295 pdmR3DevHlp_CritSectRwIsInitialized,
6296 pdmR3DevHlp_ThreadCreate,
6297 PDMR3ThreadDestroy,
6298 PDMR3ThreadIAmSuspending,
6299 PDMR3ThreadIAmRunning,
6300 PDMR3ThreadSleep,
6301 PDMR3ThreadSuspend,
6302 PDMR3ThreadResume,
6303 pdmR3DevHlp_SetAsyncNotification,
6304 pdmR3DevHlp_AsyncNotificationCompleted,
6305 pdmR3DevHlp_RTCRegister,
6306 pdmR3DevHlp_PCIBusRegister,
6307 pdmR3DevHlp_IommuRegister,
6308 pdmR3DevHlp_PICRegister,
6309 pdmR3DevHlp_ApicRegister,
6310 pdmR3DevHlp_IoApicRegister,
6311 pdmR3DevHlp_HpetRegister,
6312 pdmR3DevHlp_PciRawRegister,
6313 pdmR3DevHlp_DMACRegister,
6314 pdmR3DevHlp_DMARegister,
6315 pdmR3DevHlp_DMAReadMemory,
6316 pdmR3DevHlp_DMAWriteMemory,
6317 pdmR3DevHlp_DMASetDREQ,
6318 pdmR3DevHlp_DMAGetChannelMode,
6319 pdmR3DevHlp_DMASchedule,
6320 pdmR3DevHlp_CMOSWrite,
6321 pdmR3DevHlp_CMOSRead,
6322 pdmR3DevHlp_AssertEMT,
6323 pdmR3DevHlp_AssertOther,
6324 pdmR3DevHlp_LdrGetRCInterfaceSymbols,
6325 pdmR3DevHlp_LdrGetR0InterfaceSymbols,
6326 pdmR3DevHlp_CallR0,
6327 pdmR3DevHlp_VMGetSuspendReason,
6328 pdmR3DevHlp_VMGetResumeReason,
6329 pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
6330 pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
6331 pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
6332 pdmR3DevHlp_CpuGetGuestArch,
6333 pdmR3DevHlp_CpuGetGuestMicroarch,
6334 pdmR3DevHlp_CpuGetGuestAddrWidths,
6335 pdmR3DevHlp_CpuGetGuestScalableBusFrequency,
6336 pdmR3DevHlp_STAMDeregisterByPrefix,
6337 0,
6338 0,
6339 0,
6340 0,
6341 0,
6342 0,
6343 0,
6344 0,
6345 0,
6346 pdmR3DevHlp_Untrusted_GetUVM,
6347 pdmR3DevHlp_Untrusted_GetVM,
6348 pdmR3DevHlp_Untrusted_GetVMCPU,
6349 pdmR3DevHlp_Untrusted_GetCurrentCpuId,
6350 pdmR3DevHlp_Untrusted_RegisterVMMDevHeap,
6351 pdmR3DevHlp_Untrusted_FirmwareRegister,
6352 pdmR3DevHlp_Untrusted_VMReset,
6353 pdmR3DevHlp_Untrusted_VMSuspend,
6354 pdmR3DevHlp_Untrusted_VMSuspendSaveAndPowerOff,
6355 pdmR3DevHlp_Untrusted_VMPowerOff,
6356 pdmR3DevHlp_Untrusted_A20IsEnabled,
6357 pdmR3DevHlp_Untrusted_A20Set,
6358 pdmR3DevHlp_Untrusted_GetCpuId,
6359 pdmR3DevHlp_Untrusted_GetMainExecutionEngine,
6360 pdmR3DevHlp_TMTimeVirtGet,
6361 pdmR3DevHlp_TMTimeVirtGetFreq,
6362 pdmR3DevHlp_TMTimeVirtGetNano,
6363 pdmR3DevHlp_TMCpuTicksPerSecond,
6364 pdmR3DevHlp_Untrusted_GetSupDrvSession,
6365 pdmR3DevHlp_Untrusted_QueryGenericUserObject,
6366 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalTypeRegister,
6367 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalRegister,
6368 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalDeregister,
6369 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalPageTempOff,
6370 pdmR3DevHlp_Untrusted_PGMHandlerPhysicalReset,
6371 pdmR3DevHlp_Untrusted_VMMRegisterPatchMemory,
6372 pdmR3DevHlp_Untrusted_VMMDeregisterPatchMemory,
6373 pdmR3DevHlp_Untrusted_SharedModuleRegister,
6374 pdmR3DevHlp_Untrusted_SharedModuleUnregister,
6375 pdmR3DevHlp_Untrusted_SharedModuleGetPageState,
6376 pdmR3DevHlp_Untrusted_SharedModuleCheckAll,
6377 pdmR3DevHlp_Untrusted_QueryLun,
6378 pdmR3DevHlp_Untrusted_GIMDeviceRegister,
6379 pdmR3DevHlp_Untrusted_GIMGetDebugSetup,
6380 pdmR3DevHlp_Untrusted_GIMGetMmio2Regions,
6381 PDM_DEVHLPR3_VERSION /* the end */
6382};
6383
6384
6385
6386/**
6387 * Queue consumer callback for internal component.
6388 *
6389 * @returns Success indicator.
6390 * If false the item will not be removed and the flushing will stop.
6391 * @param pVM The cross context VM structure.
6392 * @param pItem The item to consume. Upon return this item will be freed.
6393 */
6394DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem)
6395{
6396 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem;
6397 LogFlow(("pdmR3DevHlpQueueConsumer: enmOp=%d pDevIns=%p\n", pTask->enmOp, pTask->pDevInsR3));
6398 switch (pTask->enmOp)
6399 {
6400 case PDMDEVHLPTASKOP_ISA_SET_IRQ:
6401 PDMIsaSetIrq(pVM, pTask->u.IsaSetIrq.iIrq, pTask->u.IsaSetIrq.iLevel, pTask->u.IsaSetIrq.uTagSrc);
6402 break;
6403
6404 case PDMDEVHLPTASKOP_PCI_SET_IRQ:
6405 {
6406 /* Same as pdmR3DevHlp_PCISetIrq, except we've got a tag already. */
6407 PPDMDEVINSR3 pDevIns = pTask->pDevInsR3;
6408 PPDMPCIDEV pPciDev = pTask->u.PciSetIrq.idxPciDev < RT_ELEMENTS(pDevIns->apPciDevs)
6409 ? pDevIns->apPciDevs[pTask->u.PciSetIrq.idxPciDev] : NULL;
6410 if (pPciDev)
6411 {
6412 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
6413 AssertBreak(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
6414 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
6415
6416 pdmLock(pVM);
6417 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, pTask->u.PciSetIrq.iIrq,
6418 pTask->u.PciSetIrq.iLevel, pTask->u.PciSetIrq.uTagSrc);
6419 pdmUnlock(pVM);
6420 }
6421 else
6422 AssertReleaseMsgFailed(("No PCI device given! (%#x)\n", pPciDev->Int.s.idxSubDev));
6423 break;
6424 }
6425
6426 case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:
6427 {
6428 PDMIoApicSetIrq(pVM, pTask->u.IoApicSetIrq.uBusDevFn, pTask->u.IoApicSetIrq.iIrq, pTask->u.IoApicSetIrq.iLevel,
6429 pTask->u.IoApicSetIrq.uTagSrc);
6430 break;
6431 }
6432
6433 case PDMDEVHLPTASKOP_IOAPIC_SEND_MSI:
6434 {
6435 PDMIoApicSendMsi(pVM, pTask->u.IoApicSendMsi.uBusDevFn, &pTask->u.IoApicSendMsi.Msi, pTask->u.IoApicSendMsi.uTagSrc);
6436 break;
6437 }
6438
6439 case PDMDEVHLPTASKOP_IOAPIC_SET_EOI:
6440 {
6441 PDMIoApicBroadcastEoi(pVM, pTask->u.IoApicSetEoi.uVector);
6442 break;
6443 }
6444
6445 default:
6446 AssertReleaseMsgFailed(("Invalid operation %d\n", pTask->enmOp));
6447 break;
6448 }
6449 return true;
6450}
6451
6452/** @} */
6453
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