Changeset 81751 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Nov 8, 2019 3:01:34 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134539
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r81745 r81751 269 269 uint32_t iDiagnosticAccess; 270 270 271 /** Number entries allocated for the reply queue. */271 /** Number entries configured for the reply queue. */ 272 272 uint32_t cReplyQueueEntries; 273 /** Number entries allocated for the outstanding request queue. */273 /** Number entries configured for the outstanding request queue. */ 274 274 uint32_t cRequestQueueEntries; 275 276 275 277 276 /** Critical section protecting the reply post queue. */ … … 286 285 PDMCRITSECT ReplyFreeQueueWriteCritSect; 287 286 288 /** Pointer to the start of the reply free queue - R3. */ 289 R3PTRTYPE(volatile uint32_t *) pReplyFreeQueueBaseR3; 290 /** Pointer to the start of the reply post queue - R3. */ 291 R3PTRTYPE(volatile uint32_t *) pReplyPostQueueBaseR3; 292 /** Pointer to the start of the request queue - R3. */ 293 R3PTRTYPE(volatile uint32_t *) pRequestQueueBaseR3; 294 295 /** Pointer to the start of the reply queue - R0. */ 296 R0PTRTYPE(volatile uint32_t *) pReplyFreeQueueBaseR0; 297 /** Pointer to the start of the reply queue - R0. */ 298 R0PTRTYPE(volatile uint32_t *) pReplyPostQueueBaseR0; 299 /** Pointer to the start of the request queue - R0. */ 300 R0PTRTYPE(volatile uint32_t *) pRequestQueueBaseR0; 301 302 /** Pointer to the start of the reply queue - RC. */ 303 RCPTRTYPE(volatile uint32_t *) pReplyFreeQueueBaseRC; 304 /** Pointer to the start of the reply queue - RC. */ 305 RCPTRTYPE(volatile uint32_t *) pReplyPostQueueBaseRC; 306 /** Pointer to the start of the request queue - RC. */ 307 RCPTRTYPE(volatile uint32_t *) pRequestQueueBaseRC; 308 /** End these RC pointers on a 64-bit boundrary. */ 309 RTRCPTR RCPtrPadding1; 287 /** The reply free qeueue (only the first cReplyQueueEntries are used). */ 288 uint32_t volatile aReplyFreeQueue[LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX]; 289 /** The reply post qeueue (only the first cReplyQueueEntries are used). */ 290 uint32_t volatile aReplyPostQueue[LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX]; 291 /** The request qeueue (only the first cRequestQueueEntries are used). */ 292 uint32_t volatile aRequestQueue[LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX]; 310 293 311 294 /** Next free entry in the reply queue the guest can write a address to. */ … … 673 656 674 657 /* We have a context reply. */ 675 ASMAtomicWriteU32(&pThis-> CTX_SUFF(pReplyPostQueueBase)[pThis->uReplyPostQueueNextEntryFreeWrite], u32MessageContext);658 ASMAtomicWriteU32(&pThis->aReplyPostQueue[pThis->uReplyPostQueueNextEntryFreeWrite], u32MessageContext); 676 659 ASMAtomicIncU32(&pThis->uReplyPostQueueNextEntryFreeWrite); 677 660 pThis->uReplyPostQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries; … … 729 712 } 730 713 731 uint32_t u32ReplyFrameAddressLow = pThis-> CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead];714 uint32_t u32ReplyFrameAddressLow = pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextAddressRead]; 732 715 733 716 pThis->uReplyFreeQueueNextAddressRead++; … … 757 740 758 741 /* We have a address reply. Set the 31th bit to indicate that. */ 759 ASMAtomicWriteU32(&pThis-> CTX_SUFF(pReplyPostQueueBase)[pThis->uReplyPostQueueNextEntryFreeWrite],742 ASMAtomicWriteU32(&pThis->aReplyPostQueue[pThis->uReplyPostQueueNextEntryFreeWrite], 760 743 RT_BIT(31) | (u32ReplyFrameAddressLow >> 1)); 761 744 ASMAtomicIncU32(&pThis->uReplyPostQueueNextEntryFreeWrite); … … 1278 1261 return rc; 1279 1262 /* Add the entry to the reply free queue. */ 1280 ASMAtomicWriteU32(&pThis-> CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextEntryFreeWrite], u32);1263 ASMAtomicWriteU32(&pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextEntryFreeWrite], u32); 1281 1264 pThis->uReplyFreeQueueNextEntryFreeWrite++; 1282 1265 pThis->uReplyFreeQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries; … … 1292 1275 uint32_t uNextWrite = ASMAtomicReadU32(&pThis->uRequestQueueNextEntryFreeWrite); 1293 1276 1294 ASMAtomicWriteU32(&pThis-> CTX_SUFF(pRequestQueueBase)[uNextWrite], u32);1277 ASMAtomicWriteU32(&pThis->aRequestQueue[uNextWrite], u32); 1295 1278 1296 1279 /* … … 1557 1540 if (idxReplyPostQueueWrite != idxReplyPostQueueRead) 1558 1541 { 1559 u32 = pThis-> CTX_SUFF(pReplyPostQueueBase)[idxReplyPostQueueRead];1542 u32 = pThis->aReplyPostQueue[idxReplyPostQueueRead]; 1560 1543 idxReplyPostQueueRead++; 1561 1544 idxReplyPostQueueRead %= pThis->cReplyQueueEntries; … … 1616 1599 if (pThis->uReplyFreeQueueNextEntryFreeWrite != pThis->uReplyFreeQueueNextAddressRead) 1617 1600 { 1618 u32 |= pThis-> CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] & UINT32_C(0xffff);1601 u32 |= pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextAddressRead] & UINT32_C(0xffff); 1619 1602 pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH; 1620 1603 lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL); … … 1622 1605 break; 1623 1606 case LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH: 1624 u32 |= pThis-> CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] >> 16;1607 u32 |= pThis->aReplyFreeQueue[pThis->uReplyFreeQueueNextAddressRead] >> 16; 1625 1608 pThis->uReplyFreeQueueNextAddressRead++; 1626 1609 pThis->uReplyFreeQueueNextAddressRead %= pThis->cReplyQueueEntries; … … 4171 4154 { 4172 4155 for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++) 4173 pHlp->pfnPrintf(pHlp, "RFQ[%u]=%#x\n", i, pThis-> pReplyFreeQueueBaseR3[i]);4156 pHlp->pfnPrintf(pHlp, "RFQ[%u]=%#x\n", i, pThis->aReplyFreeQueue[i]); 4174 4157 4175 4158 pHlp->pfnPrintf(pHlp, "\n"); 4176 4159 4177 4160 for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++) 4178 pHlp->pfnPrintf(pHlp, "RPQ[%u]=%#x\n", i, pThis-> pReplyPostQueueBaseR3[i]);4161 pHlp->pfnPrintf(pHlp, "RPQ[%u]=%#x\n", i, pThis->aReplyPostQueue[i]); 4179 4162 4180 4163 pHlp->pfnPrintf(pHlp, "\n"); 4181 4164 4182 4165 for (unsigned i = 0; i < pThis->cRequestQueueEntries; i++) 4183 pHlp->pfnPrintf(pHlp, "ReqQ[%u]=%#x\n", i, pThis-> pRequestQueueBaseR3[i]);4166 pHlp->pfnPrintf(pHlp, "ReqQ[%u]=%#x\n", i, pThis->aRequestQueue[i]); 4184 4167 } 4185 4168 … … 4196 4179 i, pDevice->pDrvBase != NULL, pDevice->cOutstandingRequests); 4197 4180 } 4198 }4199 4200 /**4201 * Allocate the queues.4202 *4203 * @returns VBox status code.4204 *4205 * @param pThis Pointer to the LsiLogic device state.4206 */4207 static int lsilogicR3QueuesAlloc(PLSILOGICSCSI pThis)4208 {4209 PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);4210 uint32_t cbQueues;4211 4212 Assert(!pThis->pReplyFreeQueueBaseR3);4213 4214 cbQueues = 2*pThis->cReplyQueueEntries * sizeof(uint32_t);4215 cbQueues += pThis->cRequestQueueEntries * sizeof(uint32_t);4216 int rc = MMHyperAlloc(pVM, cbQueues, 1, MM_TAG_PDM_DEVICE_USER,4217 (void **)&pThis->pReplyFreeQueueBaseR3);4218 if (RT_FAILURE(rc))4219 return VERR_NO_MEMORY;4220 pThis->pReplyFreeQueueBaseR0 = MMHyperR3ToR0(pVM, (void *)pThis->pReplyFreeQueueBaseR3);4221 pThis->pReplyFreeQueueBaseRC = MMHyperR3ToRC(pVM, (void *)pThis->pReplyFreeQueueBaseR3);4222 4223 pThis->pReplyPostQueueBaseR3 = pThis->pReplyFreeQueueBaseR3 + pThis->cReplyQueueEntries;4224 pThis->pReplyPostQueueBaseR0 = MMHyperR3ToR0(pVM, (void *)pThis->pReplyPostQueueBaseR3);4225 pThis->pReplyPostQueueBaseRC = MMHyperR3ToRC(pVM, (void *)pThis->pReplyPostQueueBaseR3);4226 4227 pThis->pRequestQueueBaseR3 = pThis->pReplyPostQueueBaseR3 + pThis->cReplyQueueEntries;4228 pThis->pRequestQueueBaseR0 = MMHyperR3ToR0(pVM, (void *)pThis->pRequestQueueBaseR3);4229 pThis->pRequestQueueBaseRC = MMHyperR3ToRC(pVM, (void *)pThis->pRequestQueueBaseR3);4230 4231 return VINF_SUCCESS;4232 }4233 4234 /**4235 * Free the hyper memory used or the queues.4236 *4237 * @returns nothing.4238 *4239 * @param pThis Pointer to the LsiLogic device state.4240 */4241 static void lsilogicR3QueuesFree(PLSILOGICSCSI pThis)4242 {4243 PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);4244 int rc = VINF_SUCCESS;4245 4246 AssertPtr(pThis->pReplyFreeQueueBaseR3);4247 4248 rc = MMHyperFree(pVM, (void *)pThis->pReplyFreeQueueBaseR3);4249 AssertRC(rc);4250 4251 pThis->pReplyFreeQueueBaseR3 = NULL;4252 pThis->pReplyPostQueueBaseR3 = NULL;4253 pThis->pRequestQueueBaseR3 = NULL;4254 4181 } 4255 4182 … … 4297 4224 { 4298 4225 MptRequestUnion GuestRequest; 4299 uint32_t u32RequestMessageFrameDesc = pThis-> CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextAddressRead];4226 uint32_t u32RequestMessageFrameDesc = pThis->aRequestQueue[pThis->uRequestQueueNextAddressRead]; 4300 4227 RTGCPHYS GCPhysMessageFrameAddr = LSILOGIC_RTGCPHYS_FROM_U32(pThis->u32HostMFAHighAddr, 4301 4228 (u32RequestMessageFrameDesc & ~0x07)); … … 4468 4395 { 4469 4396 /* Write only the lower 32bit part of the address. */ 4470 ASMAtomicWriteU32(&pThis-> CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextEntryFreeWrite],4397 ASMAtomicWriteU32(&pThis->aRequestQueue[pThis->uRequestQueueNextEntryFreeWrite], 4471 4398 pReq->GCPhysMessageFrameAddr & UINT32_C(0xffffffff)); 4472 4399 … … 4525 4452 4526 4453 for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++) 4527 pHlp->pfnSSMPutU32(pSSM, pThis-> pReplyFreeQueueBaseR3[i]);4454 pHlp->pfnSSMPutU32(pSSM, pThis->aReplyFreeQueue[i]); 4528 4455 for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++) 4529 pHlp->pfnSSMPutU32(pSSM, pThis-> pReplyPostQueueBaseR3[i]);4456 pHlp->pfnSSMPutU32(pSSM, pThis->aReplyPostQueue[i]); 4530 4457 for (unsigned i = 0; i < pThis->cRequestQueueEntries; i++) 4531 pHlp->pfnSSMPutU32(pSSM, pThis-> pRequestQueueBaseR3[i]);4458 pHlp->pfnSSMPutU32(pSSM, pThis->aRequestQueue[i]); 4532 4459 4533 4460 pHlp->pfnSSMPutU16(pSSM, pThis->u16NextHandle); … … 4748 4675 || cRequestQueueEntries != pThis->cRequestQueueEntries) 4749 4676 { 4750 LogFlow(("Reallocating queues cReplyQueueEntries=%u cRequestQueuEntries=%u\n", 4751 cReplyQueueEntries, cRequestQueueEntries)); 4752 lsilogicR3QueuesFree(pThis); 4677 LogRel(("Changing queue sizes: cReplyQueueEntries=%u cRequestQueuEntries=%u\n", cReplyQueueEntries, cRequestQueueEntries)); 4678 if ( cReplyQueueEntries > RT_ELEMENTS(pThis->aReplyFreeQueue) 4679 || cReplyQueueEntries < LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN 4680 || cRequestQueueEntries > RT_ELEMENTS(pThis->aRequestQueue) 4681 || cRequestQueueEntries < LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN) 4682 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Out of bounds: cReplyQueueEntries=%u cRequestQueueEntries=%u"), 4683 cReplyQueueEntries, cRequestQueueEntries); 4753 4684 pThis->cReplyQueueEntries = cReplyQueueEntries; 4754 4685 pThis->cRequestQueueEntries = cRequestQueueEntries; 4755 rc = lsilogicR3QueuesAlloc(pThis);4756 if (RT_FAILURE(rc))4757 return rc;4758 4686 } 4759 4687 … … 4775 4703 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch: Expected SPI SCSI controller")); 4776 4704 4777 pHlp->pfnSSMGetMem(pSSM, &ConfigPagesV2, 4778 sizeof(MptConfigurationPagesSupported_SSM_V2)); 4705 pHlp->pfnSSMGetMem(pSSM, &ConfigPagesV2, sizeof(MptConfigurationPagesSupported_SSM_V2)); 4779 4706 4780 4707 pPages->ManufacturingPage0 = ConfigPagesV2.ManufacturingPage0; … … 4810 4737 /* Queue content */ 4811 4738 for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++) 4812 pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis-> pReplyFreeQueueBaseR3[i]);4739 pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->aReplyFreeQueue[i]); 4813 4740 for (unsigned i = 0; i < pThis->cReplyQueueEntries; i++) 4814 pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis-> pReplyPostQueueBaseR3[i]);4741 pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->aReplyPostQueue[i]); 4815 4742 for (unsigned i = 0; i < pThis->cRequestQueueEntries; i++) 4816 pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis-> pRequestQueueBaseR3[i]);4743 pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->aRequestQueue[i]); 4817 4744 4818 4745 pHlp->pfnSSMGetU16(pSSM, &pThis->u16NextHandle); … … 5279 5206 { 5280 5207 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 5281 5282 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 5283 5284 /* Relocate queues. */ 5285 pThis->pReplyFreeQueueBaseRC += offDelta; 5286 pThis->pReplyPostQueueBaseRC += offDelta; 5287 pThis->pRequestQueueBaseRC += offDelta; 5208 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 5209 RT_NOREF(offDelta); 5288 5210 } 5289 5211 … … 5361 5283 return PDMDEV_SET_ERROR(pDevIns, rc, 5362 5284 N_("LsiLogic configuration error: failed to read ReplyQueue as integer")); 5285 if ( pThis->cReplyQueueEntries < LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN 5286 || pThis->cReplyQueueEntries > LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX - 1 /* see +1 later in the function */) 5287 return PDMDevHlpVMSetError(pDevIns, VERR_OUT_OF_RANGE, RT_SRC_POS, 5288 N_("LsiLogic configuration error: 'ReplyQueueDepth' = %u is out of ranage (%u..%u)"), 5289 pThis->cReplyQueueEntries, LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN, 5290 LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX - 1); 5363 5291 Log(("%s: ReplyQueueDepth=%u\n", __FUNCTION__, pThis->cReplyQueueEntries)); 5364 5292 … … 5366 5294 &pThis->cRequestQueueEntries, LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT); 5367 5295 if (RT_FAILURE(rc)) 5368 return PDMDEV_SET_ERROR(pDevIns, rc, 5369 N_("LsiLogic configuration error: failed to read RequestQueue as integer")); 5296 return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic configuration error: failed to read RequestQueue as integer")); 5297 if ( pThis->cRequestQueueEntries < LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN 5298 || pThis->cRequestQueueEntries > LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX - 1 /* see +1 later in the function */) 5299 return PDMDevHlpVMSetError(pDevIns, VERR_OUT_OF_RANGE, RT_SRC_POS, 5300 N_("LsiLogic configuration error: 'RequestQueue' = %u is out of ranage (%u..%u)"), 5301 pThis->cRequestQueueEntries, LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN, 5302 LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN - 1); 5370 5303 Log(("%s: RequestQueueDepth=%u\n", __FUNCTION__, pThis->cRequestQueueEntries)); 5371 5304 … … 5515 5448 */ 5516 5449 pThis->cReplyQueueEntries++; 5450 AssertLogRelReturn(pThis->cReplyQueueEntries <= RT_ELEMENTS(pThis->aReplyFreeQueue), VERR_INTERNAL_ERROR_3); 5451 AssertLogRelReturn(pThis->cReplyQueueEntries <= RT_ELEMENTS(pThis->aReplyPostQueue), VERR_INTERNAL_ERROR_3); 5452 5517 5453 pThis->cRequestQueueEntries++; 5454 AssertLogRelReturn(pThis->cRequestQueueEntries <= RT_ELEMENTS(pThis->aRequestQueue), VERR_INTERNAL_ERROR_3); 5518 5455 5519 5456 /* 5520 * Allocate memory for the queues.5457 * Device states. 5521 5458 */ 5522 rc = lsilogicR3QueuesAlloc(pThis);5523 if (RT_FAILURE(rc))5524 return rc;5525 5526 5459 if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI) 5527 5460 pThis->cDeviceStates = pThis->cPorts * LSILOGICSCSI_PCI_SPI_DEVICES_PER_BUS_MAX; -
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
r81744 r81751 32 32 #define LSILOGIC_SAS_BIOS_IO_PORT 0x438 33 33 34 #define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT 256 35 #define LSILOGICSCSI_REPLY_QUEUE_DEPTH_DEFAULT 256 34 #define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MIN 8 /**< (bird just picked this out thin air) */ 35 #define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_MAX 1024 /**< (bird just picked this out thin air) */ 36 #define LSILOGICSCSI_REQUEST_QUEUE_DEPTH_DEFAULT 256 37 38 #define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MIN 8 /**< (bird just picked this out thin air) */ 39 #define LSILOGICSCSI_REPLY_QUEUE_DEPTH_MAX 1024 /**< (bird just picked this out thin air) */ 40 #define LSILOGICSCSI_REPLY_QUEUE_DEPTH_DEFAULT 256 36 41 37 42 #define LSILOGICSCSI_MAXIMUM_CHAIN_DEPTH 3
Note:
See TracChangeset
for help on using the changeset viewer.