VirtualBox

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

Last change on this file since 23915 was 23915, checked in by vboxsync, 15 years ago

VM,PDMDevHlp,PDMDrvHlp: VM[R3]TeleportedAndNotFullyResumedYet (horrible name).

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

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