VirtualBox

Changeset 33419 in vbox for trunk/src/VBox/Devices/Bus


Ignore:
Timestamp:
Oct 25, 2010 12:45:01 PM (14 years ago)
Author:
vboxsync
Message:

PDM, PCI: save MSI-X page in saved state, multiple vectors in MSI, tweaks

Location:
trunk/src/VBox/Devices/Bus
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r33370 r33419  
    2828#include <iprt/assert.h>
    2929#include <iprt/string.h>
     30#ifdef IN_RING3
     31#include <iprt/alloc.h>
     32#endif
    3033
    3134#include "../Builtins.h"
     
    527530        if (MsiIsEnabled(pPciDev))
    528531        {
    529             Log2(("MSI interrupt: %d level=%d\n", iIrq, iLevel));
    530532            PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
    531533            MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel);
     
    534536        if (MsixIsEnabled(pPciDev))
    535537        {
    536             Log2(("MSI-X interrupt: %d level=%d\n", iIrq, iLevel));
    537538            PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
    538539            MsixNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel);
     
    919920            if (RT_FAILURE(rc))
    920921                return rc;
     922            /* Save MSI-X page state */
     923            if (pDev->Int.s.u8MsixCapOffset != 0)
     924            {
     925                Assert(pDev->Int.s.pMsixPageR3 != NULL);
     926                SSMR3PutMem(pSSM, pDev->Int.s.pMsixPageR3, 0x1000);
     927                if (RT_FAILURE(rc))
     928                    return rc;
     929            }
    921930        }
    922931    }
     
    12141223    }
    12151224
     1225    void* pvMsixPage = RTMemTmpAllocZ(0x1000);
    12161226    /*
    12171227     * Iterate all the devices.
     
    12191229    for (i = 0;; i++)
    12201230    {
     1231        PPCIDEVICE  pDev;
    12211232        PCIDEVICE   DevTmp;
    1222         PPCIDEVICE  pDev;
    12231233
    12241234        /* index / terminator */
     
    12321242        {
    12331243            AssertMsgFailed(("u32=%#x i=%#x\n", u32, i));
    1234             return rc;
     1244            goto out;
    12351245        }
    12361246
     
    12601270        rc = SSMR3GetU32(pSSM, &DevTmp.Int.s.uFlags);
    12611271        if (RT_FAILURE(rc))
    1262             return rc;
     1272            goto out;
    12631273
    12641274        rc = SSMR3GetS32(pSSM, &DevTmp.Int.s.uIrqPinState);
    12651275        if (RT_FAILURE(rc))
    1266             return rc;
     1276            goto out;
    12671277
    12681278        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsiCapOffset);
    12691279        if (RT_FAILURE(rc))
    1270             return rc;
     1280            goto out;
    12711281
    12721282        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsiCapSize);
    12731283        if (RT_FAILURE(rc))
    1274             return rc;
     1284            goto out;
    12751285
    12761286        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsixCapOffset);
    12771287        if (RT_FAILURE(rc))
    1278             return rc;
     1288            goto out;
    12791289
    12801290        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsixCapSize);
    12811291        if (RT_FAILURE(rc))
    1282             return rc;
     1292            goto out;
     1293
     1294        /* Load MSI-X page state */
     1295        if (DevTmp.Int.s.u8MsixCapOffset != 0)
     1296        {
     1297            Assert(pvMsixPage != NULL);
     1298            SSMR3GetMem(pSSM, pvMsixPage, 0x1000);
     1299            if (RT_FAILURE(rc))
     1300                goto out;
     1301        }
    12831302
    12841303        /* check that it's still around. */
     
    13031322
    13041323        pDev->Int.s.uIrqPinState = DevTmp.Int.s.uIrqPinState;
    1305     }
    1306 
    1307     return VINF_SUCCESS;
     1324        pDev->Int.s.u8MsiCapOffset  = DevTmp.Int.s.u8MsiCapOffset;
     1325        pDev->Int.s.u8MsiCapSize    = DevTmp.Int.s.u8MsiCapSize;
     1326        pDev->Int.s.u8MsixCapOffset = DevTmp.Int.s.u8MsixCapOffset;
     1327        pDev->Int.s.u8MsixCapSize   = DevTmp.Int.s.u8MsixCapSize;
     1328        if (DevTmp.Int.s.u8MsixCapSize != 0)
     1329        {
     1330            Assert(pDev->Int.s.pMsixPageR3 != NULL);
     1331            memcpy(pDev->Int.s.pMsixPageR3, pvMsixPage, 0x1000);
     1332        }
     1333    }
     1334
     1335  out:
     1336    if (pvMsixPage)
     1337        RTMemTmpFree(pvMsixPage);
     1338
     1339    return rc;
    13081340}
    13091341
     
    18921924    int32_t     iFunction;
    18931925} PciSlotAssignments[] = {
    1894     /* Due to somewhat inflexible PCI bus configuration, ConsoleImpl hardcodes 0:5:0 as HDA address, so we shalln't put elsewhere */ 
     1926    /* Due to somewhat inflexible PCI bus configuration, ConsoleImpl hardcodes 0:5:0 as HDA address, so we shalln't put elsewhere */
    18951927#if 0
    18961928    {
  • trunk/src/VBox/Devices/Bus/MsiCommon.cpp

    r33314 r33419  
    5454}
    5555
    56 DECLINLINE(bool) msiIsMME(PPCIDEVICE pDev)
    57 {
    58     return (msiGetMessageControl(pDev) & VBOX_PCI_MSI_FLAGS_QSIZE) != 0;
     56DECLINLINE(uint8_t) msiGetMme(PPCIDEVICE pDev)
     57{
     58    return (msiGetMessageControl(pDev) & VBOX_PCI_MSI_FLAGS_QSIZE) >> 4;
    5959}
    6060
     
    7878    uint16_t lo = PCIDevGetWord(pDev, pDev->Int.s.u8MsiCapOffset + iOff);
    7979
    80     /// @todo: vector encoding into lower bits of message data, for Multiple Message Enable
    81     Assert(!msiIsMME(pDev));
     80    // vector encoding into lower bits of message data
     81    uint8_t bits = msiGetMme(pDev);
     82    uint16_t uMask = ((1 << bits) - 1);
     83    lo &= ~uMask;
     84    lo |= iVector & uMask;
    8285
    8386    return RT_MAKE_U32(lo, 0);
     
    219222    uint8_t    iCapOffset  = pMsiReg->iMsiCapOffset;
    220223    uint8_t    iNextOffset = pMsiReg->iMsiNextOffset;
    221     uint16_t   iFlags   = pMsiReg->iMsiFlags;
    222 
    223     if (cVectors != 1)
    224         /* We cannot handle multiple vectors yet */
     224    bool       f64bit      = pMsiReg->fMsi64bit;
     225    uint16_t   iFlags      = 0;
     226    int        iMmc;
     227
     228    /* Compute multiple-message capable bitfield */
     229    for (iMmc = 0; iMmc < 6; iMmc++)
     230    {
     231        if ((1 << iMmc) >= cVectors)
     232            break;
     233    }
     234
     235    if ((cVectors > VBOX_MSI_MAX_ENTRIES) || (1 << iMmc) < cVectors)
    225236        return VERR_TOO_MUCH_DATA;
    226237
    227     if (cVectors > VBOX_MSI_MAX_ENTRIES)
    228         return VERR_TOO_MUCH_DATA;
    229 
    230238    Assert(iCapOffset != 0 && iCapOffset < 0xff && iNextOffset < 0xff);
    231239
    232     bool f64bit = (iFlags & VBOX_PCI_MSI_FLAGS_64BIT) != 0;
    233240    /* We always support per-vector masking */
    234     iFlags |= VBOX_PCI_MSI_FLAGS_MASKBIT;
     241    iFlags |= VBOX_PCI_MSI_FLAGS_MASKBIT | iMmc;
     242    if (f64bit)
     243        iFlags |= VBOX_PCI_MSI_FLAGS_64BIT;
     244    /* How many vectors we're capable of */
     245    iFlags |= iMmc;
    235246
    236247    pDev->Int.s.u8MsiCapOffset = iCapOffset;
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