- Timestamp:
- Nov 8, 2016 3:03:18 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
-
include/VBox/vmm/pdmapi.h (modified) (1 diff)
-
include/VBox/vmm/pdmdev.h (modified) (3 diffs)
-
src/VBox/Devices/testcase/tstDeviceStructSize.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMAll/APICAll.cpp (modified) (5 diffs)
-
src/VBox/VMM/VMMAll/PDMAll.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR0/PDMR0Device.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMR3/APIC.cpp (modified) (8 diffs)
-
src/VBox/VMM/VMMR3/PDMDevHlp.cpp (modified) (5 diffs)
-
src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMRC/PDMRCDevice.cpp (modified) (2 diffs)
-
src/VBox/VMM/include/APICInternal.h (modified) (3 diffs)
-
src/VBox/VMM/include/PDMInternal.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmapi.h
r62476 r64596 49 49 VMM_INT_DECL(bool) PDMHasIoApic(PVM pVM); 50 50 VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); 51 VMM_INT_DECL(int) PDMIoApicBroadcastEoi(PVM pVM, uint8_t uVector); 51 52 VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc); 52 53 VMM_INT_DECL(bool) PDMHasApic(PVM pVM); -
trunk/include/VBox/vmm/pdmdev.h
r64406 r64596 1385 1385 1386 1386 /** 1387 * APIC RC helpers.1388 */1389 typedef struct PDMAPICHLPRC1390 {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 PDMAPICHLPR01470 {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 PDMAPICHLPR31549 {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 and1615 * 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 time1626 * 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 time1637 * 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 /**1681 1387 * I/O APIC registration structure. 1682 1388 */ … … 3484 3190 * @param pDevIns The device instance. 3485 3191 * @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)); 3489 3194 3490 3195 /** … … 5514 5219 * @copydoc PDMDEVHLPR3::pfnAPICRegister 5515 5220 */ 5516 DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg , PCPDMAPICHLPR3 *ppApicHlpR3)5517 { 5518 return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg , ppApicHlpR3);5221 DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg) 5222 { 5223 return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg); 5519 5224 } 5520 5225 -
trunk/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
r64560 r64596 291 291 #ifdef VBOX_WITH_NEW_APIC 292 292 CHECK_MEMBER_ALIGNMENT(APICDEV, pDevInsR0, 8); 293 CHECK_MEMBER_ALIGNMENT(APICDEV, pCritSectR0, 8);294 293 CHECK_MEMBER_ALIGNMENT(APICDEV, pDevInsRC, 8); 295 CHECK_MEMBER_ALIGNMENT(APICDEV, pCritSectRC, 8);296 294 #else 297 295 # ifdef VBOX_WITH_STATISTICS -
trunk/src/VBox/VMM/VMMAll/APICAll.cpp
r64112 r64596 23 23 #include "APICInternal.h" 24 24 #include <VBox/vmm/pdmdev.h> 25 #include <VBox/vmm/pdmapi.h> 26 #include <VBox/vmm/rem.h> 25 27 #include <VBox/vmm/vm.h> 28 #include <VBox/vmm/vmm.h> 26 29 #include <VBox/vmm/vmcpuset.h> 27 30 … … 471 474 uint8_t *pbXApic = (uint8_t *)pXApicPage; 472 475 *(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);487 476 } 488 477 … … 1265 1254 if (fLevelTriggered) 1266 1255 { 1267 int rc = apicBusBroadcastEoi(pVCpu, uVector);1256 int rc = PDMIoApicBroadcastEoi(pVCpu->CTX_SUFF(pVM), uVector); 1268 1257 if (rc == VINF_SUCCESS) 1269 1258 { /* likely */ } … … 2682 2671 VMM_INT_DECL(void) apicSetInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType) 2683 2672 { 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 2687 2718 } 2688 2719 … … 2696 2727 VMM_INT_DECL(void) apicClearInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType) 2697 2728 { 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 2701 2742 } 2702 2743 -
trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
r62478 r64596 207 207 } 208 208 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 */ 217 VMM_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 209 232 /** 210 233 * Send a MSI to an I/O APIC. -
trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
r64387 r64596 48 48 extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp; 49 49 extern DECLEXPORT(const PDMPICHLPR0) g_pdmR0PicHlp; 50 extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp;51 50 extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp; 52 51 extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp; … … 525 524 526 525 527 528 529 /** @name APIC Ring-0 Helpers530 * @{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_APIC552 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);553 #endif554 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_APIC573 /* We are already on EMT if enmType is PDMAPICIRQ_HARDWARE. Don't bother with poking! */574 enmType != PDMAPICIRQ_HARDWARE &&575 #endif576 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_IOAPIC632 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 having636 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 #endif643 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 else659 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_VERSION707 };708 709 /** @} */710 711 712 713 714 526 /** @name I/O APIC Ring-0 Helpers 715 527 * @{ -
trunk/src/VBox/VMM/VMMR3/APIC.cpp
r63945 r64596 250 250 251 251 /** 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 */ 257 static 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 /** 252 283 * Resets the APIC base MSR. 253 284 * … … 1076 1107 } 1077 1108 1078 #if 0 /** @todo not referenced and will cause assertion in apicR3LoadExec (VERR_WRONG_ORDER). */1079 /**1080 * @copydoc FNSSMDEVLIVEEXEC1081 */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 #endif1095 1109 1096 1110 /** … … 1345 1359 LogFlow(("APIC: apicR3Relocate: pVM=%p pDevIns=%p offDelta=%RGi\n", pVM, pDevIns, offDelta)); 1346 1360 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); 1350 1362 1351 1363 pApic->pApicDevRC = PDMINS_2_DATA_RCPTR(pDevIns); … … 1654 1666 { 1655 1667 case PDMAPICMODE_NONE: 1656 #if 11657 1668 /** @todo permanently disabling the APIC won't really work (needs 1658 1669 * fixing in HM, CPUM, PDM and possibly other places). See 1659 1670 * @bugref{8353}. */ 1660 1671 return VMR3SetError(pVM->pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS, "APIC mode 'none' is not supported yet."); 1661 #endif1662 1672 case PDMAPICMODE_APIC: 1663 1673 case PDMAPICMODE_X2APIC: … … 1720 1730 } 1721 1731 1722 rc = PDMDevHlpAPICRegister(pDevIns, &ApicReg , &pApicDev->pApicHlpR3);1732 rc = PDMDevHlpAPICRegister(pDevIns, &ApicReg); 1723 1733 AssertLogRelRCReturn(rc, rc); 1724 pApicDev->pCritSectR3 = pApicDev->pApicHlpR3->pfnGetR3CritSect(pDevIns);1725 1734 1726 1735 /* … … 1741 1750 1742 1751 /* 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); 1744 1753 1745 1754 /* Initialize the state. */ … … 1761 1770 if (pApic->fRZEnabled) 1762 1771 { 1763 pApicDev->pApicHlpRC = pApicDev->pApicHlpR3->pfnGetRCHelpers(pDevIns);1764 pApicDev->pCritSectRC = pApicDev->pApicHlpR3->pfnGetRCCritSect(pDevIns);1765 1772 rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysApicBase, sizeof(XAPICPAGE), NIL_RTRCPTR /*pvUser*/, 1766 1773 "apicWriteMmio", "apicReadMmio"); … … 1768 1775 return rc; 1769 1776 1770 pApicDev->pApicHlpR0 = pApicDev->pApicHlpR3->pfnGetR0Helpers(pDevIns);1771 pApicDev->pCritSectR0 = pApicDev->pApicHlpR3->pfnGetR0CritSect(pDevIns);1772 1777 rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysApicBase, sizeof(XAPICPAGE), NIL_RTR0PTR /*pvUser*/, 1773 1778 "apicWriteMmio", "apicReadMmio"); -
trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
r64406 r64596 2845 2845 2846 2846 /** @interface_method_impl{PDMDEVHLPR3,pfnAPICRegister} */ 2847 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg , PCPDMAPICHLPR3 *ppApicHlpR3)2847 static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg) 2848 2848 { 2849 2849 PDMDEV_ASSERT_DEVINS(pDevIns); … … 2851 2851 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseMsrR3=%p, .pfnGetBaseMsrR3=%p, " 2852 2852 ".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", 2854 2854 pDevIns->pReg->szName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseMsrR3, 2855 2855 pApicReg->pfnGetBaseMsrR3, pApicReg->pfnSetTprR3, pApicReg->pfnGetTprR3, pApicReg->pfnWriteMsrR3, pApicReg->pfnReadMsrR3, pApicReg->pfnBusDeliverR3, pApicReg->pfnLocalInterruptR3, pApicReg->pfnGetTimerFreqR3, pApicReg->pszGetInterruptRC, 2856 2856 pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseMsrRC, pApicReg->pszSetBaseMsrRC, pApicReg->pszGetBaseMsrRC, pApicReg->pszGetBaseMsrRC, 2857 2857 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)); 2859 2859 2860 2860 /* … … 2961 2961 return VERR_INVALID_PARAMETER; 2962 2962 } 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 }2969 2963 2970 2964 /* … … 3145 3139 Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns)); 3146 3140 3147 /* set the helper pointer and return. */3148 *ppApicHlpR3 = &g_pdmR3DevApicHlp;3149 3141 LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS)); 3150 3142 return VINF_SUCCESS; … … 3427 3419 { 3428 3420 Assert(ppPciRawHlpR3); 3429 LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (pp ApicHlpR3)\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)); 3430 3422 return VERR_INVALID_PARAMETER; 3431 3423 } -
trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
r64115 r64596 178 178 179 179 180 181 182 /** @name R3 APIC Helpers183 * @{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_APIC205 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);206 #endif207 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_REM223 REMR3NotifyInterruptSet(pVM, pVCpu);224 #endif225 226 #ifdef VBOX_WITH_NEW_APIC227 if (enmType != PDMAPICIRQ_HARDWARE)228 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);229 #else230 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);231 #endif232 }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_REM265 REMR3NotifyInterruptClear(pVM, pVCpu);266 #endif267 }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_IOAPIC275 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 having279 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 #endif286 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 else303 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 461 180 /** @name Ring-3 I/O APIC Helpers 462 181 * @{ -
trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
r64378 r64596 46 46 extern DECLEXPORT(const PDMDEVHLPRC) g_pdmRCDevHlp; 47 47 extern DECLEXPORT(const PDMPICHLPRC) g_pdmRCPicHlp; 48 extern DECLEXPORT(const PDMAPICHLPRC) g_pdmRCApicHlp;49 48 extern DECLEXPORT(const PDMIOAPICHLPRC) g_pdmRCIoApicHlp; 50 49 extern DECLEXPORT(const PDMPCIHLPRC) g_pdmRCPciHlp; … … 510 509 511 510 512 513 514 /** @name APIC RC Helpers515 * @{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_IOAPIC590 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 having594 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 #endif601 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 else617 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_VERSION665 };666 667 /** @} */668 669 670 671 672 511 /** @name I/O APIC RC Helpers 673 512 * @{ -
trunk/src/VBox/VMM/include/APICInternal.h
r63634 r64596 1151 1151 /** The device instance - R3 Ptr. */ 1152 1152 PPDMDEVINSR3 pDevInsR3; 1153 /** The APIC helpers - R3 Ptr. */1154 PCPDMAPICHLPR3 pApicHlpR3;1155 /** The PDM critical section - R3 Ptr. */1156 R3PTRTYPE(PPDMCRITSECT) pCritSectR3;1157 1153 /** Alignment padding. */ 1158 1154 R3PTRTYPE(void *) pvAlignment0; … … 1160 1156 /** The device instance - R0 Ptr. */ 1161 1157 PPDMDEVINSR0 pDevInsR0; 1162 /** The APIC helpers - R0 Ptr. */1163 PCPDMAPICHLPR0 pApicHlpR0;1164 /** The PDM critical section - R0 Ptr. */1165 R0PTRTYPE(PPDMCRITSECT) pCritSectR0;1166 1158 /** Alignment padding. */ 1167 1159 R0PTRTYPE(void *) pvAlignment1; … … 1169 1161 /** The device instance - RC Ptr. */ 1170 1162 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;1177 1163 } APICDEV; 1178 1164 /** Pointer to an APIC device. */ -
trunk/src/VBox/VMM/include/PDMInternal.h
r64406 r64596 1250 1250 extern const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted; 1251 1251 extern const PDMPICHLPR3 g_pdmR3DevPicHlp; 1252 extern const PDMAPICHLPR3 g_pdmR3DevApicHlp;1253 1252 extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp; 1254 1253 extern const PDMFWHLPR3 g_pdmR3DevFirmwareHlp;
Note:
See TracChangeset
for help on using the changeset viewer.

