VirtualBox

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

Last change on this file since 91988 was 91973, checked in by vboxsync, 3 years ago

VMM: Doxygen fixes, bugref:10074

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

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