VirtualBox

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

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

infrastructure work for X2APIC support

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