VirtualBox

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

Last change on this file since 13333 was 13215, checked in by vboxsync, 16 years ago

PDM: adjusted the PCI Bus determination so that it checks whether the bus is actually there. (untested)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 131.4 KB
Line 
1/* $Id: PDMDevHlp.cpp 13215 2008-10-13 13:29:00Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_PDM_DEVICE
27#include "PDMInternal.h"
28#include <VBox/pdm.h>
29#include <VBox/mm.h>
30#include <VBox/pgm.h>
31#include <VBox/iom.h>
32#include <VBox/rem.h>
33#include <VBox/dbgf.h>
34#include <VBox/vm.h>
35#include <VBox/vmm.h>
36
37#include <VBox/version.h>
38#include <VBox/log.h>
39#include <VBox/err.h>
40#include <iprt/asm.h>
41#include <iprt/assert.h>
42#include <iprt/string.h>
43#include <iprt/thread.h>
44
45
46/*******************************************************************************
47* Defined Constants And Macros *
48*******************************************************************************/
49/** Allow physical read and writes from any thread.
50 * (pdmR3DevHlp_PhysRead and pdmR3DevHlp_PhysWrite.)
51 */
52#define PDM_PHYS_READWRITE_FROM_ANY_THREAD
53
54
55/** @name R3 DevHlp
56 * @{
57 */
58
59
60/** @copydoc PDMDEVHLPR3::pfnIOPortRegister */
61static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
62 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
63{
64 PDMDEV_ASSERT_DEVINS(pDevIns);
65 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p p32_tszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
66 Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc, pszDesc));
67 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
68
69 int rc = IOMR3IOPortRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
70
71 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
72 return rc;
73}
74
75
76/** @copydoc PDMDEVHLPR3::pfnIOPortRegisterGC */
77static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,
78 const char *pszOut, const char *pszIn,
79 const char *pszOutStr, const char *pszInStr, const char *pszDesc)
80{
81 PDMDEV_ASSERT_DEVINS(pDevIns);
82 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
83 LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
84 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));
85
86 /*
87 * Resolve the functions (one of the can be NULL).
88 */
89 int rc = VINF_SUCCESS;
90 if ( pDevIns->pDevReg->szRCMod[0]
91 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC))
92 {
93 RTGCPTR32 GCPtrIn = 0;
94 if (pszIn)
95 {
96 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszIn, &GCPtrIn);
97 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szRCMod, pszIn));
98 }
99 RTGCPTR32 GCPtrOut = 0;
100 if (pszOut && VBOX_SUCCESS(rc))
101 {
102 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOut, &GCPtrOut);
103 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szRCMod, pszOut));
104 }
105 RTGCPTR32 GCPtrInStr = 0;
106 if (pszInStr && VBOX_SUCCESS(rc))
107 {
108 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszInStr, &GCPtrInStr);
109 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szRCMod, pszInStr));
110 }
111 RTGCPTR32 GCPtrOutStr = 0;
112 if (pszOutStr && VBOX_SUCCESS(rc))
113 {
114 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszOutStr, &GCPtrOutStr);
115 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szRCMod, pszOutStr));
116 }
117
118 if (VBOX_SUCCESS(rc))
119 rc = IOMR3IOPortRegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, GCPtrOut, GCPtrIn, GCPtrOutStr, GCPtrInStr, pszDesc);
120 }
121 else
122 {
123 AssertMsgFailed(("No GC module for this driver!\n"));
124 rc = VERR_INVALID_PARAMETER;
125 }
126
127 LogFlow(("pdmR3DevHlp_IOPortRegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
128 return rc;
129}
130
131
132/** @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0 */
133static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,
134 const char *pszOut, const char *pszIn,
135 const char *pszOutStr, const char *pszInStr, const char *pszDesc)
136{
137 PDMDEV_ASSERT_DEVINS(pDevIns);
138 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
139 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
140 Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));
141
142 /*
143 * Resolve the functions (one of the can be NULL).
144 */
145 int rc = VINF_SUCCESS;
146 if ( pDevIns->pDevReg->szR0Mod[0]
147 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))
148 {
149 R0PTRTYPE(PFNIOMIOPORTIN) pfnR0PtrIn = 0;
150 if (pszIn)
151 {
152 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszIn, &pfnR0PtrIn);
153 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pDevReg->szR0Mod, pszIn));
154 }
155 R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0;
156 if (pszOut && VBOX_SUCCESS(rc))
157 {
158 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOut, &pfnR0PtrOut);
159 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pDevReg->szR0Mod, pszOut));
160 }
161 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0;
162 if (pszInStr && VBOX_SUCCESS(rc))
163 {
164 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszInStr, &pfnR0PtrInStr);
165 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pDevReg->szR0Mod, pszInStr));
166 }
167 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0;
168 if (pszOutStr && VBOX_SUCCESS(rc))
169 {
170 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszOutStr, &pfnR0PtrOutStr);
171 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pDevReg->szR0Mod, pszOutStr));
172 }
173
174 if (VBOX_SUCCESS(rc))
175 rc = IOMR3IOPortRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnR0PtrOut, pfnR0PtrIn, pfnR0PtrOutStr, pfnR0PtrInStr, pszDesc);
176 }
177 else
178 {
179 AssertMsgFailed(("No R0 module for this driver!\n"));
180 rc = VERR_INVALID_PARAMETER;
181 }
182
183 LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
184 return rc;
185}
186
187
188/** @copydoc PDMDEVHLPR3::pfnIOPortDeregister */
189static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts)
190{
191 PDMDEV_ASSERT_DEVINS(pDevIns);
192 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
193 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: Port=%#x cPorts=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
194 Port, cPorts));
195
196 int rc = IOMR3IOPortDeregister(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts);
197
198 LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
199 return rc;
200}
201
202
203/** @copydoc PDMDEVHLPR3::pfnMMIORegister */
204static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
205 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
206 const char *pszDesc)
207{
208 PDMDEV_ASSERT_DEVINS(pDevIns);
209 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
210 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p pszDesc=%p:{%s}\n",
211 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, pszDesc));
212
213 int rc = IOMR3MMIORegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);
214
215 LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
216 return rc;
217}
218
219
220/** @copydoc PDMDEVHLPR3::pfnMMIORegisterGC */
221static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
222 const char *pszWrite, const char *pszRead, const char *pszFill,
223 const char *pszDesc)
224{
225 PDMDEV_ASSERT_DEVINS(pDevIns);
226 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
227 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
228 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));
229
230 /*
231 * Resolve the functions.
232 * Not all function have to present, leave it to IOM to enforce this.
233 */
234 int rc = VINF_SUCCESS;
235 if ( pDevIns->pDevReg->szRCMod[0]
236 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC))
237 {
238 RTGCPTR32 GCPtrWrite = 0;
239 if (pszWrite)
240 rc = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszWrite, &GCPtrWrite);
241 RTGCPTR32 GCPtrRead = 0;
242 int rc2 = VINF_SUCCESS;
243 if (pszRead)
244 rc2 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszRead, &GCPtrRead);
245 RTGCPTR32 GCPtrFill = 0;
246 int rc3 = VINF_SUCCESS;
247 if (pszFill)
248 rc3 = PDMR3LdrGetSymbolRCLazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szRCMod, pszFill, &GCPtrFill);
249 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3))
250 rc = IOMR3MMIORegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, GCPtrWrite, GCPtrRead, GCPtrFill);
251 else
252 {
253 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szRCMod, pszWrite));
254 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szRCMod, pszRead));
255 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szRCMod, pszFill));
256 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc))
257 rc = rc2;
258 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc))
259 rc = rc3;
260 }
261 }
262 else
263 {
264 AssertMsgFailed(("No GC module for this driver!\n"));
265 rc = VERR_INVALID_PARAMETER;
266 }
267
268 LogFlow(("pdmR3DevHlp_MMIORegisterGC: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
269 return rc;
270}
271
272/** @copydoc PDMDEVHLPR3::pfnMMIORegisterR0 */
273static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
274 const char *pszWrite, const char *pszRead, const char *pszFill,
275 const char *pszDesc)
276{
277 PDMDEV_ASSERT_DEVINS(pDevIns);
278 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
279 LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
280 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));
281
282 /*
283 * Resolve the functions.
284 * Not all function have to present, leave it to IOM to enforce this.
285 */
286 int rc = VINF_SUCCESS;
287 if ( pDevIns->pDevReg->szR0Mod[0]
288 && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))
289 {
290 R0PTRTYPE(PFNIOMMMIOWRITE) pfnR0PtrWrite = 0;
291 if (pszWrite)
292 rc = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszWrite, &pfnR0PtrWrite);
293 R0PTRTYPE(PFNIOMMMIOREAD) pfnR0PtrRead = 0;
294 int rc2 = VINF_SUCCESS;
295 if (pszRead)
296 rc2 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszRead, &pfnR0PtrRead);
297 R0PTRTYPE(PFNIOMMMIOFILL) pfnR0PtrFill = 0;
298 int rc3 = VINF_SUCCESS;
299 if (pszFill)
300 rc3 = PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3, pDevIns->pDevReg->szR0Mod, pszFill, &pfnR0PtrFill);
301 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(rc2) && VBOX_SUCCESS(rc3))
302 rc = IOMR3MMIORegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill);
303 else
304 {
305 AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pDevReg->szR0Mod, pszWrite));
306 AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pDevReg->szR0Mod, pszRead));
307 AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pDevReg->szR0Mod, pszFill));
308 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc))
309 rc = rc2;
310 if (VBOX_FAILURE(rc3) && VBOX_SUCCESS(rc))
311 rc = rc3;
312 }
313 }
314 else
315 {
316 AssertMsgFailed(("No R0 module for this driver!\n"));
317 rc = VERR_INVALID_PARAMETER;
318 }
319
320 LogFlow(("pdmR3DevHlp_MMIORegisterR0: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
321 return rc;
322}
323
324
325/** @copydoc PDMDEVHLPR3::pfnMMIODeregister */
326static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
327{
328 PDMDEV_ASSERT_DEVINS(pDevIns);
329 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
330 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n",
331 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange));
332
333 int rc = IOMR3MMIODeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange);
334
335 LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
336 return rc;
337}
338
339
340/** @copydoc PDMDEVHLPR3::pfnROMRegister */
341static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc)
342{
343 PDMDEV_ASSERT_DEVINS(pDevIns);
344 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
345 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p fShadow=%RTbool pszDesc=%p:{%s}\n",
346 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc));
347
348 int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc);
349
350 LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
351 return rc;
352}
353
354
355/** @copydoc PDMDEVHLPR3::pfnSSMRegister */
356static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
357 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
358 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
359{
360 PDMDEV_ASSERT_DEVINS(pDevIns);
361 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
362 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: pszName=%p:{%s} u32Instance=%#x u32Version=#x cbGuess=%#x pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoaddone=%p\n",
363 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone));
364
365 int rc = SSMR3Register(pDevIns->Internal.s.pVMR3, pDevIns, pszName, u32Instance, u32Version, cbGuess,
366 pfnSavePrep, pfnSaveExec, pfnSaveDone,
367 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
368
369 LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
370 return rc;
371}
372
373
374/** @copydoc PDMDEVHLPR3::pfnTMTimerCreate */
375static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer)
376{
377 PDMDEV_ASSERT_DEVINS(pDevIns);
378 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
379 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pszDesc=%p:{%s} ppTimer=%p\n",
380 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pszDesc, pszDesc, ppTimer));
381
382 int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, enmClock, pfnCallback, pszDesc, ppTimer);
383
384 LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
385 return rc;
386}
387
388
389/** @copydoc PDMDEVHLPR3::pfnTMTimerCreateExternal */
390static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TMTimerCreateExternal(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc)
391{
392 PDMDEV_ASSERT_DEVINS(pDevIns);
393 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
394
395 return TMR3TimerCreateExternal(pDevIns->Internal.s.pVMR3, enmClock, pfnCallback, pvUser, pszDesc);
396}
397
398
399/** @copydoc PDMDEVHLPR3::pfnPCIRegister */
400static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
401{
402 PDMDEV_ASSERT_DEVINS(pDevIns);
403 PVM pVM = pDevIns->Internal.s.pVMR3;
404 VM_ASSERT_EMT(pVM);
405 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Vhxs}\n",
406 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pPciDev->config));
407
408 /*
409 * Validate input.
410 */
411 if (!pPciDev)
412 {
413 Assert(pPciDev);
414 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (pPciDev)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
415 return VERR_INVALID_PARAMETER;
416 }
417 if (!pPciDev->config[0] && !pPciDev->config[1])
418 {
419 Assert(pPciDev->config[0] || pPciDev->config[1]);
420 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (vendor)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
421 return VERR_INVALID_PARAMETER;
422 }
423 if (pDevIns->Internal.s.pPciDeviceR3)
424 {
425 /** @todo the PCI device vs. PDM device designed is a bit flawed if we have to
426 * support a PDM device with multiple PCI devices. This might become a problem
427 * when upgrading the chipset for instance because of multiple functions in some
428 * devices...
429 */
430 AssertMsgFailed(("Only one PCI device per device is currently implemented!\n"));
431 return VERR_INTERNAL_ERROR;
432 }
433
434 /*
435 * Choose the PCI bus for the device.
436 *
437 * This is simple. If the device was configured for a particular bus, the PCIBusNo
438 * configuration value will be set. If not the default bus is 0.
439 */
440 int rc;
441 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;
442 if (!pBus)
443 {
444 uint8_t u8Bus;
445 rc = CFGMR3QueryU8Def(pDevIns->Internal.s.pCfgHandle, "PCIBusNo", &u8Bus, 0);
446 AssertLogRelMsgRCReturn(rc, ("Configuration error: PCIBusNo query failed with rc=%Rrc (%s/%d)\n",
447 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance), rc);
448 AssertLogRelMsgReturn(u8Bus < RT_ELEMENTS(pVM->pdm.s.aPciBuses),
449 ("Configuration error: PCIBusNo=%d, max is %d. (%s/%d)\n", u8Bus,
450 RT_ELEMENTS(pVM->pdm.s.aPciBuses), pDevIns->pDevReg->szDeviceName, pDevIns->iInstance),
451 VERR_PDM_NO_PCI_BUS);
452 pBus = pDevIns->Internal.s.pPciBusR3 = &pVM->pdm.s.aPciBuses[u8Bus];
453 }
454 if (pBus->pDevInsR3)
455 {
456 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)
457 pDevIns->Internal.s.pPciBusR0 = MMHyperR3ToR0(pVM, pDevIns->Internal.s.pPciBusR3);
458 else
459 pDevIns->Internal.s.pPciBusR0 = NIL_RTR0PTR;
460
461 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)
462 pDevIns->Internal.s.pPciBusRC = MMHyperR3ToRC(pVM, pDevIns->Internal.s.pPciBusR3);
463 else
464 pDevIns->Internal.s.pPciBusRC = NIL_RTRCPTR;
465
466 /*
467 * Check the configuration for PCI device and function assignment.
468 */
469 int iDev = -1;
470 uint8_t u8Device;
471 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIDeviceNo", &u8Device);
472 if (VBOX_SUCCESS(rc))
473 {
474 if (u8Device > 31)
475 {
476 AssertMsgFailed(("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d)\n",
477 u8Device, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
478 return VERR_INTERNAL_ERROR;
479 }
480
481 uint8_t u8Function;
482 rc = CFGMR3QueryU8(pDevIns->Internal.s.pCfgHandle, "PCIFunctionNo", &u8Function);
483 if (VBOX_FAILURE(rc))
484 {
485 AssertMsgFailed(("Configuration error: PCIDeviceNo, but PCIFunctionNo query failed with rc=%Vrc (%s/%d)\n",
486 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
487 return rc;
488 }
489 if (u8Function > 7)
490 {
491 AssertMsgFailed(("Configuration error: PCIFunctionNo=%d, max is 7. (%s/%d)\n",
492 u8Function, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
493 return VERR_INTERNAL_ERROR;
494 }
495 iDev = (u8Device << 3) | u8Function;
496 }
497 else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
498 {
499 AssertMsgFailed(("Configuration error: PCIDeviceNo query failed with rc=%Vrc (%s/%d)\n",
500 rc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
501 return rc;
502 }
503
504 /*
505 * Call the pci bus device to do the actual registration.
506 */
507 pdmLock(pVM);
508 rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, pDevIns->pDevReg->szDeviceName, iDev);
509 pdmUnlock(pVM);
510 if (VBOX_SUCCESS(rc))
511 {
512 pPciDev->pDevIns = pDevIns;
513
514 pDevIns->Internal.s.pPciDeviceR3 = pPciDev;
515 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0)
516 pDevIns->Internal.s.pPciDeviceR0 = MMHyperR3ToR0(pVM, pPciDev);
517 else
518 pDevIns->Internal.s.pPciDeviceR0 = NIL_RTR0PTR;
519
520 if (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC)
521 pDevIns->Internal.s.pPciDeviceRC = MMHyperR3ToRC(pVM, pPciDev);
522 else
523 pDevIns->Internal.s.pPciDeviceRC = NIL_RTRCPTR;
524
525 Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n",
526 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev->devfn, pDevIns->Internal.s.pPciBusR3->iBus));
527 }
528 }
529 else
530 {
531 AssertLogRelMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n"));
532 rc = VERR_PDM_NO_PCI_BUS;
533 }
534
535 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
536 return rc;
537}
538
539
540/** @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister */
541static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
542{
543 PDMDEV_ASSERT_DEVINS(pDevIns);
544 PVM pVM = pDevIns->Internal.s.pVMR3;
545 VM_ASSERT_EMT(pVM);
546 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: iRegion=%d cbRegion=%#x enmType=%d pfnCallback=%p\n",
547 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cbRegion, enmType, pfnCallback));
548
549 /*
550 * Validate input.
551 */
552 if (iRegion < 0 || iRegion >= PCI_NUM_REGIONS)
553 {
554 Assert(iRegion >= 0 && iRegion < PCI_NUM_REGIONS);
555 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (iRegion)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
556 return VERR_INVALID_PARAMETER;
557 }
558 switch (enmType)
559 {
560 case PCI_ADDRESS_SPACE_MEM:
561 case PCI_ADDRESS_SPACE_IO:
562 case PCI_ADDRESS_SPACE_MEM_PREFETCH:
563 break;
564 default:
565 AssertMsgFailed(("enmType=%#x is unknown\n", enmType));
566 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (enmType)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
567 return VERR_INVALID_PARAMETER;
568 }
569 if (!pfnCallback)
570 {
571 Assert(pfnCallback);
572 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc (callback)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
573 return VERR_INVALID_PARAMETER;
574 }
575 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
576
577 /*
578 * Must have a PCI device registered!
579 */
580 int rc;
581 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
582 if (pPciDev)
583 {
584 /*
585 * We're currently restricted to page aligned MMIO regions.
586 */
587 if ( (enmType == PCI_ADDRESS_SPACE_MEM || enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH)
588 && cbRegion != RT_ALIGN_32(cbRegion, PAGE_SIZE))
589 {
590 Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %#x -> %#x\n",
591 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbRegion, RT_ALIGN_32(cbRegion, PAGE_SIZE)));
592 cbRegion = RT_ALIGN_32(cbRegion, PAGE_SIZE);
593 }
594
595 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;
596 Assert(pBus);
597 pdmLock(pVM);
598 rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback);
599 pdmUnlock(pVM);
600 }
601 else
602 {
603 AssertMsgFailed(("No PCI device registered!\n"));
604 rc = VERR_PDM_NOT_PCI_DEVICE;
605 }
606
607 LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
608 return rc;
609}
610
611
612/** @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks */
613static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
614 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
615{
616 PDMDEV_ASSERT_DEVINS(pDevIns);
617 PVM pVM = pDevIns->Internal.s.pVMR3;
618 VM_ASSERT_EMT(pVM);
619 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n",
620 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld));
621
622 /*
623 * Validate input and resolve defaults.
624 */
625 AssertPtr(pfnRead);
626 AssertPtr(pfnWrite);
627 AssertPtrNull(ppfnReadOld);
628 AssertPtrNull(ppfnWriteOld);
629 AssertPtrNull(pPciDev);
630
631 if (!pPciDev)
632 pPciDev = pDevIns->Internal.s.pPciDeviceR3;
633 AssertReleaseMsg(pPciDev, ("You must register your device first!\n"));
634 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3;
635 AssertRelease(pBus);
636 AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
637
638 /*
639 * Do the job.
640 */
641 pdmLock(pVM);
642 pBus->pfnSetConfigCallbacksR3(pBus->pDevInsR3, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
643 pdmUnlock(pVM);
644
645 LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
646}
647
648
649/** @copydoc PDMDEVHLPR3::pfnPCISetIrq */
650static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
651{
652 PDMDEV_ASSERT_DEVINS(pDevIns);
653 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel));
654
655 /*
656 * Validate input.
657 */
658 /** @todo iIrq and iLevel checks. */
659
660 /*
661 * Must have a PCI device registered!
662 */
663 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
664 if (pPciDev)
665 {
666 PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */
667 Assert(pBus);
668 PVM pVM = pDevIns->Internal.s.pVMR3;
669 pdmLock(pVM);
670 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel);
671 pdmUnlock(pVM);
672 }
673 else
674 AssertReleaseMsgFailed(("No PCI device registered!\n"));
675
676 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
677}
678
679
680/** @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait */
681static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
682{
683 pdmR3DevHlp_PCISetIrq(pDevIns, iIrq, iLevel);
684}
685
686
687/** @copydoc PDMDEVHLPR3::pfnISASetIrq */
688static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
689{
690 PDMDEV_ASSERT_DEVINS(pDevIns);
691 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iIrq, iLevel));
692
693 /*
694 * Validate input.
695 */
696 /** @todo iIrq and iLevel checks. */
697
698 PVM pVM = pDevIns->Internal.s.pVMR3;
699 PDMIsaSetIrq(pVM, iIrq, iLevel); /* (The API takes the lock.) */
700
701 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
702}
703
704
705/** @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait */
706static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
707{
708 pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel);
709}
710
711
712/** @copydoc PDMDEVHLPR3::pfnDriverAttach */
713static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
714{
715 PDMDEV_ASSERT_DEVINS(pDevIns);
716 PVM pVM = pDevIns->Internal.s.pVMR3;
717 VM_ASSERT_EMT(pVM);
718 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n",
719 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc));
720
721 /*
722 * Lookup the LUN, it might already be registered.
723 */
724 PPDMLUN pLunPrev = NULL;
725 PPDMLUN pLun = pDevIns->Internal.s.pLunsR3;
726 for (; pLun; pLunPrev = pLun, pLun = pLun->pNext)
727 if (pLun->iLun == iLun)
728 break;
729
730 /*
731 * Create the LUN if if wasn't found, else check if driver is already attached to it.
732 */
733 if (!pLun)
734 {
735 if ( !pBaseInterface
736 || !pszDesc
737 || !*pszDesc)
738 {
739 Assert(pBaseInterface);
740 Assert(pszDesc || *pszDesc);
741 return VERR_INVALID_PARAMETER;
742 }
743
744 pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun));
745 if (!pLun)
746 return VERR_NO_MEMORY;
747
748 pLun->iLun = iLun;
749 pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL;
750 pLun->pTop = NULL;
751 pLun->pBottom = NULL;
752 pLun->pDevIns = pDevIns;
753 pLun->pszDesc = pszDesc;
754 pLun->pBase = pBaseInterface;
755 if (!pLunPrev)
756 pDevIns->Internal.s.pLunsR3 = pLun;
757 else
758 pLunPrev->pNext = pLun;
759 Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n",
760 iLun, pszDesc, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
761 }
762 else if (pLun->pTop)
763 {
764 AssertMsgFailed(("Already attached! The device should keep track of such things!\n"));
765 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED));
766 return VERR_PDM_DRIVER_ALREADY_ATTACHED;
767 }
768 Assert(pLun->pBase == pBaseInterface);
769
770
771 /*
772 * Get the attached driver configuration.
773 */
774 int rc;
775 char szNode[48];
776 RTStrPrintf(szNode, sizeof(szNode), "LUN#%d", iLun);
777 PCFGMNODE pNode = CFGMR3GetChild(pDevIns->Internal.s.pCfgHandle, szNode);
778 if (pNode)
779 {
780 char *pszName;
781 rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName);
782 if (VBOX_SUCCESS(rc))
783 {
784 /*
785 * Find the driver.
786 */
787 PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName);
788 if (pDrv)
789 {
790 /* config node */
791 PCFGMNODE pConfigNode = CFGMR3GetChild(pNode, "Config");
792 if (!pConfigNode)
793 rc = CFGMR3InsertNode(pNode, "Config", &pConfigNode);
794 if (VBOX_SUCCESS(rc))
795 {
796 CFGMR3SetRestrictedRoot(pConfigNode);
797
798 /*
799 * Allocate the driver instance.
800 */
801 size_t cb = RT_OFFSETOF(PDMDRVINS, achInstanceData[pDrv->pDrvReg->cbInstance]);
802 cb = RT_ALIGN_Z(cb, 16);
803 PPDMDRVINS pNew = (PPDMDRVINS)MMR3HeapAllocZ(pVM, MM_TAG_PDM_DRIVER, cb);
804 if (pNew)
805 {
806 /*
807 * Initialize the instance structure (declaration order).
808 */
809 pNew->u32Version = PDM_DRVINS_VERSION;
810 //pNew->Internal.s.pUp = NULL;
811 //pNew->Internal.s.pDown = NULL;
812 pNew->Internal.s.pLun = pLun;
813 pNew->Internal.s.pDrv = pDrv;
814 pNew->Internal.s.pVM = pVM;
815 //pNew->Internal.s.fDetaching = false;
816 pNew->Internal.s.pCfgHandle = pNode;
817 pNew->pDrvHlp = &g_pdmR3DrvHlp;
818 pNew->pDrvReg = pDrv->pDrvReg;
819 pNew->pCfgHandle = pConfigNode;
820 pNew->iInstance = pDrv->cInstances++;
821 pNew->pUpBase = pBaseInterface;
822 //pNew->pDownBase = NULL;
823 //pNew->IBase.pfnQueryInterface = NULL;
824 pNew->pvInstanceData = &pNew->achInstanceData[0];
825
826 /*
827 * Link with LUN and call the constructor.
828 */
829 pLun->pTop = pLun->pBottom = pNew;
830 rc = pDrv->pDrvReg->pfnConstruct(pNew, pNew->pCfgHandle);
831 if (VBOX_SUCCESS(rc))
832 {
833 MMR3HeapFree(pszName);
834 *ppBaseInterface = &pNew->IBase;
835 Log(("PDM: Attached driver '%s'/%d to LUN#%d on device '%s'/%d.\n",
836 pDrv->pDrvReg->szDriverName, pNew->iInstance, iLun, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
837 LogFlow(("pdmR3DevHlp_DriverAttach: caller '%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
838
839 return rc; /* Might return != VINF_SUCCESS (e.g. VINF_NAT_DNS). */
840 }
841
842 /*
843 * Free the driver.
844 */
845 pLun->pTop = pLun->pBottom = NULL;
846 ASMMemFill32(pNew, cb, 0xdeadd0d0);
847 MMR3HeapFree(pNew);
848 pDrv->cInstances--;
849 }
850 else
851 {
852 AssertMsgFailed(("Failed to allocate %d bytes for instantiating driver '%s'\n", cb, pszName));
853 rc = VERR_NO_MEMORY;
854 }
855 }
856 else
857 AssertMsgFailed(("Failed to create Config node! rc=%Vrc\n", rc));
858 }
859 else
860 {
861 AssertMsgFailed(("Driver '%s' wasn't found!\n", pszName));
862 rc = VERR_PDM_DRIVER_NOT_FOUND;
863 }
864 MMR3HeapFree(pszName);
865 }
866 else
867 {
868 AssertMsgFailed(("Query for string value of \"Driver\" -> %Vrc\n", rc));
869 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
870 rc = VERR_PDM_CFG_MISSING_DRIVER_NAME;
871 }
872 }
873 else
874 rc = VERR_PDM_NO_ATTACHED_DRIVER;
875
876
877 LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
878 return rc;
879}
880
881
882/** @copydoc PDMDEVHLPR3::pfnMMHeapAlloc */
883static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
884{
885 PDMDEV_ASSERT_DEVINS(pDevIns);
886 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb));
887
888 void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);
889
890 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));
891 return pv;
892}
893
894
895/** @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ */
896static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
897{
898 PDMDEV_ASSERT_DEVINS(pDevIns);
899 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cb));
900
901 void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);
902
903 LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));
904 return pv;
905}
906
907
908/** @copydoc PDMDEVHLPR3::pfnMMHeapFree */
909static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv)
910{
911 PDMDEV_ASSERT_DEVINS(pDevIns);
912 LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pv));
913
914 MMR3HeapFree(pv);
915
916 LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
917}
918
919
920/** @copydoc PDMDEVHLPR3::pfnVMSetError */
921static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
922{
923 PDMDEV_ASSERT_DEVINS(pDevIns);
924 va_list args;
925 va_start(args, pszFormat);
926 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
927 va_end(args);
928 return rc;
929}
930
931
932/** @copydoc PDMDEVHLPR3::pfnVMSetErrorV */
933static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
934{
935 PDMDEV_ASSERT_DEVINS(pDevIns);
936 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
937 return rc;
938}
939
940
941/** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError */
942static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...)
943{
944 PDMDEV_ASSERT_DEVINS(pDevIns);
945 va_list args;
946 va_start(args, pszFormat);
947 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, args);
948 va_end(args);
949 return rc;
950}
951
952
953/** @copydoc PDMDEVHLPR3::pfnVMSetRuntimeErrorV */
954static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va)
955{
956 PDMDEV_ASSERT_DEVINS(pDevIns);
957 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFatal, pszErrorID, pszFormat, va);
958 return rc;
959}
960
961
962/** @copydoc PDMDEVHLPR3::pfnAssertEMT */
963static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
964{
965 PDMDEV_ASSERT_DEVINS(pDevIns);
966 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3))
967 return true;
968
969 char szMsg[100];
970 RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance);
971 AssertMsg1(szMsg, iLine, pszFile, pszFunction);
972 AssertBreakpoint();
973 return false;
974}
975
976
977/** @copydoc PDMDEVHLPR3::pfnAssertOther */
978static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
979{
980 PDMDEV_ASSERT_DEVINS(pDevIns);
981 if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3))
982 return true;
983
984 char szMsg[100];
985 RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance);
986 AssertMsg1(szMsg, iLine, pszFile, pszFunction);
987 AssertBreakpoint();
988 return false;
989}
990
991
992/** @copydoc PDMDEVHLPR3::pfnDBGFStopV */
993static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args)
994{
995 PDMDEV_ASSERT_DEVINS(pDevIns);
996#ifdef LOG_ENABLED
997 va_list va2;
998 va_copy(va2, args);
999 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n",
1000 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2));
1001 va_end(va2);
1002#endif
1003
1004 PVM pVM = pDevIns->Internal.s.pVMR3;
1005 VM_ASSERT_EMT(pVM);
1006 int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args);
1007
1008 LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1009 return rc;
1010}
1011
1012
1013/** @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister */
1014static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
1015{
1016 PDMDEV_ASSERT_DEVINS(pDevIns);
1017 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n",
1018 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler));
1019
1020 PVM pVM = pDevIns->Internal.s.pVMR3;
1021 VM_ASSERT_EMT(pVM);
1022 int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns);
1023
1024 LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1025 return rc;
1026}
1027
1028
1029/** @copydoc PDMDEVHLPR3::pfnSTAMRegister */
1030static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
1031{
1032 PDMDEV_ASSERT_DEVINS(pDevIns);
1033 PVM pVM = pDevIns->Internal.s.pVMR3;
1034 VM_ASSERT_EMT(pVM);
1035
1036 STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);
1037 NOREF(pVM);
1038}
1039
1040
1041
1042/** @copydoc PDMDEVHLPR3::pfnSTAMRegisterF */
1043static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
1044 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...)
1045{
1046 PDMDEV_ASSERT_DEVINS(pDevIns);
1047 PVM pVM = pDevIns->Internal.s.pVMR3;
1048 VM_ASSERT_EMT(pVM);
1049
1050 va_list args;
1051 va_start(args, pszName);
1052 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
1053 va_end(args);
1054 AssertRC(rc);
1055
1056 NOREF(pVM);
1057}
1058
1059
1060/** @copydoc PDMDEVHLPR3::pfnSTAMRegisterV */
1061static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
1062 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args)
1063{
1064 PDMDEV_ASSERT_DEVINS(pDevIns);
1065 PVM pVM = pDevIns->Internal.s.pVMR3;
1066 VM_ASSERT_EMT(pVM);
1067
1068 int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
1069 AssertRC(rc);
1070
1071 NOREF(pVM);
1072}
1073
1074
1075/** @copydoc PDMDEVHLPR3::pfnRTCRegister */
1076static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
1077{
1078 PDMDEV_ASSERT_DEVINS(pDevIns);
1079 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
1080 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n",
1081 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite,
1082 pRtcReg->pfnWrite, ppRtcHlp));
1083
1084 /*
1085 * Validate input.
1086 */
1087 if (pRtcReg->u32Version != PDM_RTCREG_VERSION)
1088 {
1089 AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version,
1090 PDM_RTCREG_VERSION));
1091 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (version)\n",
1092 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1093 return VERR_INVALID_PARAMETER;
1094 }
1095 if ( !pRtcReg->pfnWrite
1096 || !pRtcReg->pfnRead)
1097 {
1098 Assert(pRtcReg->pfnWrite);
1099 Assert(pRtcReg->pfnRead);
1100 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (callbacks)\n",
1101 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1102 return VERR_INVALID_PARAMETER;
1103 }
1104
1105 if (!ppRtcHlp)
1106 {
1107 Assert(ppRtcHlp);
1108 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc (ppRtcHlp)\n",
1109 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1110 return VERR_INVALID_PARAMETER;
1111 }
1112
1113 /*
1114 * Only one DMA device.
1115 */
1116 PVM pVM = pDevIns->Internal.s.pVMR3;
1117 if (pVM->pdm.s.pRtc)
1118 {
1119 AssertMsgFailed(("Only one RTC device is supported!\n"));
1120 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n",
1121 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1122 return VERR_INVALID_PARAMETER;
1123 }
1124
1125 /*
1126 * Allocate and initialize pci bus structure.
1127 */
1128 int rc = VINF_SUCCESS;
1129 PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc));
1130 if (pRtc)
1131 {
1132 pRtc->pDevIns = pDevIns;
1133 pRtc->Reg = *pRtcReg;
1134 pVM->pdm.s.pRtc = pRtc;
1135
1136 /* set the helper pointer. */
1137 *ppRtcHlp = &g_pdmR3DevRtcHlp;
1138 Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n",
1139 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
1140 }
1141 else
1142 rc = VERR_NO_MEMORY;
1143
1144 LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Vrc\n",
1145 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1146 return rc;
1147}
1148
1149
1150/** @copydoc PDMDEVHLPR3::pfnPDMQueueCreate */
1151static DECLCALLBACK(int) pdmR3DevHlp_PDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
1152 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue)
1153{
1154 PDMDEV_ASSERT_DEVINS(pDevIns);
1155 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fGCEnabled=%RTbool ppQueue=%p\n",
1156 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue));
1157
1158 PVM pVM = pDevIns->Internal.s.pVMR3;
1159 VM_ASSERT_EMT(pVM);
1160 int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue);
1161
1162 LogFlow(("pdmR3DevHlp_PDMQueueCreate: caller='%s'/%d: returns %Vrc *ppQueue=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *ppQueue));
1163 return rc;
1164}
1165
1166
1167/** @copydoc PDMDEVHLPR3::pfnCritSectInit */
1168static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName)
1169{
1170 PDMDEV_ASSERT_DEVINS(pDevIns);
1171 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszName=%p:{%s}\n",
1172 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pCritSect, pszName, pszName));
1173
1174 PVM pVM = pDevIns->Internal.s.pVMR3;
1175 VM_ASSERT_EMT(pVM);
1176 int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, pszName);
1177
1178 LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1179 return rc;
1180}
1181
1182
1183/** @copydoc PDMDEVHLPR3::pfnUTCNow */
1184static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
1185{
1186 PDMDEV_ASSERT_DEVINS(pDevIns);
1187 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: pTime=%p\n",
1188 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pTime));
1189
1190 pTime = TMR3UTCNow(pDevIns->Internal.s.pVMR3, pTime);
1191
1192 LogFlow(("pdmR3DevHlp_UTCNow: caller='%s'/%d: returns %RU64\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, RTTimeSpecGetNano(pTime)));
1193 return pTime;
1194}
1195
1196
1197/** @copydoc PDMDEVHLPR3::pfnPDMThreadCreate */
1198static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
1199 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
1200{
1201 PDMDEV_ASSERT_DEVINS(pDevIns);
1202 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
1203 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",
1204 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));
1205
1206 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
1207
1208 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
1209 rc, *ppThread));
1210 return rc;
1211}
1212
1213
1214/** @copydoc PDMDEVHLPR3::pfnGetVM */
1215static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns)
1216{
1217 PDMDEV_ASSERT_DEVINS(pDevIns);
1218 LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));
1219 return pDevIns->Internal.s.pVMR3;
1220}
1221
1222
1223/** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */
1224static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
1225{
1226 PDMDEV_ASSERT_DEVINS(pDevIns);
1227 PVM pVM = pDevIns->Internal.s.pVMR3;
1228 VM_ASSERT_EMT(pVM);
1229 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, .pfnSetIrqR3=%p, "
1230 ".pfnSaveExecR3=%p, .pfnLoadExecR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p\n",
1231 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3,
1232 pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnSaveExecR3, pPciBusReg->pfnLoadExecR3,
1233 pPciBusReg->pfnFakePCIBIOSR3, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3));
1234
1235 /*
1236 * Validate the structure.
1237 */
1238 if (pPciBusReg->u32Version != PDM_PCIBUSREG_VERSION)
1239 {
1240 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREG_VERSION));
1241 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1242 return VERR_INVALID_PARAMETER;
1243 }
1244 if ( !pPciBusReg->pfnRegisterR3
1245 || !pPciBusReg->pfnIORegionRegisterR3
1246 || !pPciBusReg->pfnSetIrqR3
1247 || !pPciBusReg->pfnSaveExecR3
1248 || !pPciBusReg->pfnLoadExecR3
1249 || (!pPciBusReg->pfnFakePCIBIOSR3 && !pVM->pdm.s.aPciBuses[0].pDevInsR3)) /* Only the first bus needs to do the BIOS work. */
1250 {
1251 Assert(pPciBusReg->pfnRegisterR3);
1252 Assert(pPciBusReg->pfnIORegionRegisterR3);
1253 Assert(pPciBusReg->pfnSetIrqR3);
1254 Assert(pPciBusReg->pfnSaveExecR3);
1255 Assert(pPciBusReg->pfnLoadExecR3);
1256 Assert(pPciBusReg->pfnFakePCIBIOSR3);
1257 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1258 return VERR_INVALID_PARAMETER;
1259 }
1260 if ( pPciBusReg->pszSetIrqRC
1261 && !VALID_PTR(pPciBusReg->pszSetIrqRC))
1262 {
1263 Assert(VALID_PTR(pPciBusReg->pszSetIrqRC));
1264 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1265 return VERR_INVALID_PARAMETER;
1266 }
1267 if ( pPciBusReg->pszSetIrqR0
1268 && !VALID_PTR(pPciBusReg->pszSetIrqR0))
1269 {
1270 Assert(VALID_PTR(pPciBusReg->pszSetIrqR0));
1271 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1272 return VERR_INVALID_PARAMETER;
1273 }
1274 if (!ppPciHlpR3)
1275 {
1276 Assert(ppPciHlpR3);
1277 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (ppPciHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1278 return VERR_INVALID_PARAMETER;
1279 }
1280
1281 /*
1282 * Find free PCI bus entry.
1283 */
1284 unsigned iBus = 0;
1285 for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++)
1286 if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3)
1287 break;
1288 if (iBus >= RT_ELEMENTS(pVM->pdm.s.aPciBuses))
1289 {
1290 AssertMsgFailed(("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses)));
1291 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc (pci bus)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1292 return VERR_INVALID_PARAMETER;
1293 }
1294 PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus];
1295
1296 /*
1297 * Resolve and init the RC bits.
1298 */
1299 if (pPciBusReg->pszSetIrqRC)
1300 {
1301 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC);
1302 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPciBusReg->pszSetIrqRC, rc));
1303 if (VBOX_FAILURE(rc))
1304 {
1305 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1306 return rc;
1307 }
1308 pPciBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
1309 }
1310 else
1311 {
1312 pPciBus->pfnSetIrqRC = 0;
1313 pPciBus->pDevInsRC = 0;
1314 }
1315
1316 /*
1317 * Resolve and init the R0 bits.
1318 */
1319 if (pPciBusReg->pszSetIrqR0)
1320 {
1321 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0);
1322 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc));
1323 if (VBOX_FAILURE(rc))
1324 {
1325 LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1326 return rc;
1327 }
1328 pPciBus->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
1329 }
1330 else
1331 {
1332 pPciBus->pfnSetIrqR0 = 0;
1333 pPciBus->pDevInsR0 = 0;
1334 }
1335
1336 /*
1337 * Init the R3 bits.
1338 */
1339 pPciBus->iBus = iBus;
1340 pPciBus->pDevInsR3 = pDevIns;
1341 pPciBus->pfnRegisterR3 = pPciBusReg->pfnRegisterR3;
1342 pPciBus->pfnIORegionRegisterR3 = pPciBusReg->pfnIORegionRegisterR3;
1343 pPciBus->pfnSetConfigCallbacksR3 = pPciBusReg->pfnSetConfigCallbacksR3;
1344 pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3;
1345 pPciBus->pfnSaveExecR3 = pPciBusReg->pfnSaveExecR3;
1346 pPciBus->pfnLoadExecR3 = pPciBusReg->pfnLoadExecR3;
1347 pPciBus->pfnFakePCIBIOSR3 = pPciBusReg->pfnFakePCIBIOSR3;
1348
1349 Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
1350
1351 /* set the helper pointer and return. */
1352 *ppPciHlpR3 = &g_pdmR3DevPciHlp;
1353 LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
1354 return VINF_SUCCESS;
1355}
1356
1357
1358/** @copydoc PDMDEVHLPR3::pfnPICRegister */
1359static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
1360{
1361 PDMDEV_ASSERT_DEVINS(pDevIns);
1362 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
1363 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlpR3=%p\n",
1364 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3,
1365 pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC,
1366 pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0,
1367 ppPicHlpR3));
1368
1369 /*
1370 * Validate input.
1371 */
1372 if (pPicReg->u32Version != PDM_PICREG_VERSION)
1373 {
1374 AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION));
1375 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1376 return VERR_INVALID_PARAMETER;
1377 }
1378 if ( !pPicReg->pfnSetIrqR3
1379 || !pPicReg->pfnGetInterruptR3)
1380 {
1381 Assert(pPicReg->pfnSetIrqR3);
1382 Assert(pPicReg->pfnGetInterruptR3);
1383 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1384 return VERR_INVALID_PARAMETER;
1385 }
1386 if ( ( pPicReg->pszSetIrqRC
1387 || pPicReg->pszGetInterruptRC)
1388 && ( !VALID_PTR(pPicReg->pszSetIrqRC)
1389 || !VALID_PTR(pPicReg->pszGetInterruptRC))
1390 )
1391 {
1392 Assert(VALID_PTR(pPicReg->pszSetIrqRC));
1393 Assert(VALID_PTR(pPicReg->pszGetInterruptRC));
1394 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1395 return VERR_INVALID_PARAMETER;
1396 }
1397 if ( pPicReg->pszSetIrqRC
1398 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC))
1399 {
1400 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_RC);
1401 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (RC flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1402 return VERR_INVALID_PARAMETER;
1403 }
1404 if ( pPicReg->pszSetIrqR0
1405 && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0))
1406 {
1407 Assert(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_R0);
1408 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (R0 flag)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1409 return VERR_INVALID_PARAMETER;
1410 }
1411 if (!ppPicHlpR3)
1412 {
1413 Assert(ppPicHlpR3);
1414 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc (ppPicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1415 return VERR_INVALID_PARAMETER;
1416 }
1417
1418 /*
1419 * Only one PIC device.
1420 */
1421 PVM pVM = pDevIns->Internal.s.pVMR3;
1422 if (pVM->pdm.s.Pic.pDevInsR3)
1423 {
1424 AssertMsgFailed(("Only one pic device is supported!\n"));
1425 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1426 return VERR_INVALID_PARAMETER;
1427 }
1428
1429 /*
1430 * RC stuff.
1431 */
1432 if (pPicReg->pszSetIrqRC)
1433 {
1434 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC);
1435 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszSetIrqRC, rc));
1436 if (VBOX_SUCCESS(rc))
1437 {
1438 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC);
1439 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pPicReg->pszGetInterruptRC, rc));
1440 }
1441 if (VBOX_FAILURE(rc))
1442 {
1443 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1444 return rc;
1445 }
1446 pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
1447 }
1448 else
1449 {
1450 pVM->pdm.s.Pic.pDevInsRC = 0;
1451 pVM->pdm.s.Pic.pfnSetIrqRC = 0;
1452 pVM->pdm.s.Pic.pfnGetInterruptRC = 0;
1453 }
1454
1455 /*
1456 * R0 stuff.
1457 */
1458 if (pPicReg->pszSetIrqR0)
1459 {
1460 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0);
1461 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszSetIrqR0, rc));
1462 if (VBOX_SUCCESS(rc))
1463 {
1464 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0);
1465 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pPicReg->pszGetInterruptR0, rc));
1466 }
1467 if (VBOX_FAILURE(rc))
1468 {
1469 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1470 return rc;
1471 }
1472 pVM->pdm.s.Pic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
1473 Assert(pVM->pdm.s.Pic.pDevInsR0);
1474 }
1475 else
1476 {
1477 pVM->pdm.s.Pic.pfnSetIrqR0 = 0;
1478 pVM->pdm.s.Pic.pfnGetInterruptR0 = 0;
1479 pVM->pdm.s.Pic.pDevInsR0 = 0;
1480 }
1481
1482 /*
1483 * R3 stuff.
1484 */
1485 pVM->pdm.s.Pic.pDevInsR3 = pDevIns;
1486 pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3;
1487 pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3;
1488 Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
1489
1490 /* set the helper pointer and return. */
1491 *ppPicHlpR3 = &g_pdmR3DevPicHlp;
1492 LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
1493 return VINF_SUCCESS;
1494}
1495
1496
1497/** @copydoc PDMDEVHLPR3::pfnAPICRegister */
1498static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
1499{
1500 PDMDEV_ASSERT_DEVINS(pDevIns);
1501 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
1502 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, "
1503 ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnWriteMSR3=%p, .pfnReadMSR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
1504 ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszWriteMSRRC=%p:{%s}, .pszReadMSRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n",
1505 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3,
1506 pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnWriteMSRR3, pApicReg->pfnReadMSRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC,
1507 pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC,
1508 pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszWriteMSRRC, pApicReg->pszWriteMSRRC, pApicReg->pszReadMSRRC, pApicReg->pszReadMSRRC, pApicReg->pszBusDeliverRC,
1509 pApicReg->pszBusDeliverRC, ppApicHlpR3));
1510
1511 /*
1512 * Validate input.
1513 */
1514 if (pApicReg->u32Version != PDM_APICREG_VERSION)
1515 {
1516 AssertMsgFailed(("u32Version=%#x expected %#x\n", pApicReg->u32Version, PDM_APICREG_VERSION));
1517 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1518 return VERR_INVALID_PARAMETER;
1519 }
1520 if ( !pApicReg->pfnGetInterruptR3
1521 || !pApicReg->pfnHasPendingIrqR3
1522 || !pApicReg->pfnSetBaseR3
1523 || !pApicReg->pfnGetBaseR3
1524 || !pApicReg->pfnSetTPRR3
1525 || !pApicReg->pfnGetTPRR3
1526 || !pApicReg->pfnWriteMSRR3
1527 || !pApicReg->pfnReadMSRR3
1528 || !pApicReg->pfnBusDeliverR3)
1529 {
1530 Assert(pApicReg->pfnGetInterruptR3);
1531 Assert(pApicReg->pfnHasPendingIrqR3);
1532 Assert(pApicReg->pfnSetBaseR3);
1533 Assert(pApicReg->pfnGetBaseR3);
1534 Assert(pApicReg->pfnSetTPRR3);
1535 Assert(pApicReg->pfnGetTPRR3);
1536 Assert(pApicReg->pfnWriteMSRR3);
1537 Assert(pApicReg->pfnReadMSRR3);
1538 Assert(pApicReg->pfnBusDeliverR3);
1539 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1540 return VERR_INVALID_PARAMETER;
1541 }
1542 if ( ( pApicReg->pszGetInterruptRC
1543 || pApicReg->pszHasPendingIrqRC
1544 || pApicReg->pszSetBaseRC
1545 || pApicReg->pszGetBaseRC
1546 || pApicReg->pszSetTPRRC
1547 || pApicReg->pszGetTPRRC
1548 || pApicReg->pszWriteMSRRC
1549 || pApicReg->pszReadMSRRC
1550 || pApicReg->pszBusDeliverRC)
1551 && ( !VALID_PTR(pApicReg->pszGetInterruptRC)
1552 || !VALID_PTR(pApicReg->pszHasPendingIrqRC)
1553 || !VALID_PTR(pApicReg->pszSetBaseRC)
1554 || !VALID_PTR(pApicReg->pszGetBaseRC)
1555 || !VALID_PTR(pApicReg->pszSetTPRRC)
1556 || !VALID_PTR(pApicReg->pszGetTPRRC)
1557 || !VALID_PTR(pApicReg->pszWriteMSRRC)
1558 || !VALID_PTR(pApicReg->pszReadMSRRC)
1559 || !VALID_PTR(pApicReg->pszBusDeliverRC))
1560 )
1561 {
1562 Assert(VALID_PTR(pApicReg->pszGetInterruptRC));
1563 Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC));
1564 Assert(VALID_PTR(pApicReg->pszSetBaseRC));
1565 Assert(VALID_PTR(pApicReg->pszGetBaseRC));
1566 Assert(VALID_PTR(pApicReg->pszSetTPRRC));
1567 Assert(VALID_PTR(pApicReg->pszGetTPRRC));
1568 Assert(VALID_PTR(pApicReg->pszReadMSRRC));
1569 Assert(VALID_PTR(pApicReg->pszWriteMSRRC));
1570 Assert(VALID_PTR(pApicReg->pszBusDeliverRC));
1571 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1572 return VERR_INVALID_PARAMETER;
1573 }
1574 if ( ( pApicReg->pszGetInterruptR0
1575 || pApicReg->pszHasPendingIrqR0
1576 || pApicReg->pszSetBaseR0
1577 || pApicReg->pszGetBaseR0
1578 || pApicReg->pszSetTPRR0
1579 || pApicReg->pszGetTPRR0
1580 || pApicReg->pszWriteMSRR0
1581 || pApicReg->pszReadMSRR0
1582 || pApicReg->pszBusDeliverR0)
1583 && ( !VALID_PTR(pApicReg->pszGetInterruptR0)
1584 || !VALID_PTR(pApicReg->pszHasPendingIrqR0)
1585 || !VALID_PTR(pApicReg->pszSetBaseR0)
1586 || !VALID_PTR(pApicReg->pszGetBaseR0)
1587 || !VALID_PTR(pApicReg->pszSetTPRR0)
1588 || !VALID_PTR(pApicReg->pszGetTPRR0)
1589 || !VALID_PTR(pApicReg->pszReadMSRR0)
1590 || !VALID_PTR(pApicReg->pszWriteMSRR0)
1591 || !VALID_PTR(pApicReg->pszBusDeliverR0))
1592 )
1593 {
1594 Assert(VALID_PTR(pApicReg->pszGetInterruptR0));
1595 Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0));
1596 Assert(VALID_PTR(pApicReg->pszSetBaseR0));
1597 Assert(VALID_PTR(pApicReg->pszGetBaseR0));
1598 Assert(VALID_PTR(pApicReg->pszSetTPRR0));
1599 Assert(VALID_PTR(pApicReg->pszGetTPRR0));
1600 Assert(VALID_PTR(pApicReg->pszReadMSRR0));
1601 Assert(VALID_PTR(pApicReg->pszWriteMSRR0));
1602 Assert(VALID_PTR(pApicReg->pszBusDeliverR0));
1603 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1604 return VERR_INVALID_PARAMETER;
1605 }
1606 if (!ppApicHlpR3)
1607 {
1608 Assert(ppApicHlpR3);
1609 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (ppApicHlpR3)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1610 return VERR_INVALID_PARAMETER;
1611 }
1612
1613 /*
1614 * Only one APIC device. On SMP we have single logical device covering all LAPICs,
1615 * as they need to communicate and share state easily.
1616 */
1617 PVM pVM = pDevIns->Internal.s.pVMR3;
1618 if (pVM->pdm.s.Apic.pDevInsR3)
1619 {
1620 AssertMsgFailed(("Only one apic device is supported!\n"));
1621 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1622 return VERR_INVALID_PARAMETER;
1623 }
1624
1625 /*
1626 * Resolve & initialize the RC bits.
1627 */
1628 if (pApicReg->pszGetInterruptRC)
1629 {
1630 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, &pVM->pdm.s.Apic.pfnGetInterruptRC);
1631 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetInterruptRC, rc));
1632 if (RT_SUCCESS(rc))
1633 {
1634 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC);
1635 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszHasPendingIrqRC, rc));
1636 }
1637 if (RT_SUCCESS(rc))
1638 {
1639 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, &pVM->pdm.s.Apic.pfnSetBaseRC);
1640 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetBaseRC, rc));
1641 }
1642 if (RT_SUCCESS(rc))
1643 {
1644 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, &pVM->pdm.s.Apic.pfnGetBaseRC);
1645 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetBaseRC, rc));
1646 }
1647 if (RT_SUCCESS(rc))
1648 {
1649 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, &pVM->pdm.s.Apic.pfnSetTPRRC);
1650 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszSetTPRRC, rc));
1651 }
1652 if (RT_SUCCESS(rc))
1653 {
1654 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, &pVM->pdm.s.Apic.pfnGetTPRRC);
1655 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, rc));
1656 }
1657 if (RT_SUCCESS(rc))
1658 {
1659 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszWriteMSRRC, &pVM->pdm.s.Apic.pfnWriteMSRRC);
1660 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszWriteMSRRC, rc));
1661 }
1662 if (RT_SUCCESS(rc))
1663 {
1664 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszReadMSRRC, &pVM->pdm.s.Apic.pfnReadMSRRC);
1665 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszReadMSRRC, rc));
1666 }
1667 if (RT_SUCCESS(rc))
1668 {
1669 rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC);
1670 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, rc));
1671 }
1672 if (VBOX_FAILURE(rc))
1673 {
1674 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1675 return rc;
1676 }
1677 pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
1678 }
1679 else
1680 {
1681 pVM->pdm.s.Apic.pDevInsRC = 0;
1682 pVM->pdm.s.Apic.pfnGetInterruptRC = 0;
1683 pVM->pdm.s.Apic.pfnHasPendingIrqRC = 0;
1684 pVM->pdm.s.Apic.pfnSetBaseRC = 0;
1685 pVM->pdm.s.Apic.pfnGetBaseRC = 0;
1686 pVM->pdm.s.Apic.pfnSetTPRRC = 0;
1687 pVM->pdm.s.Apic.pfnGetTPRRC = 0;
1688 pVM->pdm.s.Apic.pfnWriteMSRRC = 0;
1689 pVM->pdm.s.Apic.pfnReadMSRRC = 0;
1690 pVM->pdm.s.Apic.pfnBusDeliverRC = 0;
1691 }
1692
1693 /*
1694 * Resolve & initialize the R0 bits.
1695 */
1696 if (pApicReg->pszGetInterruptR0)
1697 {
1698 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, &pVM->pdm.s.Apic.pfnGetInterruptR0);
1699 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetInterruptR0, rc));
1700 if (RT_SUCCESS(rc))
1701 {
1702 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0);
1703 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc));
1704 }
1705 if (RT_SUCCESS(rc))
1706 {
1707 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, &pVM->pdm.s.Apic.pfnSetBaseR0);
1708 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetBaseR0, rc));
1709 }
1710 if (RT_SUCCESS(rc))
1711 {
1712 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, &pVM->pdm.s.Apic.pfnGetBaseR0);
1713 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetBaseR0, rc));
1714 }
1715 if (RT_SUCCESS(rc))
1716 {
1717 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, &pVM->pdm.s.Apic.pfnSetTPRR0);
1718 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszSetTPRR0, rc));
1719 }
1720 if (RT_SUCCESS(rc))
1721 {
1722 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, &pVM->pdm.s.Apic.pfnGetTPRR0);
1723 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, rc));
1724 }
1725 if (RT_SUCCESS(rc))
1726 {
1727 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszWriteMSRR0, &pVM->pdm.s.Apic.pfnWriteMSRR0);
1728 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszWriteMSRR0, rc));
1729 }
1730 if (RT_SUCCESS(rc))
1731 {
1732 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszReadMSRR0, &pVM->pdm.s.Apic.pfnReadMSRR0);
1733 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszReadMSRR0, rc));
1734 }
1735 if (RT_SUCCESS(rc))
1736 {
1737 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0);
1738 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc));
1739 }
1740 if (VBOX_FAILURE(rc))
1741 {
1742 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1743 return rc;
1744 }
1745 pVM->pdm.s.Apic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
1746 Assert(pVM->pdm.s.Apic.pDevInsR0);
1747 }
1748 else
1749 {
1750 pVM->pdm.s.Apic.pfnGetInterruptR0 = 0;
1751 pVM->pdm.s.Apic.pfnHasPendingIrqR0 = 0;
1752 pVM->pdm.s.Apic.pfnSetBaseR0 = 0;
1753 pVM->pdm.s.Apic.pfnGetBaseR0 = 0;
1754 pVM->pdm.s.Apic.pfnSetTPRR0 = 0;
1755 pVM->pdm.s.Apic.pfnGetTPRR0 = 0;
1756 pVM->pdm.s.Apic.pfnWriteMSRR0 = 0;
1757 pVM->pdm.s.Apic.pfnReadMSRR0 = 0;
1758 pVM->pdm.s.Apic.pfnBusDeliverR0 = 0;
1759 pVM->pdm.s.Apic.pDevInsR0 = 0;
1760 }
1761
1762 /*
1763 * Initialize the HC bits.
1764 */
1765 pVM->pdm.s.Apic.pDevInsR3 = pDevIns;
1766 pVM->pdm.s.Apic.pfnGetInterruptR3 = pApicReg->pfnGetInterruptR3;
1767 pVM->pdm.s.Apic.pfnHasPendingIrqR3 = pApicReg->pfnHasPendingIrqR3;
1768 pVM->pdm.s.Apic.pfnSetBaseR3 = pApicReg->pfnSetBaseR3;
1769 pVM->pdm.s.Apic.pfnGetBaseR3 = pApicReg->pfnGetBaseR3;
1770 pVM->pdm.s.Apic.pfnSetTPRR3 = pApicReg->pfnSetTPRR3;
1771 pVM->pdm.s.Apic.pfnGetTPRR3 = pApicReg->pfnGetTPRR3;
1772 pVM->pdm.s.Apic.pfnWriteMSRR3 = pApicReg->pfnWriteMSRR3;
1773 pVM->pdm.s.Apic.pfnReadMSRR3 = pApicReg->pfnReadMSRR3;
1774 pVM->pdm.s.Apic.pfnBusDeliverR3 = pApicReg->pfnBusDeliverR3;
1775 Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
1776
1777 /* set the helper pointer and return. */
1778 *ppApicHlpR3 = &g_pdmR3DevApicHlp;
1779 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
1780 return VINF_SUCCESS;
1781}
1782
1783
1784/** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */
1785static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
1786{
1787 PDMDEV_ASSERT_DEVINS(pDevIns);
1788 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
1789 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n",
1790 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3,
1791 pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3));
1792
1793 /*
1794 * Validate input.
1795 */
1796 if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION)
1797 {
1798 AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION));
1799 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (version)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1800 return VERR_INVALID_PARAMETER;
1801 }
1802 if (!pIoApicReg->pfnSetIrqR3)
1803 {
1804 Assert(pIoApicReg->pfnSetIrqR3);
1805 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1806 return VERR_INVALID_PARAMETER;
1807 }
1808 if ( pIoApicReg->pszSetIrqRC
1809 && !VALID_PTR(pIoApicReg->pszSetIrqRC))
1810 {
1811 Assert(VALID_PTR(pIoApicReg->pszSetIrqRC));
1812 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1813 return VERR_INVALID_PARAMETER;
1814 }
1815 if ( pIoApicReg->pszSetIrqR0
1816 && !VALID_PTR(pIoApicReg->pszSetIrqR0))
1817 {
1818 Assert(VALID_PTR(pIoApicReg->pszSetIrqR0));
1819 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (GC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1820 return VERR_INVALID_PARAMETER;
1821 }
1822 if (!ppIoApicHlpR3)
1823 {
1824 Assert(ppIoApicHlpR3);
1825 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (ppApicHlp)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1826 return VERR_INVALID_PARAMETER;
1827 }
1828
1829 /*
1830 * The I/O APIC requires the APIC to be present (hacks++).
1831 * If the I/O APIC does GC stuff so must the APIC.
1832 */
1833 PVM pVM = pDevIns->Internal.s.pVMR3;
1834 if (!pVM->pdm.s.Apic.pDevInsR3)
1835 {
1836 AssertMsgFailed(("Configuration error / Init order error! No APIC!\n"));
1837 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1838 return VERR_INVALID_PARAMETER;
1839 }
1840 if ( pIoApicReg->pszSetIrqRC
1841 && !pVM->pdm.s.Apic.pDevInsRC)
1842 {
1843 AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n"));
1844 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (no GC APIC)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1845 return VERR_INVALID_PARAMETER;
1846 }
1847
1848 /*
1849 * Only one I/O APIC device.
1850 */
1851 if (pVM->pdm.s.IoApic.pDevInsR3)
1852 {
1853 AssertMsgFailed(("Only one ioapic device is supported!\n"));
1854 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc (only one)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1855 return VERR_INVALID_PARAMETER;
1856 }
1857
1858 /*
1859 * Resolve & initialize the GC bits.
1860 */
1861 if (pIoApicReg->pszSetIrqRC)
1862 {
1863 int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC);
1864 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pIoApicReg->pszSetIrqRC, rc));
1865 if (VBOX_FAILURE(rc))
1866 {
1867 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1868 return rc;
1869 }
1870 pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
1871 }
1872 else
1873 {
1874 pVM->pdm.s.IoApic.pDevInsRC = 0;
1875 pVM->pdm.s.IoApic.pfnSetIrqRC = 0;
1876 }
1877
1878 /*
1879 * Resolve & initialize the R0 bits.
1880 */
1881 if (pIoApicReg->pszSetIrqR0)
1882 {
1883 int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0);
1884 AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc));
1885 if (VBOX_FAILURE(rc))
1886 {
1887 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1888 return rc;
1889 }
1890 pVM->pdm.s.IoApic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
1891 Assert(pVM->pdm.s.IoApic.pDevInsR0);
1892 }
1893 else
1894 {
1895 pVM->pdm.s.IoApic.pfnSetIrqR0 = 0;
1896 pVM->pdm.s.IoApic.pDevInsR0 = 0;
1897 }
1898
1899 /*
1900 * Initialize the R3 bits.
1901 */
1902 pVM->pdm.s.IoApic.pDevInsR3 = pDevIns;
1903 pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3;
1904 Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
1905
1906 /* set the helper pointer and return. */
1907 *ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp;
1908 LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VINF_SUCCESS));
1909 return VINF_SUCCESS;
1910}
1911
1912
1913/** @copydoc PDMDEVHLPR3::pfnDMACRegister */
1914static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
1915{
1916 PDMDEV_ASSERT_DEVINS(pDevIns);
1917 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
1918 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",
1919 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister,
1920 pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp));
1921
1922 /*
1923 * Validate input.
1924 */
1925 if (pDmacReg->u32Version != PDM_DMACREG_VERSION)
1926 {
1927 AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version,
1928 PDM_DMACREG_VERSION));
1929 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (version)\n",
1930 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1931 return VERR_INVALID_PARAMETER;
1932 }
1933 if ( !pDmacReg->pfnRun
1934 || !pDmacReg->pfnRegister
1935 || !pDmacReg->pfnReadMemory
1936 || !pDmacReg->pfnWriteMemory
1937 || !pDmacReg->pfnSetDREQ
1938 || !pDmacReg->pfnGetChannelMode)
1939 {
1940 Assert(pDmacReg->pfnRun);
1941 Assert(pDmacReg->pfnRegister);
1942 Assert(pDmacReg->pfnReadMemory);
1943 Assert(pDmacReg->pfnWriteMemory);
1944 Assert(pDmacReg->pfnSetDREQ);
1945 Assert(pDmacReg->pfnGetChannelMode);
1946 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (callbacks)\n",
1947 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1948 return VERR_INVALID_PARAMETER;
1949 }
1950
1951 if (!ppDmacHlp)
1952 {
1953 Assert(ppDmacHlp);
1954 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc (ppDmacHlp)\n",
1955 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1956 return VERR_INVALID_PARAMETER;
1957 }
1958
1959 /*
1960 * Only one DMA device.
1961 */
1962 PVM pVM = pDevIns->Internal.s.pVMR3;
1963 if (pVM->pdm.s.pDmac)
1964 {
1965 AssertMsgFailed(("Only one DMA device is supported!\n"));
1966 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n",
1967 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
1968 return VERR_INVALID_PARAMETER;
1969 }
1970
1971 /*
1972 * Allocate and initialize pci bus structure.
1973 */
1974 int rc = VINF_SUCCESS;
1975 PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac));
1976 if (pDmac)
1977 {
1978 pDmac->pDevIns = pDevIns;
1979 pDmac->Reg = *pDmacReg;
1980 pVM->pdm.s.pDmac = pDmac;
1981
1982 /* set the helper pointer. */
1983 *ppDmacHlp = &g_pdmR3DevDmacHlp;
1984 Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n",
1985 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
1986 }
1987 else
1988 rc = VERR_NO_MEMORY;
1989
1990 LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Vrc\n",
1991 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
1992 return rc;
1993}
1994
1995
1996/** @copydoc PDMDEVHLPR3::pfnPhysRead */
1997static DECLCALLBACK(void) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
1998{
1999 PDMDEV_ASSERT_DEVINS(pDevIns);
2000 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n",
2001 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
2002
2003 /*
2004 * For the convenience of the device we put no thread restriction on this interface.
2005 * That means we'll have to check which thread we're in and choose our path.
2006 */
2007#ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD
2008 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead);
2009#else
2010 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3))
2011 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead);
2012 else
2013 {
2014 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2015 PVMREQ pReq;
2016 AssertCompileSize(RTGCPHYS, 4);
2017 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT,
2018 (PFNRT)PGMPhysRead, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead);
2019 while (rc == VERR_TIMEOUT)
2020 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
2021 AssertReleaseRC(rc);
2022 VMR3ReqFree(pReq);
2023 }
2024#endif
2025 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2026}
2027
2028
2029/** @copydoc PDMDEVHLPR3::pfnPhysWrite */
2030static DECLCALLBACK(void) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
2031{
2032 PDMDEV_ASSERT_DEVINS(pDevIns);
2033 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n",
2034 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
2035
2036 /*
2037 * For the convenience of the device we put no thread restriction on this interface.
2038 * That means we'll have to check which thread we're in and choose our path.
2039 */
2040#ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD
2041 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite);
2042#else
2043 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3))
2044 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite);
2045 else
2046 {
2047 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2048 PVMREQ pReq;
2049 AssertCompileSize(RTGCPHYS, 4);
2050 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT,
2051 (PFNRT)PGMPhysWrite, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite);
2052 while (rc == VERR_TIMEOUT)
2053 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
2054 AssertReleaseRC(rc);
2055 VMR3ReqFree(pReq);
2056 }
2057#endif
2058 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2059}
2060
2061
2062/** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */
2063static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
2064{
2065 PDMDEV_ASSERT_DEVINS(pDevIns);
2066 PVM pVM = pDevIns->Internal.s.pVMR3;
2067 VM_ASSERT_EMT(pVM);
2068 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%VGv cb=%#x\n",
2069 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pvDst, GCVirtSrc, cb));
2070
2071 if (!VM_IS_EMT(pVM))
2072 return VERR_ACCESS_DENIED;
2073
2074 int rc = PGMPhysSimpleReadGCPtr(pVM, pvDst, GCVirtSrc, cb);
2075
2076 LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2077
2078 return rc;
2079}
2080
2081
2082/** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */
2083static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
2084{
2085 PDMDEV_ASSERT_DEVINS(pDevIns);
2086 PVM pVM = pDevIns->Internal.s.pVMR3;
2087 VM_ASSERT_EMT(pVM);
2088 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%VGv pvSrc=%p cb=%#x\n",
2089 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCVirtDst, pvSrc, cb));
2090
2091 if (!VM_IS_EMT(pVM))
2092 return VERR_ACCESS_DENIED;
2093
2094 int rc = PGMPhysSimpleWriteGCPtr(pVM, GCVirtDst, pvSrc, cb);
2095
2096 LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2097
2098 return rc;
2099}
2100
2101
2102/** @copydoc PDMDEVHLPR3::pfnPhysReserve */
2103static DECLCALLBACK(int) pdmR3DevHlp_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc)
2104{
2105 PDMDEV_ASSERT_DEVINS(pDevIns);
2106 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2107 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: GCPhys=%VGp cbRange=%#x pszDesc=%p:{%s}\n",
2108 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, cbRange, pszDesc, pszDesc));
2109
2110 int rc = MMR3PhysReserve(pDevIns->Internal.s.pVMR3, GCPhys, cbRange, pszDesc);
2111
2112 LogFlow(("pdmR3DevHlp_PhysReserve: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2113
2114 return rc;
2115}
2116
2117
2118/** @copydoc PDMDEVHLPR3::pfnObsoletePhys2HCVirt */
2119static DECLCALLBACK(int) pdmR3DevHlp_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC)
2120{
2121 PDMDEV_ASSERT_DEVINS(pDevIns);
2122 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2123 NOREF(GCPhys);
2124 NOREF(cbRange);
2125 NOREF(ppvHC);
2126 return VERR_ACCESS_DENIED;
2127}
2128
2129
2130/** @copydoc PDMDEVHLPR3::pfnObsoletePhysGCPtr2HCPtr */
2131static DECLCALLBACK(int) pdmR3DevHlp_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr)
2132{
2133 PDMDEV_ASSERT_DEVINS(pDevIns);
2134 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2135 NOREF(GCPtr);
2136 NOREF(pHCPtr);
2137 return VERR_ACCESS_DENIED;
2138}
2139
2140
2141/** @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys */
2142static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
2143{
2144 PDMDEV_ASSERT_DEVINS(pDevIns);
2145 PVM pVM = pDevIns->Internal.s.pVMR3;
2146 VM_ASSERT_EMT(pVM);
2147 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%VGv pGCPhys=%p\n",
2148 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPtr, pGCPhys));
2149
2150 if (!VM_IS_EMT(pVM))
2151 return VERR_ACCESS_DENIED;
2152
2153 int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, pGCPhys);
2154
2155 LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Vrc *pGCPhys=%VGp\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pGCPhys));
2156
2157 return rc;
2158}
2159
2160
2161/** @copydoc PDMDEVHLPR3::pfnVMState */
2162static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns)
2163{
2164 PDMDEV_ASSERT_DEVINS(pDevIns);
2165
2166 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);
2167
2168 LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
2169 enmVMState, VMR3GetStateName(enmVMState)));
2170 return enmVMState;
2171}
2172
2173
2174/** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */
2175static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
2176{
2177 PDMDEV_ASSERT_DEVINS(pDevIns);
2178 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2179
2180 bool fRc = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMR3);
2181
2182 LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fRc));
2183 return fRc;
2184}
2185
2186
2187/** @copydoc PDMDEVHLPR3::pfnA20Set */
2188static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable)
2189{
2190 PDMDEV_ASSERT_DEVINS(pDevIns);
2191 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2192 LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fEnable));
2193 //Assert(*(unsigned *)&fEnable <= 1);
2194 PGMR3PhysSetA20(pDevIns->Internal.s.pVMR3, fEnable);
2195}
2196
2197
2198/** @copydoc PDMDEVHLPR3::pfnVMReset */
2199static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns)
2200{
2201 PDMDEV_ASSERT_DEVINS(pDevIns);
2202 PVM pVM = pDevIns->Internal.s.pVMR3;
2203 VM_ASSERT_EMT(pVM);
2204 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: VM_FF_RESET %d -> 1\n",
2205 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_RESET)));
2206
2207 /*
2208 * We postpone this operation because we're likely to be inside a I/O instruction
2209 * and the EIP will be updated when we return.
2210 * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation.
2211 */
2212 bool fHaltOnReset;
2213 int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset);
2214 if (VBOX_SUCCESS(rc) && fHaltOnReset)
2215 {
2216 Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n"));
2217 rc = VINF_EM_HALT;
2218 }
2219 else
2220 {
2221 VM_FF_SET(pVM, VM_FF_RESET);
2222 rc = VINF_EM_RESET;
2223 }
2224
2225 LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2226 return rc;
2227}
2228
2229
2230/** @copydoc PDMDEVHLPR3::pfnVMSuspend */
2231static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns)
2232{
2233 PDMDEV_ASSERT_DEVINS(pDevIns);
2234 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2235 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n",
2236 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2237
2238 int rc = VMR3Suspend(pDevIns->Internal.s.pVMR3);
2239
2240 LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2241 return rc;
2242}
2243
2244
2245/** @copydoc PDMDEVHLPR3::pfnVMPowerOff */
2246static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns)
2247{
2248 PDMDEV_ASSERT_DEVINS(pDevIns);
2249 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2250 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n",
2251 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2252
2253 int rc = VMR3PowerOff(pDevIns->Internal.s.pVMR3);
2254
2255 LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2256 return rc;
2257}
2258
2259
2260/** @copydoc PDMDEVHLPR3::pfnLockVM */
2261static DECLCALLBACK(int) pdmR3DevHlp_LockVM(PPDMDEVINS pDevIns)
2262{
2263 return VMMR3Lock(pDevIns->Internal.s.pVMR3);
2264}
2265
2266
2267/** @copydoc PDMDEVHLPR3::pfnUnlockVM */
2268static DECLCALLBACK(int) pdmR3DevHlp_UnlockVM(PPDMDEVINS pDevIns)
2269{
2270 return VMMR3Unlock(pDevIns->Internal.s.pVMR3);
2271}
2272
2273
2274/** @copydoc PDMDEVHLPR3::pfnAssertVMLock */
2275static DECLCALLBACK(bool) pdmR3DevHlp_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
2276{
2277 PVM pVM = pDevIns->Internal.s.pVMR3;
2278 if (VMMR3LockIsOwner(pVM))
2279 return true;
2280
2281 RTNATIVETHREAD NativeThreadOwner = VMMR3LockGetOwner(pVM);
2282 RTTHREAD ThreadOwner = RTThreadFromNative(NativeThreadOwner);
2283 char szMsg[100];
2284 RTStrPrintf(szMsg, sizeof(szMsg), "AssertVMLocked '%s'/%d ThreadOwner=%RTnthrd/%RTthrd/'%s' Self='%s'\n",
2285 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance,
2286 NativeThreadOwner, ThreadOwner, RTThreadGetName(ThreadOwner), RTThreadSelfName());
2287 AssertMsg1(szMsg, iLine, pszFile, pszFunction);
2288 AssertBreakpoint();
2289 return false;
2290}
2291
2292/** @copydoc PDMDEVHLPR3::pfnDMARegister */
2293static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
2294{
2295 PDMDEV_ASSERT_DEVINS(pDevIns);
2296 PVM pVM = pDevIns->Internal.s.pVMR3;
2297 VM_ASSERT_EMT(pVM);
2298 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n",
2299 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser));
2300 int rc = VINF_SUCCESS;
2301 if (pVM->pdm.s.pDmac)
2302 pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pfnTransferHandler, pvUser);
2303 else
2304 {
2305 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
2306 rc = VERR_PDM_NO_DMAC_INSTANCE;
2307 }
2308 LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Vrc\n",
2309 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2310 return rc;
2311}
2312
2313/** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */
2314static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
2315{
2316 PDMDEV_ASSERT_DEVINS(pDevIns);
2317 PVM pVM = pDevIns->Internal.s.pVMR3;
2318 VM_ASSERT_EMT(pVM);
2319 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n",
2320 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead));
2321 int rc = VINF_SUCCESS;
2322 if (pVM->pdm.s.pDmac)
2323 {
2324 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
2325 if (pcbRead)
2326 *pcbRead = cb;
2327 }
2328 else
2329 {
2330 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
2331 rc = VERR_PDM_NO_DMAC_INSTANCE;
2332 }
2333 LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Vrc\n",
2334 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2335 return rc;
2336}
2337
2338/** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */
2339static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
2340{
2341 PDMDEV_ASSERT_DEVINS(pDevIns);
2342 PVM pVM = pDevIns->Internal.s.pVMR3;
2343 VM_ASSERT_EMT(pVM);
2344 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n",
2345 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten));
2346 int rc = VINF_SUCCESS;
2347 if (pVM->pdm.s.pDmac)
2348 {
2349 uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
2350 if (pcbWritten)
2351 *pcbWritten = cb;
2352 }
2353 else
2354 {
2355 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
2356 rc = VERR_PDM_NO_DMAC_INSTANCE;
2357 }
2358 LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Vrc\n",
2359 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2360 return rc;
2361}
2362
2363/** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */
2364static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
2365{
2366 PDMDEV_ASSERT_DEVINS(pDevIns);
2367 PVM pVM = pDevIns->Internal.s.pVMR3;
2368 VM_ASSERT_EMT(pVM);
2369 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n",
2370 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel, uLevel));
2371 int rc = VINF_SUCCESS;
2372 if (pVM->pdm.s.pDmac)
2373 pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel);
2374 else
2375 {
2376 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
2377 rc = VERR_PDM_NO_DMAC_INSTANCE;
2378 }
2379 LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Vrc\n",
2380 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2381 return rc;
2382}
2383
2384/** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */
2385static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
2386{
2387 PDMDEV_ASSERT_DEVINS(pDevIns);
2388 PVM pVM = pDevIns->Internal.s.pVMR3;
2389 VM_ASSERT_EMT(pVM);
2390 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n",
2391 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, uChannel));
2392 uint8_t u8Mode;
2393 if (pVM->pdm.s.pDmac)
2394 u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel);
2395 else
2396 {
2397 AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
2398 u8Mode = 3 << 2 /* illegal mode type */;
2399 }
2400 LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n",
2401 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Mode));
2402 return u8Mode;
2403}
2404
2405/** @copydoc PDMDEVHLPR3::pfnDMASchedule */
2406static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns)
2407{
2408 PDMDEV_ASSERT_DEVINS(pDevIns);
2409 PVM pVM = pDevIns->Internal.s.pVMR3;
2410 VM_ASSERT_EMT(pVM);
2411 LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n",
2412 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VM_FF_ISSET(pVM, VM_FF_PDM_DMA)));
2413
2414 AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
2415 VM_FF_SET(pVM, VM_FF_PDM_DMA);
2416 REMR3NotifyDmaPending(pVM);
2417 VMR3NotifyFF(pVM, true);
2418}
2419
2420
2421/** @copydoc PDMDEVHLPR3::pfnCMOSWrite */
2422static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
2423{
2424 PDMDEV_ASSERT_DEVINS(pDevIns);
2425 PVM pVM = pDevIns->Internal.s.pVMR3;
2426 VM_ASSERT_EMT(pVM);
2427
2428 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n",
2429 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, u8Value));
2430 int rc;
2431 if (pVM->pdm.s.pRtc)
2432 rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pVM->pdm.s.pRtc->pDevIns, iReg, u8Value);
2433 else
2434 rc = VERR_PDM_NO_RTC_INSTANCE;
2435
2436 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n",
2437 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2438 return rc;
2439}
2440
2441
2442/** @copydoc PDMDEVHLPR3::pfnCMOSRead */
2443static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
2444{
2445 PDMDEV_ASSERT_DEVINS(pDevIns);
2446 PVM pVM = pDevIns->Internal.s.pVMR3;
2447 VM_ASSERT_EMT(pVM);
2448
2449 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n",
2450 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iReg, pu8Value));
2451 int rc;
2452 if (pVM->pdm.s.pRtc)
2453 rc = pVM->pdm.s.pRtc->Reg.pfnRead(pVM->pdm.s.pRtc->pDevIns, iReg, pu8Value);
2454 else
2455 rc = VERR_PDM_NO_RTC_INSTANCE;
2456
2457 LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Vrc\n",
2458 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2459 return rc;
2460}
2461
2462
2463/** @copydoc PDMDEVHLPR3::pfnGetCpuId */
2464static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
2465 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
2466{
2467 PDMDEV_ASSERT_DEVINS(pDevIns);
2468 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n",
2469 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx));
2470 AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx);
2471
2472 CPUMGetGuestCpuId(pDevIns->Internal.s.pVMR3, iLeaf, pEax, pEbx, pEcx, pEdx);
2473
2474 LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n",
2475 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx));
2476}
2477
2478
2479/** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */
2480static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
2481{
2482 PDMDEV_ASSERT_DEVINS(pDevIns);
2483 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n",
2484 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange));
2485
2486 int rc = MMR3PhysRomProtect(pDevIns->Internal.s.pVMR3, GCPhysStart, cbRange);
2487
2488 LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2489 return rc;
2490}
2491
2492
2493/**
2494 * @copydoc PDMDEVHLPR3::pfnMMIO2Register
2495 */
2496static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
2497{
2498 PDMDEV_ASSERT_DEVINS(pDevIns);
2499 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2500 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: iRegion=#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n",
2501 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, cb, fFlags, ppv, pszDesc, pszDesc));
2502
2503 int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
2504
2505 LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2506 return rc;
2507}
2508
2509
2510/**
2511 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister
2512 */
2513static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
2514{
2515 PDMDEV_ASSERT_DEVINS(pDevIns);
2516 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2517 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: iRegion=#x\n",
2518 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion));
2519
2520 AssertReturn(iRegion == UINT32_MAX, VERR_INVALID_PARAMETER);
2521
2522 int rc = PGMR3PhysMMIO2Deregister(pDevIns->Internal.s.pVMR3, pDevIns, iRegion);
2523
2524 LogFlow(("pdmR3DevHlp_MMIO2Deregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2525 return rc;
2526}
2527
2528
2529/**
2530 * @copydoc PDMDEVHLPR3::pfnMMIO2Map
2531 */
2532static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
2533{
2534 PDMDEV_ASSERT_DEVINS(pDevIns);
2535 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2536 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n",
2537 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys));
2538
2539 int rc = PGMR3PhysMMIO2Map(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys);
2540
2541 LogFlow(("pdmR3DevHlp_MMIO2Map: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2542 return rc;
2543}
2544
2545
2546/**
2547 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap
2548 */
2549static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
2550{
2551 PDMDEV_ASSERT_DEVINS(pDevIns);
2552 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2553 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: iRegion=#x GCPhys=%#RGp\n",
2554 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, GCPhys));
2555
2556 int rc = PGMR3PhysMMIO2Unmap(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, GCPhys);
2557
2558 LogFlow(("pdmR3DevHlp_MMIO2Unmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
2559 return rc;
2560}
2561
2562
2563/**
2564 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
2565 */
2566static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
2567 const char *pszDesc, PRTRCPTR pRCPtr)
2568{
2569 PDMDEV_ASSERT_DEVINS(pDevIns);
2570 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2571 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: iRegion=#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",
2572 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));
2573
2574 int rc = MMR3HyperMapMMIO2(pDevIns->Internal.s.pVMR3, pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
2575
2576 LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc, *pRCPtr));
2577 return rc;
2578}
2579
2580
2581/**
2582 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
2583 */
2584static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)
2585{
2586 PDMDEV_ASSERT_DEVINS(pDevIns);
2587 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2588
2589 int rc = PDMR3RegisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys, pvHeap, cbSize);
2590 return rc;
2591}
2592
2593
2594/**
2595 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap
2596 */
2597static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
2598{
2599 PDMDEV_ASSERT_DEVINS(pDevIns);
2600 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
2601
2602 int rc = PDMR3UnregisterVMMDevHeap(pDevIns->Internal.s.pVMR3, GCPhys);
2603 return rc;
2604}
2605
2606
2607/**
2608 * The device helper structure for trusted devices.
2609 */
2610const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =
2611{
2612 PDM_DEVHLP_VERSION,
2613 pdmR3DevHlp_IOPortRegister,
2614 pdmR3DevHlp_IOPortRegisterGC,
2615 pdmR3DevHlp_IOPortRegisterR0,
2616 pdmR3DevHlp_IOPortDeregister,
2617 pdmR3DevHlp_MMIORegister,
2618 pdmR3DevHlp_MMIORegisterGC,
2619 pdmR3DevHlp_MMIORegisterR0,
2620 pdmR3DevHlp_MMIODeregister,
2621 pdmR3DevHlp_ROMRegister,
2622 pdmR3DevHlp_SSMRegister,
2623 pdmR3DevHlp_TMTimerCreate,
2624 pdmR3DevHlp_TMTimerCreateExternal,
2625 pdmR3DevHlp_PCIRegister,
2626 pdmR3DevHlp_PCIIORegionRegister,
2627 pdmR3DevHlp_PCISetConfigCallbacks,
2628 pdmR3DevHlp_PCISetIrq,
2629 pdmR3DevHlp_PCISetIrqNoWait,
2630 pdmR3DevHlp_ISASetIrq,
2631 pdmR3DevHlp_ISASetIrqNoWait,
2632 pdmR3DevHlp_DriverAttach,
2633 pdmR3DevHlp_MMHeapAlloc,
2634 pdmR3DevHlp_MMHeapAllocZ,
2635 pdmR3DevHlp_MMHeapFree,
2636 pdmR3DevHlp_VMSetError,
2637 pdmR3DevHlp_VMSetErrorV,
2638 pdmR3DevHlp_VMSetRuntimeError,
2639 pdmR3DevHlp_VMSetRuntimeErrorV,
2640 pdmR3DevHlp_AssertEMT,
2641 pdmR3DevHlp_AssertOther,
2642 pdmR3DevHlp_DBGFStopV,
2643 pdmR3DevHlp_DBGFInfoRegister,
2644 pdmR3DevHlp_STAMRegister,
2645 pdmR3DevHlp_STAMRegisterF,
2646 pdmR3DevHlp_STAMRegisterV,
2647 pdmR3DevHlp_RTCRegister,
2648 pdmR3DevHlp_PDMQueueCreate,
2649 pdmR3DevHlp_CritSectInit,
2650 pdmR3DevHlp_UTCNow,
2651 pdmR3DevHlp_PDMThreadCreate,
2652 pdmR3DevHlp_PhysGCPtr2GCPhys,
2653 pdmR3DevHlp_VMState,
2654 0,
2655 0,
2656 0,
2657 0,
2658 0,
2659 0,
2660 0,
2661 pdmR3DevHlp_GetVM,
2662 pdmR3DevHlp_PCIBusRegister,
2663 pdmR3DevHlp_PICRegister,
2664 pdmR3DevHlp_APICRegister,
2665 pdmR3DevHlp_IOAPICRegister,
2666 pdmR3DevHlp_DMACRegister,
2667 pdmR3DevHlp_PhysRead,
2668 pdmR3DevHlp_PhysWrite,
2669 pdmR3DevHlp_PhysReadGCVirt,
2670 pdmR3DevHlp_PhysWriteGCVirt,
2671 pdmR3DevHlp_PhysReserve,
2672 pdmR3DevHlp_Obsolete_Phys2HCVirt,
2673 pdmR3DevHlp_Obsolete_PhysGCPtr2HCPtr,
2674 pdmR3DevHlp_A20IsEnabled,
2675 pdmR3DevHlp_A20Set,
2676 pdmR3DevHlp_VMReset,
2677 pdmR3DevHlp_VMSuspend,
2678 pdmR3DevHlp_VMPowerOff,
2679 pdmR3DevHlp_LockVM,
2680 pdmR3DevHlp_UnlockVM,
2681 pdmR3DevHlp_AssertVMLock,
2682 pdmR3DevHlp_DMARegister,
2683 pdmR3DevHlp_DMAReadMemory,
2684 pdmR3DevHlp_DMAWriteMemory,
2685 pdmR3DevHlp_DMASetDREQ,
2686 pdmR3DevHlp_DMAGetChannelMode,
2687 pdmR3DevHlp_DMASchedule,
2688 pdmR3DevHlp_CMOSWrite,
2689 pdmR3DevHlp_CMOSRead,
2690 pdmR3DevHlp_GetCpuId,
2691 pdmR3DevHlp_ROMProtectShadow,
2692 pdmR3DevHlp_MMIO2Register,
2693 pdmR3DevHlp_MMIO2Deregister,
2694 pdmR3DevHlp_MMIO2Map,
2695 pdmR3DevHlp_MMIO2Unmap,
2696 pdmR3DevHlp_MMHyperMapMMIO2,
2697 pdmR3DevHlp_RegisterVMMDevHeap,
2698 pdmR3DevHlp_UnregisterVMMDevHeap,
2699 PDM_DEVHLP_VERSION /* the end */
2700};
2701
2702
2703
2704
2705/** @copydoc PDMDEVHLPR3::pfnGetVM */
2706static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns)
2707{
2708 PDMDEV_ASSERT_DEVINS(pDevIns);
2709 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2710 return NULL;
2711}
2712
2713
2714/** @copydoc PDMDEVHLPR3::pfnPCIBusRegister */
2715static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
2716{
2717 PDMDEV_ASSERT_DEVINS(pDevIns);
2718 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2719 NOREF(pPciBusReg);
2720 NOREF(ppPciHlpR3);
2721 return VERR_ACCESS_DENIED;
2722}
2723
2724
2725/** @copydoc PDMDEVHLPR3::pfnPICRegister */
2726static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
2727{
2728 PDMDEV_ASSERT_DEVINS(pDevIns);
2729 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2730 NOREF(pPicReg);
2731 NOREF(ppPicHlpR3);
2732 return VERR_ACCESS_DENIED;
2733}
2734
2735
2736/** @copydoc PDMDEVHLPR3::pfnAPICRegister */
2737static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
2738{
2739 PDMDEV_ASSERT_DEVINS(pDevIns);
2740 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2741 NOREF(pApicReg);
2742 NOREF(ppApicHlpR3);
2743 return VERR_ACCESS_DENIED;
2744}
2745
2746
2747/** @copydoc PDMDEVHLPR3::pfnIOAPICRegister */
2748static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
2749{
2750 PDMDEV_ASSERT_DEVINS(pDevIns);
2751 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2752 NOREF(pIoApicReg);
2753 NOREF(ppIoApicHlpR3);
2754 return VERR_ACCESS_DENIED;
2755}
2756
2757
2758/** @copydoc PDMDEVHLPR3::pfnDMACRegister */
2759static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
2760{
2761 PDMDEV_ASSERT_DEVINS(pDevIns);
2762 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2763 NOREF(pDmacReg);
2764 NOREF(ppDmacHlp);
2765 return VERR_ACCESS_DENIED;
2766}
2767
2768
2769/** @copydoc PDMDEVHLPR3::pfnPhysRead */
2770static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
2771{
2772 PDMDEV_ASSERT_DEVINS(pDevIns);
2773 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2774 NOREF(GCPhys);
2775 NOREF(pvBuf);
2776 NOREF(cbRead);
2777}
2778
2779
2780/** @copydoc PDMDEVHLPR3::pfnPhysWrite */
2781static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
2782{
2783 PDMDEV_ASSERT_DEVINS(pDevIns);
2784 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2785 NOREF(GCPhys);
2786 NOREF(pvBuf);
2787 NOREF(cbWrite);
2788}
2789
2790
2791/** @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt */
2792static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
2793{
2794 PDMDEV_ASSERT_DEVINS(pDevIns);
2795 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2796 NOREF(pvDst);
2797 NOREF(GCVirtSrc);
2798 NOREF(cb);
2799 return VERR_ACCESS_DENIED;
2800}
2801
2802
2803/** @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt */
2804static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
2805{
2806 PDMDEV_ASSERT_DEVINS(pDevIns);
2807 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2808 NOREF(GCVirtDst);
2809 NOREF(pvSrc);
2810 NOREF(cb);
2811 return VERR_ACCESS_DENIED;
2812}
2813
2814
2815/** @copydoc PDMDEVHLPR3::pfnPhysReserve */
2816static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_PhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc)
2817{
2818 PDMDEV_ASSERT_DEVINS(pDevIns);
2819 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2820 NOREF(GCPhys);
2821 NOREF(cbRange);
2822 return VERR_ACCESS_DENIED;
2823}
2824
2825
2826/** @copydoc PDMDEVHLPR3::pfnObsoletePhys2HCVirt */
2827static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC)
2828{
2829 PDMDEV_ASSERT_DEVINS(pDevIns);
2830 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2831 NOREF(GCPhys);
2832 NOREF(cbRange);
2833 NOREF(ppvHC);
2834 return VERR_ACCESS_DENIED;
2835}
2836
2837
2838/** @copydoc PDMDEVHLPR3::pfnObsoletePhysGCPtr2HCPtr */
2839static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr)
2840{
2841 PDMDEV_ASSERT_DEVINS(pDevIns);
2842 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2843 NOREF(GCPtr);
2844 NOREF(pHCPtr);
2845 return VERR_ACCESS_DENIED;
2846}
2847
2848
2849/** @copydoc PDMDEVHLPR3::pfnA20IsEnabled */
2850static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns)
2851{
2852 PDMDEV_ASSERT_DEVINS(pDevIns);
2853 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2854 return false;
2855}
2856
2857
2858/** @copydoc PDMDEVHLPR3::pfnA20Set */
2859static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable)
2860{
2861 PDMDEV_ASSERT_DEVINS(pDevIns);
2862 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2863 NOREF(fEnable);
2864}
2865
2866
2867/** @copydoc PDMDEVHLPR3::pfnVMReset */
2868static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns)
2869{
2870 PDMDEV_ASSERT_DEVINS(pDevIns);
2871 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2872 return VERR_ACCESS_DENIED;
2873}
2874
2875
2876/** @copydoc PDMDEVHLPR3::pfnVMSuspend */
2877static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns)
2878{
2879 PDMDEV_ASSERT_DEVINS(pDevIns);
2880 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2881 return VERR_ACCESS_DENIED;
2882}
2883
2884
2885/** @copydoc PDMDEVHLPR3::pfnVMPowerOff */
2886static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns)
2887{
2888 PDMDEV_ASSERT_DEVINS(pDevIns);
2889 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2890 return VERR_ACCESS_DENIED;
2891}
2892
2893
2894/** @copydoc PDMDEVHLPR3::pfnLockVM */
2895static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_LockVM(PPDMDEVINS pDevIns)
2896{
2897 PDMDEV_ASSERT_DEVINS(pDevIns);
2898 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2899 return VERR_ACCESS_DENIED;
2900}
2901
2902
2903/** @copydoc PDMDEVHLPR3::pfnUnlockVM */
2904static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnlockVM(PPDMDEVINS pDevIns)
2905{
2906 PDMDEV_ASSERT_DEVINS(pDevIns);
2907 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2908 return VERR_ACCESS_DENIED;
2909}
2910
2911
2912/** @copydoc PDMDEVHLPR3::pfnAssertVMLock */
2913static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_AssertVMLock(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
2914{
2915 PDMDEV_ASSERT_DEVINS(pDevIns);
2916 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2917 return false;
2918}
2919
2920
2921/** @copydoc PDMDEVHLPR3::pfnDMARegister */
2922static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
2923{
2924 PDMDEV_ASSERT_DEVINS(pDevIns);
2925 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2926 return VERR_ACCESS_DENIED;
2927}
2928
2929
2930/** @copydoc PDMDEVHLPR3::pfnDMAReadMemory */
2931static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
2932{
2933 PDMDEV_ASSERT_DEVINS(pDevIns);
2934 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2935 if (pcbRead)
2936 *pcbRead = 0;
2937 return VERR_ACCESS_DENIED;
2938}
2939
2940
2941/** @copydoc PDMDEVHLPR3::pfnDMAWriteMemory */
2942static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
2943{
2944 PDMDEV_ASSERT_DEVINS(pDevIns);
2945 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2946 if (pcbWritten)
2947 *pcbWritten = 0;
2948 return VERR_ACCESS_DENIED;
2949}
2950
2951
2952/** @copydoc PDMDEVHLPR3::pfnDMASetDREQ */
2953static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
2954{
2955 PDMDEV_ASSERT_DEVINS(pDevIns);
2956 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2957 return VERR_ACCESS_DENIED;
2958}
2959
2960
2961/** @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode */
2962static DECLCALLBACK(uint8_t) pdmR3DevHlp_Untrusted_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
2963{
2964 PDMDEV_ASSERT_DEVINS(pDevIns);
2965 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2966 return 3 << 2 /* illegal mode type */;
2967}
2968
2969
2970/** @copydoc PDMDEVHLPR3::pfnDMASchedule */
2971static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_DMASchedule(PPDMDEVINS pDevIns)
2972{
2973 PDMDEV_ASSERT_DEVINS(pDevIns);
2974 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2975}
2976
2977
2978/** @copydoc PDMDEVHLPR3::pfnCMOSWrite */
2979static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
2980{
2981 PDMDEV_ASSERT_DEVINS(pDevIns);
2982 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2983 return VERR_ACCESS_DENIED;
2984}
2985
2986
2987/** @copydoc PDMDEVHLPR3::pfnCMOSRead */
2988static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
2989{
2990 PDMDEV_ASSERT_DEVINS(pDevIns);
2991 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
2992 return VERR_ACCESS_DENIED;
2993}
2994
2995
2996/** @copydoc PDMDEVHLPR3::pfnGetCpuId */
2997static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
2998 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
2999{
3000 PDMDEV_ASSERT_DEVINS(pDevIns);
3001 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3002}
3003
3004
3005/** @copydoc PDMDEVHLPR3::pfnROMProtectShadow */
3006static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
3007{
3008 PDMDEV_ASSERT_DEVINS(pDevIns);
3009 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3010 return VERR_ACCESS_DENIED;
3011}
3012
3013
3014/** @copydoc PDMDEVHLPR3::pfnMMIO2Register */
3015static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
3016{
3017 PDMDEV_ASSERT_DEVINS(pDevIns);
3018 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3019 return VERR_ACCESS_DENIED;
3020}
3021
3022
3023/** @copydoc PDMDEVHLPR3::pfnMMIO2Deregister */
3024static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
3025{
3026 PDMDEV_ASSERT_DEVINS(pDevIns);
3027 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3028 return VERR_ACCESS_DENIED;
3029}
3030
3031
3032/** @copydoc PDMDEVHLPR3::pfnMMIO2Map */
3033static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3034{
3035 PDMDEV_ASSERT_DEVINS(pDevIns);
3036 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3037 return VERR_ACCESS_DENIED;
3038}
3039
3040
3041/** @copydoc PDMDEVHLPR3::pfnMMIO2Unmap */
3042static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3043{
3044 PDMDEV_ASSERT_DEVINS(pDevIns);
3045 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3046 return VERR_ACCESS_DENIED;
3047}
3048
3049
3050/** @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2 */
3051static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_MMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr)
3052{
3053 PDMDEV_ASSERT_DEVINS(pDevIns);
3054 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3055 return VERR_ACCESS_DENIED;
3056}
3057
3058
3059/** @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap */
3060static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)
3061{
3062 PDMDEV_ASSERT_DEVINS(pDevIns);
3063 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3064 return VERR_ACCESS_DENIED;
3065}
3066
3067
3068/** @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap */
3069static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
3070{
3071 PDMDEV_ASSERT_DEVINS(pDevIns);
3072 AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
3073 return VERR_ACCESS_DENIED;
3074}
3075
3076
3077/**
3078 * The device helper structure for non-trusted devices.
3079 */
3080const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =
3081{
3082 PDM_DEVHLP_VERSION,
3083 pdmR3DevHlp_IOPortRegister,
3084 pdmR3DevHlp_IOPortRegisterGC,
3085 pdmR3DevHlp_IOPortRegisterR0,
3086 pdmR3DevHlp_IOPortDeregister,
3087 pdmR3DevHlp_MMIORegister,
3088 pdmR3DevHlp_MMIORegisterGC,
3089 pdmR3DevHlp_MMIORegisterR0,
3090 pdmR3DevHlp_MMIODeregister,
3091 pdmR3DevHlp_ROMRegister,
3092 pdmR3DevHlp_SSMRegister,
3093 pdmR3DevHlp_TMTimerCreate,
3094 pdmR3DevHlp_TMTimerCreateExternal,
3095 pdmR3DevHlp_PCIRegister,
3096 pdmR3DevHlp_PCIIORegionRegister,
3097 pdmR3DevHlp_PCISetConfigCallbacks,
3098 pdmR3DevHlp_PCISetIrq,
3099 pdmR3DevHlp_PCISetIrqNoWait,
3100 pdmR3DevHlp_ISASetIrq,
3101 pdmR3DevHlp_ISASetIrqNoWait,
3102 pdmR3DevHlp_DriverAttach,
3103 pdmR3DevHlp_MMHeapAlloc,
3104 pdmR3DevHlp_MMHeapAllocZ,
3105 pdmR3DevHlp_MMHeapFree,
3106 pdmR3DevHlp_VMSetError,
3107 pdmR3DevHlp_VMSetErrorV,
3108 pdmR3DevHlp_VMSetRuntimeError,
3109 pdmR3DevHlp_VMSetRuntimeErrorV,
3110 pdmR3DevHlp_AssertEMT,
3111 pdmR3DevHlp_AssertOther,
3112 pdmR3DevHlp_DBGFStopV,
3113 pdmR3DevHlp_DBGFInfoRegister,
3114 pdmR3DevHlp_STAMRegister,
3115 pdmR3DevHlp_STAMRegisterF,
3116 pdmR3DevHlp_STAMRegisterV,
3117 pdmR3DevHlp_RTCRegister,
3118 pdmR3DevHlp_PDMQueueCreate,
3119 pdmR3DevHlp_CritSectInit,
3120 pdmR3DevHlp_UTCNow,
3121 pdmR3DevHlp_PDMThreadCreate,
3122 pdmR3DevHlp_PhysGCPtr2GCPhys,
3123 pdmR3DevHlp_VMState,
3124 0,
3125 0,
3126 0,
3127 0,
3128 0,
3129 0,
3130 0,
3131 pdmR3DevHlp_Untrusted_GetVM,
3132 pdmR3DevHlp_Untrusted_PCIBusRegister,
3133 pdmR3DevHlp_Untrusted_PICRegister,
3134 pdmR3DevHlp_Untrusted_APICRegister,
3135 pdmR3DevHlp_Untrusted_IOAPICRegister,
3136 pdmR3DevHlp_Untrusted_DMACRegister,
3137 pdmR3DevHlp_Untrusted_PhysRead,
3138 pdmR3DevHlp_Untrusted_PhysWrite,
3139 pdmR3DevHlp_Untrusted_PhysReadGCVirt,
3140 pdmR3DevHlp_Untrusted_PhysWriteGCVirt,
3141 pdmR3DevHlp_Untrusted_PhysReserve,
3142 pdmR3DevHlp_Untrusted_Obsolete_Phys2HCVirt,
3143 pdmR3DevHlp_Untrusted_Obsolete_PhysGCPtr2HCPtr,
3144 pdmR3DevHlp_Untrusted_A20IsEnabled,
3145 pdmR3DevHlp_Untrusted_A20Set,
3146 pdmR3DevHlp_Untrusted_VMReset,
3147 pdmR3DevHlp_Untrusted_VMSuspend,
3148 pdmR3DevHlp_Untrusted_VMPowerOff,
3149 pdmR3DevHlp_Untrusted_LockVM,
3150 pdmR3DevHlp_Untrusted_UnlockVM,
3151 pdmR3DevHlp_Untrusted_AssertVMLock,
3152 pdmR3DevHlp_Untrusted_DMARegister,
3153 pdmR3DevHlp_Untrusted_DMAReadMemory,
3154 pdmR3DevHlp_Untrusted_DMAWriteMemory,
3155 pdmR3DevHlp_Untrusted_DMASetDREQ,
3156 pdmR3DevHlp_Untrusted_DMAGetChannelMode,
3157 pdmR3DevHlp_Untrusted_DMASchedule,
3158 pdmR3DevHlp_Untrusted_CMOSWrite,
3159 pdmR3DevHlp_Untrusted_CMOSRead,
3160 pdmR3DevHlp_Untrusted_GetCpuId,
3161 pdmR3DevHlp_Untrusted_ROMProtectShadow,
3162 pdmR3DevHlp_Untrusted_MMIO2Register,
3163 pdmR3DevHlp_Untrusted_MMIO2Deregister,
3164 pdmR3DevHlp_Untrusted_MMIO2Map,
3165 pdmR3DevHlp_Untrusted_MMIO2Unmap,
3166 pdmR3DevHlp_Untrusted_MMHyperMapMMIO2,
3167 pdmR3DevHlp_Untrusted_RegisterVMMDevHeap,
3168 pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap,
3169 PDM_DEVHLP_VERSION /* the end */
3170};
3171
3172
3173
3174/**
3175 * Queue consumer callback for internal component.
3176 *
3177 * @returns Success indicator.
3178 * If false the item will not be removed and the flushing will stop.
3179 * @param pVM The VM handle.
3180 * @param pItem The item to consume. Upon return this item will be freed.
3181 */
3182DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem)
3183{
3184 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem;
3185 LogFlow(("pdmR3DevHlpQueueConsumer: enmOp=%d pDevIns=%p\n", pTask->enmOp, pTask->pDevInsR3));
3186 switch (pTask->enmOp)
3187 {
3188 case PDMDEVHLPTASKOP_ISA_SET_IRQ:
3189 PDMIsaSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
3190 break;
3191
3192 case PDMDEVHLPTASKOP_PCI_SET_IRQ:
3193 pdmR3DevHlp_PCISetIrq(pTask->pDevInsR3, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
3194 break;
3195
3196 case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:
3197 PDMIoApicSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
3198 break;
3199
3200 default:
3201 AssertReleaseMsgFailed(("Invalid operation %d\n", pTask->enmOp));
3202 break;
3203 }
3204 return true;
3205}
3206
3207/** @} */
3208
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