Esempio n. 1
0
void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel, uint32_t uTagSrc)
{
    AssertMsg(msiIsEnabled(pDev), ("Must be enabled to use that"));

    uint32_t   uMask = *msiGetMaskBits(pDev);
    uint32_t*  puPending = msiGetPendingBits(pDev);

    LogFlow(("MsiNotify: %d pending=%x mask=%x\n", iVector, *puPending, uMask));

    /* We only trigger MSI on level up */
    if ((iLevel & PDM_IRQ_LEVEL_HIGH) == 0)
    {
        /* @todo: maybe clear pending interrupts on level down? */
#if 0
        *puPending &= ~(1<<iVector);
        LogFlow(("msi: clear pending %d, now %x\n", iVector, *puPending));
#endif
        return;
    }

    if ((uMask & (1<<iVector)) != 0)
    {
        *puPending |= (1<<iVector);
        LogFlow(("msi: %d is masked, mark pending, now %x\n", iVector, *puPending));
        return;
    }

    RTGCPHYS   GCAddr = msiGetMsiAddress(pDev);
    uint32_t   u32Value = msiGetMsiData(pDev, iVector);

    *puPending &= ~(1<<iVector);

    Assert(pPciHlp->pfnIoApicSendMsi != NULL);
    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value, uTagSrc);
}
Esempio n. 2
0
void MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel, uint32_t uTagSrc)
{
    AssertMsg(msixIsEnabled(pDev), ("Must be enabled to use that"));

    Assert(pPciHlp->pfnIoApicSendMsi != NULL);

    /* We only trigger MSI-X on level up */
    if ((iLevel & PDM_IRQ_LEVEL_HIGH) == 0)
    {
        return;
    }

    // if this vector is somehow disabled
    if (msixIsMasked(pDev) || msixIsVectorMasked(pDev, iVector))
    {
        // mark pending bit
        msixSetPending(pDev, iVector);
        return;
    }

    // clear pending bit
    msixClearPending(pDev, iVector);

    RTGCPHYS   GCAddr = msixGetMsiAddress(pDev, iVector);
    uint32_t   u32Value = msixGetMsiData(pDev, iVector);

    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value, uTagSrc);
}