Changeset 44696 in vbox
- Timestamp:
- Feb 14, 2013 7:52:24 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r44695 r44696 975 975 * @returns VBox status code. 976 976 * @param pThis Pointer to the LsiLogic device state. 977 * @param uOffset Offset of the register to write. 978 * @param pv Pointer to the value to write 979 * @param cb Number of bytes to write. 980 */ 981 static int lsilogicRegisterWrite(PLSILOGICSCSI pThis, uint32_t uOffset, void const *pv, unsigned cb) 982 { 983 uint32_t u32 = *(uint32_t *)pv; 984 985 LogFlowFunc(("pThis=%#p uOffset=%#x pv=%#p{%.*Rhxs} cb=%u\n", pThis, uOffset, pv, cb, pv, cb)); 986 987 switch (uOffset) 977 * @param offReg Offset of the register to write. 978 * @param u32 The value being written. 979 */ 980 static int lsilogicRegisterWrite(PLSILOGICSCSI pThis, uint32_t offReg, uint32_t u32) 981 { 982 LogFlowFunc(("pThis=%#p offReg=%#x u32=%#x\n", pThis, offReg, u32)); 983 switch (offReg) 988 984 { 989 985 case LSILOGIC_REG_REPLY_QUEUE: … … 1278 1274 default: /* Ignore. */ 1279 1275 { 1276 /** @todo LSILOGIC_REG_DIAG_* should return all F's when accessed by MMIO. We 1277 * return 0. Likely to apply to undefined offsets as well. */ 1280 1278 break; 1281 1279 } … … 1287 1285 } 1288 1286 1289 PDMBOTHCBDECL(int) lsilogicIOPortWrite (PPDMDEVINS pDevIns, void *pvUser, 1290 RTIOPORT Port, uint32_t u32, unsigned cb) 1291 { 1292 PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI); 1293 uint32_t uOffset = Port - pThis->IOPortBase; 1294 1295 Assert(cb <= 4); 1296 1297 int rc = lsilogicRegisterWrite(pThis, uOffset, &u32, cb); 1298 if (rc == VINF_IOM_R3_MMIO_WRITE) 1299 rc = VINF_IOM_R3_IOPORT_WRITE; 1287 /** 1288 * @callback_method_impl{FNIOMIOPORTOUT} 1289 */ 1290 PDMBOTHCBDECL(int) lsilogicIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1291 { 1292 PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI); 1293 uint32_t offReg = Port - pThis->IOPortBase; 1294 int rc; 1295 1296 if (!(offReg & 3)) 1297 { 1298 rc = lsilogicRegisterWrite(pThis, offReg, u32); 1299 if (rc == VINF_IOM_R3_MMIO_WRITE) 1300 rc = VINF_IOM_R3_IOPORT_WRITE; 1301 } 1302 else 1303 { 1304 Log(("lsilogicIOPortWrite: Ignoring misaligned write - offReg=%#x u32=%#x cb=%#x\n", offReg, u32, cb)); 1305 rc = VINF_SUCCESS; 1306 } 1300 1307 1301 1308 return rc; … … 1317 1324 } 1318 1325 1319 PDMBOTHCBDECL(int) lsilogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, 1320 RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 1321 { 1322 PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI); 1323 uint32_t uOffset = GCPhysAddr - pThis->GCPhysMMIOBase; 1324 1325 return lsilogicRegisterWrite(pThis, uOffset, pv, cb); 1326 /** 1327 * @callback_method_impl{FNIOMMMIOWRITE} 1328 */ 1329 PDMBOTHCBDECL(int) lsilogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 1330 { 1331 PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI); 1332 uint32_t offReg = GCPhysAddr - pThis->GCPhysMMIOBase; 1333 uint32_t u32; 1334 int rc; 1335 1336 /* See comments in lsilogicR3Map regarding size and alignment. */ 1337 if (cb == 4) 1338 u32 = *(uint32_t const *)pv; 1339 else 1340 { 1341 if (cb > 4) 1342 u32 = *(uint32_t const *)pv; 1343 else if (cb >= 2) 1344 u32 = *(uint16_t const *)pv; 1345 else 1346 u32 = *(uint8_t const *)pv; 1347 Log(("lsilogicMMIOWrite: Non-DWORD write access - offReg=%#x u32=%#x cb=%#x\n", offReg, u32, cb)); 1348 } 1349 1350 if (!(offReg & 3)) 1351 { 1352 rc = lsilogicRegisterWrite(pThis, offReg, u32); 1353 if (rc == VINF_IOM_R3_MMIO_WRITE) 1354 rc = VINF_IOM_R3_IOPORT_WRITE; 1355 } 1356 else 1357 { 1358 Log(("lsilogicIOPortWrite: Ignoring misaligned write - offReg=%#x u32=%#x cb=%#x\n", offReg, u32, cb)); 1359 rc = VINF_SUCCESS; 1360 } 1361 return rc; 1326 1362 } 1327 1363 … … 3788 3824 pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port)); 3789 3825 3790 uint8_t iRegister = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3791 ? Port - LSILOGIC_BIOS_IO_PORT 3792 : Port - LSILOGIC_SAS_BIOS_IO_PORT; 3793 return vboxscsiReadString(pDevIns, &pThis->VBoxSCSI, iRegister, 3794 pGCPtrDst, pcTransfer, cb); 3795 } 3796 3826 uint8_t iRegister = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3827 ? Port - LSILOGIC_BIOS_IO_PORT 3828 : Port - LSILOGIC_SAS_BIOS_IO_PORT; 3829 return vboxscsiReadString(pDevIns, &pThis->VBoxSCSI, iRegister, pGCPtrDst, pcTransfer, cb); 3830 } 3831 3832 /** 3833 * @callback_method_impl{FNPCIIOREGIONMAP} 3834 */ 3797 3835 static DECLCALLBACK(int) lsilogicR3Map(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, 3798 3836 RTGCPHYS GCPhysAddress, uint32_t cb, … … 3818 3856 { 3819 3857 /* 3820 * Non-4-byte access to LSILOGIC_REG_REPLY_QUEUE may cause real strange 3821 * behavior because the data is part of a physical guest address. But 3822 * some drivers use 1-byte access to scan for SCSI controllers. So, we 3823 * simplify our code by telling IOM to read DWORDs. 3858 * Non-4-byte read access to LSILOGIC_REG_REPLY_QUEUE may cause real strange behavior 3859 * because the data is part of a physical guest address. But some drivers use 1-byte 3860 * access to scan for SCSI controllers. So, we simplify our code by telling IOM to 3861 * read DWORDs. 3862 * 3863 * Regarding writes, we couldn't find anything specific in the specs about what should 3864 * happen. So far we've ignored unaligned writes and assumed the missing bytes of 3865 * byte and word access to be zero. We suspect that IOMMMIO_FLAGS_WRITE_ONLY_DWORD 3866 * or IOMMMIO_FLAGS_WRITE_DWORD_ZEROED would be the most appropriate here, but since we 3867 * don't have real hw to test one, the old behavior is kept exactly like it used to be. 3824 3868 */ 3869 /** @todo Check out unaligned writes and non-dword writes on real LsiLogic 3870 * hardware. */ 3825 3871 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 3826 3872 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_PASSTHRU,
Note:
See TracChangeset
for help on using the changeset viewer.