VirtualBox

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

Last change on this file since 18370 was 18143, checked in by vboxsync, 16 years ago

VMM,Devices: Changed ROM registration and fixed some shadowed ROM issues in the new phys code.

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