VirtualBox

Ignore:
Timestamp:
Apr 27, 2020 1:23:11 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137575
Message:

VMMR0: Move the PDM R0 device helper into its own file like it is done in R3, move the PDM R0 driver helpers to PDMR0Driver as it belongs there really

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r83941 r84007  
    6060extern DECLEXPORT(const PDMHPETHLPR0)   g_pdmR0HpetHlp;
    6161extern DECLEXPORT(const PDMPCIRAWHLPR0) g_pdmR0PciRawHlp;
    62 extern DECLEXPORT(const PDMDRVHLPR0)    g_pdmR0DrvHlp;
    6362RT_C_DECLS_END
    6463
     
    9190*   Internal Functions                                                                                                           *
    9291*********************************************************************************************************************************/
    93 static bool pdmR0IsaSetIrq(PGVM pGVM, int iIrq, int iLevel, uint32_t uTagSrc);
    9492
    9593
     
    184182            pdmR0DeviceDestroy(pGVM, pDevIns, i);
    185183    }
    186 }
    187 
    188 
    189 /** @name Ring-0 Device Helpers
    190  * @{
    191  */
    192 
    193 /** @interface_method_impl{PDMDEVHLPR0,pfnIoPortSetUpContextEx} */
    194 static DECLCALLBACK(int) pdmR0DevHlp_IoPortSetUpContextEx(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
    195                                                           PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
    196                                                           PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr,
    197                                                           void *pvUser)
    198 {
    199     PDMDEV_ASSERT_DEVINS(pDevIns);
    200     LogFlow(("pdmR0DevHlp_IoPortSetUpContextEx: caller='%s'/%d: hIoPorts=%#x pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p pvUser=%p\n",
    201              pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser));
    202     PGVM pGVM = pDevIns->Internal.s.pGVM;
    203     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    204     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
    205 
    206     int rc = IOMR0IoPortSetUpContext(pGVM, pDevIns, hIoPorts, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser);
    207 
    208     LogFlow(("pdmR0DevHlp_IoPortSetUpContextEx: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    209     return rc;
    210 }
    211 
    212 
    213 /** @interface_method_impl{PDMDEVHLPR0,pfnMmioSetUpContextEx} */
    214 static DECLCALLBACK(int) pdmR0DevHlp_MmioSetUpContextEx(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
    215                                                         PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser)
    216 {
    217     PDMDEV_ASSERT_DEVINS(pDevIns);
    218     LogFlow(("pdmR0DevHlp_MmioSetUpContextEx: caller='%s'/%d: hRegion=%#x pfnWrite=%p pfnRead=%p pfnFill=%p pvUser=%p\n",
    219              pDevIns->pReg->szName, pDevIns->iInstance, hRegion, pfnWrite, pfnRead, pfnFill, pvUser));
    220     PGVM pGVM = pDevIns->Internal.s.pGVM;
    221     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    222     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
    223 
    224     int rc = IOMR0MmioSetUpContext(pGVM, pDevIns, hRegion, pfnWrite, pfnRead, pfnFill, pvUser);
    225 
    226     LogFlow(("pdmR0DevHlp_MmioSetUpContextEx: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    227     return rc;
    228 }
    229 
    230 
    231 /** @interface_method_impl{PDMDEVHLPR0,pfnMmio2SetUpContext} */
    232 static DECLCALLBACK(int) pdmR0DevHlp_Mmio2SetUpContext(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion,
    233                                                        size_t offSub, size_t cbSub, void **ppvMapping)
    234 {
    235     PDMDEV_ASSERT_DEVINS(pDevIns);
    236     LogFlow(("pdmR0DevHlp_Mmio2SetUpContext: caller='%s'/%d: hRegion=%#x offSub=%#zx cbSub=%#zx ppvMapping=%p\n",
    237              pDevIns->pReg->szName, pDevIns->iInstance, hRegion, offSub, cbSub, ppvMapping));
    238     *ppvMapping = NULL;
    239 
    240     PGVM pGVM = pDevIns->Internal.s.pGVM;
    241     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    242     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
    243 
    244     int rc = PGMR0PhysMMIO2MapKernel(pGVM, pDevIns, hRegion, offSub, cbSub, ppvMapping);
    245 
    246     LogFlow(("pdmR0DevHlp_Mmio2SetUpContext: caller='%s'/%d: returns %Rrc (%p)\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *ppvMapping));
    247     return rc;
    248 }
    249 
    250 
    251 /** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysRead} */
    252 static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
    253                                                  void *pvBuf, size_t cbRead)
    254 {
    255     PDMDEV_ASSERT_DEVINS(pDevIns);
    256     if (!pPciDev) /* NULL is an alias for the default PCI device. */
    257         pPciDev = pDevIns->apPciDevs[0];
    258     AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
    259     PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
    260 
    261 #ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
    262     /*
    263      * Just check the busmaster setting here and forward the request to the generic read helper.
    264      */
    265     if (PCIDevIsBusmaster(pPciDev))
    266     { /* likely */ }
    267     else
    268     {
    269         Log(("pdmRCDevHlp_PCIPhysRead: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n",
    270              pDevIns, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbRead));
    271         memset(pvBuf, 0xff, cbRead);
    272         return VERR_PDM_NOT_PCI_BUS_MASTER;
    273     }
    274 #endif
    275 
    276 #ifdef VBOX_WITH_IOMMU_AMD
    277     /** @todo IOMMU: Optimize/re-organize things here later. */
    278     PGVM        pGVM         = pDevIns->Internal.s.pGVM;
    279     PPDMIOMMUR0 pIommu       = &pGVM->pdmr0.s.aIommus[0];
    280     PPDMDEVINS  pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    281     if (   pDevInsIommu
    282         && pDevInsIommu != pDevIns)
    283     {
    284         RTGCPHYS GCPhysOut;
    285         uint16_t const uDeviceId = VBOX_PCI_BUSDEVFN_MAKE(pPciDev->Int.s.idxPdmBus, pPciDev->uDevFn);
    286         int rc = pIommu->pfnMemRead(pDevInsIommu, uDeviceId, GCPhys, cbRead, &GCPhysOut);
    287         if (RT_FAILURE(rc))
    288         {
    289             Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
    290                  GCPhys, cbRead, rc));
    291             return rc;
    292         }
    293     }
    294 #endif
    295 
    296     return pDevIns->pHlpR0->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
    297 }
    298 
    299 
    300 /** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysWrite} */
    301 static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
    302                                                   const void *pvBuf, size_t cbWrite)
    303 {
    304     PDMDEV_ASSERT_DEVINS(pDevIns);
    305     if (!pPciDev) /* NULL is an alias for the default PCI device. */
    306         pPciDev = pDevIns->apPciDevs[0];
    307     AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
    308     PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
    309 
    310 #ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
    311     /*
    312      * Just check the busmaster setting here and forward the request to the generic read helper.
    313      */
    314     if (PCIDevIsBusmaster(pPciDev))
    315     { /* likely */ }
    316     else
    317     {
    318         Log(("pdmRCDevHlp_PCIPhysWrite: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
    319              pDevIns, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbWrite));
    320         return VERR_PDM_NOT_PCI_BUS_MASTER;
    321     }
    322 #endif
    323 
    324 #ifdef VBOX_WITH_IOMMU_AMD
    325     /** @todo IOMMU: Optimize/re-organize things here later. */
    326     PGVM        pGVM          = pDevIns->Internal.s.pGVM;
    327     PPDMIOMMUR0 pIommu        = &pGVM->pdmr0.s.aIommus[0];
    328     PPDMDEVINS   pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    329     if (   pDevInsIommu
    330         && pDevInsIommu != pDevIns)
    331     {
    332         RTGCPHYS GCPhysOut;
    333         uint16_t const uDeviceId = VBOX_PCI_BUSDEVFN_MAKE(pPciDev->Int.s.idxPdmBus, pPciDev->uDevFn);
    334         int rc = pIommu->pfnMemWrite(pDevInsIommu, uDeviceId, GCPhys, cbWrite, &GCPhysOut);
    335         if (RT_FAILURE(rc))
    336         {
    337             Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
    338                  GCPhys, cbWrite, rc));
    339             return rc;
    340         }
    341     }
    342 #endif
    343 
    344     return pDevIns->pHlpR0->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
    345 }
    346 
    347 
    348 /** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */
    349 static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
    350 {
    351     PDMDEV_ASSERT_DEVINS(pDevIns);
    352     if (!pPciDev) /* NULL is an alias for the default PCI device. */
    353         pPciDev = pDevIns->apPciDevs[0];
    354     AssertReturnVoid(pPciDev);
    355     LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
    356              pDevIns, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iIrq, iLevel));
    357     PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
    358 
    359     PGVM         pGVM      = pDevIns->Internal.s.pGVM;
    360     size_t const idxBus    = pPciDev->Int.s.idxPdmBus;
    361     AssertReturnVoid(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses));
    362     PPDMPCIBUSR0 pPciBusR0 = &pGVM->pdmr0.s.aPciBuses[idxBus];
    363 
    364     pdmLock(pGVM);
    365 
    366     uint32_t uTagSrc;
    367     if (iLevel & PDM_IRQ_LEVEL_HIGH)
    368     {
    369         pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
    370         if (iLevel == PDM_IRQ_LEVEL_HIGH)
    371             VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    372         else
    373             VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    374     }
    375     else
    376         uTagSrc = pDevIns->Internal.s.pIntR3R0->uLastIrqTag;
    377 
    378     if (pPciBusR0->pDevInsR0)
    379     {
    380         pPciBusR0->pfnSetIrqR0(pPciBusR0->pDevInsR0, pPciDev, iIrq, iLevel, uTagSrc);
    381 
    382         pdmUnlock(pGVM);
    383 
    384         if (iLevel == PDM_IRQ_LEVEL_LOW)
    385             VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    386     }
    387     else
    388     {
    389         pdmUnlock(pGVM);
    390 
    391         /* queue for ring-3 execution. */
    392         PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pGVM->pdm.s.pDevHlpQueueR0);
    393         AssertReturnVoid(pTask);
    394 
    395         pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
    396         pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
    397         pTask->u.PciSetIRQ.iIrq = iIrq;
    398         pTask->u.PciSetIRQ.iLevel = iLevel;
    399         pTask->u.PciSetIRQ.uTagSrc = uTagSrc;
    400         pTask->u.PciSetIRQ.pPciDevR3 = MMHyperR0ToR3(pGVM, pPciDev);
    401 
    402         PDMQueueInsertEx(pGVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
    403     }
    404 
    405     LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
    406 }
    407 
    408 
    409 /** @interface_method_impl{PDMDEVHLPR0,pfnISASetIrq} */
    410 static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    411 {
    412     PDMDEV_ASSERT_DEVINS(pDevIns);
    413     LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
    414     PGVM pGVM = pDevIns->Internal.s.pGVM;
    415 
    416     pdmLock(pGVM);
    417     uint32_t uTagSrc;
    418     if (iLevel & PDM_IRQ_LEVEL_HIGH)
    419     {
    420         pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
    421         if (iLevel == PDM_IRQ_LEVEL_HIGH)
    422             VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    423         else
    424             VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    425     }
    426     else
    427         uTagSrc = pDevIns->Internal.s.pIntR3R0->uLastIrqTag;
    428 
    429     bool fRc = pdmR0IsaSetIrq(pGVM, iIrq, iLevel, uTagSrc);
    430 
    431     if (iLevel == PDM_IRQ_LEVEL_LOW && fRc)
    432         VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    433     pdmUnlock(pGVM);
    434     LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
    435 }
    436 
    437 
    438 /** @interface_method_impl{PDMDEVHLPR0,pfnIoApicSendMsi} */
    439 static DECLCALLBACK(void) pdmR0DevHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
    440 {
    441     PDMDEV_ASSERT_DEVINS(pDevIns);
    442     LogFlow(("pdmR0DevHlp_IoApicSendMsi: caller=%p/%d: GCPhys=%RGp uValue=%#x\n", pDevIns, pDevIns->iInstance, GCPhys, uValue));
    443     PGVM pGVM = pDevIns->Internal.s.pGVM;
    444 
    445     uint32_t uTagSrc;
    446     pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
    447     VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    448 
    449     if (pGVM->pdm.s.IoApic.pDevInsR0)
    450         pGVM->pdm.s.IoApic.pfnSendMsiR0(pGVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc);
    451     else
    452         AssertFatalMsgFailed(("Lazy bastards!"));
    453 
    454     LogFlow(("pdmR0DevHlp_IoApicSendMsi: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
    455 }
    456 
    457 
    458 /** @interface_method_impl{PDMDEVHLPR0,pfnPhysRead} */
    459 static DECLCALLBACK(int) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
    460 {
    461     PDMDEV_ASSERT_DEVINS(pDevIns);
    462     LogFlow(("pdmR0DevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
    463              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
    464 
    465     VBOXSTRICTRC rcStrict = PGMPhysRead(pDevIns->Internal.s.pGVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
    466     AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
    467 
    468     Log(("pdmR0DevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
    469     return VBOXSTRICTRC_VAL(rcStrict);
    470 }
    471 
    472 
    473 /** @interface_method_impl{PDMDEVHLPR0,pfnPhysWrite} */
    474 static DECLCALLBACK(int) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
    475 {
    476     PDMDEV_ASSERT_DEVINS(pDevIns);
    477     LogFlow(("pdmR0DevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
    478              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
    479 
    480     VBOXSTRICTRC rcStrict = PGMPhysWrite(pDevIns->Internal.s.pGVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
    481     AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
    482 
    483     Log(("pdmR0DevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
    484     return VBOXSTRICTRC_VAL(rcStrict);
    485 }
    486 
    487 
    488 /** @interface_method_impl{PDMDEVHLPR0,pfnA20IsEnabled} */
    489 static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
    490 {
    491     PDMDEV_ASSERT_DEVINS(pDevIns);
    492     LogFlow(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
    493 
    494     bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pGVM));
    495 
    496     Log(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
    497     return fEnabled;
    498 }
    499 
    500 
    501 /** @interface_method_impl{PDMDEVHLPR0,pfnVMState} */
    502 static DECLCALLBACK(VMSTATE) pdmR0DevHlp_VMState(PPDMDEVINS pDevIns)
    503 {
    504     PDMDEV_ASSERT_DEVINS(pDevIns);
    505 
    506     VMSTATE enmVMState = pDevIns->Internal.s.pGVM->enmVMState;
    507 
    508     LogFlow(("pdmR0DevHlp_VMState: caller=%p/%d: returns %d\n", pDevIns, pDevIns->iInstance, enmVMState));
    509     return enmVMState;
    510 }
    511 
    512 
    513 /** @interface_method_impl{PDMDEVHLPR0,pfnVMSetError} */
    514 static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
    515 {
    516     PDMDEV_ASSERT_DEVINS(pDevIns);
    517     va_list args;
    518     va_start(args, pszFormat);
    519     int rc2 = VMSetErrorV(pDevIns->Internal.s.pGVM, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
    520     va_end(args);
    521     return rc;
    522 }
    523 
    524 
    525 /** @interface_method_impl{PDMDEVHLPR0,pfnVMSetErrorV} */
    526 static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
    527 {
    528     PDMDEV_ASSERT_DEVINS(pDevIns);
    529     int rc2 = VMSetErrorV(pDevIns->Internal.s.pGVM, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
    530     return rc;
    531 }
    532 
    533 
    534 /** @interface_method_impl{PDMDEVHLPR0,pfnVMSetRuntimeError} */
    535 static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
    536 {
    537     PDMDEV_ASSERT_DEVINS(pDevIns);
    538     va_list va;
    539     va_start(va, pszFormat);
    540     int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pGVM, fFlags, pszErrorId, pszFormat, va);
    541     va_end(va);
    542     return rc;
    543 }
    544 
    545 
    546 /** @interface_method_impl{PDMDEVHLPR0,pfnVMSetRuntimeErrorV} */
    547 static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
    548 {
    549     PDMDEV_ASSERT_DEVINS(pDevIns);
    550     int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pGVM, fFlags, pszErrorId, pszFormat, va);
    551     return rc;
    552 }
    553 
    554 
    555 
    556 /** @interface_method_impl{PDMDEVHLPR0,pfnGetVM} */
    557 static DECLCALLBACK(PVMCC)  pdmR0DevHlp_GetVM(PPDMDEVINS pDevIns)
    558 {
    559     PDMDEV_ASSERT_DEVINS(pDevIns);
    560     LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    561     return pDevIns->Internal.s.pGVM;
    562 }
    563 
    564 
    565 /** @interface_method_impl{PDMDEVHLPR0,pfnGetVMCPU} */
    566 static DECLCALLBACK(PVMCPUCC) pdmR0DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
    567 {
    568     PDMDEV_ASSERT_DEVINS(pDevIns);
    569     LogFlow(("pdmR0DevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    570     return VMMGetCpu(pDevIns->Internal.s.pGVM);
    571 }
    572 
    573 
    574 /** @interface_method_impl{PDMDEVHLPRC,pfnGetCurrentCpuId} */
    575 static DECLCALLBACK(VMCPUID) pdmR0DevHlp_GetCurrentCpuId(PPDMDEVINS pDevIns)
    576 {
    577     PDMDEV_ASSERT_DEVINS(pDevIns);
    578     VMCPUID idCpu = VMMGetCpuId(pDevIns->Internal.s.pGVM);
    579     LogFlow(("pdmR0DevHlp_GetCurrentCpuId: caller='%p'/%d for CPU %u\n", pDevIns, pDevIns->iInstance, idCpu));
    580     return idCpu;
    581 }
    582 
    583 
    584 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerToPtr} */
    585 static DECLCALLBACK(PTMTIMERR0) pdmR0DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    586 {
    587     PDMDEV_ASSERT_DEVINS(pDevIns);
    588     RT_NOREF(pDevIns);
    589     return (PTMTIMERR0)MMHyperR3ToCC(pDevIns->Internal.s.pGVM, hTimer);
    590 }
    591 
    592 
    593 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerFromMicro} */
    594 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
    595 {
    596     return TMTimerFromMicro(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMicroSecs);
    597 }
    598 
    599 
    600 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerFromMilli} */
    601 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromMilli(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
    602 {
    603     return TMTimerFromMilli(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMilliSecs);
    604 }
    605 
    606 
    607 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerFromNano} */
    608 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
    609 {
    610     return TMTimerFromNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cNanoSecs);
    611 }
    612 
    613 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerGet} */
    614 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    615 {
    616     return TMTimerGet(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    617 }
    618 
    619 
    620 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerGetFreq} */
    621 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    622 {
    623     return TMTimerGetFreq(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    624 }
    625 
    626 
    627 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerGetNano} */
    628 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    629 {
    630     return TMTimerGetNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    631 }
    632 
    633 
    634 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerIsActive} */
    635 static DECLCALLBACK(bool) pdmR0DevHlp_TimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    636 {
    637     return TMTimerIsActive(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    638 }
    639 
    640 
    641 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerIsLockOwner} */
    642 static DECLCALLBACK(bool) pdmR0DevHlp_TimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    643 {
    644     return TMTimerIsLockOwner(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    645 }
    646 
    647 
    648 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerLockClock} */
    649 static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlp_TimerLockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
    650 {
    651     return TMTimerLock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
    652 }
    653 
    654 
    655 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerLockClock2} */
    656 static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlp_TimerLockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer,
    657                                                               PPDMCRITSECT pCritSect, int rcBusy)
    658 {
    659     VBOXSTRICTRC rc = TMTimerLock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
    660     if (rc == VINF_SUCCESS)
    661     {
    662         rc = PDMCritSectEnter(pCritSect, rcBusy);
    663         if (rc == VINF_SUCCESS)
    664             return rc;
    665         AssertRC(VBOXSTRICTRC_VAL(rc));
    666         TMTimerUnlock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    667     }
    668     else
    669         AssertRC(VBOXSTRICTRC_VAL(rc));
    670     return rc;
    671 }
    672 
    673 
    674 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerSet} */
    675 static DECLCALLBACK(int) pdmR0DevHlp_TimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
    676 {
    677     return TMTimerSet(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), uExpire);
    678 }
    679 
    680 
    681 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetFrequencyHint} */
    682 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
    683 {
    684     return TMTimerSetFrequencyHint(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), uHz);
    685 }
    686 
    687 
    688 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetMicro} */
    689 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
    690 {
    691     return TMTimerSetMicro(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMicrosToNext);
    692 }
    693 
    694 
    695 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetMillies} */
    696 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
    697 {
    698     return TMTimerSetMillies(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMilliesToNext);
    699 }
    700 
    701 
    702 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetNano} */
    703 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
    704 {
    705     return TMTimerSetNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cNanosToNext);
    706 }
    707 
    708 
    709 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetRelative} */
    710 static DECLCALLBACK(int) pdmR0DevHlp_TimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
    711 {
    712     return TMTimerSetRelative(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cTicksToNext, pu64Now);
    713 }
    714 
    715 
    716 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerStop} */
    717 static DECLCALLBACK(int) pdmR0DevHlp_TimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    718 {
    719     return TMTimerStop(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    720 }
    721 
    722 
    723 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerUnlockClock} */
    724 static DECLCALLBACK(void) pdmR0DevHlp_TimerUnlockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
    725 {
    726     TMTimerUnlock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    727 }
    728 
    729 
    730 /** @interface_method_impl{PDMDEVHLPR0,pfnTimerUnlockClock2} */
    731 static DECLCALLBACK(void) pdmR0DevHlp_TimerUnlockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
    732 {
    733     TMTimerUnlock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
    734     int rc = PDMCritSectLeave(pCritSect);
    735     AssertRC(rc);
    736 }
    737 
    738 
    739 /** @interface_method_impl{PDMDEVHLPR0,pfnTMTimeVirtGet} */
    740 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TMTimeVirtGet(PPDMDEVINS pDevIns)
    741 {
    742     PDMDEV_ASSERT_DEVINS(pDevIns);
    743     LogFlow(("pdmR0DevHlp_TMTimeVirtGet: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    744     return TMVirtualGet(pDevIns->Internal.s.pGVM);
    745 }
    746 
    747 
    748 /** @interface_method_impl{PDMDEVHLPR0,pfnTMTimeVirtGetFreq} */
    749 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TMTimeVirtGetFreq(PPDMDEVINS pDevIns)
    750 {
    751     PDMDEV_ASSERT_DEVINS(pDevIns);
    752     LogFlow(("pdmR0DevHlp_TMTimeVirtGetFreq: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    753     return TMVirtualGetFreq(pDevIns->Internal.s.pGVM);
    754 }
    755 
    756 
    757 /** @interface_method_impl{PDMDEVHLPR0,pfnTMTimeVirtGetNano} */
    758 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TMTimeVirtGetNano(PPDMDEVINS pDevIns)
    759 {
    760     PDMDEV_ASSERT_DEVINS(pDevIns);
    761     LogFlow(("pdmR0DevHlp_TMTimeVirtGetNano: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    762     return TMVirtualToNano(pDevIns->Internal.s.pGVM, TMVirtualGet(pDevIns->Internal.s.pGVM));
    763 }
    764 
    765 
    766 /** @interface_method_impl{PDMDEVHLPR0,pfnQueueToPtr} */
    767 static DECLCALLBACK(PPDMQUEUE)  pdmR0DevHlp_QueueToPtr(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
    768 {
    769     PDMDEV_ASSERT_DEVINS(pDevIns);
    770     RT_NOREF(pDevIns);
    771     return (PPDMQUEUE)MMHyperR3ToCC(pDevIns->Internal.s.pGVM, hQueue);
    772 }
    773 
    774 
    775 /** @interface_method_impl{PDMDEVHLPR0,pfnQueueAlloc} */
    776 static DECLCALLBACK(PPDMQUEUEITEMCORE) pdmR0DevHlp_QueueAlloc(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
    777 {
    778     return PDMQueueAlloc(pdmR0DevHlp_QueueToPtr(pDevIns, hQueue));
    779 }
    780 
    781 
    782 /** @interface_method_impl{PDMDEVHLPR0,pfnQueueInsert} */
    783 static DECLCALLBACK(void) pdmR0DevHlp_QueueInsert(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue, PPDMQUEUEITEMCORE pItem)
    784 {
    785     return PDMQueueInsert(pdmR0DevHlp_QueueToPtr(pDevIns, hQueue), pItem);
    786 }
    787 
    788 
    789 /** @interface_method_impl{PDMDEVHLPR0,pfnQueueInsertEx} */
    790 static DECLCALLBACK(void) pdmR0DevHlp_QueueInsertEx(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue, PPDMQUEUEITEMCORE pItem,
    791                                                     uint64_t cNanoMaxDelay)
    792 {
    793     return PDMQueueInsertEx(pdmR0DevHlp_QueueToPtr(pDevIns, hQueue), pItem, cNanoMaxDelay);
    794 }
    795 
    796 
    797 /** @interface_method_impl{PDMDEVHLPR0,pfnQueueFlushIfNecessary} */
    798 static DECLCALLBACK(bool) pdmR0DevHlp_QueueFlushIfNecessary(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
    799 {
    800     return PDMQueueFlushIfNecessary(pdmR0DevHlp_QueueToPtr(pDevIns, hQueue));
    801 }
    802 
    803 
    804 /** @interface_method_impl{PDMDEVHLPR0,pfnTaskTrigger} */
    805 static DECLCALLBACK(int) pdmR0DevHlp_TaskTrigger(PPDMDEVINS pDevIns, PDMTASKHANDLE hTask)
    806 {
    807     PDMDEV_ASSERT_DEVINS(pDevIns);
    808     LogFlow(("pdmR0DevHlp_TaskTrigger: caller='%s'/%d: hTask=%RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, hTask));
    809 
    810     int rc = PDMTaskTrigger(pDevIns->Internal.s.pGVM, PDMTASKTYPE_DEV, pDevIns->pDevInsForR3, hTask);
    811 
    812     LogFlow(("pdmR0DevHlp_TaskTrigger: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    813     return rc;
    814 }
    815 
    816 
    817 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventSignal} */
    818 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventSignal(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent)
    819 {
    820     PDMDEV_ASSERT_DEVINS(pDevIns);
    821     LogFlow(("pdmR0DevHlp_SUPSemEventSignal: caller='%s'/%d: hEvent=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEvent));
    822 
    823     int rc = SUPSemEventSignal(pDevIns->Internal.s.pGVM->pSession, hEvent);
    824 
    825     LogFlow(("pdmR0DevHlp_SUPSemEventSignal: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    826     return rc;
    827 }
    828 
    829 
    830 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventWaitNoResume} */
    831 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint32_t cMillies)
    832 {
    833     PDMDEV_ASSERT_DEVINS(pDevIns);
    834     LogFlow(("pdmR0DevHlp_SUPSemEventWaitNoResume: caller='%s'/%d: hEvent=%p cNsTimeout=%RU32\n",
    835              pDevIns->pReg->szName, pDevIns->iInstance, hEvent, cMillies));
    836 
    837     int rc = SUPSemEventWaitNoResume(pDevIns->Internal.s.pGVM->pSession, hEvent, cMillies);
    838 
    839     LogFlow(("pdmR0DevHlp_SUPSemEventWaitNoResume: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    840     return rc;
    841 }
    842 
    843 
    844 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventWaitNsAbsIntr} */
    845 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t uNsTimeout)
    846 {
    847     PDMDEV_ASSERT_DEVINS(pDevIns);
    848     LogFlow(("pdmR0DevHlp_SUPSemEventWaitNsAbsIntr: caller='%s'/%d: hEvent=%p uNsTimeout=%RU64\n",
    849              pDevIns->pReg->szName, pDevIns->iInstance, hEvent, uNsTimeout));
    850 
    851     int rc = SUPSemEventWaitNsAbsIntr(pDevIns->Internal.s.pGVM->pSession, hEvent, uNsTimeout);
    852 
    853     LogFlow(("pdmR0DevHlp_SUPSemEventWaitNsAbsIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    854     return rc;
    855 }
    856 
    857 
    858 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventWaitNsRelIntr} */
    859 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t cNsTimeout)
    860 {
    861     PDMDEV_ASSERT_DEVINS(pDevIns);
    862     LogFlow(("pdmR0DevHlp_SUPSemEventWaitNsRelIntr: caller='%s'/%d: hEvent=%p cNsTimeout=%RU64\n",
    863              pDevIns->pReg->szName, pDevIns->iInstance, hEvent, cNsTimeout));
    864 
    865     int rc = SUPSemEventWaitNsRelIntr(pDevIns->Internal.s.pGVM->pSession, hEvent, cNsTimeout);
    866 
    867     LogFlow(("pdmR0DevHlp_SUPSemEventWaitNsRelIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    868     return rc;
    869 }
    870 
    871 
    872 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventGetResolution} */
    873 static DECLCALLBACK(uint32_t) pdmR0DevHlp_SUPSemEventGetResolution(PPDMDEVINS pDevIns)
    874 {
    875     PDMDEV_ASSERT_DEVINS(pDevIns);
    876     LogFlow(("pdmR0DevHlp_SUPSemEventGetResolution: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
    877 
    878     uint32_t cNsResolution = SUPSemEventGetResolution(pDevIns->Internal.s.pGVM->pSession);
    879 
    880     LogFlow(("pdmR0DevHlp_SUPSemEventGetResolution: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, cNsResolution));
    881     return cNsResolution;
    882 }
    883 
    884 
    885 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventMultiSignal} */
    886 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventMultiSignal(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
    887 {
    888     PDMDEV_ASSERT_DEVINS(pDevIns);
    889     LogFlow(("pdmR0DevHlp_SUPSemEventMultiSignal: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
    890 
    891     int rc = SUPSemEventMultiSignal(pDevIns->Internal.s.pGVM->pSession, hEventMulti);
    892 
    893     LogFlow(("pdmR0DevHlp_SUPSemEventMultiSignal: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    894     return rc;
    895 }
    896 
    897 
    898 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventMultiReset} */
    899 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventMultiReset(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
    900 {
    901     PDMDEV_ASSERT_DEVINS(pDevIns);
    902     LogFlow(("pdmR0DevHlp_SUPSemEventMultiReset: caller='%s'/%d: hEventMulti=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti));
    903 
    904     int rc = SUPSemEventMultiReset(pDevIns->Internal.s.pGVM->pSession, hEventMulti);
    905 
    906     LogFlow(("pdmR0DevHlp_SUPSemEventMultiReset: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    907     return rc;
    908 }
    909 
    910 
    911 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventMultiWaitNoResume} */
    912 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventMultiWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
    913                                                                   uint32_t cMillies)
    914 {
    915     PDMDEV_ASSERT_DEVINS(pDevIns);
    916     LogFlow(("pdmR0DevHlp_SUPSemEventMultiWaitNoResume: caller='%s'/%d: hEventMulti=%p cMillies=%RU32\n",
    917              pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, cMillies));
    918 
    919     int rc = SUPSemEventMultiWaitNoResume(pDevIns->Internal.s.pGVM->pSession, hEventMulti, cMillies);
    920 
    921     LogFlow(("pdmR0DevHlp_SUPSemEventMultiWaitNoResume: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    922     return rc;
    923 }
    924 
    925 
    926 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventMultiWaitNsAbsIntr} */
    927 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventMultiWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
    928                                                                    uint64_t uNsTimeout)
    929 {
    930     PDMDEV_ASSERT_DEVINS(pDevIns);
    931     LogFlow(("pdmR0DevHlp_SUPSemEventMultiWaitNsAbsIntr: caller='%s'/%d: hEventMulti=%p uNsTimeout=%RU64\n",
    932              pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, uNsTimeout));
    933 
    934     int rc = SUPSemEventMultiWaitNsAbsIntr(pDevIns->Internal.s.pGVM->pSession, hEventMulti, uNsTimeout);
    935 
    936     LogFlow(("pdmR0DevHlp_SUPSemEventMultiWaitNsAbsIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    937     return rc;
    938 }
    939 
    940 
    941 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventMultiWaitNsRelIntr} */
    942 static DECLCALLBACK(int) pdmR0DevHlp_SUPSemEventMultiWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti,
    943                                                                    uint64_t cNsTimeout)
    944 {
    945     PDMDEV_ASSERT_DEVINS(pDevIns);
    946     LogFlow(("pdmR0DevHlp_SUPSemEventMultiWaitNsRelIntr: caller='%s'/%d: hEventMulti=%p cNsTimeout=%RU64\n",
    947              pDevIns->pReg->szName, pDevIns->iInstance, hEventMulti, cNsTimeout));
    948 
    949     int rc = SUPSemEventMultiWaitNsRelIntr(pDevIns->Internal.s.pGVM->pSession, hEventMulti, cNsTimeout);
    950 
    951     LogFlow(("pdmR0DevHlp_SUPSemEventMultiWaitNsRelIntr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    952     return rc;
    953 }
    954 
    955 
    956 /** @interface_method_impl{PDMDEVHLPR0,pfnSUPSemEventMultiGetResolution} */
    957 static DECLCALLBACK(uint32_t) pdmR0DevHlp_SUPSemEventMultiGetResolution(PPDMDEVINS pDevIns)
    958 {
    959     PDMDEV_ASSERT_DEVINS(pDevIns);
    960     LogFlow(("pdmR0DevHlp_SUPSemEventMultiGetResolution: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
    961 
    962     uint32_t cNsResolution = SUPSemEventMultiGetResolution(pDevIns->Internal.s.pGVM->pSession);
    963 
    964     LogFlow(("pdmR0DevHlp_SUPSemEventMultiGetResolution: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, cNsResolution));
    965     return cNsResolution;
    966 }
    967 
    968 
    969 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectGetNop} */
    970 static DECLCALLBACK(PPDMCRITSECT) pdmR0DevHlp_CritSectGetNop(PPDMDEVINS pDevIns)
    971 {
    972     PDMDEV_ASSERT_DEVINS(pDevIns);
    973     PGVM pGVM = pDevIns->Internal.s.pGVM;
    974 
    975     PPDMCRITSECT pCritSect = &pGVM->pdm.s.NopCritSect;
    976     LogFlow(("pdmR0DevHlp_CritSectGetNop: caller='%s'/%d: return %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
    977     return pCritSect;
    978 }
    979 
    980 
    981 /** @interface_method_impl{PDMDEVHLPR0,pfnSetDeviceCritSect} */
    982 static DECLCALLBACK(int) pdmR0DevHlp_SetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
    983 {
    984     /*
    985      * Validate input.
    986      *
    987      * Note! We only allow the automatically created default critical section
    988      *       to be replaced by this API.
    989      */
    990     PDMDEV_ASSERT_DEVINS(pDevIns);
    991     AssertPtrReturn(pCritSect, VERR_INVALID_POINTER);
    992     LogFlow(("pdmR0DevHlp_SetDeviceCritSect: caller='%s'/%d: pCritSect=%p (%s)\n",
    993              pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pCritSect->s.pszName));
    994     AssertReturn(PDMCritSectIsInitialized(pCritSect), VERR_INVALID_PARAMETER);
    995     PGVM pGVM = pDevIns->Internal.s.pGVM;
    996     AssertReturn(pCritSect->s.pVMR0 == pGVM, VERR_INVALID_PARAMETER);
    997 
    998     VM_ASSERT_EMT(pGVM);
    999     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
    1000 
    1001     /*
    1002      * Check that ring-3 has already done this, then effect the change.
    1003      */
    1004     AssertReturn(pDevIns->pDevInsForR3R0->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_CHANGED_CRITSECT, VERR_WRONG_ORDER);
    1005     pDevIns->pCritSectRoR0 = pCritSect;
    1006 
    1007     LogFlow(("pdmR0DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    1008     return VINF_SUCCESS;
    1009 }
    1010 
    1011 
    1012 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectEnter} */
    1013 static DECLCALLBACK(int)      pdmR0DevHlp_CritSectEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy)
    1014 {
    1015     PDMDEV_ASSERT_DEVINS(pDevIns);
    1016     RT_NOREF(pDevIns); /** @todo pass pDevIns->Internal.s.pGVM to the crit sect code.   */
    1017     return PDMCritSectEnter(pCritSect, rcBusy);
    1018 }
    1019 
    1020 
    1021 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectEnterDebug} */
    1022 static DECLCALLBACK(int)      pdmR0DevHlp_CritSectEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
    1023 {
    1024     PDMDEV_ASSERT_DEVINS(pDevIns);
    1025     RT_NOREF(pDevIns); /** @todo pass pDevIns->Internal.s.pGVM to the crit sect code.   */
    1026     return PDMCritSectEnterDebug(pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
    1027 }
    1028 
    1029 
    1030 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectTryEnter} */
    1031 static DECLCALLBACK(int)      pdmR0DevHlp_CritSectTryEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
    1032 {
    1033     PDMDEV_ASSERT_DEVINS(pDevIns);
    1034     RT_NOREF(pDevIns); /** @todo pass pDevIns->Internal.s.pGVM to the crit sect code.   */
    1035     return PDMCritSectTryEnter(pCritSect);
    1036 }
    1037 
    1038 
    1039 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectTryEnterDebug} */
    1040 static DECLCALLBACK(int)      pdmR0DevHlp_CritSectTryEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
    1041 {
    1042     PDMDEV_ASSERT_DEVINS(pDevIns);
    1043     RT_NOREF(pDevIns); /** @todo pass pDevIns->Internal.s.pGVM to the crit sect code.   */
    1044     return PDMCritSectTryEnterDebug(pCritSect, uId, RT_SRC_POS_ARGS);
    1045 }
    1046 
    1047 
    1048 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectLeave} */
    1049 static DECLCALLBACK(int)      pdmR0DevHlp_CritSectLeave(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
    1050 {
    1051     PDMDEV_ASSERT_DEVINS(pDevIns);
    1052     RT_NOREF(pDevIns); /** @todo pass pDevIns->Internal.s.pGVM to the crit sect code.   */
    1053     return PDMCritSectLeave(pCritSect);
    1054 }
    1055 
    1056 
    1057 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectIsOwner} */
    1058 static DECLCALLBACK(bool)     pdmR0DevHlp_CritSectIsOwner(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
    1059 {
    1060     PDMDEV_ASSERT_DEVINS(pDevIns);
    1061     RT_NOREF(pDevIns); /** @todo pass pDevIns->Internal.s.pGVM to the crit sect code.   */
    1062     return PDMCritSectIsOwner(pCritSect);
    1063 }
    1064 
    1065 
    1066 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectIsInitialized} */
    1067 static DECLCALLBACK(bool)     pdmR0DevHlp_CritSectIsInitialized(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
    1068 {
    1069     PDMDEV_ASSERT_DEVINS(pDevIns);
    1070     RT_NOREF(pDevIns);
    1071     return PDMCritSectIsInitialized(pCritSect);
    1072 }
    1073 
    1074 
    1075 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectHasWaiters} */
    1076 static DECLCALLBACK(bool)     pdmR0DevHlp_CritSectHasWaiters(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
    1077 {
    1078     PDMDEV_ASSERT_DEVINS(pDevIns);
    1079     RT_NOREF(pDevIns);
    1080     return PDMCritSectHasWaiters(pCritSect);
    1081 }
    1082 
    1083 
    1084 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectGetRecursion} */
    1085 static DECLCALLBACK(uint32_t) pdmR0DevHlp_CritSectGetRecursion(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
    1086 {
    1087     PDMDEV_ASSERT_DEVINS(pDevIns);
    1088     RT_NOREF(pDevIns);
    1089     return PDMCritSectGetRecursion(pCritSect);
    1090 }
    1091 
    1092 
    1093 /** @interface_method_impl{PDMDEVHLPR0,pfnCritSectScheduleExitEvent} */
    1094 static DECLCALLBACK(int) pdmR0DevHlp_CritSectScheduleExitEvent(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect,
    1095                                                                SUPSEMEVENT hEventToSignal)
    1096 {
    1097     PDMDEV_ASSERT_DEVINS(pDevIns);
    1098     RT_NOREF(pDevIns);
    1099     return PDMHCCritSectScheduleExitEvent(pCritSect, hEventToSignal);
    1100 }
    1101 
    1102 
    1103 /** @interface_method_impl{PDMDEVHLPR0,pfnDBGFTraceBuf} */
    1104 static DECLCALLBACK(RTTRACEBUF) pdmR0DevHlp_DBGFTraceBuf(PPDMDEVINS pDevIns)
    1105 {
    1106     PDMDEV_ASSERT_DEVINS(pDevIns);
    1107     RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pGVM->hTraceBufR0;
    1108     LogFlow(("pdmR0DevHlp_DBGFTraceBuf: caller='%p'/%d: returns %p\n", pDevIns, pDevIns->iInstance, hTraceBuf));
    1109     return hTraceBuf;
    1110 }
    1111 
    1112 
    1113 /** @interface_method_impl{PDMDEVHLPR0,pfnPCIBusSetUpContext} */
    1114 static DECLCALLBACK(int) pdmR0DevHlp_PCIBusSetUpContext(PPDMDEVINS pDevIns, PPDMPCIBUSREGR0 pPciBusReg, PCPDMPCIHLPR0 *ppPciHlp)
    1115 {
    1116     PDMDEV_ASSERT_DEVINS(pDevIns);
    1117     LogFlow(("pdmR0DevHlp_PCIBusSetUpContext: caller='%p'/%d: pPciBusReg=%p{.u32Version=%#x, .iBus=%#u, .pfnSetIrq=%p, u32EnvVersion=%#x} ppPciHlp=%p\n",
    1118              pDevIns, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->iBus, pPciBusReg->pfnSetIrq,
    1119              pPciBusReg->u32EndVersion, ppPciHlp));
    1120     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1121 
    1122     /*
    1123      * Validate input.
    1124      */
    1125     AssertPtrReturn(pPciBusReg, VERR_INVALID_POINTER);
    1126     AssertLogRelMsgReturn(pPciBusReg->u32Version == PDM_PCIBUSREGCC_VERSION,
    1127                           ("%#x vs %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREGCC_VERSION), VERR_VERSION_MISMATCH);
    1128     AssertPtrReturn(pPciBusReg->pfnSetIrq, VERR_INVALID_POINTER);
    1129     AssertLogRelMsgReturn(pPciBusReg->u32EndVersion == PDM_PCIBUSREGCC_VERSION,
    1130                           ("%#x vs %#x\n", pPciBusReg->u32EndVersion, PDM_PCIBUSREGCC_VERSION), VERR_VERSION_MISMATCH);
    1131 
    1132     AssertPtrReturn(ppPciHlp, VERR_INVALID_POINTER);
    1133 
    1134     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
    1135     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    1136 
    1137     /* Check the shared bus data (registered earlier from ring-3): */
    1138     uint32_t iBus = pPciBusReg->iBus;
    1139     ASMCompilerBarrier();
    1140     AssertLogRelMsgReturn(iBus < RT_ELEMENTS(pGVM->pdm.s.aPciBuses), ("iBus=%#x\n", iBus), VERR_OUT_OF_RANGE);
    1141     PPDMPCIBUS pPciBusShared = &pGVM->pdm.s.aPciBuses[iBus];
    1142     AssertLogRelMsgReturn(pPciBusShared->iBus == iBus, ("%u vs %u\n", pPciBusShared->iBus, iBus), VERR_INVALID_PARAMETER);
    1143     AssertLogRelMsgReturn(pPciBusShared->pDevInsR3 == pDevIns->pDevInsForR3,
    1144                           ("%p vs %p (iBus=%u)\n", pPciBusShared->pDevInsR3, pDevIns->pDevInsForR3, iBus), VERR_NOT_OWNER);
    1145 
    1146     /* Check that the bus isn't already registered in ring-0: */
    1147     AssertCompile(RT_ELEMENTS(pGVM->pdm.s.aPciBuses) == RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses));
    1148     PPDMPCIBUSR0 pPciBusR0 = &pGVM->pdmr0.s.aPciBuses[iBus];
    1149     AssertLogRelMsgReturn(pPciBusR0->pDevInsR0 == NULL,
    1150                           ("%p (caller pDevIns=%p, iBus=%u)\n", pPciBusR0->pDevInsR0, pDevIns, iBus),
    1151                           VERR_ALREADY_EXISTS);
    1152 
    1153     /*
    1154      * Do the registering.
    1155      */
    1156     pPciBusR0->iBus        = iBus;
    1157     pPciBusR0->uPadding0   = 0xbeefbeef;
    1158     pPciBusR0->pfnSetIrqR0 = pPciBusReg->pfnSetIrq;
    1159     pPciBusR0->pDevInsR0   = pDevIns;
    1160 
    1161     *ppPciHlp = &g_pdmR0PciHlp;
    1162 
    1163     LogFlow(("pdmR0DevHlp_PCIBusSetUpContext: caller='%p'/%d: returns VINF_SUCCESS\n", pDevIns, pDevIns->iInstance));
    1164     return VINF_SUCCESS;
    1165 }
    1166 
    1167 
    1168 /** @interface_method_impl{PDMDEVHLPR0,pfnIommuSetUpContext} */
    1169 static DECLCALLBACK(int) pdmR0DevHlp_IommuSetUpContext(PPDMDEVINS pDevIns, PPDMIOMMUREGR0 pIommuReg, PCPDMIOMMUHLPR0 *ppIommuHlp)
    1170 {
    1171     PDMDEV_ASSERT_DEVINS(pDevIns);
    1172     LogFlow(("pdmR0DevHlp_IommuSetUpContext: caller='%p'/%d: pIommuReg=%p{.u32Version=%#x, u32TheEnd=%#x} ppIommuHlp=%p\n",
    1173              pDevIns, pDevIns->iInstance, pIommuReg, pIommuReg->u32Version, pIommuReg->u32TheEnd, ppIommuHlp));
    1174     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1175 
    1176     /*
    1177      * Validate input.
    1178      */
    1179     AssertPtrReturn(pIommuReg, VERR_INVALID_POINTER);
    1180     AssertLogRelMsgReturn(pIommuReg->u32Version == PDM_IOMMUREGCC_VERSION,
    1181                           ("%#x vs %#x\n", pIommuReg->u32Version, PDM_IOMMUREGCC_VERSION), VERR_VERSION_MISMATCH);
    1182     AssertLogRelMsgReturn(pIommuReg->u32TheEnd == PDM_IOMMUREGCC_VERSION,
    1183                           ("%#x vs %#x\n", pIommuReg->u32TheEnd, PDM_IOMMUREGCC_VERSION), VERR_VERSION_MISMATCH);
    1184 
    1185     AssertPtrReturn(ppIommuHlp, VERR_INVALID_POINTER);
    1186 
    1187     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
    1188     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    1189 
    1190     /* Check the IOMMU shared data (registered earlier from ring-3). */
    1191     uint32_t const idxIommu = pIommuReg->idxIommu;
    1192     ASMCompilerBarrier();
    1193     AssertLogRelMsgReturn(idxIommu < RT_ELEMENTS(pGVM->pdm.s.aIommus), ("idxIommu=%#x\n", idxIommu), VERR_OUT_OF_RANGE);
    1194     PPDMIOMMU pIommuShared = &pGVM->pdm.s.aIommus[idxIommu];
    1195     AssertLogRelMsgReturn(pIommuShared->idxIommu == idxIommu, ("%u vs %u\n", pIommuShared->idxIommu, idxIommu), VERR_INVALID_PARAMETER);
    1196     AssertLogRelMsgReturn(pIommuShared->pDevInsR3 == pDevIns->pDevInsForR3,
    1197                           ("%p vs %p (idxIommu=%u)\n", pIommuShared->pDevInsR3, pDevIns->pDevInsForR3, idxIommu), VERR_NOT_OWNER);
    1198 
    1199     /* Check that the IOMMU isn't already registered in ring-0. */
    1200     AssertCompile(RT_ELEMENTS(pGVM->pdm.s.aIommus) == RT_ELEMENTS(pGVM->pdmr0.s.aIommus));
    1201     PPDMIOMMUR0 pIommuR0 = &pGVM->pdmr0.s.aIommus[idxIommu];
    1202     AssertLogRelMsgReturn(pIommuR0->pDevInsR0 == NULL,
    1203                           ("%p (caller pDevIns=%p, idxIommu=%u)\n", pIommuR0->pDevInsR0, pDevIns, idxIommu),
    1204                           VERR_ALREADY_EXISTS);
    1205 
    1206     /*
    1207      * Register.
    1208      */
    1209     pIommuR0->idxIommu    = idxIommu;
    1210     pIommuR0->uPadding0   = 0xdeaddead;
    1211     pIommuR0->pDevInsR0   = pDevIns;
    1212 
    1213     *ppIommuHlp = &g_pdmR0IommuHlp;
    1214 
    1215     LogFlow(("pdmR0DevHlp_IommuSetUpContext: caller='%p'/%d: returns VINF_SUCCESS\n", pDevIns, pDevIns->iInstance));
    1216     return VINF_SUCCESS;
    1217 }
    1218 
    1219 
    1220 /** @interface_method_impl{PDMDEVHLPR0,pfnPICSetUpContext} */
    1221 static DECLCALLBACK(int) pdmR0DevHlp_PICSetUpContext(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
    1222 {
    1223     PDMDEV_ASSERT_DEVINS(pDevIns);
    1224     LogFlow(("pdmR0DevHlp_PICSetUpContext: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnGetInterrupt=%p, .u32TheEnd=%#x } ppPicHlp=%p\n",
    1225              pDevIns->pReg->szName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrq, pPicReg->pfnGetInterrupt, pPicReg->u32TheEnd, ppPicHlp));
    1226     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1227 
    1228     /*
    1229      * Validate input.
    1230      */
    1231     AssertMsgReturn(pPicReg->u32Version == PDM_PICREG_VERSION,
    1232                     ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32Version, PDM_PICREG_VERSION),
    1233                     VERR_VERSION_MISMATCH);
    1234     AssertPtrReturn(pPicReg->pfnSetIrq, VERR_INVALID_POINTER);
    1235     AssertPtrReturn(pPicReg->pfnGetInterrupt, VERR_INVALID_POINTER);
    1236     AssertMsgReturn(pPicReg->u32TheEnd == PDM_PICREG_VERSION,
    1237                     ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32TheEnd, PDM_PICREG_VERSION),
    1238                     VERR_VERSION_MISMATCH);
    1239     AssertPtrReturn(ppPicHlp, VERR_INVALID_POINTER);
    1240 
    1241     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
    1242     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    1243 
    1244     /* Check that it's the same device as made the ring-3 registrations: */
    1245     AssertLogRelMsgReturn(pGVM->pdm.s.Pic.pDevInsR3 == pDevIns->pDevInsForR3,
    1246                           ("%p vs %p\n", pGVM->pdm.s.Pic.pDevInsR3, pDevIns->pDevInsForR3), VERR_NOT_OWNER);
    1247 
    1248     /* Check that it isn't already registered in ring-0: */
    1249     AssertLogRelMsgReturn(pGVM->pdm.s.Pic.pDevInsR0 == NULL, ("%p (caller pDevIns=%p)\n", pGVM->pdm.s.Pic.pDevInsR0, pDevIns),
    1250                           VERR_ALREADY_EXISTS);
    1251 
    1252     /*
    1253      * Take down the callbacks and instance.
    1254      */
    1255     pGVM->pdm.s.Pic.pDevInsR0 = pDevIns;
    1256     pGVM->pdm.s.Pic.pfnSetIrqR0 = pPicReg->pfnSetIrq;
    1257     pGVM->pdm.s.Pic.pfnGetInterruptR0 = pPicReg->pfnGetInterrupt;
    1258     Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    1259 
    1260     /* set the helper pointer and return. */
    1261     *ppPicHlp = &g_pdmR0PicHlp;
    1262     LogFlow(("pdmR0DevHlp_PICSetUpContext: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    1263     return VINF_SUCCESS;
    1264 }
    1265 
    1266 
    1267 /** @interface_method_impl{PDMDEVHLPR0,pfnApicSetUpContext} */
    1268 static DECLCALLBACK(int) pdmR0DevHlp_ApicSetUpContext(PPDMDEVINS pDevIns)
    1269 {
    1270     PDMDEV_ASSERT_DEVINS(pDevIns);
    1271     LogFlow(("pdmR0DevHlp_ApicSetUpContext: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
    1272     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1273 
    1274     /*
    1275      * Validate input.
    1276      */
    1277     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
    1278     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    1279 
    1280     /* Check that it's the same device as made the ring-3 registrations: */
    1281     AssertLogRelMsgReturn(pGVM->pdm.s.Apic.pDevInsR3 == pDevIns->pDevInsForR3,
    1282                           ("%p vs %p\n", pGVM->pdm.s.Apic.pDevInsR3, pDevIns->pDevInsForR3), VERR_NOT_OWNER);
    1283 
    1284     /* Check that it isn't already registered in ring-0: */
    1285     AssertLogRelMsgReturn(pGVM->pdm.s.Apic.pDevInsR0 == NULL, ("%p (caller pDevIns=%p)\n", pGVM->pdm.s.Apic.pDevInsR0, pDevIns),
    1286                           VERR_ALREADY_EXISTS);
    1287 
    1288     /*
    1289      * Take down the instance.
    1290      */
    1291     pGVM->pdm.s.Apic.pDevInsR0 = pDevIns;
    1292     Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    1293 
    1294     /* set the helper pointer and return. */
    1295     LogFlow(("pdmR0DevHlp_ApicSetUpContext: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    1296     return VINF_SUCCESS;
    1297 }
    1298 
    1299 
    1300 /** @interface_method_impl{PDMDEVHLPR0,pfnIoApicSetUpContext} */
    1301 static DECLCALLBACK(int) pdmR0DevHlp_IoApicSetUpContext(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
    1302 {
    1303     PDMDEV_ASSERT_DEVINS(pDevIns);
    1304     LogFlow(("pdmR0DevHlp_IoApicSetUpContext: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnSendMsi=%p, .pfnSetEoi=%p, .u32TheEnd=%#x } ppIoApicHlp=%p\n",
    1305              pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrq, pIoApicReg->pfnSendMsi, pIoApicReg->pfnSetEoi, pIoApicReg->u32TheEnd, ppIoApicHlp));
    1306     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1307 
    1308     /*
    1309      * Validate input.
    1310      */
    1311     AssertMsgReturn(pIoApicReg->u32Version == PDM_IOAPICREG_VERSION,
    1312                     ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32Version, PDM_IOAPICREG_VERSION),
    1313                     VERR_VERSION_MISMATCH);
    1314     AssertPtrReturn(pIoApicReg->pfnSetIrq, VERR_INVALID_POINTER);
    1315     AssertPtrReturn(pIoApicReg->pfnSendMsi, VERR_INVALID_POINTER);
    1316     AssertPtrReturn(pIoApicReg->pfnSetEoi, VERR_INVALID_POINTER);
    1317     AssertMsgReturn(pIoApicReg->u32TheEnd == PDM_IOAPICREG_VERSION,
    1318                     ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32TheEnd, PDM_IOAPICREG_VERSION),
    1319                     VERR_VERSION_MISMATCH);
    1320     AssertPtrReturn(ppIoApicHlp, VERR_INVALID_POINTER);
    1321 
    1322     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
    1323     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    1324 
    1325     /* Check that it's the same device as made the ring-3 registrations: */
    1326     AssertLogRelMsgReturn(pGVM->pdm.s.IoApic.pDevInsR3 == pDevIns->pDevInsForR3,
    1327                           ("%p vs %p\n", pGVM->pdm.s.IoApic.pDevInsR3, pDevIns->pDevInsForR3), VERR_NOT_OWNER);
    1328 
    1329     /* Check that it isn't already registered in ring-0: */
    1330     AssertLogRelMsgReturn(pGVM->pdm.s.IoApic.pDevInsR0 == NULL, ("%p (caller pDevIns=%p)\n", pGVM->pdm.s.IoApic.pDevInsR0, pDevIns),
    1331                           VERR_ALREADY_EXISTS);
    1332 
    1333     /*
    1334      * Take down the callbacks and instance.
    1335      */
    1336     pGVM->pdm.s.IoApic.pDevInsR0    = pDevIns;
    1337     pGVM->pdm.s.IoApic.pfnSetIrqR0  = pIoApicReg->pfnSetIrq;
    1338     pGVM->pdm.s.IoApic.pfnSendMsiR0 = pIoApicReg->pfnSendMsi;
    1339     pGVM->pdm.s.IoApic.pfnSetEoiR0  = pIoApicReg->pfnSetEoi;
    1340     Log(("PDM: Registered IOAPIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    1341 
    1342     /* set the helper pointer and return. */
    1343     *ppIoApicHlp = &g_pdmR0IoApicHlp;
    1344     LogFlow(("pdmR0DevHlp_IoApicSetUpContext: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    1345     return VINF_SUCCESS;
    1346 }
    1347 
    1348 
    1349 /** @interface_method_impl{PDMDEVHLPR0,pfnHpetSetUpContext} */
    1350 static DECLCALLBACK(int) pdmR0DevHlp_HpetSetUpContext(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR0 *ppHpetHlp)
    1351 {
    1352     PDMDEV_ASSERT_DEVINS(pDevIns);
    1353     LogFlow(("pdmR0DevHlp_HpetSetUpContext: caller='%s'/%d: pHpetReg=%p:{.u32Version=%#x, } ppHpetHlp=%p\n",
    1354              pDevIns->pReg->szName, pDevIns->iInstance, pHpetReg, pHpetReg->u32Version, ppHpetHlp));
    1355     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1356 
    1357     /*
    1358      * Validate input.
    1359      */
    1360     AssertMsgReturn(pHpetReg->u32Version == PDM_HPETREG_VERSION,
    1361                     ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pHpetReg->u32Version, PDM_HPETREG_VERSION),
    1362                     VERR_VERSION_MISMATCH);
    1363     AssertPtrReturn(ppHpetHlp, VERR_INVALID_POINTER);
    1364 
    1365     VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
    1366     VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
    1367 
    1368     /* Check that it's the same device as made the ring-3 registrations: */
    1369     AssertLogRelMsgReturn(pGVM->pdm.s.pHpet == pDevIns->pDevInsForR3, ("%p vs %p\n", pGVM->pdm.s.pHpet, pDevIns->pDevInsForR3),
    1370                           VERR_NOT_OWNER);
    1371 
    1372     ///* Check that it isn't already registered in ring-0: */
    1373     //AssertLogRelMsgReturn(pGVM->pdm.s.Hpet.pDevInsR0 == NULL, ("%p (caller pDevIns=%p)\n", pGVM->pdm.s.Hpet.pDevInsR0, pDevIns),
    1374     //                      VERR_ALREADY_EXISTS);
    1375 
    1376     /*
    1377      * Nothing to take down here at present.
    1378      */
    1379     Log(("PDM: Registered HPET device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    1380 
    1381     /* set the helper pointer and return. */
    1382     *ppHpetHlp = &g_pdmR0HpetHlp;
    1383     LogFlow(("pdmR0DevHlp_HpetSetUpContext: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    1384     return VINF_SUCCESS;
    1385 }
    1386 
    1387 
    1388 /**
    1389  * The Ring-0 Device Helper Callbacks.
    1390  */
    1391 extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp =
    1392 {
    1393     PDM_DEVHLPR0_VERSION,
    1394     pdmR0DevHlp_IoPortSetUpContextEx,
    1395     pdmR0DevHlp_MmioSetUpContextEx,
    1396     pdmR0DevHlp_Mmio2SetUpContext,
    1397     pdmR0DevHlp_PCIPhysRead,
    1398     pdmR0DevHlp_PCIPhysWrite,
    1399     pdmR0DevHlp_PCISetIrq,
    1400     pdmR0DevHlp_ISASetIrq,
    1401     pdmR0DevHlp_IoApicSendMsi,
    1402     pdmR0DevHlp_PhysRead,
    1403     pdmR0DevHlp_PhysWrite,
    1404     pdmR0DevHlp_A20IsEnabled,
    1405     pdmR0DevHlp_VMState,
    1406     pdmR0DevHlp_VMSetError,
    1407     pdmR0DevHlp_VMSetErrorV,
    1408     pdmR0DevHlp_VMSetRuntimeError,
    1409     pdmR0DevHlp_VMSetRuntimeErrorV,
    1410     pdmR0DevHlp_GetVM,
    1411     pdmR0DevHlp_GetVMCPU,
    1412     pdmR0DevHlp_GetCurrentCpuId,
    1413     pdmR0DevHlp_TimerToPtr,
    1414     pdmR0DevHlp_TimerFromMicro,
    1415     pdmR0DevHlp_TimerFromMilli,
    1416     pdmR0DevHlp_TimerFromNano,
    1417     pdmR0DevHlp_TimerGet,
    1418     pdmR0DevHlp_TimerGetFreq,
    1419     pdmR0DevHlp_TimerGetNano,
    1420     pdmR0DevHlp_TimerIsActive,
    1421     pdmR0DevHlp_TimerIsLockOwner,
    1422     pdmR0DevHlp_TimerLockClock,
    1423     pdmR0DevHlp_TimerLockClock2,
    1424     pdmR0DevHlp_TimerSet,
    1425     pdmR0DevHlp_TimerSetFrequencyHint,
    1426     pdmR0DevHlp_TimerSetMicro,
    1427     pdmR0DevHlp_TimerSetMillies,
    1428     pdmR0DevHlp_TimerSetNano,
    1429     pdmR0DevHlp_TimerSetRelative,
    1430     pdmR0DevHlp_TimerStop,
    1431     pdmR0DevHlp_TimerUnlockClock,
    1432     pdmR0DevHlp_TimerUnlockClock2,
    1433     pdmR0DevHlp_TMTimeVirtGet,
    1434     pdmR0DevHlp_TMTimeVirtGetFreq,
    1435     pdmR0DevHlp_TMTimeVirtGetNano,
    1436     pdmR0DevHlp_QueueToPtr,
    1437     pdmR0DevHlp_QueueAlloc,
    1438     pdmR0DevHlp_QueueInsert,
    1439     pdmR0DevHlp_QueueInsertEx,
    1440     pdmR0DevHlp_QueueFlushIfNecessary,
    1441     pdmR0DevHlp_TaskTrigger,
    1442     pdmR0DevHlp_SUPSemEventSignal,
    1443     pdmR0DevHlp_SUPSemEventWaitNoResume,
    1444     pdmR0DevHlp_SUPSemEventWaitNsAbsIntr,
    1445     pdmR0DevHlp_SUPSemEventWaitNsRelIntr,
    1446     pdmR0DevHlp_SUPSemEventGetResolution,
    1447     pdmR0DevHlp_SUPSemEventMultiSignal,
    1448     pdmR0DevHlp_SUPSemEventMultiReset,
    1449     pdmR0DevHlp_SUPSemEventMultiWaitNoResume,
    1450     pdmR0DevHlp_SUPSemEventMultiWaitNsAbsIntr,
    1451     pdmR0DevHlp_SUPSemEventMultiWaitNsRelIntr,
    1452     pdmR0DevHlp_SUPSemEventMultiGetResolution,
    1453     pdmR0DevHlp_CritSectGetNop,
    1454     pdmR0DevHlp_SetDeviceCritSect,
    1455     pdmR0DevHlp_CritSectEnter,
    1456     pdmR0DevHlp_CritSectEnterDebug,
    1457     pdmR0DevHlp_CritSectTryEnter,
    1458     pdmR0DevHlp_CritSectTryEnterDebug,
    1459     pdmR0DevHlp_CritSectLeave,
    1460     pdmR0DevHlp_CritSectIsOwner,
    1461     pdmR0DevHlp_CritSectIsInitialized,
    1462     pdmR0DevHlp_CritSectHasWaiters,
    1463     pdmR0DevHlp_CritSectGetRecursion,
    1464     pdmR0DevHlp_CritSectScheduleExitEvent,
    1465     pdmR0DevHlp_DBGFTraceBuf,
    1466     pdmR0DevHlp_PCIBusSetUpContext,
    1467     pdmR0DevHlp_IommuSetUpContext,
    1468     pdmR0DevHlp_PICSetUpContext,
    1469     pdmR0DevHlp_ApicSetUpContext,
    1470     pdmR0DevHlp_IoApicSetUpContext,
    1471     pdmR0DevHlp_HpetSetUpContext,
    1472     NULL /*pfnReserved1*/,
    1473     NULL /*pfnReserved2*/,
    1474     NULL /*pfnReserved3*/,
    1475     NULL /*pfnReserved4*/,
    1476     NULL /*pfnReserved5*/,
    1477     NULL /*pfnReserved6*/,
    1478     NULL /*pfnReserved7*/,
    1479     NULL /*pfnReserved8*/,
    1480     NULL /*pfnReserved9*/,
    1481     NULL /*pfnReserved10*/,
    1482     PDM_DEVHLPR0_VERSION
    1483 };
    1484 
    1485 /** @} */
    1486 
    1487 
    1488 
    1489 
    1490 /** @name PIC Ring-0 Helpers
    1491  * @{
    1492  */
    1493 
    1494 /** @interface_method_impl{PDMPICHLP,pfnSetInterruptFF} */
    1495 static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
    1496 {
    1497     PDMDEV_ASSERT_DEVINS(pDevIns);
    1498     PGVM     pGVM  = (PGVM)pDevIns->Internal.s.pGVM;
    1499     PVMCPUCC pVCpu = &pGVM->aCpus[0];     /* for PIC we always deliver to CPU 0, MP use APIC */
    1500     /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
    1501     APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 1 /* u8Level */, VINF_SUCCESS /* rcRZ */);
    1502 }
    1503 
    1504 
    1505 /** @interface_method_impl{PDMPICHLP,pfnClearInterruptFF} */
    1506 static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
    1507 {
    1508     PDMDEV_ASSERT_DEVINS(pDevIns);
    1509     PGVM     pGVM  = (PGVM)pDevIns->Internal.s.pGVM;
    1510     PVMCPUCC pVCpu = &pGVM->aCpus[0];     /* for PIC we always deliver to CPU 0, MP use APIC */
    1511     /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
    1512     APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 0 /* u8Level */, VINF_SUCCESS /* rcRZ */);
    1513 }
    1514 
    1515 
    1516 /** @interface_method_impl{PDMPICHLP,pfnLock} */
    1517 static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    1518 {
    1519     PDMDEV_ASSERT_DEVINS(pDevIns);
    1520     return pdmLockEx(pDevIns->Internal.s.pGVM, rc);
    1521 }
    1522 
    1523 
    1524 /** @interface_method_impl{PDMPICHLP,pfnUnlock} */
    1525 static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
    1526 {
    1527     PDMDEV_ASSERT_DEVINS(pDevIns);
    1528     pdmUnlock(pDevIns->Internal.s.pGVM);
    1529 }
    1530 
    1531 
    1532 /**
    1533  * The Ring-0 PIC Helper Callbacks.
    1534  */
    1535 extern DECLEXPORT(const PDMPICHLP) g_pdmR0PicHlp =
    1536 {
    1537     PDM_PICHLP_VERSION,
    1538     pdmR0PicHlp_SetInterruptFF,
    1539     pdmR0PicHlp_ClearInterruptFF,
    1540     pdmR0PicHlp_Lock,
    1541     pdmR0PicHlp_Unlock,
    1542     PDM_PICHLP_VERSION
    1543 };
    1544 
    1545 /** @} */
    1546 
    1547 
    1548 /** @name I/O APIC Ring-0 Helpers
    1549  * @{
    1550  */
    1551 
    1552 /** @interface_method_impl{PDMIOAPICHLP,pfnApicBusDeliver} */
    1553 static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
    1554                                                        uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
    1555                                                        uint8_t u8TriggerMode, uint32_t uTagSrc)
    1556 {
    1557     PDMDEV_ASSERT_DEVINS(pDevIns);
    1558     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1559     LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 uVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
    1560              pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc));
    1561     return APICBusDeliver(pGVM, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
    1562 }
    1563 
    1564 
    1565 /** @interface_method_impl{PDMIOAPICHLP,pfnLock} */
    1566 static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    1567 {
    1568     PDMDEV_ASSERT_DEVINS(pDevIns);
    1569     return pdmLockEx(pDevIns->Internal.s.pGVM, rc);
    1570 }
    1571 
    1572 
    1573 /** @interface_method_impl{PDMIOAPICHLP,pfnUnlock} */
    1574 static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
    1575 {
    1576     PDMDEV_ASSERT_DEVINS(pDevIns);
    1577     pdmUnlock(pDevIns->Internal.s.pGVM);
    1578 }
    1579 
    1580 
    1581 /**
    1582  * The Ring-0 I/O APIC Helper Callbacks.
    1583  */
    1584 extern DECLEXPORT(const PDMIOAPICHLP) g_pdmR0IoApicHlp =
    1585 {
    1586     PDM_IOAPICHLP_VERSION,
    1587     pdmR0IoApicHlp_ApicBusDeliver,
    1588     pdmR0IoApicHlp_Lock,
    1589     pdmR0IoApicHlp_Unlock,
    1590     PDM_IOAPICHLP_VERSION
    1591 };
    1592 
    1593 /** @} */
    1594 
    1595 
    1596 
    1597 
    1598 /** @name PCI Bus Ring-0 Helpers
    1599  * @{
    1600  */
    1601 
    1602 /** @interface_method_impl{PDMPCIHLPR0,pfnIsaSetIrq} */
    1603 static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
    1604 {
    1605     PDMDEV_ASSERT_DEVINS(pDevIns);
    1606     Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
    1607     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1608 
    1609     pdmLock(pGVM);
    1610     pdmR0IsaSetIrq(pGVM, iIrq, iLevel, uTagSrc);
    1611     pdmUnlock(pGVM);
    1612 }
    1613 
    1614 
    1615 /** @interface_method_impl{PDMPCIHLPR0,pfnIoApicSetIrq} */
    1616 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
    1617 {
    1618     PDMDEV_ASSERT_DEVINS(pDevIns);
    1619     Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
    1620     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1621 
    1622     if (pGVM->pdm.s.IoApic.pDevInsR0)
    1623         pGVM->pdm.s.IoApic.pfnSetIrqR0(pGVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc);
    1624     else if (pGVM->pdm.s.IoApic.pDevInsR3)
    1625     {
    1626         /* queue for ring-3 execution. */
    1627         PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pGVM->pdm.s.pDevHlpQueueR0);
    1628         if (pTask)
    1629         {
    1630             pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
    1631             pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
    1632             pTask->u.IoApicSetIRQ.iIrq = iIrq;
    1633             pTask->u.IoApicSetIRQ.iLevel = iLevel;
    1634             pTask->u.IoApicSetIRQ.uTagSrc = uTagSrc;
    1635 
    1636             PDMQueueInsertEx(pGVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
    1637         }
    1638         else
    1639             AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
    1640     }
    1641 }
    1642 
    1643 
    1644 /** @interface_method_impl{PDMPCIHLPR0,pfnIoApicSendMsi} */
    1645 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc)
    1646 {
    1647     PDMDEV_ASSERT_DEVINS(pDevIns);
    1648     Log4(("pdmR0PciHlp_IoApicSendMsi: GCPhys=%p uValue=%d uTagSrc=%#x\n", GCPhys, uValue, uTagSrc));
    1649     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1650     if (pGVM->pdm.s.IoApic.pDevInsR0)
    1651         pGVM->pdm.s.IoApic.pfnSendMsiR0(pGVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc);
    1652     else
    1653         AssertFatalMsgFailed(("Lazy bastards!"));
    1654 }
    1655 
    1656 
    1657 /** @interface_method_impl{PDMPCIHLPR0,pfnLock} */
    1658 static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
    1659 {
    1660     PDMDEV_ASSERT_DEVINS(pDevIns);
    1661     return pdmLockEx(pDevIns->Internal.s.pGVM, rc);
    1662 }
    1663 
    1664 
    1665 /** @interface_method_impl{PDMPCIHLPR0,pfnUnlock} */
    1666 static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns)
    1667 {
    1668     PDMDEV_ASSERT_DEVINS(pDevIns);
    1669     pdmUnlock(pDevIns->Internal.s.pGVM);
    1670 }
    1671 
    1672 
    1673 /** @interface_method_impl{PDMPCIHLPR0,pfnGetBusByNo} */
    1674 static DECLCALLBACK(PPDMDEVINS) pdmR0PciHlp_GetBusByNo(PPDMDEVINS pDevIns, uint32_t idxPdmBus)
    1675 {
    1676     PDMDEV_ASSERT_DEVINS(pDevIns);
    1677     PGVM pGVM = pDevIns->Internal.s.pGVM;
    1678     AssertReturn(idxPdmBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses), NULL);
    1679     PPDMDEVINS pRetDevIns = pGVM->pdmr0.s.aPciBuses[idxPdmBus].pDevInsR0;
    1680     LogFlow(("pdmR3PciHlp_GetBusByNo: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pRetDevIns));
    1681     return pRetDevIns;
    1682 }
    1683 
    1684 
    1685 /**
    1686  * The Ring-0 PCI Bus Helper Callbacks.
    1687  */
    1688 extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp =
    1689 {
    1690     PDM_PCIHLPR0_VERSION,
    1691     pdmR0PciHlp_IsaSetIrq,
    1692     pdmR0PciHlp_IoApicSetIrq,
    1693     pdmR0PciHlp_IoApicSendMsi,
    1694     pdmR0PciHlp_Lock,
    1695     pdmR0PciHlp_Unlock,
    1696     pdmR0PciHlp_GetBusByNo,
    1697     PDM_PCIHLPR0_VERSION, /* the end */
    1698 };
    1699 
    1700 /** @} */
    1701 
    1702 
    1703 /** @name IOMMU Ring-0 Helpers
    1704  * @{
    1705  */
    1706 
    1707 /**
    1708  * The Ring-0 IOMMU Helper Callbacks.
    1709  */
    1710 extern DECLEXPORT(const PDMIOMMUHLPR0) g_pdmR0IommuHlp =
    1711 {
    1712     PDM_IOMMUHLPR0_VERSION,
    1713     PDM_IOMMUHLPR0_VERSION, /* the end */
    1714 };
    1715 
    1716 /** @} */
    1717 
    1718 
    1719 /** @name HPET Ring-0 Helpers
    1720  * @{
    1721  */
    1722 /* none */
    1723 
    1724 /**
    1725  * The Ring-0 HPET Helper Callbacks.
    1726  */
    1727 extern DECLEXPORT(const PDMHPETHLPR0) g_pdmR0HpetHlp =
    1728 {
    1729     PDM_HPETHLPR0_VERSION,
    1730     PDM_HPETHLPR0_VERSION, /* the end */
    1731 };
    1732 
    1733 /** @} */
    1734 
    1735 
    1736 /** @name Raw PCI Ring-0 Helpers
    1737  * @{
    1738  */
    1739 /* none */
    1740 
    1741 /**
    1742  * The Ring-0 PCI raw Helper Callbacks.
    1743  */
    1744 extern DECLEXPORT(const PDMPCIRAWHLPR0) g_pdmR0PciRawHlp =
    1745 {
    1746     PDM_PCIRAWHLPR0_VERSION,
    1747     PDM_PCIRAWHLPR0_VERSION, /* the end */
    1748 };
    1749 
    1750 /** @} */
    1751 
    1752 
    1753 /** @name Ring-0 Context Driver Helpers
    1754  * @{
    1755  */
    1756 
    1757 /** @interface_method_impl{PDMDRVHLPR0,pfnVMSetError} */
    1758 static DECLCALLBACK(int) pdmR0DrvHlp_VMSetError(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
    1759 {
    1760     PDMDRV_ASSERT_DRVINS(pDrvIns);
    1761     va_list args;
    1762     va_start(args, pszFormat);
    1763     int rc2 = VMSetErrorV(pDrvIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
    1764     va_end(args);
    1765     return rc;
    1766 }
    1767 
    1768 
    1769 /** @interface_method_impl{PDMDRVHLPR0,pfnVMSetErrorV} */
    1770 static DECLCALLBACK(int) pdmR0DrvHlp_VMSetErrorV(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
    1771 {
    1772     PDMDRV_ASSERT_DRVINS(pDrvIns);
    1773     int rc2 = VMSetErrorV(pDrvIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
    1774     return rc;
    1775 }
    1776 
    1777 
    1778 /** @interface_method_impl{PDMDRVHLPR0,pfnVMSetRuntimeError} */
    1779 static DECLCALLBACK(int) pdmR0DrvHlp_VMSetRuntimeError(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId,
    1780                                                        const char *pszFormat, ...)
    1781 {
    1782     PDMDRV_ASSERT_DRVINS(pDrvIns);
    1783     va_list va;
    1784     va_start(va, pszFormat);
    1785     int rc = VMSetRuntimeErrorV(pDrvIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
    1786     va_end(va);
    1787     return rc;
    1788 }
    1789 
    1790 
    1791 /** @interface_method_impl{PDMDRVHLPR0,pfnVMSetRuntimeErrorV} */
    1792 static DECLCALLBACK(int) pdmR0DrvHlp_VMSetRuntimeErrorV(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId,
    1793                                                         const char *pszFormat, va_list va)
    1794 {
    1795     PDMDRV_ASSERT_DRVINS(pDrvIns);
    1796     int rc = VMSetRuntimeErrorV(pDrvIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
    1797     return rc;
    1798 }
    1799 
    1800 
    1801 /** @interface_method_impl{PDMDRVHLPR0,pfnAssertEMT} */
    1802 static DECLCALLBACK(bool) pdmR0DrvHlp_AssertEMT(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction)
    1803 {
    1804     PDMDRV_ASSERT_DRVINS(pDrvIns);
    1805     if (VM_IS_EMT(pDrvIns->Internal.s.pVMR0))
    1806         return true;
    1807 
    1808     RTAssertMsg1Weak("AssertEMT", iLine, pszFile, pszFunction);
    1809     RTAssertPanic();
    1810     return false;
    1811 }
    1812 
    1813 
    1814 /** @interface_method_impl{PDMDRVHLPR0,pfnAssertOther} */
    1815 static DECLCALLBACK(bool) pdmR0DrvHlp_AssertOther(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction)
    1816 {
    1817     PDMDRV_ASSERT_DRVINS(pDrvIns);
    1818     if (!VM_IS_EMT(pDrvIns->Internal.s.pVMR0))
    1819         return true;
    1820 
    1821     RTAssertMsg1Weak("AssertOther", iLine, pszFile, pszFunction);
    1822     RTAssertPanic();
    1823     return false;
    1824 }
    1825 
    1826 
    1827 /**
    1828  * The Ring-0 Context Driver Helper Callbacks.
    1829  */
    1830 extern DECLEXPORT(const PDMDRVHLPR0) g_pdmR0DrvHlp =
    1831 {
    1832     PDM_DRVHLPRC_VERSION,
    1833     pdmR0DrvHlp_VMSetError,
    1834     pdmR0DrvHlp_VMSetErrorV,
    1835     pdmR0DrvHlp_VMSetRuntimeError,
    1836     pdmR0DrvHlp_VMSetRuntimeErrorV,
    1837     pdmR0DrvHlp_AssertEMT,
    1838     pdmR0DrvHlp_AssertOther,
    1839     PDM_DRVHLPRC_VERSION
    1840 };
    1841 
    1842 /** @} */
    1843 
    1844 
    1845 
    1846 
    1847 /**
    1848  * Sets an irq on the PIC and I/O APIC.
    1849  *
    1850  * @returns true if delivered, false if postponed.
    1851  * @param   pGVM        The global (ring-0) VM structure.
    1852  * @param   iIrq        The irq.
    1853  * @param   iLevel      The new level.
    1854  * @param   uTagSrc     The IRQ tag and source.
    1855  *
    1856  * @remarks The caller holds the PDM lock.
    1857  */
    1858 static bool pdmR0IsaSetIrq(PGVM pGVM, int iIrq, int iLevel, uint32_t uTagSrc)
    1859 {
    1860     if (RT_LIKELY(    (   pGVM->pdm.s.IoApic.pDevInsR0
    1861                        || !pGVM->pdm.s.IoApic.pDevInsR3)
    1862                   &&  (   pGVM->pdm.s.Pic.pDevInsR0
    1863                        || !pGVM->pdm.s.Pic.pDevInsR3)))
    1864     {
    1865         if (pGVM->pdm.s.Pic.pDevInsR0)
    1866             pGVM->pdm.s.Pic.pfnSetIrqR0(pGVM->pdm.s.Pic.pDevInsR0, iIrq, iLevel, uTagSrc);
    1867         if (pGVM->pdm.s.IoApic.pDevInsR0)
    1868             pGVM->pdm.s.IoApic.pfnSetIrqR0(pGVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc);
    1869         return true;
    1870     }
    1871 
    1872     /* queue for ring-3 execution. */
    1873     PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pGVM->pdm.s.pDevHlpQueueR0);
    1874     AssertReturn(pTask, false);
    1875 
    1876     pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
    1877     pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
    1878     pTask->u.IsaSetIRQ.iIrq = iIrq;
    1879     pTask->u.IsaSetIRQ.iLevel = iLevel;
    1880     pTask->u.IsaSetIRQ.uTagSrc = uTagSrc;
    1881 
    1882     PDMQueueInsertEx(pGVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
    1883     return false;
    1884184}
    1885185
Note: See TracChangeset for help on using the changeset viewer.

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