VirtualBox

Changeset 32935 in vbox


Ignore:
Timestamp:
Oct 6, 2010 9:28:42 AM (15 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
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/include/VBox/pdmapi.h

    r30072 r32935  
    4444VMMDECL(int)    PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level);
    4545VMMDECL(int)    PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level);
     46VMMDECL(int)    PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue);
    4647VMMDECL(bool)   PDMHasIoApic(PVM pVM);
    4748VMMDECL(int)    PDMApicHasPendingIrq(PVM pVM, bool *pfPending);
  • TabularUnified trunk/include/VBox/pdmdev.h

    r32820 r32935  
    579579
    580580    /**
     581     * Send an MSI.
     582     *
     583     * @param   pDevIns         PCI device instance.
     584     * @param   GCAddr          Physical address MSI request was written.
     585     * @param   uValue          Value written.
     586     * @thread  EMT only.
     587     */
     588    DECLRCCALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
     589
     590
     591    /**
    581592     * Acquires the PDM lock.
    582593     *
     
    603614typedef RCPTRTYPE(const PDMPCIHLPRC *) PCPDMPCIHLPRC;
    604615
    605 /** Current PDMPCIHLPR3 version number. */
    606 #define PDM_PCIHLPRC_VERSION                    PDM_VERSION_MAKE(0xfffd, 1, 0)
     616/** Current PDMPCIHLPRC version number. */
     617#define PDM_PCIHLPRC_VERSION                    PDM_VERSION_MAKE(0xfffd, 2, 0)
    607618
    608619
     
    634645     */
    635646    DECLR0CALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     647
     648    /**
     649     * Send an MSI.
     650     *
     651     * @param   pDevIns         PCI device instance.
     652     * @param   GCAddr          Physical address MSI request was written.
     653     * @param   uValue          Value written.
     654     * @thread  EMT only.
     655     */
     656    DECLR0CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
     657
    636658
    637659    /**
     
    661683
    662684/** Current PDMPCIHLPR0 version number. */
    663 #define PDM_PCIHLPR0_VERSION                    PDM_VERSION_MAKE(0xfffc, 1, 0)
     685#define PDM_PCIHLPR0_VERSION                    PDM_VERSION_MAKE(0xfffc, 2, 0)
    664686
    665687/**
     
    690712     */
    691713    DECLR3CALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     714
     715    /**
     716     * Send an MSI.
     717     *
     718     * @param   pDevIns         PCI device instance.
     719     * @param   GCAddr          Physical address MSI request was written.
     720     * @param   uValue          Value written.
     721     * @thread  EMT only.
     722     */
     723    DECLR3CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
    692724
    693725    /**
     
    751783
    752784/** Current PDMPCIHLPR3 version number. */
    753 #define PDM_PCIHLPR3_VERSION                    PDM_VERSION_MAKE(0xfffb, 1, 0)
     785#define PDM_PCIHLPR3_VERSION                    PDM_VERSION_MAKE(0xfffb, 2, 0)
    754786
    755787
     
    14491481    /** The name of the R0 SetIrq entry point. */
    14501482    const char         *pszSetIrqR0;
     1483
     1484    /**
     1485     * Send a MSI.
     1486     *
     1487     * @param   pDevIns         Device instance of the I/O APIC.
     1488     * @param   GCPhys          Request address.
     1489     * @param   uValue          Request value.
     1490     */
     1491    DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
     1492
     1493    /** The name of the GC SendMsi entry point. */
     1494    const char         *pszSendMsiRC;
     1495
     1496    /** The name of the R0 SendMsi entry point. */
     1497    const char         *pszSendMsiR0;
    14511498} PDMIOAPICREG;
    14521499/** Pointer to an APIC registration structure. */
     
    14541501
    14551502/** Current PDMAPICREG version number. */
    1456 #define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 1, 0)
     1503#define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 2, 0)
    14571504
    14581505
  • TabularUnified 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    }
  • TabularUnified 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}
  • TabularUnified 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);
  • TabularUnified 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))
  • TabularUnified 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 
  • TabularUnified trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r32774 r32935  
    31953195};
    31963196#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    3197 
  • TabularUnified trunk/src/VBox/VMM/PDMDevHlp.cpp

    r32820 r32935  
    20432043    else
    20442044    {
    2045         pPciBus->pfnSetIrqRC = 0;
    2046         pPciBus->pDevInsRC   = 0;
     2045        pPciBus->pfnSetIrqRC  = 0;
     2046        pPciBus->pDevInsRC    = 0;
    20472047    }
    20482048
     
    25552555        return VERR_INVALID_PARAMETER;
    25562556    }
    2557     if (!pIoApicReg->pfnSetIrqR3)
     2557    if (!pIoApicReg->pfnSetIrqR3 || !pIoApicReg->pfnSendMsiR3)
    25582558    {
    25592559        Assert(pIoApicReg->pfnSetIrqR3);
     
    25682568        return VERR_INVALID_PARAMETER;
    25692569    }
     2570    if (    pIoApicReg->pszSendMsiRC
     2571        &&  !VALID_PTR(pIoApicReg->pszSendMsiRC))
     2572    {
     2573        Assert(VALID_PTR(pIoApicReg->pszSendMsiRC));
     2574        LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     2575        return VERR_INVALID_PARAMETER;
     2576    }
    25702577    if (    pIoApicReg->pszSetIrqR0
    25712578        &&  !VALID_PTR(pIoApicReg->pszSetIrqR0))
    25722579    {
    25732580        Assert(VALID_PTR(pIoApicReg->pszSetIrqR0));
     2581        LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     2582        return VERR_INVALID_PARAMETER;
     2583    }
     2584    if (    pIoApicReg->pszSendMsiR0
     2585        &&  !VALID_PTR(pIoApicReg->pszSendMsiR0))
     2586    {
     2587        Assert(VALID_PTR(pIoApicReg->pszSendMsiR0));
    25742588        LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    25752589        return VERR_INVALID_PARAMETER;
     
    26312645    }
    26322646
     2647    if (pIoApicReg->pszSendMsiRC)
     2648    {
     2649        int rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pReg->szRCMod, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSendMsiRC);
     2650        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pIoApicReg->pszSendMsiRC, rc));
     2651        if (RT_FAILURE(rc))
     2652        {
     2653            LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     2654            return rc;
     2655        }
     2656    }
     2657    else
     2658    {
     2659        pVM->pdm.s.IoApic.pfnSendMsiRC = 0;
     2660    }
     2661
    26332662    /*
    26342663     * Resolve & initialize the R0 bits.
     
    26522681    }
    26532682
     2683    if (pIoApicReg->pszSendMsiR0)
     2684    {
     2685        int rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pReg->szR0Mod, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSendMsiR0);
     2686        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pIoApicReg->pszSendMsiR0, rc));
     2687        if (RT_FAILURE(rc))
     2688        {
     2689            LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     2690            return rc;
     2691        }
     2692    }
     2693    else
     2694    {
     2695        pVM->pdm.s.IoApic.pfnSendMsiR0 = 0;
     2696    }
     2697
     2698
    26542699    /*
    26552700     * Initialize the R3 bits.
     
    26572702    pVM->pdm.s.IoApic.pDevInsR3   = pDevIns;
    26582703    pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3;
     2704    pVM->pdm.s.IoApic.pfnSendMsiR3 = pIoApicReg->pfnSendMsiR3;
    26592705    Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    26602706
  • TabularUnified trunk/src/VBox/VMM/PDMDevMiscHlp.cpp

    r28800 r32935  
    458458}
    459459
    460 
    461460/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
    462461static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    463462{
    464463    PDMDEV_ASSERT_DEVINS(pDevIns);
    465     Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
     464    Log4(("pdmR3PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
    466465    PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);
    467466}
    468467
     468/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
     469static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
     470{
     471    PDMDEV_ASSERT_DEVINS(pDevIns);
     472    Log4(("pdmR3PciHlp_IoApicSendMsi: address=%p value=%x\n", GCAddr, uValue));
     473    PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, GCAddr, uValue);
     474}
    469475
    470476/** @interface_method_impl{PDMPCIHLPR3,pfnIsMMIO2Base} */
     
    535541    pdmR3PciHlp_IsaSetIrq,
    536542    pdmR3PciHlp_IoApicSetIrq,
     543    pdmR3PciHlp_IoApicSendMsi,
    537544    pdmR3PciHlp_IsMMIO2Base,
    538545    pdmR3PciHlp_GetRCHelpers,
  • TabularUnified trunk/src/VBox/VMM/PDMInternal.h

    r32820 r32935  
    548548    /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
    549549    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     550    /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
     551    DECLR3CALLBACKMEMBER(void,      pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
    550552
    551553    /** Pointer to the PIC device instance - R0. */
     
    553555    /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
    554556    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     557    /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
     558    DECLR0CALLBACKMEMBER(void,      pfnSendMsiR0,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
    555559
    556560    /** Pointer to the APIC device instance - RC Ptr. */
     
    558562    /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
    559563    DECLRCCALLBACKMEMBER(void,      pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
     564     /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
     565    DECLRCCALLBACKMEMBER(void,      pfnSendMsiRC,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
     566
     567    uint8_t                         Alignment[4];
    560568} PDMIOAPIC;
    561569
  • TabularUnified trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r28800 r32935  
    154154}
    155155
     156/**
     157 * Send a MSI to an I/O APIC.
     158 *
     159 * @returns VBox status code.
     160 * @param   pVM             VM handle.
     161 * @param   GCAddr          Request address.
     162 * @param   u8Value         REquest value.
     163 */
     164VMMDECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)
     165{
     166    if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
     167    {
     168        Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi));
     169        pdmLock(pVM);
     170        pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), GCAddr, uValue);
     171        pdmUnlock(pVM);
     172        return VINF_SUCCESS;
     173    }
     174    return VERR_PDM_NO_PIC_INSTANCE;
     175}
     176
     177
    156178
    157179/**
  • TabularUnified trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp

    r32156 r32935  
    5555static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
    5656static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
    57 
    58 
    59 
     57static void pdmRCIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue);
    6058
    6159/** @name Raw-Mode Context Device Helpers
     
    553551{
    554552    PDMDEV_ASSERT_DEVINS(pDevIns);
    555     Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
     553    Log4(("pdmRCPciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
    556554    pdmRCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
     555}
     556
     557/** @interface_method_impl{PDMPCIHLPRC,pfnIoApicSendMsi} */
     558static DECLCALLBACK(void) pdmRCPciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
     559{
     560    PDMDEV_ASSERT_DEVINS(pDevIns);
     561    Log4(("pdmRCPciHlp_IoApicSendMsi: Address=%p Value=%d\n", GCAddr, uValue));
     562    pdmRCIoApicSendMsi(pDevIns->Internal.s.pVMRC, GCAddr, uValue);
    557563}
    558564
     
    582588    pdmRCPciHlp_IsaSetIrq,
    583589    pdmRCPciHlp_IoApicSetIrq,
     590    pdmRCPciHlp_IoApicSendMsi,
    584591    pdmRCPciHlp_Lock,
    585592    pdmRCPciHlp_Unlock,
     
    786793    }
    787794}
     795
     796
     797/**
     798 * Sends an MSI to I/O APIC.
     799 *
     800 * @param   pVM     The VM handle.
     801 * @param   GCAddr  Address of the message.
     802 * @param   uValue  Value of the message.
     803 */
     804static void pdmRCIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)
     805{
     806    if (pVM->pdm.s.IoApic.pDevInsRC)
     807    {
     808        pdmLock(pVM);
     809        pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCAddr, uValue);
     810        pdmUnlock(pVM);
     811    }
     812}
  • TabularUnified trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r32156 r32935  
    5757static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel);
    5858static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel);
    59 
     59static void pdmR0IoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue);
    6060
    6161
     
    592592}
    593593
     594/** @interface_method_impl{PDMPCIHLPR0,pfnIoApicSendMsi} */
     595static DECLCALLBACK(void) pdmR0PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
     596{
     597    PDMDEV_ASSERT_DEVINS(pDevIns);
     598    Log4(("pdmR0PciHlp_IoApicSendMsi: Address=%p Value=%d\n", GCAddr, uValue));
     599    pdmR0IoApicSendMsi(pDevIns->Internal.s.pVMR0, GCAddr, uValue);
     600}
    594601
    595602/** @interface_method_impl{PDMPCIHLPR0,pfnLock} */
     
    617624    pdmR0PciHlp_IsaSetIrq,
    618625    pdmR0PciHlp_IoApicSetIrq,
     626    pdmR0PciHlp_IoApicSendMsi,
    619627    pdmR0PciHlp_Lock,
    620628    pdmR0PciHlp_Unlock,
     
    846854}
    847855
     856/**
     857 * Sends an MSI to I/O APIC.
     858 *
     859 * @param   pVM     The VM handle.
     860 * @param   GCAddr  Address of the message.
     861 * @param   uValue  Value of the message.
     862 */
     863static void pdmR0IoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)
     864{
     865    if (pVM->pdm.s.IoApic.pDevInsR0)
     866    {
     867        pdmLock(pVM);
     868        pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCAddr, uValue);
     869        pdmUnlock(pVM);
     870    }
     871}
     872
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