Changeset 108865 in vbox
- Timestamp:
- Apr 7, 2025 10:17:36 AM (13 days ago)
- svn:sync-xref-src-repo-rev:
- 168315
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/gic-its.h
r108864 r108865 52 52 /** The guest page shift (x86). */ 53 53 #define GITS_CMD_QUEUE_PAGE_SHIFT 12 54 55 /** The GITS command size in bytes. */ 56 #define GITS_CMD_SIZE 32 54 57 55 58 /** GITS_CTLR: Control register - RW. */ … … 78 81 RT_BF_ASSERT_COMPILE_CHECKS(GITS_BF_CTRL_REG_CTLR_, UINT32_C(0), UINT32_MAX, 79 82 (ENABLED, IM_DE, RSVD_3_2, ITS_NUMBER, UMSI_IRQ, RSVD_30_9, QUIESCENT)); 83 /** GITS_CTLR: Mask of valid read-write bits. */ 84 #define GITS_BF_CTRL_REG_CTLR_RW_MASK (UINT32_MAX & ~( GITS_BF_CTRL_REG_CTLR_IM_DE_MASK \ 85 | GITS_BF_CTRL_REG_CTLR_RSVD_3_2_MASK \ 86 | GITS_BF_CTRL_REG_CTLR_ITS_NUMBER_MASK \ 87 | GITS_BF_CTRL_REG_CTLR_RSVD_30_9_MASK \ 88 | GITS_BF_CTRL_REG_CTLR_QUIESCENT_MASK)) 80 89 81 90 /** GITS_IIDR: Implementer and revision register - RO. */ … … 392 401 } GITSITSTYPE; 393 402 394 /** GITS command size in bytes. */395 #define GITS_CMD_SIZE 32396 397 403 /** 398 404 * ITS command. … … 418 424 /** Pointer to a const ITS command. */ 419 425 typedef GITSCMD const *PCGITSCMD; 420 426 AssertCompileSize(GITSCMD, GITS_CMD_SIZE); 421 427 422 428 #endif /* !VBOX_INCLUDED_gic_its_h */ -
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 } -
trunk/src/VBox/VMM/include/GITSInternal.h
r108864 r108865 43 43 */ 44 44 45 /** 46 * GITS error diagnostics. 47 * Sorted alphabetically so it's easier to add and locate items, no other reason. 48 * 49 * @note Members of this enum are used as array indices, so no gaps in enum 50 * values are not allowed. Update g_apszItsDiagDesc when you modify 51 * fields in this enum. 52 */ 53 typedef enum GITSDIAG 54 { 55 /* No error, this must be zero! */ 56 kGitsDiag_None = 0, 57 58 /* Command queue errors. */ 59 kGitsDiag_CmdQueue_PhysAddr_Invalid, 60 61 /* Member for determining array index limit. */ 62 kGitsDiag_End, 63 64 /* Usual 32-bit hack. */ 65 kGitsDiag_32Bit_Hack = 0x7fffffff 66 } GITSDIAG; 67 AssertCompileSize(GITSDIAG, 4); 68 45 69 #if 0 46 70 /** … … 80 104 /** @name Control registers. 81 105 * @{ */ 82 /** Whether the ITS is enabled. */ 83 bool fEnabled; 84 /** Whether unmapped MSI reporting interrupt is enabled. */ 85 bool fUnmappedMsiReport; 86 /** Whether the ITS is quiescent and can be powered down. */ 87 bool fQuiescent; 88 /** Padding. */ 89 bool fPadding0; 90 /** The ITS table descriptor registers. */ 106 /** The ITS control register (GITS_CTLR). */ 107 uint32_t uCtrlReg; 108 /** Implmentation-specific error diagnostic. */ 109 GITSDIAG enmDiag; 110 /** The ITS type register (GITS_TYPER). */ 111 RTUINT64U uTypeReg; 112 /** The ITS table descriptor registers (GITS_BASER<n>). */ 91 113 RTUINT64U aItsTableRegs[8]; 92 /** The ITS command queue base registers . */114 /** The ITS command queue base registers (GITS_CBASER). */ 93 115 RTUINT64U uCmdBaseReg; 94 /** The ITS command read register . */116 /** The ITS command read register (GITS_CREADR). */ 95 117 uint32_t uCmdReadReg; 96 /** The ITS command write register . */118 /** The ITS command write register (GITS_CWRITER). */ 97 119 uint32_t uCmdWriteReg; 98 120 /** @} */ … … 102 124 /** @} */ 103 125 104 /** @name Command queue thread.126 /** @name Command queue. 105 127 * @{ */ 106 128 /** The command-queue thread. */ … … 108 130 /** The event semaphore the command-queue thread waits on. */ 109 131 SUPSEMEVENT hEvtCmdQueue; 132 /** Errors while processing command-queue. */ 133 uint32_t uCmdQueueError; 134 /** Padding. */ 135 uint32_t uPadding0; 110 136 /** @} */ 111 137 … … 123 149 typedef GITSDEV const *PCGITSDEV; 124 150 AssertCompileSizeAlignment(GITSDEV, 8); 151 AssertCompileMemberAlignment(GITSDEV, aItsTableRegs, 8); 152 AssertCompileMemberAlignment(GITSDEV, uCmdReadReg, 4); 153 AssertCompileMemberAlignment(GITSDEV, uCmdWriteReg, 4); 154 AssertCompileMemberAlignment(GITSDEV, hEvtCmdQueue, 8); 125 155 AssertCompileMemberAlignment(GITSDEV, uArchRev, 8); 126 156 … … 135 165 DECL_HIDDEN_CALLBACK(void) gitsR3DbgInfo(PCGITSDEV pGitsDev, PCDBGFINFOHLP pHlp, const char *pszArgs); 136 166 DECL_HIDDEN_CALLBACK(int) gitsR3CmdQueueProcess(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, void *pvBuf, uint32_t cbBuf); 137 DECL_HIDDEN_CALLBACK(bool) gitsR3CmdQueueCanProcessRequests(PCGITSDEV pGitsDev);138 DECL_HIDDEN_CALLBACK(bool) gitsR3CmdQueueIsEmpty(PCGITSDEV pGitsDev);139 167 #endif 140 168
Note:
See TracChangeset
for help on using the changeset viewer.