VirtualBox

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

Last change on this file since 18004 was 17534, checked in by vboxsync, 16 years ago

PGM: Made PGMPhysRead/Write return VERR_PGM_PHYS_WR_HIT_HANDLER when encountering a handler in R0 and RC. Adjusted PGMPhysReadGCPtr and PGMPhysWriteGCPtr to not waste time on setting A and D bits if they are already set.

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