VirtualBox

Changeset 64596 in vbox for trunk


Ignore:
Timestamp:
Nov 8, 2016 3:03:18 PM (8 years ago)
Author:
vboxsync
Message:

VMM/APIC, PDM: Clean up PDM APIC helper interface, call VMM directly instead.

Location:
trunk
Files:
12 edited

Legend:

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

    r62476 r64596  
    4949VMM_INT_DECL(bool)      PDMHasIoApic(PVM pVM);
    5050VMM_INT_DECL(int)       PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
     51VMM_INT_DECL(int)       PDMIoApicBroadcastEoi(PVM pVM, uint8_t uVector);
    5152VMM_INT_DECL(int)       PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc);
    5253VMM_INT_DECL(bool)      PDMHasApic(PVM pVM);
  • trunk/include/VBox/vmm/pdmdev.h

    r64406 r64596  
    13851385
    13861386/**
    1387  * APIC RC helpers.
    1388  */
    1389 typedef struct PDMAPICHLPRC
    1390 {
    1391     /** Structure version. PDM_APICHLPRC_VERSION defines the current version. */
    1392     uint32_t                u32Version;
    1393 
    1394     /**
    1395      * Set the interrupt force action flag.
    1396      *
    1397      * @param   pDevIns         Device instance of the APIC.
    1398      * @param   enmType         IRQ type.
    1399      * @param   idCpu           Virtual CPU to set flag upon.
    1400      */
    1401     DECLRCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    1402 
    1403     /**
    1404      * Clear the interrupt force action flag.
    1405      *
    1406      * @param   pDevIns         Device instance of the APIC.
    1407      * @param   enmType         IRQ type.
    1408      * @param   idCpu           Virtual CPU to clear flag upon.
    1409      */
    1410     DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    1411 
    1412     /**
    1413      * Broadcasts an EOI for an interrupt vector to the I/O APICs.
    1414      *
    1415      * @returns VBox status code.
    1416      * @param   pDevIns         The APIC device instance.
    1417      * @param   u8Vector        The interrupt vector.
    1418      */
    1419     DECLRCCALLBACKMEMBER(int, pfnBusBroadcastEoi,(PPDMDEVINS pDevIns, uint8_t u8Vector));
    1420 
    1421     /**
    1422      * Calculates an IRQ tag for a timer, IPI or similar event.
    1423      *
    1424      * @returns The IRQ tag.
    1425      * @param   pDevIns         Device instance of the APIC.
    1426      * @param   u8Level         PDM_IRQ_LEVEL_HIGH or PDM_IRQ_LEVEL_FLIP_FLOP.
    1427      */
    1428     DECLRCCALLBACKMEMBER(uint32_t, pfnCalcIrqTag,(PPDMDEVINS pDevIns, uint8_t u8Level));
    1429 
    1430     /**
    1431      * Acquires the PDM lock.
    1432      *
    1433      * @returns VINF_SUCCESS on success.
    1434      * @returns rc if we failed to acquire the lock.
    1435      * @param   pDevIns         The APIC device instance.
    1436      * @param   rc              What to return if we fail to acquire the lock.
    1437      */
    1438     DECLRCCALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
    1439 
    1440     /**
    1441      * Releases the PDM lock.
    1442      *
    1443      * @param   pDevIns         The APIC device instance.
    1444      */
    1445     DECLRCCALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
    1446 
    1447     /**
    1448      * Get the virtual CPU id corresponding to the current EMT.
    1449      *
    1450      * @param   pDevIns         The APIC device instance.
    1451      */
    1452     DECLRCCALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
    1453 
    1454     /** Just a safety precaution. */
    1455     uint32_t                u32TheEnd;
    1456 } PDMAPICHLPRC;
    1457 /** Pointer to APIC GC helpers. */
    1458 typedef RCPTRTYPE(PDMAPICHLPRC *) PPDMAPICHLPRC;
    1459 /** Pointer to const APIC helpers. */
    1460 typedef RCPTRTYPE(const PDMAPICHLPRC *) PCPDMAPICHLPRC;
    1461 
    1462 /** Current PDMAPICHLPRC version number. */
    1463 #define PDM_APICHLPRC_VERSION                   PDM_VERSION_MAKE(0xfff5, 5, 0)
    1464 
    1465 
    1466 /**
    1467  * APIC R0 helpers.
    1468  */
    1469 typedef struct PDMAPICHLPR0
    1470 {
    1471     /** Structure version. PDM_APICHLPR0_VERSION defines the current version. */
    1472     uint32_t                u32Version;
    1473 
    1474     /**
    1475      * Set the interrupt force action flag.
    1476      *
    1477      * @param   pDevIns         Device instance of the APIC.
    1478      * @param   enmType         IRQ type.
    1479      * @param   idCpu           Virtual CPU to set flag upon.
    1480      */
    1481     DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    1482 
    1483     /**
    1484      * Clear the interrupt force action flag.
    1485      *
    1486      * @param   pDevIns         Device instance of the APIC.
    1487      * @param   enmType         IRQ type.
    1488      * @param   idCpu           Virtual CPU to clear flag upon.
    1489      */
    1490     DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    1491 
    1492     /**
    1493      * Broadcasts an EOI for an interrupt vector to the I/O APICs.
    1494      *
    1495      * @returns VBox status code.
    1496      * @param   pDevIns         The APIC device instance.
    1497      * @param   u8Vector        The interrupt vector.
    1498      */
    1499     DECLR0CALLBACKMEMBER(int, pfnBusBroadcastEoi,(PPDMDEVINS pDevIns, uint8_t u8Vector));
    1500 
    1501     /**
    1502      * Calculates an IRQ tag for a timer, IPI or similar event.
    1503      *
    1504      * @returns The IRQ tag.
    1505      * @param   pDevIns         Device instance of the APIC.
    1506      * @param   u8Level         PDM_IRQ_LEVEL_HIGH or PDM_IRQ_LEVEL_FLIP_FLOP.
    1507      */
    1508     DECLR0CALLBACKMEMBER(uint32_t, pfnCalcIrqTag,(PPDMDEVINS pDevIns, uint8_t u8Level));
    1509 
    1510     /**
    1511      * Acquires the PDM lock.
    1512      *
    1513      * @returns VINF_SUCCESS on success.
    1514      * @returns rc if we failed to acquire the lock.
    1515      * @param   pDevIns         The APIC device instance.
    1516      * @param   rc              What to return if we fail to acquire the lock.
    1517      */
    1518     DECLR0CALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
    1519 
    1520     /**
    1521      * Releases the PDM lock.
    1522      *
    1523      * @param   pDevIns         The APIC device instance.
    1524      */
    1525     DECLR0CALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
    1526 
    1527     /**
    1528      * Get the virtual CPU id corresponding to the current EMT.
    1529      *
    1530      * @param   pDevIns         The APIC device instance.
    1531      */
    1532     DECLR0CALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
    1533 
    1534     /** Just a safety precaution. */
    1535     uint32_t                u32TheEnd;
    1536 } PDMAPICHLPR0;
    1537 /** Pointer to APIC GC helpers. */
    1538 typedef RCPTRTYPE(PDMAPICHLPR0 *) PPDMAPICHLPR0;
    1539 /** Pointer to const APIC helpers. */
    1540 typedef R0PTRTYPE(const PDMAPICHLPR0 *) PCPDMAPICHLPR0;
    1541 
    1542 /** Current PDMAPICHLPR0 version number. */
    1543 #define PDM_APICHLPR0_VERSION                   PDM_VERSION_MAKE(0xfff4, 5, 0)
    1544 
    1545 /**
    1546  * APIC R3 helpers.
    1547  */
    1548 typedef struct PDMAPICHLPR3
    1549 {
    1550     /** Structure version. PDM_APICHLPR3_VERSION defines the current version. */
    1551     uint32_t                u32Version;
    1552 
    1553     /**
    1554      * Set the interrupt force action flag.
    1555      *
    1556      * @param   pDevIns         Device instance of the APIC.
    1557      * @param   enmType         IRQ type.
    1558      * @param   idCpu           Virtual CPU to set flag upon.
    1559      */
    1560     DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    1561 
    1562     /**
    1563      * Clear the interrupt force action flag.
    1564      *
    1565      * @param   pDevIns         Device instance of the APIC.
    1566      * @param   enmType         IRQ type.
    1567      * @param   idCpu           Virtual CPU to clear flag upon.
    1568      */
    1569     DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
    1570 
    1571     /**
    1572      * Broadcasts an EOI for an interrupt vector to the I/O APICs.
    1573      *
    1574      * @returns VBox status code.
    1575      * @param   pDevIns         The APIC device instance.
    1576      * @param   u8Vector        The interrupt vector.
    1577      */
    1578     DECLR3CALLBACKMEMBER(int, pfnBusBroadcastEoi,(PPDMDEVINS pDevIns, uint8_t u8Vector));
    1579 
    1580     /**
    1581      * Calculates an IRQ tag for a timer, IPI or similar event.
    1582      *
    1583      * @returns The IRQ tag.
    1584      * @param   pDevIns         Device instance of the APIC.
    1585      * @param   u8Level         PDM_IRQ_LEVEL_HIGH or PDM_IRQ_LEVEL_FLIP_FLOP.
    1586      */
    1587     DECLR3CALLBACKMEMBER(uint32_t, pfnCalcIrqTag,(PPDMDEVINS pDevIns, uint8_t u8Level));
    1588 
    1589     /**
    1590      * Modifies APIC-related bits in the CPUID feature mask and preps MSRs.
    1591      *
    1592      * @param   pDevIns         Device instance of the APIC.
    1593      * @param   enmMode         Max supported APIC mode.
    1594      */
    1595     DECLR3CALLBACKMEMBER(void, pfnSetFeatureLevel,(PPDMDEVINS pDevIns, PDMAPICMODE enmMode));
    1596 
    1597     /**
    1598      * Get the virtual CPU id corresponding to the current EMT.
    1599      *
    1600      * @param   pDevIns         The APIC device instance.
    1601      */
    1602     DECLR3CALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
    1603 
    1604     /**
    1605      * Sends Startup IPI to given virtual CPU.
    1606      *
    1607      * @param   pDevIns         The APIC device instance.
    1608      * @param   idCpu           Virtual CPU to perform Startup IPI on.
    1609      * @param   uVector         Startup IPI vector.
    1610      */
    1611     DECLR3CALLBACKMEMBER(void,    pfnSendStartupIpi,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector));
    1612 
    1613     /**
    1614      * Sends INIT IPI to given virtual CPU, should result in reset and
    1615      * halting till Startup IPI.
    1616      *
    1617      * @param   pDevIns         The APIC device instance.
    1618      * @param   idCpu           Virtual CPU to perform INIT IPI on.
    1619      */
    1620     DECLR3CALLBACKMEMBER(void,    pfnSendInitIpi,(PPDMDEVINS pDevIns, VMCPUID idCpu));
    1621 
    1622     /**
    1623      * Gets the address of the RC APIC helpers.
    1624      *
    1625      * This should be called at both construction and relocation time
    1626      * to obtain the correct address of the RC helpers.
    1627      *
    1628      * @returns GC pointer to the APIC helpers.
    1629      * @param   pDevIns         Device instance of the APIC.
    1630      */
    1631     DECLR3CALLBACKMEMBER(PCPDMAPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
    1632 
    1633     /**
    1634      * Gets the address of the R0 APIC helpers.
    1635      *
    1636      * This should be called at both construction and relocation time
    1637      * to obtain the correct address of the R0 helpers.
    1638      *
    1639      * @returns R0 pointer to the APIC helpers.
    1640      * @param   pDevIns         Device instance of the APIC.
    1641      */
    1642     DECLR3CALLBACKMEMBER(PCPDMAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
    1643 
    1644     /**
    1645      * Get the critical section used to synchronize the PICs, PCI and stuff.
    1646      *
    1647      * @returns Ring-3 pointer to the critical section.
    1648      * @param   pDevIns         The APIC device instance.
    1649      */
    1650     DECLR3CALLBACKMEMBER(R3PTRTYPE(PPDMCRITSECT), pfnGetR3CritSect,(PPDMDEVINS pDevIns));
    1651 
    1652     /**
    1653      * Get the critical section used to synchronize the PICs, PCI and stuff.
    1654      *
    1655      * @returns Raw-mode context pointer to the critical section.
    1656      * @param   pDevIns         The APIC device instance.
    1657      */
    1658     DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnGetRCCritSect,(PPDMDEVINS pDevIns));
    1659 
    1660     /**
    1661      * Get the critical section used to synchronize the PICs, PCI and stuff.
    1662      *
    1663      * @returns Ring-0 pointer to the critical section.
    1664      * @param   pDevIns         The APIC device instance.
    1665      */
    1666     DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnGetR0CritSect,(PPDMDEVINS pDevIns));
    1667 
    1668     /** Just a safety precaution. */
    1669     uint32_t                u32TheEnd;
    1670 } PDMAPICHLPR3;
    1671 /** Pointer to APIC helpers. */
    1672 typedef R3PTRTYPE(PDMAPICHLPR3 *) PPDMAPICHLPR3;
    1673 /** Pointer to const APIC helpers. */
    1674 typedef R3PTRTYPE(const PDMAPICHLPR3 *) PCPDMAPICHLPR3;
    1675 
    1676 /** Current PDMAPICHLP version number. */
    1677 #define PDM_APICHLPR3_VERSION                   PDM_VERSION_MAKE(0xfff3, 4, 0)
    1678 
    1679 
    1680 /**
    16811387 * I/O APIC registration structure.
    16821388 */
     
    34843190     * @param   pDevIns             The device instance.
    34853191     * @param   pApicReg            Pointer to a APIC registration structure.
    3486      * @param   ppApicHlpR3         Where to store the pointer to the APIC helpers.
    3487      */
    3488     DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3));
     3192     */
     3193    DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg));
    34893194
    34903195    /**
     
    55145219 * @copydoc PDMDEVHLPR3::pfnAPICRegister
    55155220 */
    5516 DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
    5517 {
    5518     return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg, ppApicHlpR3);
     5221DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg)
     5222{
     5223    return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg);
    55195224}
    55205225
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSize.cpp

    r64560 r64596  
    291291#ifdef VBOX_WITH_NEW_APIC
    292292    CHECK_MEMBER_ALIGNMENT(APICDEV, pDevInsR0, 8);
    293     CHECK_MEMBER_ALIGNMENT(APICDEV, pCritSectR0, 8);
    294293    CHECK_MEMBER_ALIGNMENT(APICDEV, pDevInsRC, 8);
    295     CHECK_MEMBER_ALIGNMENT(APICDEV, pCritSectRC, 8);
    296294#else
    297295# ifdef VBOX_WITH_STATISTICS
  • trunk/src/VBox/VMM/VMMAll/APICAll.cpp

    r64112 r64596  
    2323#include "APICInternal.h"
    2424#include <VBox/vmm/pdmdev.h>
     25#include <VBox/vmm/pdmapi.h>
     26#include <VBox/vmm/rem.h>
    2527#include <VBox/vmm/vm.h>
     28#include <VBox/vmm/vmm.h>
    2629#include <VBox/vmm/vmcpuset.h>
    2730
     
    471474    uint8_t *pbXApic = (uint8_t *)pXApicPage;
    472475    *(uint32_t *)(pbXApic + offReg) = uReg;
    473 }
    474 
    475 
    476 /**
    477  * Broadcasts the EOI to the I/O APICs.
    478  *
    479  * @param   pVCpu           The cross context virtual CPU structure.
    480  * @param   uVector         The interrupt vector corresponding to the EOI.
    481  */
    482 DECLINLINE(int) apicBusBroadcastEoi(PVMCPU pVCpu, uint8_t uVector)
    483 {
    484     PVM      pVM      = pVCpu->CTX_SUFF(pVM);
    485     PAPICDEV pApicDev = VM_TO_APICDEV(pVM);
    486     return pApicDev->CTX_SUFF(pApicHlp)->pfnBusBroadcastEoi(pApicDev->CTX_SUFF(pDevIns), uVector);
    487476}
    488477
     
    12651254        if (fLevelTriggered)
    12661255        {
    1267             int rc = apicBusBroadcastEoi(pVCpu, uVector);
     1256            int rc = PDMIoApicBroadcastEoi(pVCpu->CTX_SUFF(pVM), uVector);
    12681257            if (rc == VINF_SUCCESS)
    12691258            { /* likely */ }
     
    26822671VMM_INT_DECL(void) apicSetInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType)
    26832672{
    2684     PVM      pVM      = pVCpu->CTX_SUFF(pVM);
    2685     PAPICDEV pApicDev = VM_TO_APICDEV(pVM);
    2686     CTX_SUFF(pApicDev->pApicHlp)->pfnSetInterruptFF(pApicDev->CTX_SUFF(pDevIns), enmType, pVCpu->idCpu);
     2673    switch (enmType)
     2674    {
     2675        case PDMAPICIRQ_HARDWARE:
     2676            VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
     2677            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     2678            break;
     2679        case PDMAPICIRQ_UPDATE_PENDING: VMCPU_FF_SET(pVCpu, VMCPU_FF_UPDATE_APIC);    break;
     2680        case PDMAPICIRQ_NMI:            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);  break;
     2681        case PDMAPICIRQ_SMI:            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);  break;
     2682        case PDMAPICIRQ_EXTINT:         VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);  break;
     2683        default:
     2684            AssertMsgFailed(("enmType=%d\n", enmType));
     2685            break;
     2686    }
     2687
     2688    /*
     2689     * We need to wake up the target CPU if we're not on EMT.
     2690     */
     2691#if defined(IN_RING0)
     2692    PVM     pVM   = pVCpu->CTX_SUFF(pVM);
     2693    VMCPUID idCpu = pVCpu->idCpu;
     2694    if (   enmType != PDMAPICIRQ_HARDWARE
     2695        && VMMGetCpuId(pVM) != idCpu)
     2696    {
     2697        switch (VMCPU_GET_STATE(pVCpu))
     2698        {
     2699            case VMCPUSTATE_STARTED_EXEC:
     2700                GVMMR0SchedPokeEx(pVM, idCpu, false /* fTakeUsedLock */);
     2701                break;
     2702
     2703            case VMCPUSTATE_STARTED_HALTED:
     2704                GVMMR0SchedWakeUpEx(pVM, idCpu, false /* fTakeUsedLock */);
     2705                break;
     2706
     2707            default:
     2708                break; /* nothing to do in other states. */
     2709        }
     2710    }
     2711#elif defined(IN_RING3)
     2712# ifdef VBOX_WITH_REM
     2713    REMR3NotifyInterruptSet(pVCpu->CTX_SUFF(pVM), pVCpu);
     2714# endif
     2715    if (enmType != PDMAPICIRQ_HARDWARE)
     2716        VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
     2717#endif
    26872718}
    26882719
     
    26962727VMM_INT_DECL(void) apicClearInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType)
    26972728{
    2698     PVM      pVM      = pVCpu->CTX_SUFF(pVM);
    2699     PAPICDEV pApicDev = VM_TO_APICDEV(pVM);
    2700     pApicDev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(pApicDev->CTX_SUFF(pDevIns), enmType, pVCpu->idCpu);
     2729    /* NMI/SMI can't be cleared. */
     2730    switch (enmType)
     2731    {
     2732        case PDMAPICIRQ_HARDWARE:   VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC); break;
     2733        case PDMAPICIRQ_EXTINT:     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);  break;
     2734        default:
     2735            AssertMsgFailed(("enmType=%d\n", enmType));
     2736            break;
     2737    }
     2738
     2739#if defined(IN_RING3) && defined(VBOX_WITH_REM)
     2740    REMR3NotifyInterruptClear(pVCpu->CTX_SUFF(pVM), pVCpu);
     2741#endif
    27012742}
    27022743
  • trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r62478 r64596  
    207207}
    208208
     209
     210/**
     211 * Broadcasts an EOI to the I/O APICs.
     212 *
     213 * @return VBox status code (incl. scheduling status codes).
     214 * @param   pVCpu           The cross context virtual CPU structure.
     215 * @param   uVector         The interrupt vector corresponding to the EOI.
     216 */
     217VMM_INT_DECL(int) PDMIoApicBroadcastEoi(PVM pVM, uint8_t uVector)
     218{
     219    /* At present, we support only a maximum of one I/O APIC per-VM. If we ever implement having
     220       multiple I/O APICs per-VM, we'll have to broadcast this EOI to all of the I/O APICs. */
     221    if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
     222    {
     223        Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi));
     224        return pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), uVector);
     225    }
     226
     227    /* We shouldn't return failure if no I/O APIC is present. */
     228    return VINF_SUCCESS;
     229}
     230
     231
    209232/**
    210233 * Send a MSI to an I/O APIC.
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r64387 r64596  
    4848extern DECLEXPORT(const PDMDEVHLPR0)    g_pdmR0DevHlp;
    4949extern DECLEXPORT(const PDMPICHLPR0)    g_pdmR0PicHlp;
    50 extern DECLEXPORT(const PDMAPICHLPR0)   g_pdmR0ApicHlp;
    5150extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp;
    5251extern DECLEXPORT(const PDMPCIHLPR0)    g_pdmR0PciHlp;
     
    525524
    526525
    527 
    528 
    529 /** @name APIC Ring-0 Helpers
    530  * @{
    531  */
    532 
    533 /** @interface_method_impl{PDMAPICHLPR0,pfnSetInterruptFF} */
    534 static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    535 {
    536     PDMDEV_ASSERT_DEVINS(pDevIns);
    537     PVM    pVM   = pDevIns->Internal.s.pVMR0;
    538     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    539 
    540     AssertReturnVoid(idCpu < pVM->cCpus);
    541 
    542     LogFlow(("pdmR0ApicHlp_SetInterruptFF: CPU%d=caller=%p/%d: VM_FF_INTERRUPT %d -> 1 (CPU%d)\n",
    543              VMMGetCpuId(pVM), pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC), idCpu));
    544 
    545     switch (enmType)
    546     {
    547         case PDMAPICIRQ_UPDATE_PENDING:
    548             VMCPU_FF_SET(pVCpu, VMCPU_FF_UPDATE_APIC);
    549             break;
    550         case PDMAPICIRQ_HARDWARE:
    551 #ifdef VBOX_WITH_NEW_APIC
    552             VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
    553 #endif
    554             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    555             break;
    556         case PDMAPICIRQ_NMI:
    557             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
    558             break;
    559         case PDMAPICIRQ_SMI:
    560             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
    561             break;
    562         case PDMAPICIRQ_EXTINT:
    563             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    564             break;
    565         default:
    566             AssertMsgFailed(("enmType=%d\n", enmType));
    567             break;
    568     }
    569 
    570     /* We need to wake up the target CPU. */
    571     if (
    572 #ifdef VBOX_WITH_NEW_APIC
    573         /* We are already on EMT if enmType is PDMAPICIRQ_HARDWARE. Don't bother with poking! */
    574         enmType != PDMAPICIRQ_HARDWARE &&
    575 #endif
    576         VMMGetCpuId(pVM) != idCpu)
    577     {
    578         switch (VMCPU_GET_STATE(pVCpu))
    579         {
    580             case VMCPUSTATE_STARTED_EXEC:
    581                 GVMMR0SchedPokeEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
    582                 break;
    583 
    584             case VMCPUSTATE_STARTED_HALTED:
    585                 GVMMR0SchedWakeUpEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
    586                 break;
    587 
    588             default:
    589                 break; /* nothing to do in other states. */
    590         }
    591     }
    592 }
    593 
    594 
    595 /** @interface_method_impl{PDMAPICHLPR0,pfnClearInterruptFF} */
    596 static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    597 {
    598     PDMDEV_ASSERT_DEVINS(pDevIns);
    599     PVM    pVM   = pDevIns->Internal.s.pVMR0;
    600     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    601 
    602     AssertReturnVoid(idCpu < pVM->cCpus);
    603 
    604     LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
    605              pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    606 
    607     /* Note: NMI/SMI can't be cleared. */
    608     switch (enmType)
    609     {
    610         case PDMAPICIRQ_HARDWARE:
    611             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    612             break;
    613         case PDMAPICIRQ_EXTINT:
    614             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    615             break;
    616         case PDMAPICIRQ_UPDATE_PENDING:
    617             VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
    618             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_UPDATE_APIC);
    619             break;
    620         default:
    621             AssertMsgFailed(("enmType=%d\n", enmType));
    622             break;
    623     }
    624 }
    625 
    626 
    627 /** @interface_method_impl{PDMAPICHLPR0,pfnBusBroadcastEoi} */
    628 static DECLCALLBACK(int) pdmR0ApicHlp_BusBroadcastEoi(PPDMDEVINS pDevIns, uint8_t u8Vector)
    629 {
    630     /* pfnSetEoi will be NULL in the old IOAPIC code as it's not implemented. */
    631 #ifdef VBOX_WITH_NEW_IOAPIC
    632     PDMDEV_ASSERT_DEVINS(pDevIns);
    633     PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
    634 
    635     /* At present, we support only a maximum of one I/O APIC per-VM. If we ever implement having
    636        multiple I/O APICs per-VM, we'll have to broadcast this EOI to all of the I/O APICs. */
    637     if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
    638     {
    639         Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi));
    640         return pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Vector);
    641     }
    642 #endif
    643     return VINF_SUCCESS;
    644 }
    645 
    646 
    647 /** @interface_method_impl{PDMAPICHLPR0,pfnCalcIrqTag} */
    648 static DECLCALLBACK(uint32_t) pdmR0ApicHlp_CalcIrqTag(PPDMDEVINS pDevIns, uint8_t u8Level)
    649 {
    650     PDMDEV_ASSERT_DEVINS(pDevIns);
    651     PVM pVM = pDevIns->Internal.s.pVMR0;
    652 
    653     pdmLock(pVM);
    654 
    655     uint32_t uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
    656     if (u8Level == PDM_IRQ_LEVEL_HIGH)
    657         VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    658     else
    659         VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    660 
    661 
    662     pdmUnlock(pVM);
    663     LogFlow(("pdmR0ApicHlp_CalcIrqTag: caller=%p/%d: returns %#x (u8Level=%d)\n",
    664              pDevIns, pDevIns->iInstance, uTagSrc, u8Level));
    665     return uTagSrc;
    666 }
    667 
    668 
    669 /** @interface_method_impl{PDMAPICHLPR0,pfnLock} */
    670 static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    671 {
    672     PDMDEV_ASSERT_DEVINS(pDevIns);
    673     return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
    674 }
    675 
    676 
    677 /** @interface_method_impl{PDMAPICHLPR0,pfnUnlock} */
    678 static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns)
    679 {
    680     PDMDEV_ASSERT_DEVINS(pDevIns);
    681     pdmUnlock(pDevIns->Internal.s.pVMR0);
    682 }
    683 
    684 
    685 /** @interface_method_impl{PDMAPICHLPR0,pfnGetCpuId} */
    686 static DECLCALLBACK(VMCPUID) pdmR0ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
    687 {
    688     PDMDEV_ASSERT_DEVINS(pDevIns);
    689     return VMMGetCpuId(pDevIns->Internal.s.pVMR0);
    690 }
    691 
    692 
    693 /**
    694  * The Ring-0 APIC Helper Callbacks.
    695  */
    696 extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp =
    697 {
    698     PDM_APICHLPR0_VERSION,
    699     pdmR0ApicHlp_SetInterruptFF,
    700     pdmR0ApicHlp_ClearInterruptFF,
    701     pdmR0ApicHlp_BusBroadcastEoi,
    702     pdmR0ApicHlp_CalcIrqTag,
    703     pdmR0ApicHlp_Lock,
    704     pdmR0ApicHlp_Unlock,
    705     pdmR0ApicHlp_GetCpuId,
    706     PDM_APICHLPR0_VERSION
    707 };
    708 
    709 /** @} */
    710 
    711 
    712 
    713 
    714526/** @name I/O APIC Ring-0 Helpers
    715527 * @{
  • trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r63945 r64596  
    250250
    251251/**
     252 * Sets the CPUID feature bits for the APIC mode.
     253 *
     254 * @param   pVM             The cross context VM structure.
     255 * @param   enmMode         The APIC mode.
     256 */
     257static void apicR3SetCpuIdFeatureLevel(PVM pVM, PDMAPICMODE enmMode)
     258{
     259    switch (enmMode)
     260    {
     261        case PDMAPICMODE_NONE:
     262            CPUMR3ClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC);
     263            CPUMR3ClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);
     264            break;
     265
     266        case PDMAPICMODE_APIC:
     267            CPUMR3ClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC);
     268            CPUMR3SetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);
     269            break;
     270
     271        case PDMAPICMODE_X2APIC:
     272            CPUMR3SetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);
     273            CPUMR3SetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_X2APIC);
     274            break;
     275
     276        default:
     277            AssertMsgFailed(("Unknown/invalid APIC mode: %d\n", (int)enmMode));
     278    }
     279}
     280
     281
     282/**
    252283 * Resets the APIC base MSR.
    253284 *
     
    10761107}
    10771108
    1078 #if 0 /** @todo not referenced and will cause assertion in apicR3LoadExec (VERR_WRONG_ORDER). */
    1079 /**
    1080  * @copydoc FNSSMDEVLIVEEXEC
    1081  */
    1082 static DECLCALLBACK(int) apicR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
    1083 {
    1084     PAPICDEV pApicDev = PDMINS_2_DATA(pDevIns, PAPICDEV);
    1085     PVM      pVM      = PDMDevHlpGetVM(pApicDev->pDevInsR3);
    1086     RT_NOREF1(uPass);
    1087 
    1088     LogFlow(("APIC: apicR3LiveExec: uPass=%u\n", uPass));
    1089 
    1090     int rc = apicR3SaveVMData(pVM, pSSM);
    1091     AssertRCReturn(rc, rc);
    1092     return VINF_SSM_DONT_CALL_AGAIN;
    1093 }
    1094 #endif
    10951109
    10961110/**
     
    13451359    LogFlow(("APIC: apicR3Relocate: pVM=%p pDevIns=%p offDelta=%RGi\n", pVM, pDevIns, offDelta));
    13461360
    1347     pApicDev->pDevInsRC   = PDMDEVINS_2_RCPTR(pDevIns);
    1348     pApicDev->pApicHlpRC  = pApicDev->pApicHlpR3->pfnGetRCHelpers(pDevIns);
    1349     pApicDev->pCritSectRC = pApicDev->pApicHlpR3->pfnGetRCCritSect(pDevIns);
     1361    pApicDev->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    13501362
    13511363    pApic->pApicDevRC   = PDMINS_2_DATA_RCPTR(pDevIns);
     
    16541666    {
    16551667        case PDMAPICMODE_NONE:
    1656 #if 1
    16571668            /** @todo permanently disabling the APIC won't really work (needs
    16581669             *        fixing in HM, CPUM, PDM and possibly other places). See
    16591670             *        @bugref{8353}. */
    16601671            return VMR3SetError(pVM->pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS, "APIC mode 'none' is not supported yet.");
    1661 #endif
    16621672        case PDMAPICMODE_APIC:
    16631673        case PDMAPICMODE_X2APIC:
     
    17201730    }
    17211731
    1722     rc = PDMDevHlpAPICRegister(pDevIns, &ApicReg, &pApicDev->pApicHlpR3);
     1732    rc = PDMDevHlpAPICRegister(pDevIns, &ApicReg);
    17231733    AssertLogRelRCReturn(rc, rc);
    1724     pApicDev->pCritSectR3 = pApicDev->pApicHlpR3->pfnGetR3CritSect(pDevIns);
    17251734
    17261735    /*
     
    17411750
    17421751    /* Tell CPUM about the APIC feature level so it can adjust APICBASE MSR GP mask and CPUID bits. */
    1743     pApicDev->pApicHlpR3->pfnSetFeatureLevel(pDevIns, pApic->enmMaxMode);
     1752    apicR3SetCpuIdFeatureLevel(pVM, pApic->enmMaxMode);
    17441753
    17451754    /* Initialize the state. */
     
    17611770    if (pApic->fRZEnabled)
    17621771    {
    1763         pApicDev->pApicHlpRC  = pApicDev->pApicHlpR3->pfnGetRCHelpers(pDevIns);
    1764         pApicDev->pCritSectRC = pApicDev->pApicHlpR3->pfnGetRCCritSect(pDevIns);
    17651772        rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysApicBase, sizeof(XAPICPAGE), NIL_RTRCPTR /*pvUser*/,
    17661773                                     "apicWriteMmio", "apicReadMmio");
     
    17681775            return rc;
    17691776
    1770         pApicDev->pApicHlpR0  = pApicDev->pApicHlpR3->pfnGetR0Helpers(pDevIns);
    1771         pApicDev->pCritSectR0 = pApicDev->pApicHlpR3->pfnGetR0CritSect(pDevIns);
    17721777        rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysApicBase, sizeof(XAPICPAGE), NIL_RTR0PTR /*pvUser*/,
    17731778                                     "apicWriteMmio", "apicReadMmio");
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r64406 r64596  
    28452845
    28462846/** @interface_method_impl{PDMDEVHLPR3,pfnAPICRegister} */
    2847 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
     2847static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg)
    28482848{
    28492849    PDMDEV_ASSERT_DEVINS(pDevIns);
     
    28512851    LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseMsrR3=%p, .pfnGetBaseMsrR3=%p, "
    28522852             ".pfnSetTprR3=%p, .pfnGetTprR3=%p, .pfnWriteMsr3=%p, .pfnReadMsr3=%p, .pfnBusDeliverR3=%p, .pfnLocalInterruptR3=%p .pfnGetTimerFreqR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseMsrRC=%p:{%s}, pszGetBaseMsrRC=%p:{%s}, "
    2853              ".pszSetTprRC=%p:{%s}, .pszGetTprRC=%p:{%s}, .pszWriteMsrRC=%p:{%s}, .pszReadMsrRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}, .pszLocalInterruptRC=%p:{%s}, .pszGetTimerFreqRC=%p:{%s}} ppApicHlpR3=%p\n",
     2853             ".pszSetTprRC=%p:{%s}, .pszGetTprRC=%p:{%s}, .pszWriteMsrRC=%p:{%s}, .pszReadMsrRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}, .pszLocalInterruptRC=%p:{%s}, .pszGetTimerFreqRC=%p:{%s}}\n",
    28542854             pDevIns->pReg->szName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseMsrR3,
    28552855             pApicReg->pfnGetBaseMsrR3, pApicReg->pfnSetTprR3, pApicReg->pfnGetTprR3, pApicReg->pfnWriteMsrR3, pApicReg->pfnReadMsrR3, pApicReg->pfnBusDeliverR3, pApicReg->pfnLocalInterruptR3, pApicReg->pfnGetTimerFreqR3, pApicReg->pszGetInterruptRC,
    28562856             pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseMsrRC, pApicReg->pszSetBaseMsrRC, pApicReg->pszGetBaseMsrRC, pApicReg->pszGetBaseMsrRC,
    28572857             pApicReg->pszSetTprRC, pApicReg->pszSetTprRC, pApicReg->pszGetTprRC, pApicReg->pszGetTprRC, pApicReg->pszWriteMsrRC, pApicReg->pszWriteMsrRC, pApicReg->pszReadMsrRC, pApicReg->pszReadMsrRC, pApicReg->pszBusDeliverRC,
    2858              pApicReg->pszBusDeliverRC, pApicReg->pszLocalInterruptRC, pApicReg->pszLocalInterruptRC, pApicReg->pszGetTimerFreqRC, pApicReg->pszGetTimerFreqRC, ppApicHlpR3));
     2858             pApicReg->pszBusDeliverRC, pApicReg->pszLocalInterruptRC, pApicReg->pszLocalInterruptRC, pApicReg->pszGetTimerFreqRC, pApicReg->pszGetTimerFreqRC));
    28592859
    28602860    /*
     
    29612961        return VERR_INVALID_PARAMETER;
    29622962    }
    2963     if (!ppApicHlpR3)
    2964     {
    2965         Assert(ppApicHlpR3);
    2966         LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (ppApicHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    2967         return VERR_INVALID_PARAMETER;
    2968     }
    29692963
    29702964    /*
     
    31453139    Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    31463140
    3147     /* set the helper pointer and return. */
    3148     *ppApicHlpR3 = &g_pdmR3DevApicHlp;
    31493141    LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
    31503142    return VINF_SUCCESS;
     
    34273419    {
    34283420        Assert(ppPciRawHlpR3);
    3429         LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (ppApicHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     3421        LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (ppPciRawHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
    34303422        return VERR_INVALID_PARAMETER;
    34313423    }
  • trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp

    r64115 r64596  
    178178
    179179
    180 
    181 
    182 /** @name R3 APIC Helpers
    183  * @{
    184  */
    185 
    186 /** @interface_method_impl{PDMAPICHLPR3,pfnSetInterruptFF} */
    187 static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    188 {
    189     PDMDEV_ASSERT_DEVINS(pDevIns);
    190     PVM pVM = pDevIns->Internal.s.pVMR3;
    191     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    192 
    193     AssertReturnVoid(idCpu < pVM->cCpus);
    194 
    195     LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 1\n",
    196              pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    197 
    198     switch (enmType)
    199     {
    200         case PDMAPICIRQ_UPDATE_PENDING:
    201             VMCPU_FF_SET(pVCpu, VMCPU_FF_UPDATE_APIC);
    202             break;
    203         case PDMAPICIRQ_HARDWARE:
    204 #ifdef VBOX_WITH_NEW_APIC
    205             VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
    206 #endif
    207             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    208             break;
    209         case PDMAPICIRQ_NMI:
    210             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
    211             break;
    212         case PDMAPICIRQ_SMI:
    213             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
    214             break;
    215         case PDMAPICIRQ_EXTINT:
    216             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    217             break;
    218         default:
    219             AssertMsgFailed(("enmType=%d\n", enmType));
    220             break;
    221     }
    222 #ifdef VBOX_WITH_REM
    223     REMR3NotifyInterruptSet(pVM, pVCpu);
    224 #endif
    225 
    226 #ifdef VBOX_WITH_NEW_APIC
    227     if (enmType != PDMAPICIRQ_HARDWARE)
    228         VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
    229 #else
    230     VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
    231 #endif
    232 }
    233 
    234 
    235 /** @interface_method_impl{PDMAPICHLPR3,pfnClearInterruptFF} */
    236 static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    237 {
    238     PDMDEV_ASSERT_DEVINS(pDevIns);
    239     PVM pVM = pDevIns->Internal.s.pVMR3;
    240     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    241 
    242     AssertReturnVoid(idCpu < pVM->cCpus);
    243 
    244     LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 0\n",
    245              pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    246 
    247     /* Note: NMI/SMI can't be cleared. */
    248     switch (enmType)
    249     {
    250         case PDMAPICIRQ_HARDWARE:
    251             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    252             break;
    253         case PDMAPICIRQ_EXTINT:
    254             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    255             break;
    256         case PDMAPICIRQ_UPDATE_PENDING:
    257             VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
    258             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_UPDATE_APIC);
    259             break;
    260         default:
    261             AssertMsgFailed(("enmType=%d\n", enmType));
    262             break;
    263     }
    264 #ifdef VBOX_WITH_REM
    265     REMR3NotifyInterruptClear(pVM, pVCpu);
    266 #endif
    267 }
    268 
    269 
    270 /** @interface_method_impl{PDMAPICHLPR3,pfnBusBroadcastEoi} */
    271 static DECLCALLBACK(int) pdmR3ApicHlp_BusBroadcastEoi(PPDMDEVINS pDevIns, uint8_t u8Vector)
    272 {
    273     /* pfnSetEoi will be NULL in the old IOAPIC code as it's not implemented. */
    274 #ifdef VBOX_WITH_NEW_IOAPIC
    275     PDMDEV_ASSERT_DEVINS(pDevIns);
    276     PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
    277 
    278     /* At present, we support only a maximum of one I/O APIC per-VM. If we ever implement having
    279        multiple I/O APICs per-VM, we'll have to broadcast this EOI to all of the I/O APICs. */
    280     if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
    281     {
    282         Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi));
    283         return pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Vector);
    284     }
    285 #endif
    286     return VINF_SUCCESS;
    287 }
    288 
    289 
    290 /** @interface_method_impl{PDMAPICHLPR3,pfnCalcIrqTag} */
    291 static DECLCALLBACK(uint32_t) pdmR3ApicHlp_CalcIrqTag(PPDMDEVINS pDevIns, uint8_t u8Level)
    292 {
    293     PDMDEV_ASSERT_DEVINS(pDevIns);
    294     PVM pVM = pDevIns->Internal.s.pVMR3;
    295     Assert(u8Level == PDM_IRQ_LEVEL_HIGH || u8Level == PDM_IRQ_LEVEL_FLIP_FLOP);
    296 
    297     pdmLock(pVM);
    298 
    299     uint32_t uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
    300     if (u8Level == PDM_IRQ_LEVEL_HIGH)
    301         VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    302     else
    303         VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    304 
    305 
    306     pdmUnlock(pVM);
    307     LogFlow(("pdmR3ApicHlp_CalcIrqTag: caller='%s'/%d: returns %#x (u8Level=%d)\n",
    308              pDevIns->pReg->szName, pDevIns->iInstance, uTagSrc, u8Level));
    309     return uTagSrc;
    310 }
    311 
    312 
    313 /** @interface_method_impl{PDMAPICHLPR3,pfnSetFeatureLevel} */
    314 static DECLCALLBACK(void) pdmR3ApicHlp_SetFeatureLevel(PPDMDEVINS pDevIns, PDMAPICMODE enmMode)
    315 {
    316     PDMDEV_ASSERT_DEVINS(pDevIns);
    317     LogFlow(("pdmR3ApicHlp_SetFeatureLevel: caller='%s'/%d: mode=%d\n",
    318              pDevIns->pReg->szName, pDevIns->iInstance, (int)enmMode));
    319     switch (enmMode)
    320     {
    321         case PDMAPICMODE_NONE:
    322             CPUMR3ClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
    323             CPUMR3ClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
    324             break;
    325         case PDMAPICMODE_APIC:
    326             CPUMR3ClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
    327             CPUMR3SetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
    328             break;
    329         case PDMAPICMODE_X2APIC:
    330             CPUMR3SetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
    331             CPUMR3SetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
    332             break;
    333         default:
    334             AssertMsgFailed(("Unknown APIC mode: %d\n", (int)enmMode));
    335     }
    336 }
    337 
    338 /** @interface_method_impl{PDMAPICHLPR3,pfnGetCpuId} */
    339 static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
    340 {
    341     PDMDEV_ASSERT_DEVINS(pDevIns);
    342     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    343     return VMMGetCpuId(pDevIns->Internal.s.pVMR3);
    344 }
    345 
    346 
    347 /** @interface_method_impl{PDMAPICHLPR3,pfnSendStartupIpi} */
    348 static DECLCALLBACK(void) pdmR3ApicHlp_SendStartupIpi(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector)
    349 {
    350     PDMDEV_ASSERT_DEVINS(pDevIns);
    351     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    352     VMMR3SendStartupIpi(pDevIns->Internal.s.pVMR3, idCpu, uVector);
    353 }
    354 
    355 
    356 /** @interface_method_impl{PDMAPICHLPR3,pfnSendInitIpi} */
    357 static DECLCALLBACK(void) pdmR3ApicHlp_SendInitIpi(PPDMDEVINS pDevIns, VMCPUID idCpu)
    358 {
    359     PDMDEV_ASSERT_DEVINS(pDevIns);
    360     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    361     VMMR3SendInitIpi(pDevIns->Internal.s.pVMR3, idCpu);
    362 }
    363 
    364 
    365 /** @interface_method_impl{PDMAPICHLPR3,pfnGetRCHelpers} */
    366 static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
    367 {
    368     PDMDEV_ASSERT_DEVINS(pDevIns);
    369     PVM pVM = pDevIns->Internal.s.pVMR3;
    370     VM_ASSERT_EMT(pVM);
    371 
    372     RTRCPTR pRCHelpers = NIL_RTRCPTR;
    373     if (!HMIsEnabled(pVM))
    374     {
    375         int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCApicHlp", &pRCHelpers);
    376         AssertReleaseRC(rc);
    377         AssertRelease(pRCHelpers);
    378     }
    379 
    380     LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
    381              pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
    382     return pRCHelpers;
    383 }
    384 
    385 
    386 /** @interface_method_impl{PDMAPICHLPR3,pfnGetR0Helpers} */
    387 static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
    388 {
    389     PDMDEV_ASSERT_DEVINS(pDevIns);
    390     PVM pVM = pDevIns->Internal.s.pVMR3;
    391     VM_ASSERT_EMT(pVM);
    392     PCPDMAPICHLPR0 pR0Helpers = 0;
    393     int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0ApicHlp", &pR0Helpers);
    394     AssertReleaseRC(rc);
    395     AssertRelease(pR0Helpers);
    396     LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
    397              pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
    398     return pR0Helpers;
    399 }
    400 
    401 
    402 /** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
    403 static DECLCALLBACK(R3PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR3CritSect(PPDMDEVINS pDevIns)
    404 {
    405     PDMDEV_ASSERT_DEVINS(pDevIns);
    406     LogFlow(("pdmR3ApicHlp_Lock: caller='%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
    407     return &pDevIns->Internal.s.pVMR3->pdm.s.CritSect;
    408 }
    409 
    410 
    411 /** @interface_method_impl{PDMAPICHLPR3,pfnGetRCCritSect} */
    412 static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetRCCritSect(PPDMDEVINS pDevIns)
    413 {
    414     PDMDEV_ASSERT_DEVINS(pDevIns);
    415     PVM pVM = pDevIns->Internal.s.pVMR3;
    416     RTRCPTR RCPtr = MMHyperCCToRC(pVM, &pVM->pdm.s.CritSect);
    417     LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RRv\n", pDevIns->pReg->szName, pDevIns->iInstance, RCPtr));
    418     return RCPtr;
    419 }
    420 
    421 
    422 /** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
    423 static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR0CritSect(PPDMDEVINS pDevIns)
    424 {
    425     PDMDEV_ASSERT_DEVINS(pDevIns);
    426     PVM pVM = pDevIns->Internal.s.pVMR3;
    427     RTR0PTR R0Ptr = MMHyperCCToR0(pVM, &pVM->pdm.s.CritSect);
    428     LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, R0Ptr));
    429     return R0Ptr;
    430 }
    431 
    432 
    433 
    434 /**
    435  * APIC Device Helpers.
    436  */
    437 const PDMAPICHLPR3 g_pdmR3DevApicHlp =
    438 {
    439     PDM_APICHLPR3_VERSION,
    440     pdmR3ApicHlp_SetInterruptFF,
    441     pdmR3ApicHlp_ClearInterruptFF,
    442     pdmR3ApicHlp_BusBroadcastEoi,
    443     pdmR3ApicHlp_CalcIrqTag,
    444     pdmR3ApicHlp_SetFeatureLevel,
    445     pdmR3ApicHlp_GetCpuId,
    446     pdmR3ApicHlp_SendStartupIpi,
    447     pdmR3ApicHlp_SendInitIpi,
    448     pdmR3ApicHlp_GetRCHelpers,
    449     pdmR3ApicHlp_GetR0Helpers,
    450     pdmR3ApicHlp_GetR3CritSect,
    451     pdmR3ApicHlp_GetRCCritSect,
    452     pdmR3ApicHlp_GetR0CritSect,
    453     PDM_APICHLPR3_VERSION /* the end */
    454 };
    455 
    456 /** @} */
    457 
    458 
    459 
    460 
    461180/** @name Ring-3 I/O APIC Helpers
    462181 * @{
  • trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp

    r64378 r64596  
    4646extern DECLEXPORT(const PDMDEVHLPRC)    g_pdmRCDevHlp;
    4747extern DECLEXPORT(const PDMPICHLPRC)    g_pdmRCPicHlp;
    48 extern DECLEXPORT(const PDMAPICHLPRC)   g_pdmRCApicHlp;
    4948extern DECLEXPORT(const PDMIOAPICHLPRC) g_pdmRCIoApicHlp;
    5049extern DECLEXPORT(const PDMPCIHLPRC)    g_pdmRCPciHlp;
     
    510509
    511510
    512 
    513 
    514 /** @name APIC RC Helpers
    515  * @{
    516  */
    517 
    518 /** @interface_method_impl{PDMAPICHLPRC,pfnSetInterruptFF} */
    519 static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    520 {
    521     PDMDEV_ASSERT_DEVINS(pDevIns);
    522     PVM pVM = pDevIns->Internal.s.pVMRC;
    523     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    524 
    525     AssertReturnVoid(idCpu < pVM->cCpus);
    526 
    527     LogFlow(("pdmRCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
    528              pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    529     switch (enmType)
    530     {
    531         case PDMAPICIRQ_UPDATE_PENDING:
    532             VMCPU_FF_SET(pVCpu, VMCPU_FF_UPDATE_APIC);
    533             break;
    534         case PDMAPICIRQ_HARDWARE:
    535             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    536             break;
    537         case PDMAPICIRQ_NMI:
    538             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
    539             break;
    540         case PDMAPICIRQ_SMI:
    541             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
    542             break;
    543         case PDMAPICIRQ_EXTINT:
    544             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    545             break;
    546         default:
    547             AssertMsgFailed(("enmType=%d\n", enmType));
    548             break;
    549     }
    550 }
    551 
    552 
    553 /** @interface_method_impl{PDMAPICHLPRC,pfnClearInterruptFF} */
    554 static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    555 {
    556     PDMDEV_ASSERT_DEVINS(pDevIns);
    557     PVM pVM = pDevIns->Internal.s.pVMRC;
    558     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    559 
    560     AssertReturnVoid(idCpu < pVM->cCpus);
    561 
    562     LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
    563              pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    564 
    565     /* Note: NMI/SMI can't be cleared. */
    566     switch (enmType)
    567     {
    568         case PDMAPICIRQ_HARDWARE:
    569             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    570             break;
    571         case PDMAPICIRQ_EXTINT:
    572             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    573             break;
    574         case PDMAPICIRQ_UPDATE_PENDING:
    575             VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
    576             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_UPDATE_APIC);
    577             break;
    578         default:
    579             AssertMsgFailed(("enmType=%d\n", enmType));
    580             break;
    581     }
    582 }
    583 
    584 
    585 /** @interface_method_impl{PDMAPICHLPRC,pfnBusBroadcastEoi} */
    586 static DECLCALLBACK(int) pdmRCApicHlp_BusBroadcastEoi(PPDMDEVINS pDevIns, uint8_t u8Vector)
    587 {
    588     /* pfnSetEoi will be NULL in the old IOAPIC code as it's not implemented. */
    589 #ifdef VBOX_WITH_NEW_IOAPIC
    590     PDMDEV_ASSERT_DEVINS(pDevIns);
    591     PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
    592 
    593     /* At present, we support only a maximum of one I/O APIC per-VM. If we ever implement having
    594        multiple I/O APICs per-VM, we'll have to broadcast this EOI to all of the I/O APICs. */
    595     if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
    596     {
    597         Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi));
    598         return pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Vector);
    599     }
    600 #endif
    601     return VINF_SUCCESS;
    602 }
    603 
    604 
    605 /** @interface_method_impl{PDMAPICHLPRC,pfnCalcIrqTag} */
    606 static DECLCALLBACK(uint32_t) pdmRCApicHlp_CalcIrqTag(PPDMDEVINS pDevIns, uint8_t u8Level)
    607 {
    608     PDMDEV_ASSERT_DEVINS(pDevIns);
    609     PVM pVM = pDevIns->Internal.s.pVMRC;
    610 
    611     pdmLock(pVM);
    612 
    613     uint32_t uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
    614     if (u8Level == PDM_IRQ_LEVEL_HIGH)
    615         VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    616     else
    617         VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
    618 
    619 
    620     pdmUnlock(pVM);
    621     LogFlow(("pdmRCApicHlp_CalcIrqTag: caller=%p/%d: returns %#x (u8Level=%d)\n",
    622              pDevIns, pDevIns->iInstance, uTagSrc, u8Level));
    623     return uTagSrc;
    624 }
    625 
    626 
    627 /** @interface_method_impl{PDMAPICHLPRC,pfnLock} */
    628 static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    629 {
    630     PDMDEV_ASSERT_DEVINS(pDevIns);
    631     return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
    632 }
    633 
    634 
    635 /** @interface_method_impl{PDMAPICHLPRC,pfnUnlock} */
    636 static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns)
    637 {
    638     PDMDEV_ASSERT_DEVINS(pDevIns);
    639     pdmUnlock(pDevIns->Internal.s.pVMRC);
    640 }
    641 
    642 
    643 /** @interface_method_impl{PDMAPICHLPRC,pfnGetCpuId} */
    644 static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns)
    645 {
    646     PDMDEV_ASSERT_DEVINS(pDevIns);
    647     return VMMGetCpuId(pDevIns->Internal.s.pVMRC);
    648 }
    649 
    650 
    651 /**
    652  * The Raw-Mode Context APIC Helper Callbacks.
    653  */
    654 extern DECLEXPORT(const PDMAPICHLPRC) g_pdmRCApicHlp =
    655 {
    656     PDM_APICHLPRC_VERSION,
    657     pdmRCApicHlp_SetInterruptFF,
    658     pdmRCApicHlp_ClearInterruptFF,
    659     pdmRCApicHlp_BusBroadcastEoi,
    660     pdmRCApicHlp_CalcIrqTag,
    661     pdmRCApicHlp_Lock,
    662     pdmRCApicHlp_Unlock,
    663     pdmRCApicHlp_GetCpuId,
    664     PDM_APICHLPRC_VERSION
    665 };
    666 
    667 /** @} */
    668 
    669 
    670 
    671 
    672511/** @name I/O APIC RC Helpers
    673512 * @{
  • trunk/src/VBox/VMM/include/APICInternal.h

    r63634 r64596  
    11511151    /** The device instance - R3 Ptr. */
    11521152    PPDMDEVINSR3                pDevInsR3;
    1153     /** The APIC helpers - R3 Ptr. */
    1154     PCPDMAPICHLPR3              pApicHlpR3;
    1155     /** The PDM critical section - R3 Ptr. */
    1156     R3PTRTYPE(PPDMCRITSECT)     pCritSectR3;
    11571153    /** Alignment padding. */
    11581154    R3PTRTYPE(void *)           pvAlignment0;
     
    11601156    /** The device instance - R0 Ptr. */
    11611157    PPDMDEVINSR0                pDevInsR0;
    1162     /** The APIC helpers - R0 Ptr. */
    1163     PCPDMAPICHLPR0              pApicHlpR0;
    1164     /** The PDM critical section - R0 Ptr. */
    1165     R0PTRTYPE(PPDMCRITSECT)     pCritSectR0;
    11661158    /** Alignment padding. */
    11671159    R0PTRTYPE(void *)           pvAlignment1;
     
    11691161    /** The device instance - RC Ptr. */
    11701162    PPDMDEVINSRC                pDevInsRC;
    1171     /** The APIC helpers - RC Ptr. */
    1172     PCPDMAPICHLPRC              pApicHlpRC;
    1173     /** The PDM critical section - RC Ptr. */
    1174     RCPTRTYPE(PPDMCRITSECT)     pCritSectRC;
    1175     /** Alignment padding. */
    1176     RCPTRTYPE(void *)           pvAlignment2;
    11771163} APICDEV;
    11781164/** Pointer to an APIC device. */
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r64406 r64596  
    12501250extern const PDMDEVHLPR3    g_pdmR3DevHlpUnTrusted;
    12511251extern const PDMPICHLPR3    g_pdmR3DevPicHlp;
    1252 extern const PDMAPICHLPR3   g_pdmR3DevApicHlp;
    12531252extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp;
    12541253extern const PDMFWHLPR3     g_pdmR3DevFirmwareHlp;
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