VirtualBox

Changeset 81938 in vbox


Ignore:
Timestamp:
Nov 18, 2019 12:14:05 PM (5 years ago)
Author:
vboxsync
Message:

DevIoApic,PDM: Refactored the IOAPIC registration to be done directly for each context. Converted CFGM calls. Use default device prefix for statistics. bugref:9218

Location:
trunk
Files:
6 edited

Legend:

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

    r81928 r81938  
    14361436
    14371437/**
    1438  * I/O APIC registration structure.
     1438 * I/O APIC registration structure (all contexts).
    14391439 */
    14401440typedef struct PDMIOAPICREG
     
    14541454     *          Actually, as per 2018-07-21 this isn't true (bird).
    14551455     */
    1456     DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
    1457 
    1458     /** The name of the RC SetIrq entry point. */
    1459     const char         *pszSetIrqRC;
    1460 
    1461     /** The name of the R0 SetIrq entry point. */
    1462     const char         *pszSetIrqR0;
     1456    DECLCALLBACKMEMBER(void, pfnSetIrq)(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc);
    14631457
    14641458    /**
     
    14731467     *          Actually, as per 2018-07-21 this isn't true (bird).
    14741468     */
    1475     DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
    1476 
    1477     /** The name of the RC SendMsi entry point. */
    1478     const char         *pszSendMsiRC;
    1479 
    1480     /** The name of the R0 SendMsi entry point. */
    1481     const char         *pszSendMsiR0;
     1469    DECLCALLBACKMEMBER(void, pfnSendMsi)(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc);
    14821470
    14831471    /**
     
    14941482     *          Actually, as per 2018-07-21 this isn't true (bird).
    14951483     */
    1496     DECLR3CALLBACKMEMBER(int, pfnSetEoiR3,(PPDMDEVINS pDevIns, uint8_t u8Vector));
    1497 
    1498     /** The name of the RC SetEoi entry point. */
    1499     const char         *pszSetEoiRC;
    1500 
    1501     /** The name of the R0 SetEoi entry point. */
    1502     const char         *pszSetEoiR0;
     1484    DECLCALLBACKMEMBER(int, pfnSetEoi)(PPDMDEVINS pDevIns, uint8_t u8Vector);
     1485
     1486    /** Just a safety precaution. */
     1487    uint32_t                u32TheEnd;
    15031488} PDMIOAPICREG;
    15041489/** Pointer to an APIC registration structure. */
     
    15061491
    15071492/** Current PDMAPICREG version number. */
    1508 #define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 5, 0)
    1509 
    1510 
    1511 /**
    1512  * IOAPIC RC helpers.
    1513  */
    1514 typedef struct PDMIOAPICHLPRC
    1515 {
    1516     /** Structure version. PDM_IOAPICHLPRC_VERSION defines the current version. */
     1493#define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 6, 0)
     1494
     1495
     1496/**
     1497 * IOAPIC helpers, same in all contexts.
     1498 */
     1499typedef struct PDMIOAPICHLP
     1500{
     1501    /** Structure version. PDM_IOAPICHLP_VERSION defines the current version. */
    15171502    uint32_t                u32Version;
    15181503
     
    15321517     * @param   uTagSrc         The IRQ tag and source (for tracing).
    15331518     */
    1534     DECLRCCALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    1535                                                   uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
     1519    DECLCALLBACKMEMBER(int, pfnApicBusDeliver)(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
     1520                                               uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc);
    15361521
    15371522    /**
     
    15431528     * @param   rc              What to return if we fail to acquire the lock.
    15441529     */
    1545     DECLRCCALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
     1530    DECLCALLBACKMEMBER(int,   pfnLock)(PPDMDEVINS pDevIns, int rc);
    15461531
    15471532    /**
     
    15501535     * @param   pDevIns         The IOAPIC device instance.
    15511536     */
    1552     DECLRCCALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
     1537    DECLCALLBACKMEMBER(void,  pfnUnlock)(PPDMDEVINS pDevIns);
    15531538
    15541539    /** Just a safety precaution. */
    15551540    uint32_t                u32TheEnd;
    1556 } PDMIOAPICHLPRC;
    1557 /** Pointer to IOAPIC RC helpers. */
    1558 typedef RCPTRTYPE(PDMIOAPICHLPRC *) PPDMIOAPICHLPRC;
     1541} PDMIOAPICHLP;
     1542/** Pointer to IOAPIC helpers. */
     1543typedef PDMIOAPICHLP * PPDMIOAPICHLP;
    15591544/** Pointer to const IOAPIC helpers. */
    1560 typedef RCPTRTYPE(const PDMIOAPICHLPRC *) PCPDMIOAPICHLPRC;
    1561 
    1562 /** Current PDMIOAPICHLPRC version number. */
    1563 #define PDM_IOAPICHLPRC_VERSION                 PDM_VERSION_MAKE(0xfff1, 2, 0)
    1564 
    1565 
    1566 /**
    1567  * IOAPIC R0 helpers.
    1568  */
    1569 typedef struct PDMIOAPICHLPR0
    1570 {
    1571     /** Structure version. PDM_IOAPICHLPR0_VERSION defines the current version. */
    1572     uint32_t                u32Version;
    1573 
    1574     /**
    1575      * Private interface between the IOAPIC and APIC.
    1576      *
    1577      * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
    1578      *
    1579      * @returns status code.
    1580      * @param   pDevIns         Device instance of the IOAPIC.
    1581      * @param   u8Dest          See APIC implementation.
    1582      * @param   u8DestMode      See APIC implementation.
    1583      * @param   u8DeliveryMode  See APIC implementation.
    1584      * @param   uVector         See APIC implementation.
    1585      * @param   u8Polarity      See APIC implementation.
    1586      * @param   u8TriggerMode   See APIC implementation.
    1587      * @param   uTagSrc         The IRQ tag and source (for tracing).
    1588      */
    1589     DECLR0CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    1590                                                   uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
    1591 
    1592     /**
    1593      * Acquires the PDM lock.
    1594      *
    1595      * @returns VINF_SUCCESS on success.
    1596      * @returns rc if we failed to acquire the lock.
    1597      * @param   pDevIns         The IOAPIC device instance.
    1598      * @param   rc              What to return if we fail to acquire the lock.
    1599      */
    1600     DECLR0CALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
    1601 
    1602     /**
    1603      * Releases the PDM lock.
    1604      *
    1605      * @param   pDevIns         The IOAPIC device instance.
    1606      */
    1607     DECLR0CALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
    1608 
    1609     /** Just a safety precaution. */
    1610     uint32_t                u32TheEnd;
    1611 } PDMIOAPICHLPR0;
    1612 /** Pointer to IOAPIC R0 helpers. */
    1613 typedef R0PTRTYPE(PDMIOAPICHLPR0 *) PPDMIOAPICHLPR0;
    1614 /** Pointer to const IOAPIC helpers. */
    1615 typedef R0PTRTYPE(const PDMIOAPICHLPR0 *) PCPDMIOAPICHLPR0;
    1616 
    1617 /** Current PDMIOAPICHLPR0 version number. */
    1618 #define PDM_IOAPICHLPR0_VERSION                 PDM_VERSION_MAKE(0xfff0, 2, 0)
    1619 
    1620 /**
    1621  * IOAPIC R3 helpers.
    1622  */
    1623 typedef struct PDMIOAPICHLPR3
    1624 {
    1625     /** Structure version. PDM_IOAPICHLPR3_VERSION defines the current version. */
    1626     uint32_t                u32Version;
    1627 
    1628     /**
    1629      * Private interface between the IOAPIC and APIC.
    1630      *
    1631      * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
    1632      *
    1633      * @returns status code
    1634      * @param   pDevIns         Device instance of the IOAPIC.
    1635      * @param   u8Dest          See APIC implementation.
    1636      * @param   u8DestMode      See APIC implementation.
    1637      * @param   u8DeliveryMode  See APIC implementation.
    1638      * @param   uVector         See APIC implementation.
    1639      * @param   u8Polarity      See APIC implementation.
    1640      * @param   u8TriggerMode   See APIC implementation.
    1641      * @param   uTagSrc         The IRQ tag and source (for tracing).
    1642      */
    1643     DECLR3CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    1644                                                   uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
    1645 
    1646     /**
    1647      * Acquires the PDM lock.
    1648      *
    1649      * @returns VINF_SUCCESS on success.
    1650      * @returns Fatal error on failure.
    1651      * @param   pDevIns         The IOAPIC device instance.
    1652      * @param   rc              Dummy for making the interface identical to the GC and R0 versions.
    1653      */
    1654     DECLR3CALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
    1655 
    1656     /**
    1657      * Releases the PDM lock.
    1658      *
    1659      * @param   pDevIns         The IOAPIC device instance.
    1660      */
    1661     DECLR3CALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
    1662 
    1663     /**
    1664      * Gets the address of the RC IOAPIC helpers.
    1665      *
    1666      * This should be called at both construction and relocation time
    1667      * to obtain the correct address of the RC helpers.
    1668      *
    1669      * @returns RC pointer to the IOAPIC helpers.
    1670      * @param   pDevIns         Device instance of the IOAPIC.
    1671      */
    1672     DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
    1673 
    1674     /**
    1675      * Gets the address of the R0 IOAPIC helpers.
    1676      *
    1677      * This should be called at both construction and relocation time
    1678      * to obtain the correct address of the R0 helpers.
    1679      *
    1680      * @returns R0 pointer to the IOAPIC helpers.
    1681      * @param   pDevIns         Device instance of the IOAPIC.
    1682      */
    1683     DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
    1684 
    1685     /** Just a safety precaution. */
    1686     uint32_t                u32TheEnd;
    1687 } PDMIOAPICHLPR3;
    1688 /** Pointer to IOAPIC R3 helpers. */
    1689 typedef R3PTRTYPE(PDMIOAPICHLPR3 *) PPDMIOAPICHLPR3;
    1690 /** Pointer to const IOAPIC helpers. */
    1691 typedef R3PTRTYPE(const PDMIOAPICHLPR3 *) PCPDMIOAPICHLPR3;
    1692 
    1693 /** Current PDMIOAPICHLPR3 version number. */
    1694 #define PDM_IOAPICHLPR3_VERSION                 PDM_VERSION_MAKE(0xffef, 2, 0)
     1545typedef const PDMIOAPICHLP * PCPDMIOAPICHLP;
     1546
     1547/** Current PDMIOAPICHLP version number. */
     1548#define PDM_IOAPICHLP_VERSION                   PDM_VERSION_MAKE(0xfff0, 2, 0)
    16951549
    16961550
     
    21441998
    21451999/** Current PDMDEVHLPR3 version number. */
    2146 #define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 35, 0)
     2000#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 36, 0)
    21472001
    21482002/**
     
    39193773     * @param   pDevIns             The device instance.
    39203774     * @param   pIoApicReg          Pointer to a I/O APIC registration structure.
    3921      * @param   ppIoApicHlpR3       Where to store the pointer to the IOAPIC
     3775     * @param   ppIoApicHlp         Where to store the pointer to the IOAPIC
    39223776     *                              helpers.
    39233777     */
    3924     DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
     3778    DECLR3CALLBACKMEMBER(int, pfnIoApicRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp));
    39253779
    39263780    /**
     
    48234677
    48244678    /**
    4825      * Sets up the PIC for the raw-mode context.
     4679     * Sets up the PIC for the ring-0 context.
    48264680     *
    48274681     * This must be called after ring-3 has registered the PIC using
     
    48324686     * @param   pPicReg     The PIC registration information for ring-0,
    48334687     *                      considered volatile and copied.
    4834      * @param   ppPicHlp    Where to return the raw-mode PIC helpers.
    4835      */
    4836     DECLRCCALLBACKMEMBER(int, pfnPCISetUpContext,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
     4688     * @param   ppPicHlp    Where to return the ring-0 PIC helpers.
     4689     */
     4690    DECLR0CALLBACKMEMBER(int, pfnPICSetUpContext,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
     4691
     4692    /**
     4693     * Sets up the IOAPIC for the ring-0 context.
     4694     *
     4695     * This must be called after ring-3 has registered the PIC using
     4696     * PDMDevHlpIoApicRegister().
     4697     *
     4698     * @returns VBox status code.
     4699     * @param   pDevIns     The device instance.
     4700     * @param   pIoApicReg  The PIC registration information for ring-0,
     4701     *                      considered volatile and copied.
     4702     * @param   ppIoApicHlp Where to return the ring-0 IOAPIC helpers.
     4703     */
     4704    DECLR0CALLBACKMEMBER(int, pfnIoApicSetUpContext,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp));
    48374705
    48384706    /** Space reserved for future members.
     
    48594727
    48604728/** Current PDMDEVHLP version number. */
    4861 #define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 11, 0)
     4729#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 12, 0)
    48624730
    48634731
     
    53155183    DECLR0CALLBACKMEMBER(int, pfnPICSetUpContext,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
    53165184
     5185    /**
     5186     * Sets up the IOAPIC for the ring-0 context.
     5187     *
     5188     * This must be called after ring-3 has registered the PIC using
     5189     * PDMDevHlpIoApicRegister().
     5190     *
     5191     * @returns VBox status code.
     5192     * @param   pDevIns     The device instance.
     5193     * @param   pIoApicReg  The PIC registration information for ring-0,
     5194     *                      considered volatile and copied.
     5195     * @param   ppIoApicHlp Where to return the ring-0 IOAPIC helpers.
     5196     */
     5197    DECLR0CALLBACKMEMBER(int, pfnIoApicSetUpContext,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp));
     5198
    53175199    /** Space reserved for future members.
    53185200     * @{ */
     
    53385220
    53395221/** Current PDMDEVHLP version number. */
    5340 #define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 12, 0)
     5222#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 13, 0)
    53415223
    53425224
     
    78257707
    78267708/**
    7827  * @copydoc PDMDEVHLPR3::pfnIOAPICRegister
    7828  */
    7829 DECLINLINE(int) PDMDevHlpIOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
    7830 {
    7831     return pDevIns->pHlpR3->pfnIOAPICRegister(pDevIns, pIoApicReg, ppIoApicHlpR3);
     7709 * @copydoc PDMDEVHLPR3::pfnIoApicRegister
     7710 */
     7711DECLINLINE(int) PDMDevHlpIoApicRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
     7712{
     7713    return pDevIns->pHlpR3->pfnIoApicRegister(pDevIns, pIoApicReg, ppIoApicHlp);
    78327714}
    78337715
     
    79707852{
    79717853    return pDevIns->CTX_SUFF(pHlp)->pfnPICSetUpContext(pDevIns, pPicReg, ppPicHlp);
     7854}
     7855
     7856/**
     7857 * @copydoc PDMDEVHLPR0::pfnIoApicSetUpContext
     7858 */
     7859DECLINLINE(int) PDMDevHlpIoApicSetUpContext(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
     7860{
     7861    return pDevIns->CTX_SUFF(pHlp)->pfnIoApicSetUpContext(pDevIns, pIoApicReg, ppIoApicHlp);
    79727862}
    79737863
  • trunk/src/VBox/Devices/PC/DevIoApic.cpp

    r81765 r81938  
    185185{
    186186    /** The device instance - R3 Ptr. */
    187     PPDMDEVINSR3            pDevInsR3;
     187    PPDMDEVINSR3                pDevInsR3;
    188188    /** The IOAPIC helpers - R3 Ptr. */
    189     PCPDMIOAPICHLPR3        pIoApicHlpR3;
     189    R3PTRTYPE(PCPDMIOAPICHLP)   pIoApicHlpR3;
    190190
    191191    /** The device instance - R0 Ptr. */
    192     PPDMDEVINSR0            pDevInsR0;
     192    PPDMDEVINSR0                pDevInsR0;
    193193    /** The IOAPIC helpers - R0 Ptr. */
    194     PCPDMIOAPICHLPR0        pIoApicHlpR0;
     194    R0PTRTYPE(PCPDMIOAPICHLP)   pIoApicHlpR0;
    195195
    196196    /** The device instance - RC Ptr. */
    197     PPDMDEVINSRC            pDevInsRC;
     197    PPDMDEVINSRC                pDevInsRC;
    198198    /** The IOAPIC helpers - RC Ptr. */
    199     PCPDMIOAPICHLPRC        pIoApicHlpRC;
     199    RCPTRTYPE(PCPDMIOAPICHLP)   pIoApicHlpRC;
    200200
    201201    /** The ID register. */
     
    11361136
    11371137    pThis->pDevInsRC    = PDMDEVINS_2_RCPTR(pDevIns);
    1138     pThis->pIoApicHlpRC = pThis->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
     1138    pThis->pIoApicHlpRC += offDelta;
    11391139}
    11401140
     
    11691169{
    11701170    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    1171     PIOAPIC pThis = PDMDEVINS_2_DATA(pDevIns, PIOAPIC);
     1171    PIOAPIC         pThis = PDMDEVINS_2_DATA(pDevIns, PIOAPIC);
     1172    PCPDMDEVHLPR3   pHlp  = pDevIns->pHlpR3;
    11721173    LogFlow(("IOAPIC: ioapicR3Construct: pThis=%p iInstance=%d\n", pThis, iInstance));
    11731174    Assert(iInstance == 0); RT_NOREF(iInstance);
     
    11831184     * Validate and read the configuration.
    11841185     */
    1185     PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "NumCPUs|RZEnabled|ChipType", "");
     1186    PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "NumCPUs|ChipType", "");
    11861187
    11871188    /* The number of CPUs is currently unused, but left in CFGM and saved-state in case an ID of 0 is
    11881189       upsets some guest which we haven't yet tested. */
    11891190    uint32_t cCpus;
    1190     int rc = CFGMR3QueryU32Def(pCfg, "NumCPUs", &cCpus, 1);
     1191    int rc = pHlp->pfnCFGMQueryU32Def(pCfg, "NumCPUs", &cCpus, 1);
    11911192    if (RT_FAILURE(rc))
    11921193        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to query integer value \"NumCPUs\""));
    11931194    pThis->cCpus = (uint8_t)cCpus;
    11941195
    1195     bool fRZEnabled;
    1196     rc = CFGMR3QueryBoolDef(pCfg, "RZEnabled", &fRZEnabled, true);
    1197     if (RT_FAILURE(rc))
    1198         return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to query boolean value \"RZEnabled\""));
    1199 
    12001196    char szChipType[16];
    1201     rc = CFGMR3QueryStringDef(pCfg, "ChipType", &szChipType[0], sizeof(szChipType), "ICH9");
     1197    rc = pHlp->pfnCFGMQueryStringDef(pCfg, "ChipType", &szChipType[0], sizeof(szChipType), "ICH9");
    12021198    if (RT_FAILURE(rc))
    12031199        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to query string value \"ChipType\""));
     
    12351231    }
    12361232    else
    1237     {
    12381233        return PDMDevHlpVMSetError(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, RT_SRC_POS,
    1239                                    N_("I/O APIC configuration error: The \"ChipType\" value \"%s\" is unsupported"),
    1240                                    szChipType);
    1241     }
    1242     Log2(("IOAPIC: cCpus=%u fRZEnabled=%RTbool szChipType=%s\n", cCpus, fRZEnabled, szChipType));
     1234                                   N_("I/O APIC configuration error: The \"ChipType\" value \"%s\" is unsupported"), szChipType);
     1235    Log2(("IOAPIC: cCpus=%u fRZEnabled=%RTbool szChipType=%s\n", cCpus, pDevIns->fR0Enabled | pDevIns->fRCEnabled, szChipType));
    12431236
    12441237    /*
     
    12531246     */
    12541247    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "IOAPIC");
    1255     if (RT_FAILURE(rc))
    1256         return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("IOAPIC: Failed to create critical section. rc=%Rrc"), rc);
     1248    AssertRCReturn(rc, rc);
    12571249# endif
    12581250
     
    12611253     */
    12621254    PDMIOAPICREG IoApicReg;
    1263     RT_ZERO(IoApicReg);
    12641255    IoApicReg.u32Version   = PDM_IOAPICREG_VERSION;
    1265     IoApicReg.pfnSetIrqR3  = ioapicSetIrq;
    1266     IoApicReg.pfnSendMsiR3 = ioapicSendMsi;
    1267     IoApicReg.pfnSetEoiR3  = ioapicSetEoi;
    1268     if (fRZEnabled)
    1269     {
    1270         IoApicReg.pszSetIrqRC  = "ioapicSetIrq";
    1271         IoApicReg.pszSetIrqR0  = "ioapicSetIrq";
    1272 
    1273         IoApicReg.pszSendMsiRC = "ioapicSendMsi";
    1274         IoApicReg.pszSendMsiR0 = "ioapicSendMsi";
    1275 
    1276         IoApicReg.pszSetEoiRC = "ioapicSetEoi";
    1277         IoApicReg.pszSetEoiR0 = "ioapicSetEoi";
    1278     }
    1279     rc = PDMDevHlpIOAPICRegister(pDevIns, &IoApicReg, &pThis->pIoApicHlpR3);
    1280     if (RT_FAILURE(rc))
    1281     {
    1282         AssertMsgFailed(("IOAPIC: PDMDevHlpIOAPICRegister failed! rc=%Rrc\n", rc));
    1283         return rc;
    1284     }
     1256    IoApicReg.pfnSetIrq    = ioapicSetIrq;
     1257    IoApicReg.pfnSendMsi   = ioapicSendMsi;
     1258    IoApicReg.pfnSetEoi    = ioapicSetEoi;
     1259    IoApicReg.u32TheEnd    = PDM_IOAPICREG_VERSION;
     1260    rc = PDMDevHlpIoApicRegister(pDevIns, &IoApicReg, &pThis->pIoApicHlpR3);
     1261    AssertRCReturn(rc, rc);
    12851262
    12861263    /*
     
    12901267                               IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_ZEROED, ioapicMmioWrite, ioapicMmioRead,
    12911268                               "I/O APIC");
    1292     if (RT_SUCCESS(rc))
     1269    AssertRCReturn(rc, rc);
     1270    if (pDevIns->fR0Enabled | pDevIns->fRCEnabled)
    12931271    {
    1294         if (fRZEnabled)
    1295         {
    1296             pThis->pIoApicHlpRC = pThis->pIoApicHlpR3->pfnGetRCHelpers(pDevIns);
    1297             rc = PDMDevHlpMMIORegisterRC(pDevIns, IOAPIC_MMIO_BASE_PHYSADDR, IOAPIC_MMIO_SIZE, NIL_RTRCPTR /* pvUser */,
    1298                                          "ioapicMmioWrite", "ioapicMmioRead");
    1299             AssertRCReturn(rc, rc);
    1300 
    1301             pThis->pIoApicHlpR0 = pThis->pIoApicHlpR3->pfnGetR0Helpers(pDevIns);
    1302             rc = PDMDevHlpMMIORegisterR0(pDevIns, IOAPIC_MMIO_BASE_PHYSADDR, IOAPIC_MMIO_SIZE, NIL_RTR0PTR /* pvUser */,
    1303                                          "ioapicMmioWrite", "ioapicMmioRead");
    1304             AssertRCReturn(rc, rc);
    1305         }
    1306     }
    1307     else
    1308     {
    1309         LogRel(("IOAPIC: PDMDevHlpMMIORegister failed! rc=%Rrc\n", rc));
    1310         return rc;
     1272        rc = PDMDevHlpMMIORegisterRC(pDevIns, IOAPIC_MMIO_BASE_PHYSADDR, IOAPIC_MMIO_SIZE, NIL_RTRCPTR /* pvUser */,
     1273                                     "ioapicMmioWrite", "ioapicMmioRead");
     1274        AssertRCReturn(rc, rc);
     1275
     1276        rc = PDMDevHlpMMIORegisterR0(pDevIns, IOAPIC_MMIO_BASE_PHYSADDR, IOAPIC_MMIO_SIZE, NIL_RTR0PTR /* pvUser */,
     1277                                     "ioapicMmioWrite", "ioapicMmioRead");
     1278        AssertRCReturn(rc, rc);
    13111279    }
    13121280
     
    13151283     */
    13161284    rc = PDMDevHlpSSMRegister(pDevIns, IOAPIC_SAVED_STATE_VERSION, sizeof(*pThis), ioapicR3SaveExec, ioapicR3LoadExec);
    1317     if (RT_FAILURE(rc))
    1318     {
    1319         LogRel(("IOAPIC: PDMDevHlpSSMRegister failed! rc=%Rrc\n", rc));
    1320         return rc;
    1321     }
     1285    AssertRCReturn(rc, rc);
    13221286
    13231287    /*
     
    13371301     * Statistics.
    13381302     */
    1339     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioReadRZ,  STAMTYPE_COUNTER, "/Devices/IOAPIC/RZ/MmioReadRZ",  STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in RZ.");
    1340     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioWriteRZ, STAMTYPE_COUNTER, "/Devices/IOAPIC/RZ/MmioWriteRZ", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in RZ.");
    1341     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetIrqRZ,    STAMTYPE_COUNTER, "/Devices/IOAPIC/RZ/SetIrqRZ",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in RZ.");
    1342     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetEoiRZ,    STAMTYPE_COUNTER, "/Devices/IOAPIC/RZ/SetEoiRZ",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetEoi calls in RZ.");
    1343 
    1344     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioReadR3,  STAMTYPE_COUNTER, "/Devices/IOAPIC/R3/MmioReadR3",  STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in R3");
    1345     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioWriteR3, STAMTYPE_COUNTER, "/Devices/IOAPIC/R3/MmioWriteR3", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in R3.");
    1346     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetIrqR3,    STAMTYPE_COUNTER, "/Devices/IOAPIC/R3/SetIrqR3",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in R3.");
    1347     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetEoiR3,    STAMTYPE_COUNTER, "/Devices/IOAPIC/R3/SetEoiR3",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetEoi calls in R3.");
    1348 
    1349     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRedundantEdgeIntr,   STAMTYPE_COUNTER, "/Devices/IOAPIC/RedundantEdgeIntr",   STAMUNIT_OCCURENCES, "Number of redundant edge-triggered interrupts (no IRR change).");
    1350     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRedundantLevelIntr,  STAMTYPE_COUNTER, "/Devices/IOAPIC/RedundantLevelIntr",  STAMUNIT_OCCURENCES, "Number of redundant level-triggered interrupts (no IRR change).");
    1351     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSuppressedLevelIntr, STAMTYPE_COUNTER, "/Devices/IOAPIC/SuppressedLevelIntr", STAMUNIT_OCCURENCES, "Number of suppressed level-triggered interrupts by remote IRR.");
    1352 
    1353     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatEoiContention,    STAMTYPE_COUNTER, "/Devices/IOAPIC/CritSect/ContentionSetEoi", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during EOI writes causing trips to R3.");
    1354     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetRteContention, STAMTYPE_COUNTER, "/Devices/IOAPIC/CritSect/ContentionSetRte", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during RTE writes causing trips to R3.");
    1355 
    1356     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatLevelIrqSent, STAMTYPE_COUNTER, "/Devices/IOAPIC/LevelIntr/Sent", STAMUNIT_OCCURENCES, "Number of level-triggered interrupts sent to the local APIC(s).");
    1357     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatEoiReceived,  STAMTYPE_COUNTER, "/Devices/IOAPIC/LevelIntr/Recv", STAMUNIT_OCCURENCES, "Number of EOIs received for level-triggered interrupts from the local APIC(s).");
     1303    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioReadRZ,  STAMTYPE_COUNTER, "RZ/MmioReadRZ",  STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in RZ.");
     1304    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioWriteRZ, STAMTYPE_COUNTER, "RZ/MmioWriteRZ", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in RZ.");
     1305    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetIrqRZ,    STAMTYPE_COUNTER, "RZ/SetIrqRZ",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in RZ.");
     1306    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetEoiRZ,    STAMTYPE_COUNTER, "RZ/SetEoiRZ",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetEoi calls in RZ.");
     1307
     1308    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioReadR3,  STAMTYPE_COUNTER, "R3/MmioReadR3",  STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in R3");
     1309    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMmioWriteR3, STAMTYPE_COUNTER, "R3/MmioWriteR3", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in R3.");
     1310    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetIrqR3,    STAMTYPE_COUNTER, "R3/SetIrqR3",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in R3.");
     1311    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetEoiR3,    STAMTYPE_COUNTER, "R3/SetEoiR3",    STAMUNIT_OCCURENCES, "Number of IOAPIC SetEoi calls in R3.");
     1312
     1313    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRedundantEdgeIntr,   STAMTYPE_COUNTER, "RedundantEdgeIntr",   STAMUNIT_OCCURENCES, "Number of redundant edge-triggered interrupts (no IRR change).");
     1314    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRedundantLevelIntr,  STAMTYPE_COUNTER, "RedundantLevelIntr",  STAMUNIT_OCCURENCES, "Number of redundant level-triggered interrupts (no IRR change).");
     1315    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSuppressedLevelIntr, STAMTYPE_COUNTER, "SuppressedLevelIntr", STAMUNIT_OCCURENCES, "Number of suppressed level-triggered interrupts by remote IRR.");
     1316
     1317    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatEoiContention,    STAMTYPE_COUNTER, "CritSect/ContentionSetEoi", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during EOI writes causing trips to R3.");
     1318    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetRteContention, STAMTYPE_COUNTER, "CritSect/ContentionSetRte", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during RTE writes causing trips to R3.");
     1319
     1320    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatLevelIrqSent, STAMTYPE_COUNTER, "LevelIntr/Sent", STAMUNIT_OCCURENCES, "Number of level-triggered interrupts sent to the local APIC(s).");
     1321    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatEoiReceived,  STAMTYPE_COUNTER, "LevelIntr/Recv", STAMUNIT_OCCURENCES, "Number of EOIs received for level-triggered interrupts from the local APIC(s).");
    13581322# endif
    13591323
     
    13671331}
    13681332
    1369 #endif /* IN_RING3 */
     1333#else /* !IN_RING3 */
     1334
     1335/**
     1336 * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
     1337 */
     1338static DECLCALLBACK(int) ioapicRZConstruct(PPDMDEVINS pDevIns)
     1339{
     1340    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     1341    PIOAPIC pThis = PDMDEVINS_2_DATA(pDevIns, PIOAPIC);
     1342
     1343    int rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
     1344    AssertRCReturn(rc, rc);
     1345
     1346    PDMIOAPICREG IoApicReg;
     1347    IoApicReg.u32Version   = PDM_IOAPICREG_VERSION;
     1348    IoApicReg.pfnSetIrq    = ioapicSetIrq;
     1349    IoApicReg.pfnSendMsi   = ioapicSendMsi;
     1350    IoApicReg.pfnSetEoi    = ioapicSetEoi;
     1351    IoApicReg.u32TheEnd    = PDM_IOAPICREG_VERSION;
     1352    rc = PDMDevHlpIoApicSetUpContext(pDevIns, &IoApicReg, &pThis->CTX_SUFF(pIoApicHlp));
     1353    AssertRCReturn(rc, rc);
     1354
     1355    return VINF_SUCCESS;
     1356}
     1357
     1358#endif /* !IN_RING3 */
    13701359
    13711360/**
     
    14141403#elif defined(IN_RING0)
    14151404    /* .pfnEarlyConstruct = */      NULL,
    1416     /* .pfnConstruct = */           NULL,
     1405    /* .pfnConstruct = */           ioapicRZConstruct,
    14171406    /* .pfnDestruct = */            NULL,
    14181407    /* .pfnFinalDestruct = */       NULL,
     
    14271416    /* .pfnReserved7 = */           NULL,
    14281417#elif defined(IN_RC)
    1429     /* .pfnConstruct = */           NULL,
     1418    /* .pfnConstruct = */           ioapicRZConstruct,
    14301419    /* .pfnReserved0 = */           NULL,
    14311420    /* .pfnReserved1 = */           NULL,
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r81916 r81938  
    5555extern DECLEXPORT(const PDMDEVHLPR0)    g_pdmR0DevHlp;
    5656extern DECLEXPORT(const PDMPICHLP)      g_pdmR0PicHlp;
    57 extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp;
     57extern DECLEXPORT(const PDMIOAPICHLP g_pdmR0IoApicHlp;
    5858extern DECLEXPORT(const PDMPCIHLPR0)    g_pdmR0PciHlp;
    5959extern DECLEXPORT(const PDMHPETHLPR0)   g_pdmR0HpetHlp;
     
    11101110    AssertMsgReturn(pPicReg->u32Version == PDM_PICREG_VERSION,
    11111111                    ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32Version, PDM_PICREG_VERSION),
    1112                     VERR_INVALID_PARAMETER);
     1112                    VERR_VERSION_MISMATCH);
    11131113    AssertPtrReturn(pPicReg->pfnSetIrq, VERR_INVALID_POINTER);
    11141114    AssertPtrReturn(pPicReg->pfnGetInterrupt, VERR_INVALID_POINTER);
    11151115    AssertMsgReturn(pPicReg->u32TheEnd == PDM_PICREG_VERSION,
    11161116                    ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32TheEnd, PDM_PICREG_VERSION),
    1117                     VERR_INVALID_PARAMETER);
     1117                    VERR_VERSION_MISMATCH);
    11181118    AssertPtrReturn(ppPicHlp, VERR_INVALID_POINTER);
    11191119
     
    11401140    *ppPicHlp = &g_pdmR0PicHlp;
    11411141    LogFlow(("pdmR0DevHlp_PICSetUpContext: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
     1142    return VINF_SUCCESS;
     1143}
     1144
     1145
     1146/** @interface_method_impl{PDMDEVHLPR0,pfnIoApicSetUpContext} */
     1147static DECLCALLBACK(int) pdmR0DevHlp_IoApicSetUpContext(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
     1148{
     1149    PDMDEV_ASSERT_DEVINS(pDevIns);
     1150    LogFlow(("pdmR0DevHlp_IoApicSetUpContext: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnSendMsi=%p, .pfnSetEoi=%p, .u32TheEnd=%#x } ppIoApicHlp=%p\n",
     1151             pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrq, pIoApicReg->pfnSendMsi, pIoApicReg->pfnSetEoi, pIoApicReg->u32TheEnd, ppIoApicHlp));
     1152    PGVM pGVM = pDevIns->Internal.s.pGVM;
     1153
     1154    /*
     1155     * Validate input.
     1156     */
     1157    AssertMsgReturn(pIoApicReg->u32Version == PDM_IOAPICREG_VERSION,
     1158                    ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32Version, PDM_IOAPICREG_VERSION),
     1159                    VERR_VERSION_MISMATCH);
     1160    AssertPtrReturn(pIoApicReg->pfnSetIrq, VERR_INVALID_POINTER);
     1161    AssertPtrReturn(pIoApicReg->pfnSendMsi, VERR_INVALID_POINTER);
     1162    AssertPtrReturn(pIoApicReg->pfnSetEoi, VERR_INVALID_POINTER);
     1163    AssertMsgReturn(pIoApicReg->u32TheEnd == PDM_IOAPICREG_VERSION,
     1164                    ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32TheEnd, PDM_IOAPICREG_VERSION),
     1165                    VERR_VERSION_MISMATCH);
     1166    AssertPtrReturn(ppIoApicHlp, VERR_INVALID_POINTER);
     1167
     1168    VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
     1169    VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
     1170
     1171    /* Check that it's the same device as made the ring-3 registrations: */
     1172    AssertLogRelMsgReturn(pGVM->pdm.s.IoApic.pDevInsR3 == pDevIns->pDevInsForR3,
     1173                          ("%p vs %p\n", pGVM->pdm.s.IoApic.pDevInsR3, pDevIns->pDevInsForR3), VERR_NOT_OWNER);
     1174
     1175    /* Check that it isn't already registered in ring-0: */
     1176    AssertLogRelMsgReturn(pGVM->pdm.s.IoApic.pDevInsR0 == NULL, ("%p (caller pDevIns=%p)\n", pGVM->pdm.s.IoApic.pDevInsR0, pDevIns),
     1177                          VERR_ALREADY_EXISTS);
     1178
     1179    /*
     1180     * Take down the callbacks and instance.
     1181     */
     1182    pGVM->pdm.s.IoApic.pDevInsR0    = pDevIns;
     1183    pGVM->pdm.s.IoApic.pfnSetIrqR0  = pIoApicReg->pfnSetIrq;
     1184    pGVM->pdm.s.IoApic.pfnSendMsiR0 = pIoApicReg->pfnSendMsi;
     1185    pGVM->pdm.s.IoApic.pfnSetEoiR0  = pIoApicReg->pfnSetEoi;
     1186    Log(("PDM: Registered IOAPIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
     1187
     1188    /* set the helper pointer and return. */
     1189    *ppIoApicHlp = &g_pdmR0IoApicHlp;
     1190    LogFlow(("pdmR0DevHlp_IoApicSetUpContext: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    11421191    return VINF_SUCCESS;
    11431192}
     
    12221271    pdmR0DevHlp_PCIBusSetUpContext,
    12231272    pdmR0DevHlp_PICSetUpContext,
     1273    pdmR0DevHlp_IoApicSetUpContext,
    12241274    NULL /*pfnReserved1*/,
    12251275    NULL /*pfnReserved2*/,
     
    13021352 */
    13031353
    1304 /** @interface_method_impl{PDMIOAPICHLPR0,pfnApicBusDeliver} */
     1354/** @interface_method_impl{PDMIOAPICHLP,pfnApicBusDeliver} */
    13051355static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
    13061356                                                       uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
     
    13151365
    13161366
    1317 /** @interface_method_impl{PDMIOAPICHLPR0,pfnLock} */
     1367/** @interface_method_impl{PDMIOAPICHLP,pfnLock} */
    13181368static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    13191369{
     
    13231373
    13241374
    1325 /** @interface_method_impl{PDMIOAPICHLPR0,pfnUnlock} */
     1375/** @interface_method_impl{PDMIOAPICHLP,pfnUnlock} */
    13261376static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
    13271377{
     
    13341384 * The Ring-0 I/O APIC Helper Callbacks.
    13351385 */
    1336 extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp =
    1337 {
    1338     PDM_IOAPICHLPR0_VERSION,
     1386extern DECLEXPORT(const PDMIOAPICHLP) g_pdmR0IoApicHlp =
     1387{
     1388    PDM_IOAPICHLP_VERSION,
    13391389    pdmR0IoApicHlp_ApicBusDeliver,
    13401390    pdmR0IoApicHlp_Lock,
    13411391    pdmR0IoApicHlp_Unlock,
    1342     PDM_IOAPICHLPR0_VERSION
     1392    PDM_IOAPICHLP_VERSION
    13431393};
    13441394
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r81916 r81938  
    37563756
    37573757
    3758 /** @interface_method_impl{PDMDEVHLPR3,pfnIOAPICRegister} */
    3759 static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
     3758/** @interface_method_impl{PDMDEVHLPR3,pfnIoApicRegister} */
     3759static DECLCALLBACK(int) pdmR3DevHlp_IoApicRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
    37603760{
    37613761    PDMDEV_ASSERT_DEVINS(pDevIns);
    37623762    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    3763     LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n",
    3764              pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3,
    3765              pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3));
     3763    LogFlow(("pdmR3DevHlp_IoApicRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrq=%p, .pfnSendMsi=%p, .pfnSetEoi=%p, .u32TheEnd=%#x } ppIoApicHlp=%p\n",
     3764             pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrq, pIoApicReg->pfnSendMsi, pIoApicReg->pfnSetEoi, pIoApicReg->u32TheEnd, ppIoApicHlp));
    37663765
    37673766    /*
    37683767     * Validate input.
    37693768     */
    3770     if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION)
    3771     {
    3772         AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION));
    3773         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3774         return VERR_INVALID_PARAMETER;
    3775     }
    3776     if (!pIoApicReg->pfnSetIrqR3 || !pIoApicReg->pfnSendMsiR3 || !pIoApicReg->pfnSetEoiR3)
    3777     {
    3778         Assert(pIoApicReg->pfnSetIrqR3);
    3779         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3780         return VERR_INVALID_PARAMETER;
    3781     }
    3782     if (    pIoApicReg->pszSetIrqRC
    3783         &&  !VALID_PTR(pIoApicReg->pszSetIrqRC))
    3784     {
    3785         Assert(VALID_PTR(pIoApicReg->pszSetIrqRC));
    3786         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3787         return VERR_INVALID_PARAMETER;
    3788     }
    3789     if (    pIoApicReg->pszSendMsiRC
    3790         &&  !VALID_PTR(pIoApicReg->pszSendMsiRC))
    3791     {
    3792         Assert(VALID_PTR(pIoApicReg->pszSendMsiRC));
    3793         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3794         return VERR_INVALID_PARAMETER;
    3795     }
    3796     if (    pIoApicReg->pszSetEoiRC
    3797         &&  !VALID_PTR(pIoApicReg->pszSetEoiRC))
    3798     {
    3799         Assert(VALID_PTR(pIoApicReg->pszSetEoiRC));
    3800         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3801         return VERR_INVALID_PARAMETER;
    3802     }
    3803     if (    pIoApicReg->pszSetIrqR0
    3804         &&  !VALID_PTR(pIoApicReg->pszSetIrqR0))
    3805     {
    3806         Assert(VALID_PTR(pIoApicReg->pszSetIrqR0));
    3807         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3808         return VERR_INVALID_PARAMETER;
    3809     }
    3810     if (    pIoApicReg->pszSendMsiR0
    3811         &&  !VALID_PTR(pIoApicReg->pszSendMsiR0))
    3812     {
    3813         Assert(VALID_PTR(pIoApicReg->pszSendMsiR0));
    3814         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3815         return VERR_INVALID_PARAMETER;
    3816     }
    3817     if (    pIoApicReg->pszSetEoiR0
    3818         &&  !VALID_PTR(pIoApicReg->pszSetEoiR0))
    3819     {
    3820         Assert(VALID_PTR(pIoApicReg->pszSetEoiR0));
    3821         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3822         return VERR_INVALID_PARAMETER;
    3823     }
    3824     if (!ppIoApicHlpR3)
    3825     {
    3826         Assert(ppIoApicHlpR3);
    3827         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (ppApicHlp)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3828         return VERR_INVALID_PARAMETER;
    3829     }
     3769    AssertMsgReturn(pIoApicReg->u32Version == PDM_IOAPICREG_VERSION,
     3770                    ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32Version, PDM_IOAPICREG_VERSION),
     3771                    VERR_VERSION_MISMATCH);
     3772    AssertPtrReturn(pIoApicReg->pfnSetIrq, VERR_INVALID_POINTER);
     3773    AssertPtrReturn(pIoApicReg->pfnSendMsi, VERR_INVALID_POINTER);
     3774    AssertPtrReturn(pIoApicReg->pfnSetEoi, VERR_INVALID_POINTER);
     3775    AssertMsgReturn(pIoApicReg->u32TheEnd == PDM_IOAPICREG_VERSION,
     3776                    ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg->u32TheEnd, PDM_IOAPICREG_VERSION),
     3777                    VERR_VERSION_MISMATCH);
     3778    AssertPtrReturn(ppIoApicHlp, VERR_INVALID_POINTER);
    38303779
    38313780    /*
     
    38343783     */
    38353784    PVM pVM = pDevIns->Internal.s.pVMR3;
    3836     if (!pVM->pdm.s.Apic.pDevInsR3)
    3837     {
    3838         AssertMsgFailed(("Configuration error / Init order error! No APIC!\n"));
    3839         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (no APIC)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3840         return VERR_INVALID_PARAMETER;
    3841     }
    3842 #if 0
    3843     if (    pIoApicReg->pszSetIrqRC
    3844         &&  !pVM->pdm.s.Apic.pDevInsRC)
    3845     {
    3846         AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n"));
    3847         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (no GC APIC)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3848         return VERR_INVALID_PARAMETER;
    3849     }
    3850 #endif
     3785    AssertMsgReturn(pVM->pdm.s.Apic.pDevInsR3 != NULL, ("Configuration error / Init order error! No APIC!\n"), VERR_WRONG_ORDER);
    38513786
    38523787    /*
    38533788     * Only one I/O APIC device.
    38543789     */
    3855     if (pVM->pdm.s.IoApic.pDevInsR3)
    3856     {
    3857         AssertMsgFailed(("Only one ioapic device is supported!\n"));
    3858         LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (only one)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    3859         return VERR_INVALID_PARAMETER;
    3860     }
    3861 
    3862     /*
    3863      * Resolve & initialize the GC bits.
    3864      */
    3865     if (pIoApicReg->pszSetIrqRC)
    3866     {
    3867         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC);
    3868         AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pIoApicReg->pszSetIrqRC, rc));
    3869         if (RT_FAILURE(rc))
    3870         {
    3871             LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    3872             return rc;
    3873         }
    3874         pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    3875     }
    3876     else
    3877     {
    3878         pVM->pdm.s.IoApic.pDevInsRC   = 0;
    3879         pVM->pdm.s.IoApic.pfnSetIrqRC = 0;
    3880     }
    3881 
    3882     if (pIoApicReg->pszSendMsiRC)
    3883     {
    3884         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSendMsiRC, &pVM->pdm.s.IoApic.pfnSendMsiRC);
    3885         AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pIoApicReg->pszSendMsiRC, rc));
    3886         if (RT_FAILURE(rc))
    3887         {
    3888             LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    3889             return rc;
    3890         }
    3891     }
    3892     else
    3893     {
    3894         pVM->pdm.s.IoApic.pfnSendMsiRC = 0;
    3895     }
    3896 
    3897     if (pIoApicReg->pszSetEoiRC)
    3898     {
    3899         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSetEoiRC, &pVM->pdm.s.IoApic.pfnSetEoiRC);
    3900         AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pIoApicReg->pszSetEoiRC, rc));
    3901         if (RT_FAILURE(rc))
    3902         {
    3903             LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    3904             return rc;
    3905         }
    3906     }
    3907     else
    3908     {
    3909         pVM->pdm.s.IoApic.pfnSetEoiRC = 0;
    3910     }
    3911 
    3912     /*
    3913      * Resolve & initialize the R0 bits.
    3914      */
    3915     if (pIoApicReg->pszSetIrqR0)
    3916     {
    3917         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0);
    3918         AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pIoApicReg->pszSetIrqR0, rc));
    3919         if (RT_FAILURE(rc))
    3920         {
    3921             LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    3922             return rc;
    3923         }
    3924         pVM->pdm.s.IoApic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    3925         Assert(pVM->pdm.s.IoApic.pDevInsR0);
    3926     }
    3927     else
    3928     {
    3929         pVM->pdm.s.IoApic.pfnSetIrqR0 = 0;
    3930         pVM->pdm.s.IoApic.pDevInsR0   = 0;
    3931     }
    3932 
    3933     if (pIoApicReg->pszSendMsiR0)
    3934     {
    3935         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSendMsiR0, &pVM->pdm.s.IoApic.pfnSendMsiR0);
    3936         AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pIoApicReg->pszSendMsiR0, rc));
    3937         if (RT_FAILURE(rc))
    3938         {
    3939             LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    3940             return rc;
    3941         }
    3942     }
    3943     else
    3944     {
    3945         pVM->pdm.s.IoApic.pfnSendMsiR0 = 0;
    3946     }
    3947 
    3948     if (pIoApicReg->pszSetEoiR0)
    3949     {
    3950         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSetEoiR0, &pVM->pdm.s.IoApic.pfnSetEoiR0);
    3951         AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pIoApicReg->pszSetEoiR0, rc));
    3952         if (RT_FAILURE(rc))
    3953         {
    3954             LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    3955             return rc;
    3956         }
    3957     }
    3958     else
    3959     {
    3960         pVM->pdm.s.IoApic.pfnSetEoiR0 = 0;
    3961     }
    3962 
     3790    AssertMsgReturn(pVM->pdm.s.IoApic.pDevInsR3 == NULL,
     3791                    ("Only one ioapic device is supported! (caller %s/%d)\n", pDevIns->pReg->szName, pDevIns->iInstance),
     3792                    VERR_ALREADY_EXISTS);
    39633793
    39643794    /*
    39653795     * Initialize the R3 bits.
    39663796     */
    3967     pVM->pdm.s.IoApic.pDevInsR3   = pDevIns;
    3968     pVM->pdm.s.IoApic.pfnSetIrqR3  = pIoApicReg->pfnSetIrqR3;
    3969     pVM->pdm.s.IoApic.pfnSendMsiR3 = pIoApicReg->pfnSendMsiR3;
    3970     pVM->pdm.s.IoApic.pfnSetEoiR3  = pIoApicReg->pfnSetEoiR3;
     3797    pVM->pdm.s.IoApic.pDevInsR3    = pDevIns;
     3798    pVM->pdm.s.IoApic.pfnSetIrqR3  = pIoApicReg->pfnSetIrq;
     3799    pVM->pdm.s.IoApic.pfnSendMsiR3 = pIoApicReg->pfnSendMsi;
     3800    pVM->pdm.s.IoApic.pfnSetEoiR3  = pIoApicReg->pfnSetEoi;
    39713801    Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    39723802
    39733803    /* set the helper pointer and return. */
    3974     *ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp;
    3975     LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
     3804    *ppIoApicHlp = &g_pdmR3DevIoApicHlp;
     3805    LogFlow(("pdmR3DevHlp_IoApicRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    39763806    return VINF_SUCCESS;
    39773807}
     
    47274557    pdmR3DevHlp_PICRegister,
    47284558    pdmR3DevHlp_APICRegister,
    4729     pdmR3DevHlp_IOAPICRegister,
     4559    pdmR3DevHlp_IoApicRegister,
    47304560    pdmR3DevHlp_HPETRegister,
    47314561    pdmR3DevHlp_PciRawRegister,
     
    52235053    pdmR3DevHlp_PICRegister,
    52245054    pdmR3DevHlp_APICRegister,
    5225     pdmR3DevHlp_IOAPICRegister,
     5055    pdmR3DevHlp_IoApicRegister,
    52265056    pdmR3DevHlp_HPETRegister,
    52275057    pdmR3DevHlp_PciRawRegister,
  • trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp

    r81909 r81938  
    109109 */
    110110
    111 /** @interface_method_impl{PDMIOAPICHLPR3,pfnApicBusDeliver} */
     111/** @interface_method_impl{PDMIOAPICHLP,pfnApicBusDeliver} */
    112112static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
    113113                                                       uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
     
    122122
    123123
    124 /** @interface_method_impl{PDMIOAPICHLPR3,pfnLock} */
     124/** @interface_method_impl{PDMIOAPICHLP,pfnLock} */
    125125static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    126126{
     
    131131
    132132
    133 /** @interface_method_impl{PDMIOAPICHLPR3,pfnUnlock} */
     133/** @interface_method_impl{PDMIOAPICHLP,pfnUnlock} */
    134134static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
    135135{
     
    140140
    141141
    142 /** @interface_method_impl{PDMIOAPICHLPR3,pfnGetRCHelpers} */
    143 static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
    144 {
    145     PDMDEV_ASSERT_DEVINS(pDevIns);
    146     PVM pVM = pDevIns->Internal.s.pVMR3;
    147     VM_ASSERT_EMT(pVM);
    148 
    149     RTRCPTR pRCHelpers = NIL_RTRCPTR;
    150     if (VM_IS_RAW_MODE_ENABLED(pVM))
    151     {
    152         int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);
    153         AssertReleaseRC(rc);
    154         AssertRelease(pRCHelpers);
    155     }
    156 
    157     LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
    158              pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
    159     return pRCHelpers;
    160 }
    161 
    162 
    163 /** @interface_method_impl{PDMIOAPICHLPR3,pfnGetR0Helpers} */
    164 static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
    165 {
    166     PDMDEV_ASSERT_DEVINS(pDevIns);
    167     PVM pVM = pDevIns->Internal.s.pVMR3;
    168     VM_ASSERT_EMT(pVM);
    169     PCPDMIOAPICHLPR0 pR0Helpers = 0;
    170     int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
    171     AssertReleaseRC(rc);
    172     AssertRelease(pR0Helpers);
    173     LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
    174              pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
    175     return pR0Helpers;
    176 }
    177 
    178 
    179142/**
    180143 * I/O APIC Device Helpers.
    181144 */
    182 const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =
    183 {
    184     PDM_IOAPICHLPR3_VERSION,
     145const PDMIOAPICHLP g_pdmR3DevIoApicHlp =
     146{
     147    PDM_IOAPICHLP_VERSION,
    185148    pdmR3IoApicHlp_ApicBusDeliver,
    186149    pdmR3IoApicHlp_Lock,
    187150    pdmR3IoApicHlp_Unlock,
    188     pdmR3IoApicHlp_GetRCHelpers,
    189     pdmR3IoApicHlp_GetR0Helpers,
    190     PDM_IOAPICHLPR3_VERSION /* the end */
     151    PDM_IOAPICHLP_VERSION /* the end */
    191152};
    192153
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r81922 r81938  
    13891389extern const PDMDEVHLPR3    g_pdmR3DevHlpUnTrusted;
    13901390extern const PDMPICHLP      g_pdmR3DevPicHlp;
    1391 extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp;
     1391extern const PDMIOAPICHLP  g_pdmR3DevIoApicHlp;
    13921392extern const PDMFWHLPR3     g_pdmR3DevFirmwareHlp;
    13931393extern const PDMPCIHLPR3    g_pdmR3DevPciHlp;
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