VirtualBox

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

Last change on this file since 91958 was 91944, checked in by vboxsync, 3 years ago

VMM,Devices: Eliminate direct calls to DBGFR3* and use the device helper callbacks, bugref:10074

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

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