Changeset 106370 in vbox
- Timestamp:
- Oct 16, 2024 1:25:07 PM (3 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GICAll.cpp
r106061 r106370 211 211 bool fIrqGrp1Enabled = ASMAtomicReadBool(&pThis->fIrqGrp1Enabled); 212 212 213 /* Only allow interrupts with higher priority than the current configured and running one. */ 214 uint8_t bPriority = RT_MIN(pThis->bInterruptPriority, pThis->abRunningPriorities[pThis->idxRunningPriority]); 215 213 216 /* Is anything enabled at all? */ 214 217 uint32_t bmIntForward = (bmIntPending & bmIntEnabled) & ~bmIntActive; /* Exclude the currently active interrupt. */ 215 216 /* Only allow interrupts with higher priority than the current configured and running one. */ 217 uint8_t bPriority = RT_MIN(pThis->bInterruptPriority, pThis->abRunningPriorities[pThis->idxRunningPriority]); 218 219 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->abIntPriority); i++) 220 { 221 Log4(("SGI/PPI %u, configured priority %u, running priority %u\n", i, pThis->abIntPriority[i], bPriority)); 222 if ( (bmIntForward & RT_BIT_32(i)) 223 && pThis->abIntPriority[i] < bPriority) 224 break; 225 else 226 bmIntForward &= ~RT_BIT_32(i); 227 228 if (!bmIntForward) 229 break; 218 if (bmIntForward) 219 { 220 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->abIntPriority); i++) 221 { 222 Log4(("SGI/PPI %u, configured priority %u, running priority %u\n", i, pThis->abIntPriority[i], bPriority)); 223 if ( (bmIntForward & RT_BIT_32(i)) 224 && pThis->abIntPriority[i] < bPriority) 225 break; 226 else 227 bmIntForward &= ~RT_BIT_32(i); 228 229 if (!bmIntForward) 230 break; 231 } 230 232 } 231 233 … … 247 249 248 250 249 DECLINLINE(void) gicDistHasIrqPendingForVCpu(PGICDEV pThis, PGICCPU pGicVCpu, bool *pfIrq, bool *pfFiq)251 DECLINLINE(void) gicDistHasIrqPendingForVCpu(PGICDEV pThis, PGICCPU pGicVCpu, VMCPUID idCpu, bool *pfIrq, bool *pfFiq) 250 252 { 251 253 /* Read the interrupt state. */ … … 257 259 bool fIrqGrp1Enabled = ASMAtomicReadBool(&pThis->fIrqGrp1Enabled); 258 260 261 /* Only allow interrupts with higher priority than the current configured and running one. */ 262 uint8_t bPriority = RT_MIN(pGicVCpu->bInterruptPriority, pGicVCpu->abRunningPriorities[pGicVCpu->idxRunningPriority]); 263 259 264 /* Is anything enabled at all? */ 260 265 uint32_t bmIntForward = (bmIntPending & bmIntEnabled) & ~bmIntActive; /* Exclude the currently active interrupt. */ 261 262 /* Only allow interrupts with higher priority than the current configured and running one. */ 263 uint8_t bPriority = RT_MIN(pGicVCpu->bInterruptPriority, pGicVCpu->abRunningPriorities[pGicVCpu->idxRunningPriority]); 264 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->abIntPriority); i++) 265 { 266 if ( (bmIntForward & RT_BIT_32(i)) 267 && pThis->abIntPriority[i] < bPriority) 268 break; 269 else 270 bmIntForward &= ~RT_BIT_32(i); 266 if (bmIntForward) 267 { 268 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->abIntPriority); i++) 269 { 270 Log4(("SPI %u, configured priority %u (routing %#x), running priority %u\n", i + GIC_INTID_RANGE_SPI_START, pThis->abIntPriority[i], 271 pThis->au32IntRouting[i], bPriority)); 272 if ( (bmIntForward & RT_BIT_32(i)) 273 && pThis->abIntPriority[i] < bPriority 274 && pThis->au32IntRouting[i] == idCpu) 275 break; 276 else 277 bmIntForward &= ~RT_BIT_32(i); 278 279 if (!bmIntForward) 280 break; 281 } 271 282 } 272 283 … … 303 314 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 304 315 bool fIrqDist, fFiqDist; 305 gicDistHasIrqPendingForVCpu(pGicDev, pThis, &fIrqDist, &fFiqDist);316 gicDistHasIrqPendingForVCpu(pGicDev, pThis, pVCpu->idCpu, &fIrqDist, &fFiqDist); 306 317 fIrq |= fIrqDist; 307 318 fFiq |= fFiqDist; … … 330 341 331 342 bool fIrqDist, fFiqDist; 332 gicDistHasIrqPendingForVCpu(pThis, pGicVCpu, &fIrqDist, &fFiqDist);343 gicDistHasIrqPendingForVCpu(pThis, pGicVCpu, i, &fIrqDist, &fFiqDist); 333 344 fIrq |= fIrqDist; 334 345 fFiq |= fFiqDist; … … 376 387 PGICDEV pThis = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 377 388 389 if (offReg >= GIC_DIST_REG_IROUTERn_OFF_START && offReg <= GIC_DIST_REG_IROUTERn_OFF_LAST) 390 { 391 *puValue = pThis->au32IntRouting[(offReg - GIC_DIST_REG_IROUTERn_OFF_START) / 4]; 392 return VINF_SUCCESS; 393 } 394 378 395 switch (offReg) 379 396 { … … 381 398 *puValue = (ASMAtomicReadBool(&pThis->fIrqGrp0Enabled) ? GIC_DIST_REG_CTRL_ENABLE_GRP0 : 0) 382 399 | (ASMAtomicReadBool(&pThis->fIrqGrp1Enabled) ? GIC_DIST_REG_CTRL_ENABLE_GRP1_NS : 0) 383 | GIC_DIST_REG_CTRL_DS; 400 | GIC_DIST_REG_CTRL_DS 401 | GIC_DIST_REG_CTRL_ARE_S; 384 402 break; 385 403 case GIC_DIST_REG_TYPER_OFF: … … 468 486 AssertReleaseFailed(); 469 487 break; 470 case GIC_DIST_REG_IROUTERn_OFF_START: /* Only 32 lines for now. */471 *puValue = 0; /** @todo */472 break;473 488 case GIC_DIST_REG_PIDR2_OFF: 474 489 *puValue = GIC_REDIST_REG_PIDR2_ARCH_REV_SET(GIC_REDIST_REG_PIDR2_ARCH_REV_GICV3); … … 477 492 case GIC_DIST_REG_TYPER2_OFF: 478 493 *puValue = 0; 494 break; 495 case GIC_DIST_REG_IROUTERn_OFF_START: 496 AssertFailed(); 479 497 break; 480 498 default: … … 502 520 if (offReg >= GIC_DIST_REG_IROUTERn_OFF_START && offReg <= GIC_DIST_REG_IROUTERn_OFF_LAST) 503 521 { 504 /** @todo Ignored for now, probably make this a MMIO2 region as it begins on 0x6000, see 12.9.22 of the GICv3 architecture 505 * reference manual. */ 522 uint32_t idxReg = (offReg - GIC_DIST_REG_IROUTERn_OFF_START) / 4; 523 LogFlowFunc(("GicDist: idxIRouter=%u uValue=%#x\n", idxReg, uValue)); 524 if (idxReg < RT_ELEMENTS(pThis->au32IntRouting)) 525 pThis->au32IntRouting[idxReg] = uValue; 506 526 return VINF_SUCCESS; 507 527 } … … 513 533 ASMAtomicWriteBool(&pThis->fIrqGrp0Enabled, RT_BOOL(uValue & GIC_DIST_REG_CTRL_ENABLE_GRP0)); 514 534 ASMAtomicWriteBool(&pThis->fIrqGrp1Enabled, RT_BOOL(uValue & GIC_DIST_REG_CTRL_ENABLE_GRP1_NS)); 535 Assert(!(uValue & GIC_DIST_REG_CTRL_ARE_NS)); 515 536 rcStrict = gicDistUpdateIrqState(pVM, pThis); 516 537 break; … … 542 563 break; 543 564 case GIC_DIST_REG_ICENABLERn_OFF_START: 544 //AssertReleaseFailed();565 AssertReleaseFailed(); 545 566 break; 546 567 case GIC_DIST_REG_ICENABLERn_OFF_START + 4: /* Only 32 lines for now. */ … … 596 617 for (uint32_t i = idxPrio; i < idxPrio + sizeof(uint32_t); i++) 597 618 { 619 #if 1 620 /** @todo r=aeichner This gross hack prevents Windows from hanging during boot because 621 * it tries to set the interrupt priority for PCI interrupt lines to 0 which will cause an interrupt 622 * storm later on because the lowest interrupt priority Windows seems to use is 32 for the per vCPU 623 * timer. 624 */ 625 if ((uValue & 0xff) == 0) 626 continue; 627 #endif 598 628 pThis->abIntPriority[i] = (uint8_t)(uValue & 0xff); 599 629 uValue >>= 8; … … 629 659 break; 630 660 default: 631 AssertReleaseFailed();661 //AssertReleaseFailed(); 632 662 break; 633 663 } … … 969 999 Assert((uint32_t)idxIntPending < RT_ELEMENTS(pThis->abIntPriority)); 970 1000 Assert(pThis->idxRunningPriority < RT_ELEMENTS(pThis->abRunningPriorities) - 1); 1001 1002 LogFlowFunc(("Dropping interrupt priority from %u -> %u (idxRunningPriority: %u -> %u)\n", 1003 pThis->abRunningPriorities[pThis->idxRunningPriority], 1004 pThis->abIntPriority[idxIntPending], 1005 pThis->idxRunningPriority, pThis->idxRunningPriority + 1)); 1006 971 1007 pThis->abRunningPriorities[++pThis->idxRunningPriority] = pThis->abIntPriority[idxIntPending]; 972 1008 … … 984 1020 bmPending = (ASMAtomicReadU32(&pGicDev->bmIntPending) & bmIntEnabled) & ~bmIntActive; 985 1021 idxIntPending = ASMBitFirstSet(&bmPending, sizeof(bmPending) * 8); 986 if (idxIntPending > -1) 1022 if ( idxIntPending > -1 1023 && pGicDev->abIntPriority[idxIntPending] < pThis->bInterruptPriority) 987 1024 { 988 1025 /* Mark the interrupt as active. */ … … 990 1027 991 1028 /* Drop priority. */ 992 Assert((uint32_t)idxIntPending < RT_ELEMENTS(p This->abIntPriority));1029 Assert((uint32_t)idxIntPending < RT_ELEMENTS(pGicDev->abIntPriority)); 993 1030 Assert(pThis->idxRunningPriority < RT_ELEMENTS(pThis->abRunningPriorities) - 1); 994 pThis->abRunningPriorities[++pThis->idxRunningPriority] = pThis->abIntPriority[idxIntPending]; 1031 1032 LogFlowFunc(("Dropping interrupt priority from %u -> %u (idxRunningPriority: %u -> %u)\n", 1033 pThis->abRunningPriorities[pThis->idxRunningPriority], 1034 pThis->abIntPriority[idxIntPending], 1035 pThis->idxRunningPriority, pThis->idxRunningPriority + 1)); 1036 1037 pThis->abRunningPriorities[++pThis->idxRunningPriority] = pGicDev->abIntPriority[idxIntPending]; 995 1038 996 1039 *pu64Value = idxIntPending + GIC_INTID_RANGE_SPI_START; … … 1006 1049 break; 1007 1050 case ARMV8_AARCH64_SYSREG_ICC_HPPIR1_EL1: 1008 AssertReleaseFailed(); 1009 break; 1051 { 1052 /** @todo Figure out the highest priority interrupt. */ 1053 uint32_t bmIntActive = ASMAtomicReadU32(&pThis->bmIntActive); 1054 uint32_t bmIntEnabled = ASMAtomicReadU32(&pThis->bmIntEnabled); 1055 uint32_t bmPending = (ASMAtomicReadU32(&pThis->bmIntPending) & bmIntEnabled) & ~bmIntActive; 1056 int32_t idxIntPending = ASMBitFirstSet(&bmPending, sizeof(bmPending) * 8); 1057 if (idxIntPending > -1) 1058 *pu64Value = idxIntPending; 1059 else 1060 { 1061 /** @todo This is wrong as the guest might decide to prioritize PPIs and SPIs differently. */ 1062 bmIntActive = ASMAtomicReadU32(&pGicDev->bmIntActive); 1063 bmIntEnabled = ASMAtomicReadU32(&pGicDev->bmIntEnabled); 1064 bmPending = (ASMAtomicReadU32(&pGicDev->bmIntPending) & bmIntEnabled) & ~bmIntActive; 1065 idxIntPending = ASMBitFirstSet(&bmPending, sizeof(bmPending) * 8); 1066 if (idxIntPending > -1) 1067 *pu64Value = idxIntPending + GIC_INTID_RANGE_SPI_START; 1068 else 1069 *pu64Value = GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT; 1070 } 1071 break; 1072 } 1010 1073 case ARMV8_AARCH64_SYSREG_ICC_BPR1_EL1: 1011 1074 *pu64Value = pThis->bBinaryPointGrp1 & 0x7; … … 1118 1181 { 1119 1182 /* Route to all but this vCPU. */ 1120 AssertReleaseFailed(); 1183 for (uint32_t i = 0; i < pVCpu->pVMR3->cCpus; i++) 1184 { 1185 if (i != pVCpu->idCpu) 1186 { 1187 PVMCPUCC pVCpuDst = VMMGetCpuById(pVCpu->CTX_SUFF(pVM), i); 1188 if (pVCpuDst) 1189 GICSgiSet(pVCpuDst, uIntId, true /*fAsserted*/); 1190 else 1191 AssertFailed(); 1192 } 1193 } 1121 1194 } 1122 1195 else … … 1163 1236 Assert(pThis->idxRunningPriority > 0); 1164 1237 if (RT_LIKELY(pThis->idxRunningPriority)) 1238 { 1239 LogFlowFunc(("Restoring interrupt priority from %u -> %u (idxRunningPriority: %u -> %u)\n", 1240 pThis->abRunningPriorities[pThis->idxRunningPriority], 1241 pThis->abRunningPriorities[pThis->idxRunningPriority - 1], 1242 pThis->idxRunningPriority, pThis->idxRunningPriority - 1)); 1165 1243 pThis->idxRunningPriority--; 1244 } 1166 1245 gicReDistUpdateIrqState(pThis, pVCpu); 1167 1246 break; -
trunk/src/VBox/VMM/VMMR3/GICR3.cpp
r106061 r106370 113 113 pHlp->pfnPrintf(pHlp, " INTID %u = %u\n", GIC_INTID_RANGE_SPI_START + i, pGicDev->abIntPriority[i]); 114 114 115 pHlp->pfnPrintf(pHlp, " Interrupt routing:\n"); 116 for (uint32_t i = 0; i < RT_ELEMENTS(pGicDev->au32IntRouting); i++) 117 pHlp->pfnPrintf(pHlp, " INTID %u = %u\n", GIC_INTID_RANGE_SPI_START + i, pGicDev->au32IntRouting[i]); 118 115 119 pHlp->pfnPrintf(pHlp, " fIrqGrp0Enabled = %RTbool\n", pGicDev->fIrqGrp0Enabled); 116 120 pHlp->pfnPrintf(pHlp, " fIrqGrp1Enabled = %RTbool\n", pGicDev->fIrqGrp1Enabled);
Note:
See TracChangeset
for help on using the changeset viewer.