Changeset 100165 in vbox
- Timestamp:
- Jun 13, 2023 11:56:42 AM (20 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GICAll.cpp
r100108 r100165 165 165 /* Is anything enabled at all? */ 166 166 uint32_t bmIntForward = (bmIntPending & bmIntEnabled) & ~bmIntActive; /* Exclude the currently active interrupt. */ 167 168 /* Only allow interrupts with higher priority than the current configured and running one. */ 169 uint8_t bPriority = RT_MIN(pThis->bInterruptPriority, pThis->abRunningPriorities[pThis->idxRunningPriority]); 170 171 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->abIntPriority); i++) 172 { 173 Log4(("SGI/PPI %u, configured priority %u, running priority %u\n", i, pThis->abIntPriority[i], bPriority)); 174 if ( (bmIntForward & RT_BIT_32(i)) 175 && pThis->abIntPriority[i] < bPriority) 176 break; 177 else 178 bmIntForward &= ~RT_BIT_32(i); 179 180 if (!bmIntForward) 181 break; 182 } 183 167 184 if (bmIntForward) 168 185 { … … 177 194 } 178 195 179 LogFlowFunc(("pThis=%p b mIntEnabled=%#x bmIntPending=%#x bmIntActive=%#x fIrq=%RTbool fFiq=%RTbool\n",180 pThis, b mIntEnabled, bmIntPending, bmIntActive, *pfIrq, *pfFiq));181 } 182 183 184 DECLINLINE(void) gicDistHasIrqPendingForVCpu(PGICDEV pThis, bool *pfIrq, bool *pfFiq)196 LogFlowFunc(("pThis=%p bPriority=%u bmIntEnabled=%#x bmIntPending=%#x bmIntActive=%#x fIrq=%RTbool fFiq=%RTbool\n", 197 pThis, bPriority, bmIntEnabled, bmIntPending, bmIntActive, *pfIrq, *pfFiq)); 198 } 199 200 201 DECLINLINE(void) gicDistHasIrqPendingForVCpu(PGICDEV pThis, PGICCPU pGicVCpu, bool *pfIrq, bool *pfFiq) 185 202 { 186 203 /* Read the interrupt state. */ … … 194 211 /* Is anything enabled at all? */ 195 212 uint32_t bmIntForward = (bmIntPending & bmIntEnabled) & ~bmIntActive; /* Exclude the currently active interrupt. */ 213 214 /* Only allow interrupts with higher priority than the current configured and running one. */ 215 uint8_t bPriority = RT_MIN(pGicVCpu->bInterruptPriority, pGicVCpu->abRunningPriorities[pGicVCpu->idxRunningPriority]); 216 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->abIntPriority); i++) 217 { 218 if ( (bmIntForward & RT_BIT_32(i)) 219 && pThis->abIntPriority[i] < bPriority) 220 break; 221 else 222 bmIntForward &= ~RT_BIT_32(i); 223 } 224 196 225 if (bmIntForward) 197 226 { … … 226 255 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 227 256 bool fIrqDist, fFiqDist; 228 gicDistHasIrqPendingForVCpu(pGicDev, &fIrqDist, &fFiqDist);257 gicDistHasIrqPendingForVCpu(pGicDev, pThis, &fIrqDist, &fFiqDist); 229 258 fIrq |= fIrqDist; 230 259 fFiq |= fFiqDist; … … 247 276 { 248 277 PVMCPUCC pVCpu = pVM->CTX_SUFF(apCpus)[i]; 278 PGICCPU pGicVCpu = VMCPU_TO_GICCPU(pVCpu); 249 279 250 280 bool fIrq, fFiq; 251 gicReDistHasIrqPending( VMCPU_TO_GICCPU(pVCpu), &fIrq, &fFiq);281 gicReDistHasIrqPending(pGicVCpu, &fIrq, &fFiq); 252 282 253 283 bool fIrqDist, fFiqDist; 254 gicDistHasIrqPendingForVCpu(pThis, &fIrqDist, &fFiqDist);284 gicDistHasIrqPendingForVCpu(pThis, pGicVCpu, &fIrqDist, &fFiqDist); 255 285 fIrq |= fIrqDist; 256 286 fFiq |= fFiqDist; … … 295 325 DECLINLINE(VBOXSTRICTRC) gicDistRegisterRead(PPDMDEVINS pDevIns, PVMCPUCC pVCpu, uint16_t offReg, uint32_t *puValue) 296 326 { 297 VMCPU_ASSERT_EMT(pVCpu); RT_NOREF(pVCpu);327 VMCPU_ASSERT_EMT(pVCpu); 298 328 PGICDEV pThis = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 299 329 … … 337 367 AssertReleaseFailed(); 338 368 break; 369 case GIC_DIST_REG_IPRIORITYn_OFF_START: 370 case GIC_DIST_REG_IPRIORITYn_OFF_START + 4: /* These are banked for the PEs and access the redistributor. */ 371 { 372 PGICCPU pGicVCpu = VMCPU_TO_GICCPU(pVCpu); 373 374 /* Figure out the register which is written. */ 375 uint8_t idxPrio = offReg - GIC_DIST_REG_IPRIORITYn_OFF_START; 376 Assert(idxPrio <= RT_ELEMENTS(pThis->abIntPriority) - sizeof(uint32_t)); 377 378 uint32_t u32Value = 0; 379 for (uint32_t i = idxPrio; i < idxPrio + sizeof(uint32_t); i++) 380 u32Value |= pGicVCpu->abIntPriority[i] << ((i - idxPrio) * 8); 381 382 *puValue = u32Value; 383 break; 384 } 339 385 case GIC_DIST_REG_IPRIORITYn_OFF_START + 32: /* Only 32 lines for now. */ 340 386 { 341 387 /* Figure out the register which is written. */ 342 uint8_t idxPrio = offReg - GIC_ REDIST_SGI_PPI_REG_IPRIORITYn_OFF_START - 32;388 uint8_t idxPrio = offReg - GIC_DIST_REG_IPRIORITYn_OFF_START - 32; 343 389 Assert(idxPrio <= RT_ELEMENTS(pThis->abIntPriority) - sizeof(uint32_t)); 344 390 … … 467 513 rcStrict = gicDistUpdateIrqState(pVM, pThis); 468 514 break; 515 case GIC_DIST_REG_IPRIORITYn_OFF_START: /* These are banked for the PEs and access the redistributor. */ 516 case GIC_DIST_REG_IPRIORITYn_OFF_START + 4: 517 case GIC_DIST_REG_IPRIORITYn_OFF_START + 8: 518 case GIC_DIST_REG_IPRIORITYn_OFF_START + 12: 519 case GIC_DIST_REG_IPRIORITYn_OFF_START + 16: 520 case GIC_DIST_REG_IPRIORITYn_OFF_START + 20: 521 case GIC_DIST_REG_IPRIORITYn_OFF_START + 24: 522 case GIC_DIST_REG_IPRIORITYn_OFF_START + 28: 523 { 524 PGICCPU pGicVCpu = VMCPU_TO_GICCPU(pVCpu); 525 526 /* Figure out the register which is written. */ 527 uint8_t idxPrio = offReg - GIC_DIST_REG_IPRIORITYn_OFF_START; 528 Assert(idxPrio <= RT_ELEMENTS(pGicVCpu->abIntPriority) - sizeof(uint32_t)); 529 for (uint32_t i = idxPrio; i < idxPrio + sizeof(uint32_t); i++) 530 { 531 pGicVCpu->abIntPriority[i] = (uint8_t)(uValue & 0xff); 532 uValue >>= 8; 533 } 534 break; 535 } 469 536 case GIC_DIST_REG_IPRIORITYn_OFF_START + 32: /* Only 32 lines for now. */ 470 537 case GIC_DIST_REG_IPRIORITYn_OFF_START + 36: … … 476 543 case GIC_DIST_REG_IPRIORITYn_OFF_START + 60: 477 544 { 478 /* Figure out the register wh ch is written. */479 uint8_t idxPrio = offReg - GIC_ REDIST_SGI_PPI_REG_IPRIORITYn_OFF_START - 32;545 /* Figure out the register which is written. */ 546 uint8_t idxPrio = offReg - GIC_DIST_REG_IPRIORITYn_OFF_START - 32; 480 547 Assert(idxPrio <= RT_ELEMENTS(pThis->abIntPriority) - sizeof(uint32_t)); 481 548 for (uint32_t i = idxPrio; i < idxPrio + sizeof(uint32_t); i++) … … 514 581 break; 515 582 default: 516 //AssertReleaseFailed();583 AssertReleaseFailed(); 517 584 break; 518 585 } … … 636 703 { 637 704 VMCPU_ASSERT_EMT(pVCpu); 638 RT_NOREF(pDevIns, pVCpu, offReg,uValue);705 RT_NOREF(pDevIns, pVCpu, uValue); 639 706 640 707 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 708 switch (offReg) 709 { 710 case GIC_REDIST_REG_STATUSR_OFF: 711 AssertReleaseFailed(); 712 break; 713 case GIC_REDIST_REG_WAKER_OFF: 714 Assert(uValue == 0); 715 break; 716 case GIC_REDIST_REG_PARTIDR_OFF: 717 AssertReleaseFailed(); 718 break; 719 case GIC_REDIST_REG_SETLPIR_OFF: 720 AssertReleaseFailed(); 721 break; 722 case GIC_REDIST_REG_CLRLPIR_OFF: 723 AssertReleaseFailed(); 724 break; 725 case GIC_REDIST_REG_PROPBASER_OFF: 726 AssertReleaseFailed(); 727 break; 728 case GIC_REDIST_REG_PENDBASER_OFF: 729 AssertReleaseFailed(); 730 break; 731 case GIC_REDIST_REG_INVLPIR_OFF: 732 AssertReleaseFailed(); 733 break; 734 case GIC_REDIST_REG_INVALLR_OFF: 735 AssertReleaseFailed(); 736 break; 737 default: 738 AssertReleaseFailed(); 739 break; 740 } 741 641 742 return rcStrict; 642 743 } … … 715 816 break; 716 817 default: 717 AssertReleaseFailed(); 818 //AssertReleaseFailed(); 819 break; 718 820 } 719 821 … … 794 896 break; 795 897 case ARMV8_AARCH64_SYSREG_ICC_RPR_EL1: 796 AssertReleaseFailed();898 *pu64Value = pThis->abRunningPriorities[pThis->idxRunningPriority]; 797 899 break; 798 900 case ARMV8_AARCH64_SYSREG_ICC_SGI1R_EL1: … … 808 910 { 809 911 /** @todo Figure out the highest priority interrupt. */ 810 uint32_t bmPending = ASMAtomicReadU32(&pThis->bmIntPending); 912 uint32_t bmIntActive = ASMAtomicReadU32(&pThis->bmIntActive); 913 uint32_t bmIntEnabled = ASMAtomicReadU32(&pThis->bmIntEnabled); 914 uint32_t bmPending = (ASMAtomicReadU32(&pThis->bmIntPending) & bmIntEnabled) & ~bmIntActive; 811 915 int32_t idxIntPending = ASMBitFirstSet(&bmPending, sizeof(bmPending) * 8); 812 916 if (idxIntPending > -1) … … 814 918 /* Mark the interrupt as active. */ 815 919 ASMAtomicOrU32(&pThis->bmIntActive, RT_BIT_32(idxIntPending)); 920 /* Drop priority. */ 921 Assert((uint32_t)idxIntPending < RT_ELEMENTS(pThis->abIntPriority)); 922 Assert(pThis->idxRunningPriority < RT_ELEMENTS(pThis->abRunningPriorities) - 1); 923 pThis->abRunningPriorities[++pThis->idxRunningPriority] = pThis->abIntPriority[idxIntPending]; 924 816 925 /* Clear edge level interrupts like SGIs as pending. */ 817 926 if (idxIntPending <= GIC_INTID_RANGE_SGI_LAST) 818 927 ASMAtomicBitClear(&pThis->bmIntPending, idxIntPending); 819 928 *pu64Value = idxIntPending; 929 gicReDistUpdateIrqState(pThis, pVCpu); 820 930 } 821 931 else 822 932 { 823 933 /** @todo This is wrong as the guest might decide to prioritize PPIs and SPIs differently. */ 824 bmPending = ASMAtomicReadU32(&pGicDev->bmIntPending); 934 bmIntActive = ASMAtomicReadU32(&pGicDev->bmIntActive); 935 bmIntEnabled = ASMAtomicReadU32(&pGicDev->bmIntEnabled); 936 bmPending = (ASMAtomicReadU32(&pGicDev->bmIntPending) & bmIntEnabled) & ~bmIntActive; 825 937 idxIntPending = ASMBitFirstSet(&bmPending, sizeof(bmPending) * 8); 826 938 if (idxIntPending > -1) … … 828 940 /* Mark the interrupt as active. */ 829 941 ASMAtomicOrU32(&pGicDev->bmIntActive, RT_BIT_32(idxIntPending)); 942 943 /* Drop priority. */ 944 Assert((uint32_t)idxIntPending < RT_ELEMENTS(pThis->abIntPriority)); 945 Assert(pThis->idxRunningPriority < RT_ELEMENTS(pThis->abRunningPriorities) - 1); 946 pThis->abRunningPriorities[++pThis->idxRunningPriority] = pThis->abIntPriority[idxIntPending]; 947 830 948 *pu64Value = idxIntPending + GIC_INTID_RANGE_SPI_START; 949 gicReDistUpdateIrqState(pThis, pVCpu); 831 950 } 832 951 else … … 896 1015 { 897 1016 case ARMV8_AARCH64_SYSREG_ICC_PMR_EL1: 1017 LogFlowFunc(("ICC_PMR_EL1: Interrupt priority now %u\n", (uint8_t)u64Value)); 898 1018 ASMAtomicWriteU8(&pThis->bInterruptPriority, (uint8_t)u64Value); 1019 gicReDistUpdateIrqState(pThis, pVCpu); 899 1020 break; 900 1021 case ARMV8_AARCH64_SYSREG_ICC_IAR0_EL1: … … 986 1107 else 987 1108 ASMAtomicAndU32(&pGicDev->bmIntActive, ~RT_BIT_32((uint32_t)u64Value)); 1109 1110 /* Restore previous interrupt priority. */ 1111 Assert(pThis->idxRunningPriority > 0); 1112 if (RT_LIKELY(pThis->idxRunningPriority)) 1113 pThis->idxRunningPriority--; 988 1114 gicReDistUpdateIrqState(pThis, pVCpu); 989 1115 break; … … 1114 1240 LogFlowFunc(("GIC%u\n", pVCpu->idCpu)); 1115 1241 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 1116 RT_NOREF(pVCpu); 1242 1243 memset((void *)&pVCpu->gic.s.abRunningPriorities[0], 0xff, sizeof(pVCpu->gic.s.abRunningPriorities)); 1244 pVCpu->gic.s.idxRunningPriority = 0; 1245 pVCpu->gic.s.bInterruptPriority = 0; /* Means no interrupt gets through to the PE. */ 1117 1246 } 1118 1247 -
trunk/src/VBox/VMM/VMMR3/GICR3.cpp
r100108 r100165 71 71 72 72 /** 73 * Dumps basic APIC state. 74 * 75 * @param pVM The cross context VM structure. 76 * @param pHlp The info helpers. 77 * @param pszArgs Arguments, ignored. 78 */ 79 static DECLCALLBACK(void) gicR3Info(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs) 80 { 81 RT_NOREF(pVM, pHlp, pszArgs); 82 } 83 84 85 /** 86 * Dumps GIC Distributor information. 87 * 88 * @param pVM The cross context VM structure. 89 * @param pHlp The info helpers. 90 * @param pszArgs Arguments, ignored. 91 */ 92 static DECLCALLBACK(void) gicR3InfoDist(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs) 93 { 94 RT_NOREF(pszArgs); 95 96 PGIC pGic = VM_TO_GIC(pVM); 97 PPDMDEVINS pDevIns = pGic->CTX_SUFF(pDevIns); 98 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 99 100 pHlp->pfnPrintf(pHlp, "GICv3 Distributor:\n"); 101 pHlp->pfnPrintf(pHlp, " IGRP0 = %#RX32\n", pGicDev->u32RegIGrp0); 102 pHlp->pfnPrintf(pHlp, " ICFG0 = %#RX32\n", pGicDev->u32RegICfg0); 103 pHlp->pfnPrintf(pHlp, " ICFG1 = %#RX32\n", pGicDev->u32RegICfg1); 104 pHlp->pfnPrintf(pHlp, " bmIntEnabled = %#RX32\n", pGicDev->bmIntEnabled); 105 pHlp->pfnPrintf(pHlp, " bmIntPending = %#RX32\n", pGicDev->bmIntPending); 106 pHlp->pfnPrintf(pHlp, " bmIntActive = %#RX32\n", pGicDev->bmIntActive); 107 pHlp->pfnPrintf(pHlp, " Interrupt priorities:\n"); 108 for (uint32_t i = 0; i < RT_ELEMENTS(pGicDev->abIntPriority); i++) 109 pHlp->pfnPrintf(pHlp, " INTID %u = %u\n", GIC_INTID_RANGE_SPI_START + i, pGicDev->abIntPriority[i]); 110 111 pHlp->pfnPrintf(pHlp, " fIrqGrp0Enabled = %RTbool\n", pGicDev->fIrqGrp0Enabled); 112 pHlp->pfnPrintf(pHlp, " fIrqGrp1Enabled = %RTbool\n", pGicDev->fIrqGrp1Enabled); 113 } 114 115 116 /** 117 * Dumps the GIC Redistributor information. 118 * 119 * @param pVM The cross context VM structure. 120 * @param pHlp The info helpers. 121 * @param pszArgs Arguments, ignored. 122 */ 123 static DECLCALLBACK(void) gicR3InfoReDist(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs) 124 { 125 NOREF(pszArgs); 126 PVMCPU pVCpu = VMMGetCpu(pVM); 127 if (!pVCpu) 128 pVCpu = pVM->apCpusR3[0]; 129 130 PGICCPU pGicVCpu = VMCPU_TO_GICCPU(pVCpu); 131 132 pHlp->pfnPrintf(pHlp, "VCPU[%u] Redistributor:\n", pVCpu->idCpu); 133 pHlp->pfnPrintf(pHlp, " IGRP0 = %#RX32\n", pGicVCpu->u32RegIGrp0); 134 pHlp->pfnPrintf(pHlp, " ICFG0 = %#RX32\n", pGicVCpu->u32RegICfg0); 135 pHlp->pfnPrintf(pHlp, " ICFG1 = %#RX32\n", pGicVCpu->u32RegICfg1); 136 pHlp->pfnPrintf(pHlp, " bmIntEnabled = %#RX32\n", pGicVCpu->bmIntEnabled); 137 pHlp->pfnPrintf(pHlp, " bmIntPending = %#RX32\n", pGicVCpu->bmIntPending); 138 pHlp->pfnPrintf(pHlp, " bmIntActive = %#RX32\n", pGicVCpu->bmIntActive); 139 pHlp->pfnPrintf(pHlp, " Interrupt priorities:\n"); 140 for (uint32_t i = 0; i < RT_ELEMENTS(pGicVCpu->abIntPriority); i++) 141 pHlp->pfnPrintf(pHlp, " INTID %u = %u\n", i, pGicVCpu->abIntPriority[i]); 142 143 pHlp->pfnPrintf(pHlp, "VCPU[%u] ICC state:\n", pVCpu->idCpu); 144 pHlp->pfnPrintf(pHlp, " fIrqGrp0Enabled = %RTbool\n", pGicVCpu->fIrqGrp0Enabled); 145 pHlp->pfnPrintf(pHlp, " fIrqGrp1Enabled = %RTbool\n", pGicVCpu->fIrqGrp1Enabled); 146 pHlp->pfnPrintf(pHlp, " bInterruptPriority = %u\n", pGicVCpu->bInterruptPriority); 147 pHlp->pfnPrintf(pHlp, " bBinaryPointGrp0 = %u\n", pGicVCpu->bBinaryPointGrp0); 148 pHlp->pfnPrintf(pHlp, " bBinaryPointGrp1 = %u\n", pGicVCpu->bBinaryPointGrp1); 149 pHlp->pfnPrintf(pHlp, " idxRunningPriority = %u\n", pGicVCpu->idxRunningPriority); 150 pHlp->pfnPrintf(pHlp, " Running priority = %u\n", pGicVCpu->abRunningPriorities[pGicVCpu->idxRunningPriority]); 151 } 152 153 154 /** 73 155 * @interface_method_impl{PDMDEVREG,pfnReset} 74 156 */ … … 201 283 202 284 /* 285 * Register debugger info callbacks. 286 * 287 * We use separate callbacks rather than arguments so they can also be 288 * dumped in an automated fashion while collecting crash diagnostics and 289 * not just used during live debugging via the VM debugger. 290 */ 291 DBGFR3InfoRegisterInternalEx(pVM, "gic", "Dumps GIC basic information.", gicR3Info, DBGFINFO_FLAGS_ALL_EMTS); 292 DBGFR3InfoRegisterInternalEx(pVM, "gicdist", "Dumps GIC Distributor information.", gicR3InfoDist, DBGFINFO_FLAGS_ALL_EMTS); 293 DBGFR3InfoRegisterInternalEx(pVM, "gicredist", "Dumps GIC Redistributor information.", gicR3InfoReDist, DBGFINFO_FLAGS_ALL_EMTS); 294 295 /* 203 296 * Statistics. 204 297 */ … … 232 325 # undef GIC_PROF_COUNTER 233 326 327 gicR3Reset(pDevIns); 234 328 return VINF_SUCCESS; 235 329 } -
trunk/src/VBox/VMM/include/GICInternal.h
r99885 r100165 64 64 IOMMMIOHANDLE hMmioReDist; 65 65 66 /** @name SPI dis itributor register state.66 /** @name SPI distributor register state. 67 67 * @{ */ 68 68 /** Interrupt Group 0 Register. */ … … 150 150 /** The interrupt controller Binary Point Register for Group 1 interrupts. */ 151 151 uint8_t bBinaryPointGrp1; 152 /** The running poriorities caused by preemption. */ 153 volatile uint8_t abRunningPriorities[256]; 154 /** The index to the current running priority. */ 155 volatile uint8_t idxRunningPriority; 152 156 /** @} */ 153 157
Note:
See TracChangeset
for help on using the changeset viewer.