VirtualBox

Changeset 68470 in vbox


Ignore:
Timestamp:
Aug 18, 2017 2:05:49 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
117615
Message:

PDM: add new PDM device helper for sending a MSI directly (from all contexts, as all contexts support such interrupt delivery)

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmdev.h

    r67668 r68470  
    499499
    500500/**
    501  * Registration record for MSI.
     501 * Registration record for MSI/MSI-X emulation.
    502502 */
    503503typedef struct PDMMSIREG
     
    553553
    554554    /**
    555      * Initialize MSI support in a PCI device.
     555     * Initialize MSI or MSI-X emulation support in a PCI device.
     556     *
     557     * This cannot handle all corner cases of the MSI/MSI-X spec, but for the
     558     * vast majority of device emulation it covers everything necessary. It's
     559     * fully automatic, taking care of all BAR and config space requirements,
     560     * and interrupt delivery is done using PDMDevHlpPCISetIrq and friends.
     561     * When MSI/MSI-X is enabled then the iIrq parameter is redefined to take
     562     * the vector number (otherwise it has the usual INTA-D meaning for PCI).
     563     *
     564     * A device not using this can still offer MSI/MSI-X. In this case it's
     565     * completely up to the device (in the MSI-X case) to create/register the
     566     * necessary MMIO BAR, handle all config space/BAR updating and take care
     567     * of delivering the interrupts appropriately.
    556568     *
    557569     * @returns VBox status code.
    558570     * @param   pDevIns         Device instance of the PCI Bus.
    559571     * @param   pPciDev         The PCI device structure.
    560      * @param   pMsiReg         MSI registration structure
     572     * @param   pMsiReg         MSI emulation registration structure
    561573     * @remarks Caller enters the PDM critical section.
    562574     */
     
    18671879/** Current PDMDEVHLPR3 version number.
    18681880 * @todo Next major revision should add piBus to pfnPCIBusRegister, and move
    1869  *       pfnMMIOExReduce up to after pfnMMIOExUnmap. */
    1870 #define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 19, 2)
     1881 *       pfnMMIOExReduce up to after pfnMMIOExUnmap, and move
     1882 *       pfnIoApicSendMsi/pfnIoApicSendMsiNoWait up to after pfnISASetIrqNoWait. */
     1883#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 19, 3)
    18711884//#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
    18721885
     
    26782691
    26792692    /**
    2680      * Initialize MSI support for the given PCI device.
     2693     * Initialize MSI or MSI-X emulation support for the given PCI device.
     2694     *
     2695     * @see PDMPCIBUSREG::pfnRegisterMsiR3 for details.
    26812696     *
    26822697     * @returns VBox status code.
     
    26842699     * @param   pPciDev             The PCI device.  NULL is an alias for the first
    26852700     *                              one registered.
    2686      * @param   pMsiReg             MSI registartion structure.
     2701     * @param   pMsiReg             MSI emulation registration structure.
    26872702     */
    26882703    DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
     
    28072822     * Attaches a driver (chain) to the device.
    28082823     *
    2809      * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
     2824     * The first call for a LUN this will serve as a registration of the LUN. The pBaseInterface and
    28102825     * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
    28112826     *
     
    32763291    DECLR3CALLBACKMEMBER(int, pfnMMIOExReduce,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion));
    32773292
     3293    /**
     3294     * Send an MSI straight to the I/O APIC.
     3295     *
     3296     * @param   pDevIns         PCI device instance.
     3297     * @param   GCPhys          Physical address MSI request was written.
     3298     * @param   uValue          Value written.
     3299     * @thread  Any thread, but will involve the emulation thread.
     3300     */
     3301    DECLR3CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue));
     3302
     3303    /**
     3304     * Send an MSI straight to the I/O APIC, but don't wait for EMT to process
     3305     * the request when not called from EMT.
     3306     *
     3307     * @param   pDevIns         PCI device instance.
     3308     * @param   GCPhys          Physical address MSI request was written.
     3309     * @param   uValue          Value written.
     3310     * @thread  Any thread, but will involve the emulation thread.
     3311     */
     3312    DECLR3CALLBACKMEMBER(void,  pfnIoApicSendMsiNoWait,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue));
     3313
    32783314    /** Space reserved for future members.
    32793315     * @{ */
    3280     DECLR3CALLBACKMEMBER(void, pfnReserved2,(void));
    3281     DECLR3CALLBACKMEMBER(void, pfnReserved3,(void));
    32823316    DECLR3CALLBACKMEMBER(void, pfnReserved4,(void));
    32833317    DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
     
    37103744    DECLRCCALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
    37113745
     3746    /**
     3747     * Send an MSI straight to the I/O APIC.
     3748     *
     3749     * @param   pDevIns         PCI device instance.
     3750     * @param   GCPhys          Physical address MSI request was written.
     3751     * @param   uValue          Value written.
     3752     * @thread  Any thread, but will involve the emulation thread.
     3753     */
     3754    DECLRCCALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue));
     3755
    37123756    /** Space reserved for future members.
    37133757     * @{ */
    3714     DECLRCCALLBACKMEMBER(void, pfnReserved1,(void));
    37153758    DECLRCCALLBACKMEMBER(void, pfnReserved2,(void));
    37163759    DECLRCCALLBACKMEMBER(void, pfnReserved3,(void));
     
    37323775typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
    37333776
    3734 /** Current PDMDEVHLP version number. */
    3735 #define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 5, 0)
     3777/** Current PDMDEVHLP version number.
     3778 * @todo Next major revision should move pfnIoApicSendMsi up to after pfnISASetIrq. */
     3779#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 5, 1)
    37363780
    37373781
     
    39694013    DECLR0CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
    39704014
     4015    /**
     4016     * Send an MSI straight to the I/O APIC.
     4017     *
     4018     * @param   pDevIns         PCI device instance.
     4019     * @param   GCPhys          Physical address MSI request was written.
     4020     * @param   uValue          Value written.
     4021     * @thread  Any thread, but will involve the emulation thread.
     4022     */
     4023    DECLR0CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue));
     4024
    39714025    /** Space reserved for future members.
    39724026     * @{ */
    3973     DECLR0CALLBACKMEMBER(void, pfnReserved1,(void));
    39744027    DECLR0CALLBACKMEMBER(void, pfnReserved2,(void));
    39754028    DECLR0CALLBACKMEMBER(void, pfnReserved3,(void));
     
    39914044typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
    39924045
    3993 /** Current PDMDEVHLP version number. */
    3994 #define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 5, 0)
     4046/** Current PDMDEVHLP version number.
     4047 * @todo Next major revision should move pfnIoApicSendMsi up to after pfnISASetIrq. */
     4048#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 5, 1)
    39954049
    39964050
     
    47804834
    47814835/**
    4782  * Initialize MSI support for the first PCI device.
     4836 * Initialize MSI or MSI-X emulation support for the first PCI device.
    47834837 *
    47844838 * @returns VBox status code.
    47854839 * @param   pDevIns             The device instance.
    4786  * @param   pMsiReg             MSI registartion structure.
     4840 * @param   pMsiReg             MSI emulation registration structure.
    47874841 */
    47884842DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
     
    49184972}
    49194973
     4974/**
     4975 * @copydoc PDMDEVHLPR3::pfnIoApicSendMsi
     4976 */
     4977DECLINLINE(void) PDMDevHlpIoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
     4978{
     4979    pDevIns->CTX_SUFF(pHlp)->pfnIoApicSendMsi(pDevIns, GCPhys, uValue);
     4980}
     4981
     4982/**
     4983 * @copydoc PDMDEVHLPR3::pfnIoApicSendMsiNoWait
     4984 */
     4985DECLINLINE(void) PDMDevHlpIoApicSendMsiNoWait(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
     4986{
     4987    pDevIns->CTX_SUFF(pHlp)->pfnIoApicSendMsi(pDevIns, GCPhys, uValue);
     4988}
     4989
    49204990#ifdef IN_RING3
    49214991
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r68009 r68470  
    205205    pdmUnlock(pVM);
    206206    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
     207}
     208
     209
     210/** @interface_method_impl{PDMDEVHLPR0,pfnIoApicSendMsi} */
     211static DECLCALLBACK(void) pdmR0DevHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
     212{
     213    PDMDEV_ASSERT_DEVINS(pDevIns);
     214    LogFlow(("pdmR0DevHlp_IoApicSendMsi: caller=%p/%d: GCPhys=%RGp uValue=%#x\n", pDevIns, pDevIns->iInstance, GCPhys, uValue));
     215    PVM pVM = pDevIns->Internal.s.pVMR0;
     216
     217    uint32_t uTagSrc;
     218    pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
     219    VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
     220
     221    if (pVM->pdm.s.IoApic.pDevInsR0)
     222        pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc);
     223    else
     224        AssertFatalMsgFailed(("Lazy bastards!"));
     225
     226    LogFlow(("pdmR0DevHlp_IoApicSendMsi: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
    207227}
    208228
     
    420440    pdmR0DevHlp_TMTimeVirtGetNano,
    421441    pdmR0DevHlp_DBGFTraceBuf,
    422     NULL,
     442    pdmR0DevHlp_IoApicSendMsi,
    423443    NULL,
    424444    NULL,
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r67668 r68470  
    18141814{
    18151815    pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel);
     1816}
     1817
     1818
     1819/** @interface_method_impl{PDMDEVHLPR3,pfnIoApicSendMsi} */
     1820static DECLCALLBACK(void) pdmR3DevHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
     1821{
     1822    PDMDEV_ASSERT_DEVINS(pDevIns);
     1823    LogFlow(("pdmR3DevHlp_IoApicSendMsi: caller='%s'/%d: GCPhys=%RGp uValue=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, uValue));
     1824
     1825    /*
     1826     * Validate input.
     1827     */
     1828    Assert(GCPhys != 0);
     1829    Assert(uValue != 0);
     1830
     1831    PVM pVM = pDevIns->Internal.s.pVMR3;
     1832
     1833    /*
     1834     * Do the job.
     1835     */
     1836    pdmLock(pVM);
     1837    uint32_t uTagSrc;
     1838    pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
     1839    VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
     1840
     1841    PDMIoApicSendMsi(pVM, GCPhys, uValue, uTagSrc);  /* (The API takes the lock recursively.) */
     1842
     1843    pdmUnlock(pVM);
     1844
     1845    LogFlow(("pdmR3DevHlp_IoApicSendMsi: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
     1846}
     1847
     1848
     1849/** @interface_method_impl{PDMDEVHLPR3,pfnIoApicSendMsiNoWait} */
     1850static DECLCALLBACK(void) pdmR3DevHlp_IoApicSendMsiNoWait(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
     1851{
     1852    pdmR3DevHlp_IoApicSendMsi(pDevIns, GCPhys, uValue);
    18161853}
    18171854
     
    36893726    pdmR3DevHlp_VMGetResumeReason,
    36903727    pdmR3DevHlp_MMIOExReduce,
    3691     0,
    3692     0,
     3728    pdmR3DevHlp_IoApicSendMsi,
     3729    pdmR3DevHlp_IoApicSendMsiNoWait,
    36933730    0,
    36943731    0,
     
    39463983    pdmR3DevHlp_VMGetResumeReason,
    39473984    pdmR3DevHlp_MMIOExReduce,
    3948     0,
    3949     0,
     3985    pdmR3DevHlp_IoApicSendMsi,
     3986    pdmR3DevHlp_IoApicSendMsiNoWait,
    39503987    0,
    39513988    0,
  • trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp

    r65338 r68470  
    204204    pdmUnlock(pVM);
    205205    LogFlow(("pdmRCDevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
     206}
     207
     208
     209/** @interface_method_impl{PDMDEVHLPRC,pfnIoApicSendMsi} */
     210static DECLCALLBACK(void) pdmRCDevHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
     211{
     212    PDMDEV_ASSERT_DEVINS(pDevIns);
     213    LogFlow(("pdmRCDevHlp_IoApicSendMsi: caller=%p/%d: GCPhys=%RGp uValue=%#x\n", pDevIns, pDevIns->iInstance, GCPhys, uValue));
     214    PVM pVM = pDevIns->Internal.s.pVMRC;
     215
     216    uint32_t uTagSrc;
     217    pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
     218    VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
     219
     220    if (pVM->pdm.s.IoApic.pDevInsRC)
     221        pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCPhys, uValue, uTagSrc);
     222    else
     223        AssertFatalMsgFailed(("Lazy bastards!"));
     224
     225    LogFlow(("pdmRCDevHlp_IoApicSendMsi: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
    206226}
    207227
     
    405425    pdmRCDevHlp_TMTimeVirtGetNano,
    406426    pdmRCDevHlp_DBGFTraceBuf,
    407     NULL,
     427    pdmRCDevHlp_IoApicSendMsi,
    408428    NULL,
    409429    NULL,
     
    587607        pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCPhys, uValue, uTagSrc);
    588608    else
    589         AssertFatalMsgFailed(("Lazy bastarts!"));
     609        AssertFatalMsgFailed(("Lazy bastards!"));
    590610}
    591611
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