VirtualBox

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

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

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. bugref:9898

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