Changeset 109021 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Apr 18, 2025 8:56:15 AM (3 weeks ago)
- svn:sync-xref-src-repo-rev:
- 168550
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GICAll.cpp
r109003 r109021 661 661 662 662 663 static void gicDistReadLpiConfigTableFromMem(PPDMDEVINS pDevIns, PGICDEV pGicDev) 664 { 663 DECLHIDDEN(void) gicDistReadLpiConfigTableFromMem(PPDMDEVINS pDevIns) 664 { 665 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 665 666 Assert(pGicDev->fEnableLpis); 666 667 LogFlowFunc(("\n")); … … 669 670 uint8_t const cIdBits = RT_BF_GET(pGicDev->uLpiConfigBaseReg.u, GIC_BF_REDIST_REG_PROPBASER_ID_BITS) + 1; 670 671 if (cIdBits < GIC_LPI_ID_BITS_MIN) 672 { 673 RT_ZERO(pGicDev->abLpiConfig); 671 674 return; 675 } 672 676 673 677 /* Copy the LPI config table from guest memory to our internal cache. */ … … 2517 2521 if (pGicDev->fEnableLpis) 2518 2522 { 2519 gicDistReadLpiConfigTableFromMem(pDevIns , pGicDev);2523 gicDistReadLpiConfigTableFromMem(pDevIns); 2520 2524 gicReDistReadLpiPendingBitmapFromMem(pDevIns, pVCpu, pGicDev); 2521 2525 } … … 2668 2672 VERR_INVALID_PARAMETER); 2669 2673 2670 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED); 2671 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); 2674 GIC_CRIT_SECT_ENTER(pDevIns); 2672 2675 2673 2676 /* Update the interrupt pending state. */ … … 2680 2683 STAM_PROFILE_STOP(&pGicCpu->StatProfSetSpi, a); 2681 2684 2682 PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);2685 GIC_CRIT_SECT_LEAVE(pDevIns); 2683 2686 return rc; 2684 2687 } … … 2707 2710 VERR_INVALID_PARAMETER); 2708 2711 2709 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED); 2710 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); 2712 GIC_CRIT_SECT_ENTER(pDevIns); 2711 2713 2712 2714 /* Update the interrupt pending state. */ … … 2719 2721 STAM_PROFILE_STOP(&pGicCpu->StatProfSetPpi, b); 2720 2722 2721 PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);2723 GIC_CRIT_SECT_LEAVE(pDevIns); 2722 2724 return rc; 2723 2725 } … … 2741 2743 uint32_t const cCpus = pVM->cCpus; 2742 2744 AssertReturn(uIntId <= GIC_INTID_RANGE_SGI_LAST, VERR_INVALID_PARAMETER); 2743 Assert( PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->pCritSectRoR3)); RT_NOREF_PV(pDevIns);2745 Assert(GIC_CRIT_SECT_IS_OWNER(pDevIns)); NOREF(pDevIns); 2744 2746 2745 2747 for (VMCPUID idCpu = 0; idCpu < cCpus; idCpu++) … … 2845 2847 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 2846 2848 2847 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED); 2848 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); 2849 GIC_CRIT_SECT_ENTER(pDevIns); 2849 2850 2850 2851 switch (u32Reg) … … 2948 2949 } 2949 2950 2950 PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);2951 GIC_CRIT_SECT_LEAVE(pDevIns); 2951 2952 2952 2953 LogFlowFunc(("pVCpu=%p u32Reg=%#x{%s} pu64Value=%RX64\n", pVCpu, u32Reg, gicIccGetRegDescription(u32Reg), *pu64Value)); … … 2972 2973 PGICCPU pGicCpu = VMCPU_TO_GICCPU(pVCpu); 2973 2974 2974 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED); 2975 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); 2975 GIC_CRIT_SECT_ENTER(pDevIns); 2976 2976 2977 2977 VBOXSTRICTRC rcStrict = VINF_SUCCESS; … … 3138 3138 } 3139 3139 3140 PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);3140 GIC_CRIT_SECT_LEAVE(pDevIns); 3141 3141 return rcStrict; 3142 3142 } -
trunk/src/VBox/VMM/VMMAll/GITSAll.cpp
r109011 r109021 31 31 *********************************************************************************************************************************/ 32 32 #define LOG_GROUP LOG_GROUP_DEV_GIC 33 #include "GI TSInternal.h"33 #include "GICInternal.h" 34 34 35 35 #include <VBox/log.h> … … 50 50 /** Gets whether the given register offset is within the specified range. */ 51 51 #define GITS_IS_REG_IN_RANGE(a_offReg, a_offFirst, a_cbRegion) ((uint32_t)(a_offReg) - (a_offFirst) < (a_cbRegion)) 52 53 /** Acquire the device critical section. */54 #define GITS_CRIT_SECT_ENTER(a_pDevIns) \55 do \56 { \57 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS); \58 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); \59 } while(0)60 61 /** Release the device critical section. */62 #define GITS_CRIT_SECT_LEAVE(a_pDevIns) PDMDevHlpCritSectLeave((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))63 64 /** Returns whether the critical section is held. */65 #define GITS_CRIT_SECT_IS_OWNER(a_pDevIns) PDMDevHlpCritSectIsOwner((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))66 52 67 53 /** GITS diagnostic enum description expansion. … … 137 123 GITSDIAG_DESC(CmdQueue_Basic_Unknown_Cmd), 138 124 GITSDIAG_DESC(CmdQueue_Basic_Invalid_PhysAddr), 125 GITSDIAG_DESC(CmdQueue_Cmd_Invall_Icid_Overflow), 139 126 GITSDIAG_DESC(CmdQueue_Cmd_Mapc_Icid_Overflow), 140 127 /* kGitsDiag_End */ … … 252 239 Log4Func(("enmDiag=%#RX32 (%s) fStallQueue=%RTbool\n", enmDiag, gitsGetDiagDescription(enmDiag))); 253 240 254 GI TS_CRIT_SECT_ENTER(pDevIns);241 GIC_CRIT_SECT_ENTER(pDevIns); 255 242 256 243 /* Record the error and stall the queue. */ … … 260 247 pGitsDev->uCmdReadReg |= GITS_BF_CTRL_REG_CREADR_STALLED_MASK; 261 248 262 GI TS_CRIT_SECT_LEAVE(pDevIns);249 GIC_CRIT_SECT_LEAVE(pDevIns); 263 250 264 251 /* Since we don't support SEIs, so there should be nothing more to do here. */ … … 296 283 { 297 284 Log4Func(("\n")); 298 Assert(GI TS_CRIT_SECT_IS_OWNER(pDevIns));285 Assert(GIC_CRIT_SECT_IS_OWNER(pDevIns)); 299 286 if ( gitsCmdQueueCanProcessRequests(pGitsDev) 300 287 && !gitsCmdQueueIsEmpty(pGitsDev)) … … 547 534 static uint32_t const s_acbPageSize[] = { _4K, _16K, _64K, _64K }; 548 535 static const char* const s_apszType[] = { "UnImpl", "Devices", "vPEs", "Intr Collections" }; 549 550 uint64_t const uReg = pGitsDev->aItsTableRegs[i].u; 551 uint16_t const uSize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SIZE); 552 uint16_t const cPages = uSize > 0 ? uSize + 1 : 0; 553 uint8_t const idxPageSize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_PAGESIZE); 554 uint64_t const cbItsTable = cPages * s_acbPageSize[idxPageSize]; 555 uint8_t const uEntrySize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_ENTRY_SIZE); 556 uint8_t const idxType = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_TYPE); 557 const char *pszType = s_apszType[idxType]; 558 pHlp->pfnPrintf(pHlp, " GITS_BASER[%u] = %#RX64\n", i, uReg); 559 pHlp->pfnPrintf(pHlp, " Size = %#x (pages=%u total=%.Rhcb)\n", uSize, cPages, cbItsTable); 560 pHlp->pfnPrintf(pHlp, " Page size = %#x (%.Rhcb)\n", idxPageSize, s_acbPageSize[idxPageSize]); 561 pHlp->pfnPrintf(pHlp, " Shareability = %#x\n", RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SHAREABILITY)); 562 pHlp->pfnPrintf(pHlp, " Phys addr = %#RX64 (addr=%#RX64)\n", uReg & GITS_BF_CTRL_REG_BASER_PHYS_ADDR_MASK, 563 gitsGetBaseRegPhysAddr(uReg)); 564 pHlp->pfnPrintf(pHlp, " Entry size = %#x (%u bytes)\n", uEntrySize, uEntrySize > 0 ? uEntrySize + 1 : 0); 565 pHlp->pfnPrintf(pHlp, " Outer cache = %#x\n", RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_OUTER_CACHE)); 566 pHlp->pfnPrintf(pHlp, " Type = %#x (%s)\n", idxType, pszType); 567 pHlp->pfnPrintf(pHlp, " Inner cache = %#x\n", RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INNER_CACHE)); 568 pHlp->pfnPrintf(pHlp, " Indirect = %RTbool\n", RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INDIRECT))); 569 pHlp->pfnPrintf(pHlp, " Valid = %RTbool\n", RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_VALID))); 536 uint64_t const uReg = pGitsDev->aItsTableRegs[i].u; 537 bool const fValid = RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_VALID)); 538 uint8_t const idxType = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_TYPE); 539 if ( fValid 540 || idxType != GITS_BASER_TYPE_UNIMPL) 541 { 542 uint16_t const uSize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SIZE); 543 uint16_t const cPages = uSize > 0 ? uSize + 1 : 0; 544 uint8_t const idxPageSize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_PAGESIZE); 545 uint64_t const cbItsTable = cPages * s_acbPageSize[idxPageSize]; 546 uint8_t const uEntrySize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_ENTRY_SIZE); 547 bool const fIndirect = RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INDIRECT)); 548 const char *pszType = s_apszType[idxType]; 549 pHlp->pfnPrintf(pHlp, " GITS_BASER[%u] = %#RX64\n", i, uReg); 550 pHlp->pfnPrintf(pHlp, " Size = %#x (pages=%u total=%.Rhcb)\n", uSize, cPages, cbItsTable); 551 pHlp->pfnPrintf(pHlp, " Page size = %#x (%.Rhcb)\n", idxPageSize, s_acbPageSize[idxPageSize]); 552 pHlp->pfnPrintf(pHlp, " Shareability = %#x\n", RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SHAREABILITY)); 553 pHlp->pfnPrintf(pHlp, " Phys addr = %#RX64 (addr=%#RX64)\n", uReg & GITS_BF_CTRL_REG_BASER_PHYS_ADDR_MASK, 554 gitsGetBaseRegPhysAddr(uReg)); 555 pHlp->pfnPrintf(pHlp, " Entry size = %#x (%u bytes)\n", uEntrySize, uEntrySize > 0 ? uEntrySize + 1 : 0); 556 pHlp->pfnPrintf(pHlp, " Outer cache = %#x\n", RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_OUTER_CACHE)); 557 pHlp->pfnPrintf(pHlp, " Type = %#x (%s)\n", idxType, pszType); 558 pHlp->pfnPrintf(pHlp, " Inner cache = %#x\n", RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INNER_CACHE)); 559 pHlp->pfnPrintf(pHlp, " Indirect = %RTbool\n", fIndirect); 560 pHlp->pfnPrintf(pHlp, " Valid = %RTbool\n", fValid); 561 } 570 562 } 571 563 … … 573 565 { 574 566 uint64_t const uReg = pGitsDev->uCmdBaseReg.u; 575 uint8_t const uSize= RT_BF_GET(uReg, GITS_BF_CTRL_REG_CBASER_SIZE);567 uint8_t const uSize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_CBASER_SIZE); 576 568 uint16_t const cPages = uSize > 0 ? uSize + 1 : 0; 577 569 pHlp->pfnPrintf(pHlp, " GITS_CBASER = %#RX64\n", uReg); … … 624 616 625 617 /* Hold the critical section as we could be accessing the device state simultaneously with MMIO accesses. */ 626 GI TS_CRIT_SECT_ENTER(pDevIns);618 GIC_CRIT_SECT_ENTER(pDevIns); 627 619 628 620 if (gitsCmdQueueCanProcessRequests(pGitsDev)) … … 645 637 646 638 /* Leave the critical section while reading (a potentially large number of) commands from guest memory. */ 647 GI TS_CRIT_SECT_LEAVE(pDevIns);639 GIC_CRIT_SECT_LEAVE(pDevIns); 648 640 649 641 if (offWrite > offRead) … … 673 665 { 674 666 /* Indicate to the guest we've fetched all commands. */ 675 GI TS_CRIT_SECT_ENTER(pDevIns);667 GIC_CRIT_SECT_ENTER(pDevIns); 676 668 pGitsDev->uCmdReadReg = offWrite; 677 669 pGitsDev->uCmdWriteReg &= ~GITS_BF_CTRL_REG_CWRITER_RETRY_MASK; 678 670 679 671 /* Don't hold the critical section while processing commands. */ 680 GI TS_CRIT_SECT_LEAVE(pDevIns);672 GIC_CRIT_SECT_LEAVE(pDevIns); 681 673 682 674 uint32_t const cCmds = cbCmds / sizeof(GITSCMD); … … 689 681 case GITS_CMD_ID_MAPC: 690 682 { 683 /* Map interrupt collection with a target CPU ID. */ 691 684 uint64_t const uDw2 = pCmd->au64[2].u; 692 685 uint8_t const fValid = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_VALID); … … 696 689 if (RT_LIKELY(uIntrCollectionId < RT_ELEMENTS(pGitsDev->auCtes))) 697 690 { 698 GI TS_CRIT_SECT_ENTER(pDevIns);691 GIC_CRIT_SECT_ENTER(pDevIns); 699 692 Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_PTA)); 700 693 pGitsDev->auCtes[uIntrCollectionId] = RT_BF_MAKE(GITS_BF_CTE_VALID, fValid) 701 694 | RT_BF_MAKE(GITS_BF_CTE_RDBASE, uTargetCpuId); 702 GI TS_CRIT_SECT_LEAVE(pDevIns);695 GIC_CRIT_SECT_LEAVE(pDevIns); 703 696 } 704 697 else … … 711 704 case GITS_CMD_ID_SYNC: 712 705 /* Nothing to do since all previous commands have committed their changes to device state. */ 706 STAM_COUNTER_INC(&pGitsDev->StatCmdSync); 707 break; 708 709 case GITS_CMD_ID_INVALL: 710 { 711 /* Reading the table is likely to take the same time as reading just one entry. */ 712 uint64_t const uDw2 = pCmd->au64[2].u; 713 uint16_t const uIntrCollectionId = RT_BF_GET(uDw2, GITS_BF_CMD_INVALL_DW2_IC_ID); 714 if (RT_LIKELY(uIntrCollectionId < RT_ELEMENTS(pGitsDev->auCtes))) 715 gicDistReadLpiConfigTableFromMem(pDevIns); 716 else 717 gitsCmdQueueSetError(pDevIns, pGitsDev, kGitsDiag_CmdQueue_Cmd_Invall_Icid_Overflow, 718 false /* fStall */); 713 719 STAM_COUNTER_INC(&pGitsDev->StatCmdInvall); 714 720 break; 715 716 case GITS_CMD_ID_INVALL: 717 /* Nothing to do as we currently do not cache interrupt mappings. */ 718 STAM_COUNTER_INC(&pGitsDev->StatCmdSync); 719 break; 721 } 720 722 721 723 default: … … 738 740 } 739 741 740 GI TS_CRIT_SECT_LEAVE(pDevIns);742 GIC_CRIT_SECT_LEAVE(pDevIns); 741 743 return VINF_SUCCESS; 742 744 }
Note:
See TracChangeset
for help on using the changeset viewer.