VirtualBox

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

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

don't allow to register PCI memory regions with a size != 2n

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette