Changeset 81852 in vbox
- Timestamp:
- Nov 14, 2019 10:11:36 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134646
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r81851 r81852 146 146 #define BM_CMD_WRITE 0x08 147 147 /** @} */ 148 149 /** Number of I/O ports per bus-master DMA controller. */ 150 #define BM_DMA_CTL_IOPORTS 8 151 /** Mask corresponding to BM_DMA_CTL_IOPORTS. */ 152 #define BM_DMA_CTL_IOPORTS_MASK 7 153 /** Shift count corresponding to BM_DMA_CTL_IOPORTS. */ 154 #define BM_DMA_CTL_IOPORTS_SHIFT 3 148 155 149 156 /** @} */ … … 602 609 uint8_t u8Type; 603 610 bool Alignment0[HC_ARCH_BITS == 64 ? 5 : 1 ]; /**< Align the struct size. */ 611 /** PCI region \#4: Bus-master DMA I/O ports. */ 612 IOMIOPORTHANDLE hIoPortsBmDma; 604 613 } PCIATAState; 605 614 … … 628 637 PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 629 638 PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *u32, unsigned cb); 630 PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);631 PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);632 639 RT_C_DECLS_END 633 640 … … 6139 6146 } 6140 6147 6141 #define VAL(port, size) ( ((port) & 7) | ((size) << 3) ) 6148 /** Helper for ataBMDMAIOPortRead and ataBMDMAIOPortWrite. */ 6149 #define VAL(port, size) ( ((port) & BM_DMA_CTL_IOPORTS_MASK) | ((size) << BM_DMA_CTL_IOPORTS_SHIFT) ) 6142 6150 6143 6151 /** 6144 * Port I/O Handler for bus master DMA IN operations. 6145 * @see FNIOMIOPORTIN for details. 6146 */ 6147 PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 6152 * @callback_method_impl{FNIOMIOPORTNEWOUT, 6153 * Port I/O Handler for bus-master DMA IN operations - both controllers.} 6154 */ 6155 static DECLCALLBACK(VBOXSTRICTRC) 6156 ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb) 6148 6157 { 6149 6158 PCIATAState *pThis = PDMDEVINS_2_DATA(pDevIns, PCIATAState *); 6150 PATACONTROLLER pCtl = &pThis->aCts[(uintptr_t)pvUser % RT_ELEMENTS(pThis->aCts)]; 6151 6152 int rc = PDMDevHlpCritSectEnter(pCtl->CTX_SUFF(pDevIns), &pCtl->lock, VINF_IOM_R3_IOPORT_READ); 6153 if (rc != VINF_SUCCESS) 6154 return rc; 6155 switch (VAL(Port, cb)) 6156 { 6157 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break; 6158 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break; 6159 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break; 6160 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break; 6161 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break; 6162 case VAL(0, 4): 6163 /* The SCO OpenServer tries to read 4 bytes starting from offset 0. */ 6164 *pu32 = ataBMDMACmdReadB(pCtl, Port) | (ataBMDMAStatusReadB(pCtl, Port) << 16); 6165 break; 6166 default: 6167 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb)); 6168 rc = VERR_IOM_IOPORT_UNUSED; 6169 break; 6170 } 6171 PDMDevHlpCritSectLeave(pCtl->CTX_SUFF(pDevIns), &pCtl->lock); 6159 PATACONTROLLER pCtl = &pThis->aCts[(offPort >> BM_DMA_CTL_IOPORTS_SHIFT) % RT_ELEMENTS(pThis->aCts)]; 6160 RT_NOREF(pvUser); 6161 6162 VBOXSTRICTRC rc = PDMDevHlpCritSectEnter(pCtl->CTX_SUFF(pDevIns), &pCtl->lock, VINF_IOM_R3_IOPORT_READ); 6163 if (rc == VINF_SUCCESS) 6164 { 6165 switch (VAL(offPort, cb)) 6166 { 6167 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, offPort); break; 6168 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, offPort); break; 6169 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, offPort); break; 6170 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, offPort); break; 6171 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, offPort); break; 6172 case VAL(0, 4): 6173 /* The SCO OpenServer tries to read 4 bytes starting from offset 0. */ 6174 *pu32 = ataBMDMACmdReadB(pCtl, offPort) | (ataBMDMAStatusReadB(pCtl, offPort) << 16); 6175 break; 6176 default: 6177 ASSERT_GUEST_MSG_FAILED(("Unsupported read from port %x size=%d\n", offPort, cb)); 6178 rc = VERR_IOM_IOPORT_UNUSED; 6179 break; 6180 } 6181 PDMDevHlpCritSectLeave(pCtl->CTX_SUFF(pDevIns), &pCtl->lock); 6182 } 6172 6183 return rc; 6173 6184 } 6174 6185 6175 6186 /** 6176 * Port I/O Handler for bus master DMA OUT operations. 6177 * @see FNIOMIOPORTOUT for details. 6178 */ 6179 PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 6187 * @callback_method_impl{FNIOMIOPORTNEWOUT, 6188 * Port I/O Handler for bus-master DMA OUT operations - both controllers.} 6189 */ 6190 static DECLCALLBACK(VBOXSTRICTRC) 6191 ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb) 6180 6192 { 6181 6193 PCIATAState *pThis = PDMDEVINS_2_DATA(pDevIns, PCIATAState *); 6182 PATACONTROLLER pCtl = &pThis->aCts[(uintptr_t)pvUser % RT_ELEMENTS(pThis->aCts)]; 6183 6184 int rc = PDMDevHlpCritSectEnter(pCtl->CTX_SUFF(pDevIns), &pCtl->lock, VINF_IOM_R3_IOPORT_WRITE); 6185 if (rc != VINF_SUCCESS) 6186 return rc; 6187 switch (VAL(Port, cb)) 6188 { 6189 case VAL(0, 1): 6194 PATACONTROLLER pCtl = &pThis->aCts[(offPort >> BM_DMA_CTL_IOPORTS_SHIFT) % RT_ELEMENTS(pThis->aCts)]; 6195 RT_NOREF(pvUser); 6196 6197 VBOXSTRICTRC rc = PDMDevHlpCritSectEnter(pCtl->CTX_SUFF(pDevIns), &pCtl->lock, VINF_IOM_R3_IOPORT_WRITE); 6198 if (rc == VINF_SUCCESS) 6199 { 6200 switch (VAL(offPort, cb)) 6201 { 6202 case VAL(0, 1): 6190 6203 #ifdef IN_RC 6191 if (u32 & BM_CMD_START) 6192 { 6193 rc = VINF_IOM_R3_IOPORT_WRITE; 6204 if (u32 & BM_CMD_START) 6205 { 6206 rc = VINF_IOM_R3_IOPORT_WRITE; 6207 break; 6208 } 6209 #endif 6210 ataBMDMACmdWriteB(pCtl, offPort, u32); 6194 6211 break; 6195 } 6196 #endif 6197 ataBMDMACmdWriteB(pCtl, Port, u32); 6198 break; 6199 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break; 6200 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break; 6201 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break; 6202 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break; 6203 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break; 6204 } 6205 PDMDevHlpCritSectLeave(pCtl->CTX_SUFF(pDevIns), &pCtl->lock); 6212 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, offPort, u32); break; 6213 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, offPort, u32); break; 6214 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, offPort, u32); break; 6215 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, offPort, u32); break; 6216 default: 6217 ASSERT_GUEST_MSG_FAILED(("Unsupported write to port %x size=%d val=%x\n", offPort, cb, u32)); 6218 break; 6219 } 6220 PDMDevHlpCritSectLeave(pCtl->CTX_SUFF(pDevIns), &pCtl->lock); 6221 } 6206 6222 return rc; 6207 6223 } … … 6210 6226 6211 6227 #ifdef IN_RING3 6212 6213 /**6214 * @callback_method_impl{FNPCIIOREGIONMAP}6215 */6216 static DECLCALLBACK(int) ataR3BMDMAIORangeMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,6217 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)6218 {6219 PCIATAState *pThis = PDMDEVINS_2_DATA(pDevIns, PCIATAState *);6220 int rc = VINF_SUCCESS;6221 RT_NOREF(iRegion, cb, enmType, pPciDev);6222 6223 Assert(enmType == PCI_ADDRESS_SPACE_IO);6224 Assert(iRegion == 4);6225 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));6226 Assert(pPciDev == pDevIns->apPciDevs[0]);6227 6228 /* Register the port range. */6229 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)6230 {6231 int rc2 = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,6232 (RTHCPTR)(uintptr_t)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead,6233 NULL, NULL, "ATA Bus Master DMA");6234 AssertRC(rc2);6235 if (rc2 < rc)6236 rc = rc2;6237 6238 if (pThis->fRCEnabled)6239 {6240 rc2 = PDMDevHlpIOPortRegisterRC(pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,6241 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead",6242 NULL, NULL, "ATA Bus Master DMA");6243 AssertRC(rc2);6244 if (rc2 < rc)6245 rc = rc2;6246 }6247 if (pThis->fR0Enabled)6248 {6249 rc2 = PDMDevHlpIOPortRegisterR0(pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,6250 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead",6251 NULL, NULL, "ATA Bus Master DMA");6252 AssertRC(rc2);6253 if (rc2 < rc)6254 rc = rc2;6255 }6256 }6257 return rc;6258 }6259 6260 6228 6261 6229 /* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */ … … 7649 7617 7650 7618 PDMPciDevSetCommand( pPciDev, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER); 7651 PDMPciDevSetClassProg( pPciDev, 0x8a); /* programming interface = PCI_IDE bus 7619 PDMPciDevSetClassProg( pPciDev, 0x8a); /* programming interface = PCI_IDE bus-master is supported */ 7652 7620 PDMPciDevSetClassSub( pPciDev, 0x01); /* class_sub = PCI_IDE */ 7653 7621 PDMPciDevSetClassBase( pPciDev, 0x01); /* class_base = PCI_mass_storage */ … … 7702 7670 if (RT_FAILURE(rc)) 7703 7671 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register PCI device")); 7704 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataR3BMDMAIORangeMap); 7705 if (RT_FAILURE(rc)) 7706 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register PCI I/O region for BMDMA")); 7672 7673 /* Region #4: I/O ports for the two bus-master DMA controllers. */ 7674 rc = PDMDevHlpPCIIORegionCreateIo(pDevIns, 4 /*iPciRegion*/, 0x10 /*cPorts*/, 7675 ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL /*pvUser*/, "ATA Bus Master DMA", 7676 NULL /*paExtDescs*/, &pThis->hIoPortsBmDma); 7677 AssertRCReturn(rc, rc); 7707 7678 7708 7679 /* … … 8070 8041 } 8071 8042 8072 #endif /* IN_RING3 */ 8043 #else /* !IN_RING3 */ 8044 8045 /** 8046 * @callback_method_impl{PDMDEVREGR0,pfnConstruct} 8047 */ 8048 static DECLCALLBACK(int) ataRZConstruct(PPDMDEVINS pDevIns) 8049 { 8050 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 8051 PCIATAState *pThis = PDMDEVINS_2_DATA(pDevIns, PCIATAState *); 8052 8053 int rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->hIoPortsBmDma, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL /*pvUser*/); 8054 AssertRCReturn(rc, rc); 8055 8056 return VINF_SUCCESS; 8057 } 8058 8059 8060 #endif /* !IN_RING3 */ 8073 8061 8074 8062 /** … … 8124 8112 #elif defined(IN_RING0) 8125 8113 /* .pfnEarlyConstruct = */ NULL, 8126 /* .pfnConstruct = */ NULL,8114 /* .pfnConstruct = */ ataRZConstruct, 8127 8115 /* .pfnDestruct = */ NULL, 8128 8116 /* .pfnFinalDestruct = */ NULL, … … 8137 8125 /* .pfnReserved7 = */ NULL, 8138 8126 #elif defined(IN_RC) 8139 /* .pfnConstruct = */ NULL,8127 /* .pfnConstruct = */ ataRZConstruct, 8140 8128 /* .pfnReserved0 = */ NULL, 8141 8129 /* .pfnReserved1 = */ NULL,
Note:
See TracChangeset
for help on using the changeset viewer.