VirtualBox

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


Ignore:
Timestamp:
Oct 6, 2010 9:28:42 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66421
Message:

PDM, VMM, PCI: reworked MSI API: now MSIs delivered via IOAPIC API, not with MMIO access, LSI logic now can work in MSI mode

Location:
trunk/src/VBox/Devices
Files:
6 edited

Legend:

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

    r32860 r32935  
    528528static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel)
    529529{
    530     if (MSIIsEnabled(pPciDev))
     530    if (MsiIsEnabled(pPciDev))
    531531    {
    532532        Log2(("Raise a MSI interrupt: %d\n", iIrq));
    533533        /* 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) */
    534534        if ((iLevel & PDM_IRQ_LEVEL_HIGH) != 0)
    535             MSINotify(pGlobals->aPciBus.CTX_SUFF(pDevIns), pPciDev, iIrq);
     535        {
     536            PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
     537            MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq);
     538        }
    536539        return;
    537540    }
     
    786789static DECLCALLBACK(int) ich9pciRegisterMsi(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg)
    787790{
    788     return MSIInit(pPciDev, pMsiReg);
     791    return MsiInit(pPciDev, pMsiReg);
    789792}
    790793
     
    16861689       )
    16871690    {
    1688         return MSIPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
     1691        return MsiPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
    16891692    }
    16901693
     
    17231726       )
    17241727    {
    1725         MSIPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, val, len);
     1728        MsiPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns),
     1729                          aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp),
     1730                          aDev, u32Address, val, len);
    17261731        return;
    17271732    }
  • trunk/src/VBox/Devices/Bus/MsiCommon.cpp

    r32862 r32935  
    9292
    9393
    94 void     MSIPciConfigWrite(PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
     94void     MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
    9595{
    9696    int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
     
    113113                /* don't change read-only bits: 1-3,7 */
    114114                val &= UINT32_C(~0x8e);
    115                 pDev->config[uAddr] &= ~val;
     115                pDev->config[uAddr] = val;
    116116                break;
    117117            case VBOX_MSI_CAP_MESSAGE_CONTROL + 1:
     
    149149                                /* To ensure that we're no longer masked */
    150150                                pDev->config[uAddr] &= ~iBit;
    151                                 MSINotify(pDevIns, pDev, maskUpdated*8 + iBitNum);
     151                                MsiNotify(pDevIns, pPciHlp, pDev, maskUpdated*8 + iBitNum);
    152152                            }
    153153                        }
     
    162162}
    163163
    164 uint32_t MSIPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len)
     164uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len)
    165165{
    166166    int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
     
    172172    {
    173173        case 1:
    174             rv = PCIDevGetByte(pDev, u32Address);
     174            rv = PCIDevGetByte(pDev,  u32Address);
    175175            break;
    176176        case 2:
    177             rv = PCIDevGetWord(pDev, u32Address);
     177            rv = PCIDevGetWord(pDev,  u32Address);
    178178            break;
    179179        case 4:
     
    190190
    191191
    192 int MSIInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
     192int MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
    193193{
    194194    uint16_t   cVectors    = pMsiReg->cVectors;
     
    225225
    226226
    227 bool     MSIIsEnabled(PPCIDEVICE pDev)
     227bool     MsiIsEnabled(PPCIDEVICE pDev)
    228228{
    229229    return PCIIsMsiCapable(pDev) && msiIsEnabled(pDev);
    230230}
    231231
    232 void MSINotify(PPDMDEVINS pDevIns, PPCIDEVICE pDev, int iVector)
     232void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector)
    233233{
    234234    Log2(("MSINotify: %d\n", iVector));
     
    250250    *upPending &= ~(1<<iVector);
    251251
    252     PDMDevHlpPhysWrite(pDevIns, GCAddr, &u32Value, sizeof(u32Value));
    253 }
     252    Assert(pPciHlp->pfnIoApicSendMsi != NULL);
     253    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value);
     254}
  • trunk/src/VBox/Devices/Bus/MsiCommon.h

    r32860 r32935  
    1515 */
    1616
     17/* Maybe belongs to types.h */
     18#ifdef IN_RING3
     19typedef PCPDMPCIHLPR3 PCPDMPCIHLP;
     20#endif
     21
     22#ifdef IN_RING0
     23typedef PCPDMPCIHLPR0 PCPDMPCIHLP;
     24#endif
     25
     26#ifdef IN_RC
     27typedef PCPDMPCIHLPRC PCPDMPCIHLP;
     28#endif
     29
    1730/* Init MSI support in the device. */
    18 int      MSIInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg);
     31int      MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg);
    1932
    2033/* If MSI is enabled, so that MSINotify() shall be used for notifications.  */
    21 bool     MSIIsEnabled(PPCIDEVICE pDev);
     34bool     MsiIsEnabled(PPCIDEVICE pDev);
     35
    2236/* Device notification (aka interrupt). */
    23 void     MSINotify(PPDMDEVINS pDevIns, PPCIDEVICE pDev, int iVector);
     37void     MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector);
    2438
    2539/* PCI config space accessors for MSI registers */
    26 void     MSIPciConfigWrite(PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len);
    27 uint32_t MSIPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
     40void     MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len);
     41uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r32857 r32935  
    356356PDMBOTHCBDECL(int)  ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
    357357PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
     358PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue);
    358359
    359360static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val);
     
    15311532    return val;
    15321533}
    1533 /**
    1534  * See chapter 10.11 MESSAGE SIGNALLED INTERRUPTS of IA-32 Intel Architecture
    1535  * Software Developer's Manual, Volume 3A: System Programming Guide, Part 1
    1536  * for details on MSI and LAPIC interaction.
    1537  */
    1538 static int apicSendMsi(APICDeviceInfo* dev, RTGCPHYS addr, uint32_t val)
    1539 {
    1540     uint8_t  dest = (addr & VBOX_MSI_ADDR_DEST_ID_MASK) >> VBOX_MSI_ADDR_DEST_ID_SHIFT;
    1541     uint8_t  vector_num = (val & VBOX_MSI_DATA_VECTOR_MASK) >> VBOX_MSI_DATA_VECTOR_SHIFT;
    1542     uint8_t  dest_mode = (addr >> VBOX_MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
    1543     uint8_t  trigger_mode = (val >> VBOX_MSI_DATA_TRIGGER_SHIFT) & 0x1;
    1544     uint8_t  delivery_mode = (val >> VBOX_MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
    1545     /**
    1546      * This bit indicates whether the message should be directed to the
    1547      * processor with the lowest interrupt priority among
    1548      * processors that can receive the interrupt, ignored ATM.
    1549      */
    1550     uint8_t  redir_hint = (addr >> VBOX_MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
    1551     uint32_t deliver_bitmask = apic_get_delivery_bitmask(dev, dest, dest_mode);
    1552 
    1553     return apic_bus_deliver(dev, deliver_bitmask, delivery_mode,
    1554                             vector_num, 0 /* polarity */, trigger_mode);
    1555 }
    15561534
    15571535static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, RTGCPHYS addr, uint32_t val)
     
    15641542#endif
    15651543
    1566     index = (addr >> 4) & 0xff;
    1567     addr -= (s->apicbase & ~0xfff);
    1568 
    1569     if (addr > 0xfff || (index == 0))
    1570         return apicSendMsi(dev, addr, val);
     1544    index = (addr >> 4) & 0xff; 
    15711545
    15721546    switch(index) {
     
    25032477     */
    25042478    uint32_t ApicBase = pThis->paLapicsR3[0].apicbase & ~0xfff;
    2505     /* See comment in msi.h, on why LAPIC and MSI share same region */
    2506     rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, VBOX_MSI_ADDR_SIZE, pThis,
     2479    rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, 0x1000, pThis,
    25072480                               apicMMIOWrite, apicMMIORead, NULL, "APIC Memory");
    25082481    if (RT_FAILURE(rc))
     
    25132486        pThis->pCritSectRC = pThis->pApicHlpR3->pfnGetRCCritSect(pDevIns);
    25142487
    2515         rc = PDMDevHlpMMIORegisterRC(pDevIns, ApicBase, VBOX_MSI_ADDR_SIZE, 0,
     2488        rc = PDMDevHlpMMIORegisterRC(pDevIns, ApicBase, 0x1000, 0,
    25162489                                     "apicMMIOWrite", "apicMMIORead", NULL);
    25172490        if (RT_FAILURE(rc))
     
    25232496        pThis->pCritSectR0 = pThis->pApicHlpR3->pfnGetR0CritSect(pDevIns);
    25242497
    2525         rc = PDMDevHlpMMIORegisterR0(pDevIns, ApicBase, VBOX_MSI_ADDR_SIZE, 0,
     2498        rc = PDMDevHlpMMIORegisterR0(pDevIns, ApicBase, 0x1000, 0,
    25262499                                     "apicMMIOWrite", "apicMMIORead", NULL);
    25272500        if (RT_FAILURE(rc))
     
    27042677}
    27052678
     2679PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
     2680{
     2681    IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
     2682
     2683    LogFlow(("ioapicSendMsi: Address=%p uValue=%\n", GCAddr, uValue));
     2684
     2685    uint8_t  dest = (GCAddr & VBOX_MSI_ADDR_DEST_ID_MASK) >> VBOX_MSI_ADDR_DEST_ID_SHIFT;
     2686    uint8_t  vector_num = (uValue & VBOX_MSI_DATA_VECTOR_MASK) >> VBOX_MSI_DATA_VECTOR_SHIFT;
     2687    uint8_t  dest_mode = (GCAddr >> VBOX_MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
     2688    uint8_t  trigger_mode = (uValue >> VBOX_MSI_DATA_TRIGGER_SHIFT) & 0x1;
     2689    uint8_t  delivery_mode = (uValue >> VBOX_MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
     2690    /**
     2691     * This bit indicates whether the message should be directed to the
     2692     * processor with the lowest interrupt priority among
     2693     * processors that can receive the interrupt, ignored ATM.
     2694     */
     2695    uint8_t  redir_hint = (GCAddr >> VBOX_MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
     2696
     2697    int rc = pThis->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(pDevIns,
     2698                                                            dest,
     2699                                                            dest_mode,
     2700                                                            delivery_mode,
     2701                                                            vector_num,
     2702                                                            0 /* polarity, n/a */,
     2703                                                            trigger_mode);
     2704    /* We must be sure that attempts to reschedule in R3
     2705       never get here */
     2706    Assert(rc == VINF_SUCCESS);
     2707}
    27062708
    27072709#ifdef IN_RING3
     
    28482850     */
    28492851    IoApicReg.u32Version  = PDM_IOAPICREG_VERSION;
    2850     IoApicReg.pfnSetIrqR3 = ioapicSetIrq;
     2852    IoApicReg.pfnSetIrqR3 = ioapicSetIrq;   
    28512853    IoApicReg.pszSetIrqRC = fGCEnabled ? "ioapicSetIrq" : NULL;
    28522854    IoApicReg.pszSetIrqR0 = fR0Enabled ? "ioapicSetIrq" : NULL;
     2855    IoApicReg.pfnSendMsiR3 = ioapicSendMsi;
     2856    IoApicReg.pszSendMsiRC = fGCEnabled ? "ioapicSendMsi" : NULL;
     2857    IoApicReg.pszSendMsiR0 = fR0Enabled ? "ioapicSendMsi" : NULL;
     2858
    28532859    rc = PDMDevHlpIOAPICRegister(pDevIns, &IoApicReg, &s->pIoApicHlpR3);
    28542860    if (RT_FAILURE(rc))
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r31382 r32935  
    4848/** Maximum number of entries in the release log. */
    4949#define MAX_REL_LOG_ERRORS 1024
     50
     51/* If LSI shall emulate MSI support */
     52#define LSILOGIC_WITH_MSI
    5053
    5154/**
     
    48484851    PCIDevSetInterruptPin(&pThis->PciDev,   0x01); /* Interrupt pin A */
    48494852
     4853#ifdef LSILOGIC_WITH_MSI
     4854    PCIDevSetStatus(&pThis->PciDev,   VBOX_PCI_STATUS_CAP_LIST);
     4855    PCIDevSetCapabilityList(&pThis->PciDev, 0x80);
     4856#endif
     4857
    48504858    pThis->pDevInsR3 = pDevIns;
    48514859    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
     
    48604868    if (RT_FAILURE(rc))
    48614869        return rc;
     4870
     4871#ifdef LSILOGIC_WITH_MSI
     4872    PDMMSIREG aMsiReg;
     4873    aMsiReg.cVectors = 1;
     4874    aMsiReg.iCapOffset = 0x80;
     4875    aMsiReg.iNextOffset = 0x0;
     4876    aMsiReg.iMsiFlags = 0;
     4877    rc = PDMDevHlpPCIRegisterMsi(pDevIns, &aMsiReg);
     4878    AssertRC(rc);
     4879    if (RT_FAILURE (rc))
     4880        return rc;
     4881#endif
    48624882
    48634883    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, LSILOGIC_PCI_SPACE_IO_SIZE, PCI_ADDRESS_SPACE_IO, lsilogicMap);
     
    51505170#endif /* IN_RING3 */
    51515171#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    5152 
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r32774 r32935  
    31953195};
    31963196#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    3197 
Note: See TracChangeset for help on using the changeset viewer.

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