VirtualBox

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

最後變更 在這個檔案從98982是 98982,由 vboxsync 提交於 2 年 前

VMM: More ARMv8 x86/amd64 separation work, get past IEM, bugref:10385 [build fix]

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

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