Changeset 108865 in vbox for trunk/src/VBox/VMM/VMMAll/GITSAll.cpp
- Timestamp:
- Apr 7, 2025 10:17:36 AM (2 weeks ago)
- svn:sync-xref-src-repo-rev:
- 168315
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GITSAll.cpp
r108864 r108865 67 67 AssertCompileSize(GITSITE, 8); 68 68 69 /** GITS diagnostic enum description expansion. 70 * The below construct ensures typos in the input to this macro are caught 71 * during compile time. */ 72 #define GITSDIAG_DESC(a_Name) RT_CONCAT(kGitsDiag_, a_Name) < kGitsDiag_End ? RT_STR(a_Name) : "Ignored" 73 /** GITS diagnostics description for members in GITSDIAG. */ 74 static const char *const g_apszGitsDiagDesc[] = 75 { 76 GITSDIAG_DESC(None), 77 GITSDIAG_DESC(CmdQueue_PhysAddr_Invalid), 78 /* kGitsDiag_End */ 79 }; 80 AssertCompile(RT_ELEMENTS(g_apszGitsDiagDesc) == kGitsDiag_End); 81 #undef GITSDIAG_DESC 82 69 83 70 84 /********************************************************************************************************************************* … … 108 122 } 109 123 124 static void gitsCmdQueueSetError(PGITSDEV pGitsDev, GITSDIAG enmError, bool fStallQueue) 125 { 126 /* Record the error and stall the queue. */ 127 pGitsDev->uCmdQueueError = enmError; 128 if (fStallQueue) 129 pGitsDev->uCmdReadReg |= GITS_BF_CTRL_REG_CREADR_STALLED_MASK; 130 131 /* Since we don't support SEIs, so there should be nothing more to do here. */ 132 Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_SEIS)); 133 } 134 110 135 111 136 DECL_FORCE_INLINE(bool) gitsCmdQueueIsEmptyEx(PCGITSDEV pGitsDev, uint32_t *poffRead, uint32_t *poffWrite) … … 117 142 118 143 119 DECL_ HIDDEN_CALLBACK(bool) gitsCmdQueueIsEmpty(PCGITSDEV pGitsDev)144 DECL_FORCE_INLINE(bool) gitsCmdQueueIsEmpty(PCGITSDEV pGitsDev) 120 145 { 121 146 uint32_t offRead; … … 125 150 126 151 127 DECL_ HIDDEN_CALLBACK(bool) gitsCmdQueueCanProcessRequests(PCGITSDEV pGitsDev)128 { 129 if ( pGitsDev->fEnabled152 DECL_FORCE_INLINE(bool) gitsCmdQueueCanProcessRequests(PCGITSDEV pGitsDev) 153 { 154 if ( (pGitsDev->uTypeReg.u & GITS_BF_CTRL_REG_CTLR_ENABLED_MASK) 130 155 && (pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_VALID_MASK) 131 156 && !(pGitsDev->uCmdReadReg & GITS_BF_CTRL_REG_CREADR_STALLED_MASK)) … … 169 194 case GITS_CTRL_REG_CTLR_OFF: 170 195 Assert(cb == 4); 171 uReg = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_ENABLED, pGitsDev->fEnabled) 172 | RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT, pGitsDev->fQuiescent); 196 uReg = pGitsDev->uCtrlReg; 173 197 break; 174 198 … … 193 217 case GITS_CTRL_REG_TYPER_OFF + 4: 194 218 { 195 uint64_t const uVal = RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PHYSICAL, 1) /* Physical LPIs supported. */ 196 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VIRTUAL, 0) */ /* Virtual LPIs not supported. */ 197 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CCT, 0) /* Collections in memory not supported. */ 198 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ITT_ENTRY_SIZE, sizeof(GITSITE)) /* ITE size in bytes. */ 199 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ID_BITS, 31) /* 32-bit event IDs. */ 200 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_DEV_BITS, 31) /* 32-bit device IDs. */ 201 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SEIS, 0) */ /** @todo SEI support. */ 202 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PTA, 0) */ /* Target is VCPU ID not address. */ 203 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_HCC, 255) /* Collection count. */ 204 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CID_BITS, 0) */ /* CIL specifies collection ID size. */ 205 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CIL, 0) */ /* 16-bit collection IDs. */ 206 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMOVP, 0) */ /* VMOVP not supported. */ 207 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_MPAM, 0) */ /* MPAM no supported. */ 208 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VSGI, 0) */ /* VSGI not supported. */ 209 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMAPP, 0) */ /* VMAPP not supported. */ 210 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SVPET, 0) */ /* SVPET not supported. */ 211 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_NID, 0) */ /* NID (doorbell) not supported. */ 212 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI, 0) */ /** @todo Reporting receipt of unmapped MSIs. */ 213 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI_IRQ, 0) */ /** @todo Generating interrupt on unmapped MSI. */ 214 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_INV, 1); /* ITS caches invalidated when clearing 215 GITS_CTLR.Enabled and GITS_BASER<n>.Valid. */ 216 uReg = uVal >> ((offReg & 7) << 3 /* to bits */); 219 uReg = pGitsDev->uTypeReg.u >> ((offReg & 7) << 3 /* to bits */); 217 220 break; 218 221 } … … 289 292 case GITS_CTRL_REG_CTLR_OFF: 290 293 Assert(cb == 4); 291 pGitsDev->fEnabled = RT_BF_GET(uValue, GITS_BF_CTRL_REG_CTLR_ENABLED); 294 Assert(!(pGitsDev->uTypeReg.u & GITS_BF_CTRL_REG_TYPER_UMSI_IRQ_MASK)); 295 pGitsDev->uCtrlReg = uValue & GITS_BF_CTRL_REG_CTLR_RW_MASK; 292 296 gitsCmdQueueThreadWakeUpIfNeeded(pDevIns, pGitsDev); 293 297 break; … … 340 344 { 341 345 Log4Func(("\n")); 342 pGitsDev->fEnabled = false; 343 pGitsDev->fUnmappedMsiReport = false; 344 pGitsDev->fQuiescent = true; 346 347 pGitsDev->uCtrlReg = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT, 1); 348 pGitsDev->uTypeReg.u = RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PHYSICAL, 1) /* Physical LPIs supported. */ 349 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VIRTUAL, 0) */ /* Virtual LPIs not supported. */ 350 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CCT, 0) /* Collections in memory not supported. */ 351 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ITT_ENTRY_SIZE, sizeof(GITSITE)) /* ITE size in bytes. */ 352 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ID_BITS, 31) /* 32-bit event IDs. */ 353 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_DEV_BITS, 31) /* 32-bit device IDs. */ 354 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SEIS, 0) */ /* Locally generated errors not recommended. */ 355 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PTA, 0) */ /* Target is VCPU ID not address. */ 356 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_HCC, 255) /* Collection count. */ 357 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CID_BITS, 0) */ /* CIL specifies collection ID size. */ 358 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CIL, 0) */ /* 16-bit collection IDs. */ 359 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMOVP, 0) */ /* VMOVP not supported. */ 360 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_MPAM, 0) */ /* MPAM no supported. */ 361 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VSGI, 0) */ /* VSGI not supported. */ 362 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMAPP, 0) */ /* VMAPP not supported. */ 363 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SVPET, 0) */ /* SVPET not supported. */ 364 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_NID, 0) */ /* NID (doorbell) not supported. */ 365 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI, 0) */ /** @todo Reporting receipt of unmapped MSIs. */ 366 /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI_IRQ, 0) */ /** @todo Generating interrupt on unmapped MSI. */ 367 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_INV, 1); /* ITS caches invalidated when clearing 368 GITS_CTLR.Enabled and GITS_BASER<n>.Valid. */ 345 369 RT_ZERO(pGitsDev->aItsTableRegs); 346 370 pGitsDev->uCmdBaseReg.u = 0; … … 356 380 357 381 pHlp->pfnPrintf(pHlp, "GIC ITS:\n"); 358 pHlp->pfnPrintf(pHlp, " uArchRev = %u\n", pGitsDev->uArchRev); 359 pHlp->pfnPrintf(pHlp, " fEnabled = %RTbool\n", pGitsDev->fEnabled); 360 pHlp->pfnPrintf(pHlp, " fUnmappedMsiReport = %RTbool\n", pGitsDev->fUnmappedMsiReport); 361 pHlp->pfnPrintf(pHlp, " fQuiescent = %RTbool\n", pGitsDev->fQuiescent); 382 383 /* Basic info, GITS_CTLR and GITS_TYPER. */ 384 { 385 GITSDIAG const enmDiag = pGitsDev->enmDiag; 386 const char *const pszDiag = enmDiag < RT_ELEMENTS(g_apszGitsDiagDesc) ? g_apszGitsDiagDesc[enmDiag] : "(Unknown)"; 387 uint32_t const uCtrlReg = pGitsDev->uCtrlReg; 388 pHlp->pfnPrintf(pHlp, " Error = %#RX32 (%s)\n", enmDiag, pszDiag); 389 pHlp->pfnPrintf(pHlp, " uArchRev = %u\n", pGitsDev->uArchRev); 390 pHlp->pfnPrintf(pHlp, " uCtrlReg = %#RX32\n", uCtrlReg); 391 pHlp->pfnPrintf(pHlp, " Enabled = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_ENABLED)); 392 pHlp->pfnPrintf(pHlp, " UMSI IRQ = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_UMSI_IRQ)); 393 pHlp->pfnPrintf(pHlp, " Quiescent = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_QUIESCENT)); 394 } 362 395 363 396 /* GITS_BASER<n>. */ … … 420 453 DECL_HIDDEN_CALLBACK(int) gitsR3CmdQueueProcess(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, void *pvBuf, uint32_t cbBuf) 421 454 { 455 /* Hold the critical section as we could be accessing the device state simultaneously with MMIO accesses. */ 422 456 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS); 423 457 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); … … 434 468 AssertRelease(cbCmdQueue <= cbBuf); /** @todo Paranoia; make this a debug assert later. */ 435 469 436 #if 0437 470 /* 438 * Allocate space for the command-queue if we haven't done so already. 439 */ 440 if (pGitsDev->pvCmdQueue != NULL) 441 { 442 if (pGitsDev->cbCmdQueue <= cbCmdQueue) 443 { /* Already allocated sufficient space. */ } 444 else 445 { 446 /* Free old allocation and allocate a new one. */ 447 RTMemFree(pGitsDev->pvCmdQueue); 448 pGitsDev->cbCmdQueue = cbCmdQueue; 449 pGitsDev->pvCmdQueue = RTMemAllocZ(cbCmdQueue); 450 if (pGitsDev->pvCmdQueue) 451 { /* likely */ } 452 else 453 return VERR_NO_MEMORY; 454 } 455 } 456 else 457 { 458 /* Allocate one. */ 459 pGitsDev->cbCmdQueue = cbCmdQueue; 460 pGitsDev->pvCmdQueue = RTMemAllocZ(cbCmdQueue); 461 if (pGitsDev->pvCmdQueue) 462 { /* likely */ } 463 else 464 return VERR_NO_MEMORY; 465 } 466 #endif 467 468 /* 469 * Read all the commands into the command queue. 471 * Read all the commands from guest memory into our command queue buffer. 470 472 */ 471 473 RTGCPHYS const GCPhysCmds = pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_PHYS_ADDR_MASK; 472 474 473 /* Leave the critical section before reading (a potentially large amount of) commands. */475 /* Temporarily leave the critical section while reading (a potentially large number of) commands from guest memory. */ 474 476 PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3); 475 477 … … 478 480 if (offWrite > offRead) 479 481 { 480 /* The commands havenot wrapped around, read them in one go. */482 /* The write offset has not wrapped around, read them in one go. */ 481 483 cbCmds = offWrite - offRead; 482 484 Assert(cbCmds <= cbBuf); … … 485 487 else 486 488 { 487 /* The commands have wrapped around, read forward and wrapped-around. */489 /* The write offset has wrapped around, read till end of buffer followed by wrapped-around data. */ 488 490 uint32_t const cbForward = cbCmdQueue - offRead; 489 491 uint32_t const cbWrapped = offWrite; … … 506 508 if (RT_SUCCESS(rc)) 507 509 { 508 509 510 uint32_t const cCmds = cbCmds / GITS_CMD_SIZE; 510 511 for (uint32_t idxCmd = 0; idxCmd < cCmds; idxCmd++) … … 519 520 520 521 /* Failed to read command queue from the physical address specified by the guest, stall queue and retry later. */ 521 522 523 /** @todo Stall the command queue. */ 522 gitsCmdQueueSetError(pGitsDev, kGitsDiag_CmdQueue_PhysAddr_Invalid, true /* fStall */); 524 523 return VINF_TRY_AGAIN; 525 524 }
Note:
See TracChangeset
for help on using the changeset viewer.