VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp@ 109008

Last change on this file since 109008 was 107809, checked in by vboxsync, 3 months ago

VMM: bugref:10759 Don't route setting/clearing of external interrupts via the APIC when no APIC is present.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 15.9 KB
Line 
1/* $Id: PDMDevMiscHlp.cpp 107809 2025-01-16 10:42:42Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_PDM_DEVICE
33#include "PDMInternal.h"
34#include <VBox/vmm/pdm.h>
35#include <VBox/vmm/pgm.h>
36#include <VBox/vmm/hm.h>
37#ifdef VBOX_VMM_TARGET_X86
38# include <VBox/vmm/pdmapic.h>
39#endif
40#include <VBox/vmm/vm.h>
41#include <VBox/vmm/vmm.h>
42
43#include <VBox/log.h>
44#include <VBox/err.h>
45#include <VBox/msi.h>
46#include <iprt/asm.h>
47#include <iprt/assert.h>
48#include <iprt/thread.h>
49
50
51#include "PDMInline.h"
52#include "dtrace/VBoxVMM.h"
53
54
55
56/** @name Ring-3 PIC Helpers
57 * @{
58 */
59
60/** @interface_method_impl{PDMPICHLP,pfnSetInterruptFF} */
61static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
62{
63 PDMDEV_ASSERT_DEVINS(pDevIns);
64 PVM pVM = pDevIns->Internal.s.pVMR3;
65
66 /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
67 Assert(pVM->enmVMState != VMSTATE_LOADING || pVM->pdm.s.fStateLoaded);
68
69#ifdef VBOX_VMM_TARGET_X86
70 PVMCPU pVCpu = pVM->apCpusR3[0]; /* for PIC we always deliver to CPU 0, SMP uses APIC */
71 if (pVM->pdm.s.Ic.pDevInsR3)
72 PDMApicSetLocalInterrupt(pVCpu, 0 /* u8Pin */, 1 /* u8Level */, VINF_SUCCESS /* rcRZ */);
73 else
74 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
75#else
76 AssertReleaseFailed();
77 RT_NOREF(pVM);
78#endif
79}
80
81
82/** @interface_method_impl{PDMPICHLP,pfnClearInterruptFF} */
83static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
84{
85 PDMDEV_ASSERT_DEVINS(pDevIns);
86 PVM pVM = pDevIns->Internal.s.pVMR3;
87
88 /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
89 Assert(pVM->enmVMState != VMSTATE_LOADING || pVM->pdm.s.fStateLoaded);
90
91#ifdef VBOX_VMM_TARGET_X86
92 PVMCPU pVCpu = pVM->apCpusR3[0]; /* for PIC we always deliver to CPU 0, SMP uses APIC */
93 if (pVM->pdm.s.Ic.pDevInsR3)
94 PDMApicSetLocalInterrupt(pVCpu, 0 /* u8Pin */, 0 /* u8Level */, VINF_SUCCESS /* rcRZ */);
95 else
96 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
97#else
98 AssertReleaseFailed();
99 RT_NOREF(pVM);
100#endif
101}
102
103
104/** @interface_method_impl{PDMPICHLP,pfnLock} */
105static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
106{
107 PDMDEV_ASSERT_DEVINS(pDevIns);
108 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
109}
110
111
112/** @interface_method_impl{PDMPICHLP,pfnUnlock} */
113static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
114{
115 PDMDEV_ASSERT_DEVINS(pDevIns);
116 pdmUnlock(pDevIns->Internal.s.pVMR3);
117}
118
119
120/**
121 * PIC Device Helpers.
122 */
123const PDMPICHLP g_pdmR3DevPicHlp =
124{
125 PDM_PICHLP_VERSION,
126 pdmR3PicHlp_SetInterruptFF,
127 pdmR3PicHlp_ClearInterruptFF,
128 pdmR3PicHlp_Lock,
129 pdmR3PicHlp_Unlock,
130 PDM_PICHLP_VERSION /* the end */
131};
132
133/** @} */
134
135
136/** @name Ring-3 I/O APIC Helpers
137 * @{
138 */
139
140/** @interface_method_impl{PDMIOAPICHLP,pfnApicBusDeliver} */
141static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
142 uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
143 uint8_t u8TriggerMode, uint32_t uTagSrc)
144{
145 PDMDEV_ASSERT_DEVINS(pDevIns);
146 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 uVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
147 pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc));
148#ifdef VBOX_VMM_TARGET_X86
149 PVM pVM = pDevIns->Internal.s.pVMR3;
150 return PDMApicBusDeliver(pVM, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
151#else
152 AssertReleaseFailed();
153 RT_NOREF(pDevIns, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
154 return VERR_NOT_IMPLEMENTED;
155#endif
156}
157
158
159/** @interface_method_impl{PDMIOAPICHLP,pfnLock} */
160static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
161{
162 PDMDEV_ASSERT_DEVINS(pDevIns);
163 LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
164 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
165}
166
167
168/** @interface_method_impl{PDMIOAPICHLP,pfnUnlock} */
169static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
170{
171 PDMDEV_ASSERT_DEVINS(pDevIns);
172 LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
173 pdmUnlock(pDevIns->Internal.s.pVMR3);
174}
175
176
177/** @interface_method_impl{PDMIOAPICHLP,pfnLockIsOwner} */
178static DECLCALLBACK(bool) pdmR3IoApicHlp_LockIsOwner(PPDMDEVINS pDevIns)
179{
180 PDMDEV_ASSERT_DEVINS(pDevIns);
181 LogFlow(("pdmR3IoApicHlp_LockIsOwner: caller='%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
182 return pdmLockIsOwner(pDevIns->Internal.s.pVMR3);
183}
184
185
186/** @interface_method_impl{PDMIOAPICHLP,pfnIommuMsiRemap} */
187static DECLCALLBACK(int) pdmR3IoApicHlp_IommuMsiRemap(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut)
188{
189 PDMDEV_ASSERT_DEVINS(pDevIns);
190 LogFlow(("pdmR3IoApicHlp_IommuRemapMsi: caller='%s'/%d: pMsiIn=(%#RX64, %#RU32)\n", pDevIns->pReg->szName,
191 pDevIns->iInstance, pMsiIn->Addr.u64, pMsiIn->Data.u32));
192
193#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
194 if (pdmIommuIsPresent(pDevIns))
195 return pdmIommuMsiRemap(pDevIns, idDevice, pMsiIn, pMsiOut);
196#else
197 RT_NOREF(pDevIns, idDevice, pMsiIn, pMsiOut);
198#endif
199 return VERR_IOMMU_NOT_PRESENT;
200}
201
202
203/**
204 * I/O APIC Device Helpers.
205 */
206const PDMIOAPICHLP g_pdmR3DevIoApicHlp =
207{
208 PDM_IOAPICHLP_VERSION,
209 pdmR3IoApicHlp_ApicBusDeliver,
210 pdmR3IoApicHlp_Lock,
211 pdmR3IoApicHlp_Unlock,
212 pdmR3IoApicHlp_LockIsOwner,
213 pdmR3IoApicHlp_IommuMsiRemap,
214 PDM_IOAPICHLP_VERSION /* the end */
215};
216
217/** @} */
218
219
220
221
222/** @name Ring-3 PCI Bus Helpers
223 * @{
224 */
225
226/** @interface_method_impl{PDMPCIHLPR3,pfnIsaSetIrq} */
227static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
228{
229 PDMDEV_ASSERT_DEVINS(pDevIns);
230 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
231 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
232}
233
234
235/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
236static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc)
237{
238 PDMDEV_ASSERT_DEVINS(pDevIns);
239 Log4(("pdmR3PciHlp_IoApicSetIrq: uBusDevFn=%#x iIrq=%d iLevel=%d uTagSrc=%#x\n", uBusDevFn, iIrq, iLevel, uTagSrc));
240 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, uBusDevFn, iIrq, iLevel, uTagSrc);
241}
242
243
244/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
245static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc)
246{
247 PDMDEV_ASSERT_DEVINS(pDevIns);
248 Assert(PCIBDF_IS_VALID(uBusDevFn));
249 Log4(("pdmR3PciHlp_IoApicSendMsi: uBusDevFn=%#x Msi (Addr=%#RX64 Data=%#x) uTagSrc=%#x\n", uBusDevFn,
250 pMsi->Addr.u64, pMsi->Data.u32, uTagSrc));
251 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, uBusDevFn, pMsi, uTagSrc);
252}
253
254
255/** @interface_method_impl{PDMPCIHLPR3,pfnLock} */
256static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
257{
258 PDMDEV_ASSERT_DEVINS(pDevIns);
259 LogFlow(("pdmR3PciHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
260 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
261}
262
263
264/** @interface_method_impl{PDMPCIHLPR3,pfnUnlock} */
265static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
266{
267 PDMDEV_ASSERT_DEVINS(pDevIns);
268 LogFlow(("pdmR3PciHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
269 pdmUnlock(pDevIns->Internal.s.pVMR3);
270}
271
272
273/** @interface_method_impl{PDMPCIHLPR3,pfnGetBusByNo} */
274static DECLCALLBACK(PPDMDEVINS) pdmR3PciHlp_GetBusByNo(PPDMDEVINS pDevIns, uint32_t idxPdmBus)
275{
276 PDMDEV_ASSERT_DEVINS(pDevIns);
277 PVM pVM = pDevIns->Internal.s.pVMR3;
278 AssertReturn(idxPdmBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses), NULL);
279 PPDMDEVINS pRetDevIns = pVM->pdm.s.aPciBuses[idxPdmBus].pDevInsR3;
280 LogFlow(("pdmR3PciHlp_GetBusByNo: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pRetDevIns));
281 return pRetDevIns;
282}
283
284
285/**
286 * PCI Bus Device Helpers.
287 */
288const PDMPCIHLPR3 g_pdmR3DevPciHlp =
289{
290 PDM_PCIHLPR3_VERSION,
291 pdmR3PciHlp_IsaSetIrq,
292 pdmR3PciHlp_IoApicSetIrq,
293 pdmR3PciHlp_IoApicSendMsi,
294 pdmR3PciHlp_Lock,
295 pdmR3PciHlp_Unlock,
296 pdmR3PciHlp_GetBusByNo,
297 PDM_PCIHLPR3_VERSION, /* the end */
298};
299
300/** @} */
301
302
303/** @name Ring-3 IOMMU Helpers
304 * @{
305 */
306
307/** @interface_method_impl{PDMIOMMUHLPR3,pfnLock} */
308static DECLCALLBACK(int) pdmR3IommuHlp_Lock(PPDMDEVINS pDevIns, int rc)
309{
310 PDMDEV_ASSERT_DEVINS(pDevIns);
311 LogFlowFunc(("caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
312 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
313}
314
315
316/** @interface_method_impl{PDMIOMMUHLPR3,pfnUnlock} */
317static DECLCALLBACK(void) pdmR3IommuHlp_Unlock(PPDMDEVINS pDevIns)
318{
319 PDMDEV_ASSERT_DEVINS(pDevIns);
320 LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
321 pdmUnlock(pDevIns->Internal.s.pVMR3);
322}
323
324
325/** @interface_method_impl{PDMIOMMUHLPR3,pfnLockIsOwner} */
326static DECLCALLBACK(bool) pdmR3IommuHlp_LockIsOwner(PPDMDEVINS pDevIns)
327{
328 PDMDEV_ASSERT_DEVINS(pDevIns);
329 LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
330 return pdmLockIsOwner(pDevIns->Internal.s.pVMR3);
331}
332
333
334/** @interface_method_impl{PDMIOMMUHLPR3,pfnSendMsi} */
335static DECLCALLBACK(void) pdmR3IommuHlp_SendMsi(PPDMDEVINS pDevIns, PCMSIMSG pMsi, uint32_t uTagSrc)
336{
337 PDMDEV_ASSERT_DEVINS(pDevIns);
338 LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
339 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, NIL_PCIBDF, pMsi, uTagSrc);
340}
341
342
343/**
344 * IOMMU Device Helpers.
345 */
346const PDMIOMMUHLPR3 g_pdmR3DevIommuHlp =
347{
348 PDM_IOMMUHLPR3_VERSION,
349 pdmR3IommuHlp_Lock,
350 pdmR3IommuHlp_Unlock,
351 pdmR3IommuHlp_LockIsOwner,
352 pdmR3IommuHlp_SendMsi,
353 PDM_IOMMUHLPR3_VERSION /* the end */
354};
355
356/** @} */
357
358
359/** @name Ring-3 HPET Helpers
360 * @{
361 */
362
363/** @interface_method_impl{PDMHPETHLPR3,pfnSetLegacyMode} */
364static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivated)
365{
366 PDMDEV_ASSERT_DEVINS(pDevIns);
367 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivated=%RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance, fActivated));
368
369 size_t i;
370 int rc = VINF_SUCCESS;
371 static const char * const s_apszDevsToNotify[] =
372 {
373 "i8254",
374 "mc146818"
375 };
376 for (i = 0; i < RT_ELEMENTS(s_apszDevsToNotify); i++)
377 {
378 PPDMIBASE pBase;
379 rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3->pUVM, "i8254", 0, &pBase);
380 if (RT_SUCCESS(rc))
381 {
382 PPDMIHPETLEGACYNOTIFY pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHPETLEGACYNOTIFY);
383 AssertLogRelMsgBreakStmt(pPort, ("%s\n", s_apszDevsToNotify[i]), rc = VERR_PDM_HPET_LEGACY_NOTIFY_MISSING);
384 pPort->pfnModeChanged(pPort, fActivated);
385 }
386 else if ( rc == VERR_PDM_DEVICE_NOT_FOUND
387 || rc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
388 rc = VINF_SUCCESS; /* the device isn't configured, ignore. */
389 else
390 AssertLogRelMsgFailedBreak(("%s -> %Rrc\n", s_apszDevsToNotify[i], rc));
391 }
392
393 /* Don't bother cleaning up, any failure here will cause a guru meditation. */
394
395 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
396 return rc;
397}
398
399
400/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
401static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
402{
403 PDMDEV_ASSERT_DEVINS(pDevIns);
404 LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
405 PVM pVM = pDevIns->Internal.s.pVMR3;
406
407 pdmLock(pVM);
408 uint32_t uTagSrc;
409 if (iLevel & PDM_IRQ_LEVEL_HIGH)
410 {
411 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
412 if (iLevel == PDM_IRQ_LEVEL_HIGH)
413 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
414 else
415 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
416 }
417 else
418 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
419
420 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
421
422 if (iLevel == PDM_IRQ_LEVEL_LOW)
423 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
424 pdmUnlock(pVM);
425 return 0;
426}
427
428
429/**
430 * HPET Device Helpers.
431 */
432const PDMHPETHLPR3 g_pdmR3DevHpetHlp =
433{
434 PDM_HPETHLPR3_VERSION,
435 pdmR3HpetHlp_SetLegacyMode,
436 pdmR3HpetHlp_SetIrq,
437 PDM_HPETHLPR3_VERSION, /* the end */
438};
439
440/** @} */
441
442
443/** @name Ring-3 Raw PCI Device Helpers
444 * @{
445 */
446
447/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
448static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
449{
450 PDMDEV_ASSERT_DEVINS(pDevIns);
451 PVM pVM = pDevIns->Internal.s.pVMR3;
452 VM_ASSERT_EMT(pVM);
453
454 RTRCPTR pRCHelpers = NIL_RTRCPTR;
455#if 0
456 if (VM_IS_RAW_MODE_ENABLED(pVM))
457 {
458 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
459 AssertReleaseRC(rc);
460 AssertRelease(pRCHelpers);
461 }
462#else
463 RT_NOREF(pVM, pDevIns);
464#endif
465
466 LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
467 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
468 return pRCHelpers;
469}
470
471
472/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
473static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
474{
475 PDMDEV_ASSERT_DEVINS(pDevIns);
476 PVM pVM = pDevIns->Internal.s.pVMR3;
477 VM_ASSERT_EMT(pVM);
478 PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
479 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
480 AssertReleaseRC(rc);
481 AssertRelease(pR0Helpers);
482 LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
483 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
484 return pR0Helpers;
485}
486
487
488/**
489 * Raw PCI Device Helpers.
490 */
491const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
492{
493 PDM_PCIRAWHLPR3_VERSION,
494 pdmR3PciRawHlp_GetRCHelpers,
495 pdmR3PciRawHlp_GetR0Helpers,
496 PDM_PCIRAWHLPR3_VERSION, /* the end */
497};
498
499/** @} */
500
501
502/* none yet */
503
504/**
505 * Firmware Device Helpers.
506 */
507const PDMFWHLPR3 g_pdmR3DevFirmwareHlp =
508{
509 PDM_FWHLPR3_VERSION,
510 PDM_FWHLPR3_VERSION
511};
512
513/**
514 * DMAC Device Helpers.
515 */
516const PDMDMACHLP g_pdmR3DevDmacHlp =
517{
518 PDM_DMACHLP_VERSION
519};
520
521
522
523
524/* none yet */
525
526/**
527 * RTC Device Helpers.
528 */
529const PDMRTCHLP g_pdmR3DevRtcHlp =
530{
531 PDM_RTCHLP_VERSION
532};
533
Note: See TracBrowser for help on using the repository browser.

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