Changeset 81848 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Nov 14, 2019 9:09:14 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134642
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r81847 r81848 85 85 /** The maxium I/O buffer size (for sanity). */ 86 86 #define ATA_MAX_IO_BUFFER_SIZE (ATA_MAX_MULT_SECTORS * ATA_MAX_SECTOR_SIZE) 87 88 /** Mask to be applied to all indexing into ATACONTROLLER::aIfs. */ 89 #define ATA_SELECTED_IF_MASK 1 87 90 88 91 /** … … 1077 1080 pCtl->BmDma.u8Status |= BM_STATUS_INT; 1078 1081 /* Only actually set the IRQ line if updating the currently selected drive. */ 1079 if (s == &pCtl->aIfs[pCtl->iSelectedIf ])1082 if (s == &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]) 1080 1083 { 1081 1084 /** @todo experiment with adaptive IRQ delivery: for reads it is … … 1108 1111 Log2(("%s: LUN#%d deasserting IRQ\n", __FUNCTION__, s->iLUN)); 1109 1112 /* Only actually unset the IRQ line if updating the currently selected drive. */ 1110 if (s == &pCtl->aIfs[pCtl->iSelectedIf ])1113 if (s == &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]) 1111 1114 { 1112 1115 if (pCtl->irq == 16) … … 4392 4395 static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val) 4393 4396 { 4394 Log2(("%s: LUN#%d write addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf ].iLUN, addr, val));4397 Log2(("%s: LUN#%d write addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK].iLUN, addr, val)); 4395 4398 addr &= 7; 4396 4399 switch (addr) … … 4442 4445 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0; 4443 4446 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0; 4444 if (((val >> 4) & 1) != pCtl->iSelectedIf)4447 if (((val >> 4) & ATA_SELECTED_IF_MASK) != pCtl->iSelectedIf) 4445 4448 { 4446 4449 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl); 4447 4450 4448 4451 /* select another drive */ 4449 pCtl->iSelectedIf = (val >> 4) & 1; 4452 uintptr_t const iSelectedIf = (val >> 4) & ATA_SELECTED_IF_MASK; 4453 pCtl->iSelectedIf = (uint8_t)iSelectedIf; 4450 4454 /* The IRQ line is multiplexed between the two drives, so 4451 4455 * update the state when switching to another drive. Only need 4452 4456 * to update interrupt line if it is enabled and there is a 4453 4457 * state change. */ 4454 if ( !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ) 4455 && ( pCtl->aIfs[pCtl->iSelectedIf].fIrqPending 4456 != pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending)) 4458 if ( !(pCtl->aIfs[iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ) 4459 && pCtl->aIfs[iSelectedIf].fIrqPending != pCtl->aIfs[iSelectedIf ^ 1].fIrqPending) 4457 4460 { 4458 if (pCtl->aIfs[ pCtl->iSelectedIf].fIrqPending)4461 if (pCtl->aIfs[iSelectedIf].fIrqPending) 4459 4462 { 4460 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[ pCtl->iSelectedIf].iLUN));4463 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[iSelectedIf].iLUN)); 4461 4464 /* The BMDMA unit unconditionally sets BM_STATUS_INT if 4462 4465 * the interrupt line is asserted. It monitors the line … … 4470 4473 else 4471 4474 { 4472 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[ pCtl->iSelectedIf].iLUN));4475 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[iSelectedIf].iLUN)); 4473 4476 if (pCtl->irq == 16) 4474 4477 PDMDevHlpPCISetIrq(pDevIns, 0, 0); … … 4481 4484 default: 4482 4485 case 7: /* command */ 4486 { 4483 4487 /* ignore commands to non-existent device */ 4484 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvMedia) 4488 uintptr_t iSelectedIf = pCtl->iSelectedIf & ATA_SELECTED_IF_MASK; 4489 if (iSelectedIf && !pCtl->aIfs[iSelectedIf].pDrvMedia) 4485 4490 break; 4486 4491 #ifndef IN_RING3 … … 4488 4493 return VINF_IOM_R3_IOPORT_WRITE; 4489 4494 #else /* IN_RING3 */ 4490 ataUnsetIRQ(&pCtl->aIfs[ pCtl->iSelectedIf]);4491 ataR3ParseCmd(&pCtl->aIfs[ pCtl->iSelectedIf], val);4495 ataUnsetIRQ(&pCtl->aIfs[iSelectedIf]); 4496 ataR3ParseCmd(&pCtl->aIfs[iSelectedIf], val); 4492 4497 #endif /* !IN_RING3 */ 4498 } 4493 4499 } 4494 4500 return VINF_SUCCESS; … … 4498 4504 static int ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32) 4499 4505 { 4500 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf ];4506 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]; 4501 4507 uint32_t val; 4502 4508 bool fHOB; … … 4676 4682 static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr) 4677 4683 { 4678 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf ];4684 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]; 4679 4685 uint32_t val; 4680 4686 RT_NOREF1(addr); … … 4685 4691 else 4686 4692 val = s->uATARegStatus; 4687 Log2(("%s: LUN#%d read addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf ].iLUN, addr, val));4693 Log2(("%s: LUN#%d read addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK].iLUN, addr, val)); 4688 4694 return val; 4689 4695 } … … 4697 4703 #endif /* !IN_RING3 */ 4698 4704 4699 Log2(("%s: LUN#%d write addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf ].iLUN, addr, val));4705 Log2(("%s: LUN#%d write addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK].iLUN, addr, val)); 4700 4706 /* RESET is common for both drives attached to a controller. */ 4701 4707 if ( !(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) … … 4768 4774 * is pending on the current interface. */ 4769 4775 if ( ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ) 4770 && pCtl->aIfs[pCtl->iSelectedIf ].fIrqPending)4776 && pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK].fIrqPending) 4771 4777 { 4772 4778 if (!(val & ATA_DEVCTL_DISABLE_IRQ)) 4773 4779 { 4774 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf ].iLUN));4780 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK].iLUN)); 4775 4781 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the 4776 4782 * interrupt line is asserted. It monitors the line for a rising … … 4784 4790 else 4785 4791 { 4786 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf ].iLUN));4792 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK].iLUN)); 4787 4793 if (pCtl->irq == 16) 4788 4794 PDMDevHlpPCISetIrq(CONTROLLER_2_DEVINS(pCtl), 0, 0); … … 4807 4813 ATADevState *s; 4808 4814 4809 s = &pCtl->aIfs[pCtl->iAIOIf ];4815 s = &pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK]; 4810 4816 Log3(("%s: if=%p\n", __FUNCTION__, s)); 4811 4817 … … 4846 4852 4847 4853 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n", 4848 __FUNCTION__, s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE ? "T2I" : "I2T",4849 s->cbTotalTransfer, s->cbElementaryTransfer,4850 s->iIOBufferCur, s->iIOBufferEnd));4854 __FUNCTION__, s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE ? "T2I" : "I2T", 4855 s->cbTotalTransfer, s->cbElementaryTransfer, 4856 s->iIOBufferCur, s->iIOBufferEnd)); 4851 4857 ataHCPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer); 4852 4858 s->cbTotalTransfer -= s->cbElementaryTransfer; … … 5010 5016 if (rc == VINF_SUCCESS) 5011 5017 { 5012 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf ];5018 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]; 5013 5019 uint32_t const iIOBufferPIODataStart = RT_MIN(s->iIOBufferPIODataStart, sizeof(s->abIOBuffer)); 5014 5020 uint32_t const iIOBufferPIODataEnd = RT_MIN(s->iIOBufferPIODataEnd, sizeof(s->abIOBuffer)); … … 5085 5091 if (rc == VINF_SUCCESS) 5086 5092 { 5087 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf ];5093 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]; 5088 5094 5089 5095 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd) … … 5171 5177 if (rc == VINF_SUCCESS) 5172 5178 { 5173 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf ];5179 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]; 5174 5180 5175 5181 uint32_t const offStart = s->iIOBufferPIODataStart; … … 5262 5268 if (rc == VINF_SUCCESS) 5263 5269 { 5264 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf ];5270 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK]; 5265 5271 5266 5272 uint32_t const offStart = s->iIOBufferPIODataStart; … … 5348 5354 { 5349 5355 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl); 5350 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf ];5356 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK]; 5351 5357 bool fRedo; 5352 5358 RTGCPHYS32 GCPhysDesc; … … 5632 5638 5633 5639 pCtl->iAIOIf = pReq->u.t.iIf; 5634 s = &pCtl->aIfs[pCtl->iAIOIf ];5640 s = &pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK]; 5635 5641 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer; 5636 5642 s->uTxDir = pReq->u.t.uTxDir; … … 5776 5782 { 5777 5783 BMDMAState *bm = &pCtl->BmDma; 5778 s = &pCtl->aIfs[pCtl->iAIOIf ]; /* Do not remove or there's an instant crash after loading the saved state */5784 s = &pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK]; /* Do not remove or there's an instant crash after loading the saved state */ 5779 5785 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */ 5780 5786 … … 5830 5836 5831 5837 case ATA_AIO_PIO: 5832 s = &pCtl->aIfs[pCtl->iAIOIf ]; /* Do not remove or there's an instant crash after loading the saved state */5838 s = &pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK]; /* Do not remove or there's an instant crash after loading the saved state */ 5833 5839 5834 5840 if (s->iSourceSink != ATAFN_SS_NULL) … … 5932 5938 * any command activity on the other drive otherwise using 5933 5939 * one thread per controller wouldn't work at all. */ 5934 s = &pCtl->aIfs[pReq->u.a.iIf ];5940 s = &pCtl->aIfs[pReq->u.a.iIf & ATA_SELECTED_IF_MASK]; 5935 5941 5936 5942 pCtl->uAsyncIOState = ATA_AIO_NEW; … … 5969 5975 u64TS = RTTimeNanoTS() - u64TS; 5970 5976 uWait = u64TS / 1000; 5977 uintptr_t const iAIOIf = pCtl->iAIOIf & ATA_SELECTED_IF_MASK; 5971 5978 Log(("%s: Ctl#%d: LUN#%d finished I/O transaction in %d microseconds\n", 5972 __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->aIfs[ pCtl->iAIOIf].iLUN, (uint32_t)(uWait)));5979 __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->aIfs[iAIOIf].iLUN, (uint32_t)(uWait))); 5973 5980 /* Mark command as finished. */ 5974 pCtl->aIfs[ pCtl->iAIOIf].u64CmdTS = 0;5981 pCtl->aIfs[iAIOIf].u64CmdTS = 0; 5975 5982 5976 5983 /* … … 5979 5986 * spin up time etc.) so the threshold is different. 5980 5987 */ 5981 if (pCtl->aIfs[ pCtl->iAIOIf].uATARegCommand != ATA_PACKET)5988 if (pCtl->aIfs[iAIOIf].uATARegCommand != ATA_PACKET) 5982 5989 { 5983 5990 if (uWait > 8 * 1000 * 1000) … … 5990 5997 */ 5991 5998 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", 5992 pCtl->aIfs[ pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));5999 pCtl->aIfs[iAIOIf].uATARegCommand, uWait / (1000 * 1000))); 5993 6000 } 5994 6001 } … … 6004 6011 */ 6005 6012 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", 6006 pCtl->aIfs[ pCtl->iAIOIf].abATAPICmd[0], uWait / (1000 * 1000)));6013 pCtl->aIfs[iAIOIf].abATAPICmd[0], uWait / (1000 * 1000))); 6007 6014 } 6008 6015 } … … 6074 6081 /* Do not start DMA transfers if there's a PIO transfer going on, 6075 6082 * or if there is already a transfer started on this controller. */ 6076 if ( !pCtl->aIfs[pCtl->iSelectedIf ].fDMA6083 if ( !pCtl->aIfs[pCtl->iSelectedIf & ATA_SELECTED_IF_MASK].fDMA 6077 6084 || (uOldBmDmaStatus & BM_STATUS_DMAING)) 6078 6085 return; 6079 6086 6080 if (pCtl->aIfs[pCtl->iAIOIf ].uATARegStatus & ATA_STAT_DRQ)6087 if (pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK].uATARegStatus & ATA_STAT_DRQ) 6081 6088 { 6082 6089 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); … … 7098 7105 } 7099 7106 7100 pHlp->pfnSSMGetU8(pSSM, &pThis->aCts[i].iSelectedIf); 7101 pHlp->pfnSSMGetU8(pSSM, &pThis->aCts[i].iAIOIf); 7107 rc = pHlp->pfnSSMGetU8(pSSM, &pThis->aCts[i].iSelectedIf); 7108 AssertRCReturn(rc, rc); 7109 AssertLogRelMsgStmt(pThis->aCts[i].iSelectedIf == (pThis->aCts[i].iSelectedIf & ATA_SELECTED_IF_MASK), 7110 ("iSelectedIf = %d\n", pThis->aCts[i].iSelectedIf), 7111 pThis->aCts[i].iSelectedIf &= ATA_SELECTED_IF_MASK); 7112 rc = pHlp->pfnSSMGetU8(pSSM, &pThis->aCts[i].iAIOIf); 7113 AssertRCReturn(rc, rc); 7114 AssertLogRelMsgStmt(pThis->aCts[i].iAIOIf == (pThis->aCts[i].iAIOIf & ATA_SELECTED_IF_MASK), 7115 ("iAIOIf = %d\n", pThis->aCts[i].iAIOIf), 7116 pThis->aCts[i].iAIOIf &= ATA_SELECTED_IF_MASK); 7102 7117 pHlp->pfnSSMGetU8(pSSM, &pThis->aCts[i].uAsyncIOState); 7103 7118 pHlp->pfnSSMGetBool(pSSM, &pThis->aCts[i].fChainedTransfer);
Note:
See TracChangeset
for help on using the changeset viewer.