VirtualBox

Changeset 33215 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Oct 18, 2010 5:51:24 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66759
Message:

PCI: fixed few MSI-related bugs, now SLES boots fine with MSI SATA

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

Legend:

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

    r33203 r33215  
    527527        if (MsiIsEnabled(pPciDev))
    528528        {
    529             Log2(("Raise a MSI interrupt: %d\n", iIrq));
    530             /* We only trigger MSI on level up, as technically it's matching flip-flop best (maybe even assert that level == PDM_IRQ_LEVEL_FLIP_FLOP) */
    531             if ((iLevel & PDM_IRQ_LEVEL_HIGH) != 0)
    532             {
    533                 PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
    534                 MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq);
    535             }
     529            Log2(("MSI interrupt: %d level=%d\n", iIrq, iLevel));
     530            PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
     531            MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel);
    536532        }
    537533        return;
  • trunk/src/VBox/Devices/Bus/MsiCommon.cpp

    r32935 r33215  
    9191}
    9292
     93DECLINLINE(bool) msiBitJustSet(uint32_t u64OldValue,
     94                               uint32_t u64NewValue,
     95                               uint32_t u64Mask)
     96{
     97    return (!(u64OldValue & u64Mask) && !!(u64NewValue & u64Mask));
     98}
     99
    93100
    94101void     MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
     
    142149                    if (maskUpdated != -1 && msiIsEnabled(pDev))
    143150                    {
    144                         for (int iBitNum = 0; i<8; i++)
     151                        uint32_t*  puPending = msiGetPendingBits(pDev);
     152                        for (int iBitNum = 0; iBitNum < 8; iBitNum++)
    145153                        {
    146154                            int32_t iBit = 1 << iBitNum;
     155                            uint32_t uVector = maskUpdated*8 + iBitNum;
     156
    147157                            if (msiBitJustCleared(pDev->config[uAddr], val, iBit))
    148158                            {
     159                                Log(("msi: mask updated bit %d@%x (%d)\n", iBitNum, uAddr, maskUpdated));
     160
    149161                                /* To ensure that we're no longer masked */
    150162                                pDev->config[uAddr] &= ~iBit;
    151                                 MsiNotify(pDevIns, pPciHlp, pDev, maskUpdated*8 + iBitNum);
     163                                if ((*puPending & (1 << uVector)) != 0)
     164                                {
     165                                    Log(("msi: notify earlier masked pending vector: %d\n", uVector));
     166                                    MsiNotify(pDevIns, pPciHlp, pDev, uVector, PDM_IRQ_LEVEL_HIGH);
     167                                }
     168                            }
     169                            if (msiBitJustSet(pDev->config[uAddr], val, iBit))
     170                            {
     171                                Log(("msi: mask vector: %d\n", uVector));
    152172                            }
    153173                        }
     
    219239    PCIDevSetWord(pDev,  iCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL, iMsiFlags);
    220240
     241    *msiGetMaskBits(pDev)    = 0;
     242    *msiGetPendingBits(pDev) = 0;
     243
    221244    PCISetMsiCapable(pDev);
    222245
     
    230253}
    231254
    232 void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector)
    233 {
    234     Log2(("MSINotify: %d\n", iVector));
    235 
     255void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel)
     256{
    236257    AssertMsg(msiIsEnabled(pDev), ("Must be enabled to use that"));
    237258
    238259    uint32_t   uMask = *msiGetMaskBits(pDev);
    239     uint32_t*  upPending = msiGetPendingBits(pDev);
     260    uint32_t*  puPending = msiGetPendingBits(pDev);
     261
     262    LogFlow(("MSINotify: %d pending=%x mask=%x\n", iVector, *puPending, uMask));
     263
     264    /* We only trigger MSI on level up */
     265    if ((iLevel & PDM_IRQ_LEVEL_HIGH) == 0)
     266    {
     267        /* @todo: maybe clear pending interrupts on level down? */
     268#if 0
     269        *puPending &= ~(1<<iVector);
     270        LogFlow(("msi: clear pending %d, now %x\n", iVector, *puPending));
     271#endif
     272        return;
     273    }
    240274
    241275    if ((uMask & (1<<iVector)) != 0)
    242276    {
    243         *upPending |= (1<<iVector);
     277        *puPending |= (1<<iVector);
     278        LogFlow(("msi: %d is masked, mark pending, now %x\n", iVector, *puPending));
    244279        return;
    245280    }
     
    248283    uint32_t   u32Value = msiGetMsiData(pDev, iVector);
    249284
    250     *upPending &= ~(1<<iVector);
     285    *puPending &= ~(1<<iVector);
    251286
    252287    Assert(pPciHlp->pfnIoApicSendMsi != NULL);
  • trunk/src/VBox/Devices/Bus/MsiCommon.h

    r32935 r33215  
    3535
    3636/* Device notification (aka interrupt). */
    37 void     MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector);
     37void     MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel);
    3838
    3939/* PCI config space accessors for MSI registers */
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