VirtualBox

Changeset 66270 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 27, 2017 6:33:42 PM (8 years ago)
Author:
vboxsync
Message:

Devices/Bus/MsiCommon.cpp: support devices with MSI, but without vector masking

File:
1 edited

Legend:

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

    r64454 r66270  
    77
    88/*
    9  * Copyright (C) 2010-2016 Oracle Corporation
     9 * Copyright (C) 2010-2017 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4343}
    4444
     45/** @todo r=klaus This design assumes that the config space cache is always
     46 * up to date, which is a wrong assumption for the "emulate passthrough" case
     47 * where only the callbacks give the correct data. */
    4548DECLINLINE(uint32_t*) msiGetMaskBits(PPDMPCIDEV pDev)
    4649{
    4750    uint8_t iOff = msiIs64Bit(pDev) ? VBOX_MSI_CAP_MASK_BITS_64 : VBOX_MSI_CAP_MASK_BITS_32;
    48     /* passthrough devices may have no masked/pending support */
     51    /* devices may have no masked/pending support */
    4952    if (iOff >= pDev->Int.s.u8MsiCapSize)
    5053        return NULL;
     
    5356}
    5457
     58/** @todo r=klaus This design assumes that the config space cache is always
     59 * up to date, which is a wrong assumption for the "emulate passthrough" case
     60 * where only the callbacks give the correct data. */
    5561DECLINLINE(uint32_t*) msiGetPendingBits(PPDMPCIDEV pDev)
    5662{
    5763    uint8_t iOff = msiIs64Bit(pDev) ? VBOX_MSI_CAP_PENDING_BITS_64 : VBOX_MSI_CAP_PENDING_BITS_32;
    58     /* passthrough devices may have no masked/pending support */
     64    /* devices may have no masked/pending support */
    5965    if (iOff >= pDev->Int.s.u8MsiCapSize)
    6066        return NULL;
     
    215221    uint8_t    iNextOffset = pMsiReg->iMsiNextOffset;
    216222    bool       f64bit      = pMsiReg->fMsi64bit;
     223    bool       fNoMasking  = pMsiReg->fMsiNoMasking;
    217224    uint16_t   iFlags      = 0;
    218     int        iMmc;
    219 
    220     /* Compute multiple-message capable bitfield */
    221     for (iMmc = 0; iMmc < 6; iMmc++)
    222     {
    223         if ((1 << iMmc) >= cVectors)
    224             break;
    225     }
    226 
    227     if ((cVectors > VBOX_MSI_MAX_ENTRIES) || (1 << iMmc) < cVectors)
    228         return VERR_TOO_MUCH_DATA;
    229225
    230226    Assert(iCapOffset != 0 && iCapOffset < 0xff && iNextOffset < 0xff);
    231227
    232     /* We always support per-vector masking */
    233     iFlags |= VBOX_PCI_MSI_FLAGS_MASKBIT | iMmc;
     228    if (!fNoMasking)
     229    {
     230        int iMmc;
     231
     232        /* Compute multiple-message capable bitfield */
     233        for (iMmc = 0; iMmc < 6; iMmc++)
     234        {
     235            if ((1 << iMmc) >= cVectors)
     236                break;
     237        }
     238
     239        if ((cVectors > VBOX_MSI_MAX_ENTRIES) || (1 << iMmc) < cVectors)
     240            return VERR_TOO_MUCH_DATA;
     241
     242        /* We support per-vector masking */
     243        iFlags |= VBOX_PCI_MSI_FLAGS_MASKBIT;
     244        /* How many vectors we're capable of */
     245        iFlags |= iMmc;
     246    }
     247    else
     248        AssertReturn(cVectors == 1, VERR_TOO_MUCH_DATA);
     249
    234250    if (f64bit)
    235251        iFlags |= VBOX_PCI_MSI_FLAGS_64BIT;
    236     /* How many vectors we're capable of */
    237     iFlags |= iMmc;
    238252
    239253    pDev->Int.s.u8MsiCapOffset = iCapOffset;
     
    244258    PCIDevSetWord(pDev,  iCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL, iFlags);
    245259
    246     *msiGetMaskBits(pDev)    = 0;
    247     *msiGetPendingBits(pDev) = 0;
     260    if (!fNoMasking)
     261    {
     262        *msiGetMaskBits(pDev)    = 0;
     263        *msiGetPendingBits(pDev) = 0;
     264    }
    248265
    249266    pciDevSetMsiCapable(pDev);
     267    if (f64bit)
     268        pciDevSetMsi64Capable(pDev);
    250269
    251270    return VINF_SUCCESS;
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