Changeset 81773 in vbox for trunk/src/VBox
- Timestamp:
- Nov 11, 2019 6:05:17 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r81765 r81773 26 26 #include <VBox/vmm/pdmthread.h> 27 27 #include <VBox/vmm/pdmcritsect.h> 28 #include <VBox/AssertGuest.h> 28 29 #include <VBox/scsi.h> 29 30 #include <VBox/sup.h> … … 248 249 /** The fault code of the I/O controller if we are in the fault state. */ 249 250 uint16_t u16IOCFaultCode; 250 251 /** I/O port address the device is mapped to. */ 252 RTIOPORT IOPortBase; 251 uint16_t u16Padding0b; 252 253 253 /** MMIO address the device is mapped to. */ 254 254 RTGCPHYS GCPhysMMIOBase; … … 367 367 SUPSEMEVENT hEvtProcess; 368 368 369 /** PCI Region \#0: I/O ports register access. */ 370 IOMIOPORTHANDLE hIoPortsReg; 371 /** PCI Region \#1: MMIO register access. */ 372 IOMMMIOHANDLE hMmioReg; 373 /** PCI Region \#2: MMIO diag. */ 374 IOMMMIOHANDLE hMmioDiag; 375 /** ISA Ports for the BIOS (when booting is configured). */ 376 IOMIOPORTHANDLE hIoPortsBios; 369 377 } LSILOGISCSI; 370 378 … … 1243 1251 * Writes a value to a register at a given offset. 1244 1252 * 1245 * @returns VBox status code. 1253 * @returns Strict VBox status code. 1254 * @param pDevIns The devie instance. 1246 1255 * @param pThis Pointer to the LsiLogic device state. 1247 1256 * @param offReg Offset of the register to write. 1248 1257 * @param u32 The value being written. 1249 1258 */ 1250 static int lsilogicRegisterWrite(PLSILOGICSCSI pThis, uint32_t offReg, uint32_t u32)1259 static VBOXSTRICTRC lsilogicRegisterWrite(PPDMDEVINS pDevIns, PLSILOGICSCSI pThis, uint32_t offReg, uint32_t u32) 1251 1260 { 1252 1261 LogFlowFunc(("pThis=%#p offReg=%#x u32=%#x\n", pThis, offReg, u32)); … … 1255 1264 case LSILOGIC_REG_REPLY_QUEUE: 1256 1265 { 1257 int rc = PDMDevHlpCritSectEnter(p This->CTX_SUFF(pDevIns), &pThis->ReplyFreeQueueWriteCritSect, VINF_IOM_R3_MMIO_WRITE);1266 int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->ReplyFreeQueueWriteCritSect, VINF_IOM_R3_MMIO_WRITE); 1258 1267 if (rc != VINF_SUCCESS) 1259 1268 return rc; … … 1262 1271 pThis->uReplyFreeQueueNextEntryFreeWrite++; 1263 1272 pThis->uReplyFreeQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries; 1264 PDMDevHlpCritSectLeave(p This->CTX_SUFF(pDevIns), &pThis->ReplyFreeQueueWriteCritSect);1273 PDMDevHlpCritSectLeave(pDevIns, &pThis->ReplyFreeQueueWriteCritSect); 1265 1274 break; 1266 1275 } 1267 1276 case LSILOGIC_REG_REQUEST_QUEUE: 1268 1277 { 1269 int rc = PDMDevHlpCritSectEnter(p This->CTX_SUFF(pDevIns), &pThis->RequestQueueCritSect, VINF_IOM_R3_MMIO_WRITE);1278 int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->RequestQueueCritSect, VINF_IOM_R3_MMIO_WRITE); 1270 1279 if (rc != VINF_SUCCESS) 1271 1280 return rc; … … 1284 1293 uNextWrite %= pThis->cRequestQueueEntries; 1285 1294 ASMAtomicWriteU32(&pThis->uRequestQueueNextEntryFreeWrite, uNextWrite); 1286 PDMDevHlpCritSectLeave(p This->CTX_SUFF(pDevIns), &pThis->RequestQueueCritSect);1295 PDMDevHlpCritSectLeave(pDevIns, &pThis->RequestQueueCritSect); 1287 1296 1288 1297 /* Send notification to R3 if there is not one sent already. Do this … … 1293 1302 { 1294 1303 LogFlowFunc(("Signal event semaphore\n")); 1295 rc = PDMDevHlpSUPSemEventSignal(p This->CTX_SUFF(pDevIns), pThis->hEvtProcess);1304 rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtProcess); 1296 1305 AssertRC(rc); 1297 1306 } … … 1514 1523 * 1515 1524 * @returns VBox status code. 1525 * @param pDevIns The device instance. 1516 1526 * @param pThis Pointer to the LsiLogic device state. 1517 1527 * @param offReg Offset of the register to read. 1518 1528 * @param pu32 Where to store the content of the register. 1519 1529 */ 1520 static int lsilogicRegisterRead(PLSILOGICSCSI pThis, uint32_t offReg, uint32_t *pu32)1530 static VBOXSTRICTRC lsilogicRegisterRead(PPDMDEVINS pDevIns, PLSILOGICSCSI pThis, uint32_t offReg, uint32_t *pu32) 1521 1531 { 1522 1532 int rc = VINF_SUCCESS; … … 1529 1539 case LSILOGIC_REG_REPLY_QUEUE: 1530 1540 { 1531 rc = PDMDevHlpCritSectEnter(p This->CTX_SUFF(pDevIns), &pThis->ReplyPostQueueCritSect, VINF_IOM_R3_MMIO_READ);1541 rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->ReplyPostQueueCritSect, VINF_IOM_R3_MMIO_READ); 1532 1542 if (rc != VINF_SUCCESS) 1533 1543 break; … … 1549 1559 lsilogicClearInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_REPLY_INTR); 1550 1560 } 1551 PDMDevHlpCritSectLeave(p This->CTX_SUFF(pDevIns), &pThis->ReplyPostQueueCritSect);1561 PDMDevHlpCritSectLeave(pDevIns, &pThis->ReplyPostQueueCritSect); 1552 1562 1553 1563 Log(("%s: Returning address %#x\n", __FUNCTION__, u32)); … … 1672 1682 1673 1683 /** 1674 * @callback_method_impl{FNIOMIOPORTOUT} 1675 */ 1676 PDMBOTHCBDECL(int) lsilogicIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb) 1684 * @callback_method_impl{FNIOMIOPORTNEWOUT} 1685 */ 1686 static DECLCALLBACK(VBOXSTRICTRC) 1687 lsilogicIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb) 1677 1688 { 1678 1689 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 1679 uint32_t offReg = uPort - pThis->IOPortBase; 1680 int rc; 1690 VBOXSTRICTRC rcStrict; 1681 1691 RT_NOREF2(pvUser, cb); 1682 1692 1683 if (!(off Reg& 3))1684 { 1685 rc = lsilogicRegisterWrite(pThis, offReg, u32);1686 if (rc == VINF_IOM_R3_MMIO_WRITE)1687 rc = VINF_IOM_R3_IOPORT_WRITE;1693 if (!(offPort & 3)) 1694 { 1695 rcStrict = lsilogicRegisterWrite(pDevIns, pThis, offPort, u32); 1696 if (rcStrict == VINF_IOM_R3_MMIO_WRITE) 1697 rcStrict = VINF_IOM_R3_IOPORT_WRITE; 1688 1698 } 1689 1699 else 1690 1700 { 1691 Log(("lsilogicIOPortWrite: Ignoring misaligned write - offReg=%#x u32=%#x cb=%#x\n", offReg, u32, cb)); 1692 rc = VINF_SUCCESS; 1693 } 1694 1695 return rc; 1696 } 1697 1698 /** 1699 * @callback_method_impl{FNIOMIOPORTIN} 1700 */ 1701 PDMBOTHCBDECL(int) lsilogicIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb) 1701 Log(("lsilogicIOPortWrite: Ignoring misaligned write - offPort=%#x u32=%#x cb=%#x\n", offPort, u32, cb)); 1702 rcStrict = VINF_SUCCESS; 1703 } 1704 1705 return rcStrict; 1706 } 1707 1708 /** 1709 * @callback_method_impl{FNIOMIOPORTNEWIN} 1710 */ 1711 static DECLCALLBACK(VBOXSTRICTRC) 1712 lsilogicIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb) 1702 1713 { 1703 1714 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 1704 uint32_t offReg = uPort - pThis->IOPortBase;1705 1715 RT_NOREF_PV(pvUser); 1706 1716 RT_NOREF_PV(cb); 1707 1717 1708 int rc = lsilogicRegisterRead(pThis, offReg& ~(uint32_t)3, pu32);1709 if (rc == VINF_IOM_R3_MMIO_READ)1710 rc = VINF_IOM_R3_IOPORT_READ;1711 1712 return rc ;1713 } 1714 1715 /** 1716 * @callback_method_impl{FNIOMMMIO WRITE}1717 */ 1718 PDMBOTHCBDECL(int) lsilogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)1718 VBOXSTRICTRC rcStrict = lsilogicRegisterRead(pDevIns, pThis, offPort & ~(uint32_t)3, pu32); 1719 if (rcStrict == VINF_IOM_R3_MMIO_READ) 1720 rcStrict = VINF_IOM_R3_IOPORT_READ; 1721 1722 return rcStrict; 1723 } 1724 1725 /** 1726 * @callback_method_impl{FNIOMMMIONEWWRITE} 1727 */ 1728 static DECLCALLBACK(VBOXSTRICTRC) lsilogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb) 1719 1729 { 1720 1730 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 1721 uint32_t offReg = GCPhysAddr - pThis->GCPhysMMIOBase;1722 1731 uint32_t u32; 1723 int rc;1724 1732 RT_NOREF_PV(pvUser); 1725 1733 1726 /* See comments in lsilogicR3 Mapregarding size and alignment. */1734 /* See comments in lsilogicR3Construct regarding size and alignment. */ 1727 1735 if (cb == 4) 1728 1736 u32 = *(uint32_t const *)pv; … … 1735 1743 else 1736 1744 u32 = *(uint8_t const *)pv; 1737 Log(("lsilogicMMIOWrite: Non-DWORD write access - offReg=%#x u32=%#x cb=%#x\n", offReg, u32, cb)); 1738 } 1739 1740 if (!(offReg & 3)) 1741 rc = lsilogicRegisterWrite(pThis, offReg, u32); 1745 Log(("lsilogicMMIOWrite: Non-DWORD write access - off=%#RGp u32=%#x cb=%#x\n", off, u32, cb)); 1746 } 1747 1748 VBOXSTRICTRC rcStrict; 1749 if (!(off & 3)) 1750 rcStrict = lsilogicRegisterWrite(pDevIns, pThis, (uint32_t)off, u32); 1742 1751 else 1743 1752 { 1744 Log(("lsilogic IOPortWrite: Ignoring misaligned write - offReg=%#x u32=%#x cb=%#x\n", offReg, u32, cb));1745 rc = VINF_SUCCESS;1746 } 1747 return rc ;1748 } 1749 1750 /** 1751 * @callback_method_impl{FNIOMMMIO READ}1752 */ 1753 PDMBOTHCBDECL(int) lsilogicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)1753 Log(("lsilogicMMIOWrite: Ignoring misaligned write - off=%#RGp u32=%#x cb=%#x\n", off, u32, cb)); 1754 rcStrict = VINF_SUCCESS; 1755 } 1756 return rcStrict; 1757 } 1758 1759 /** 1760 * @callback_method_impl{FNIOMMMIONEWREAD} 1761 */ 1762 static DECLCALLBACK(VBOXSTRICTRC) lsilogicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb) 1754 1763 { 1755 1764 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 1756 uint32_t offReg = GCPhysAddr - pThis->GCPhysMMIOBase; 1757 Assert(!(offReg & 3)); Assert(cb == 4); 1765 Assert(!(off & 3)); Assert(cb == 4); /* If any of these trigger you've changed the registration flags or IOM is busted. */ 1758 1766 RT_NOREF2(pvUser, cb); 1759 1767 1760 return lsilogicRegisterRead(pThis, offReg, (uint32_t *)pv); 1761 } 1762 1763 PDMBOTHCBDECL(int) lsilogicDiagnosticWrite(PPDMDEVINS pDevIns, void *pvUser, 1764 RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 1765 { 1766 #ifdef LOG_ENABLED 1767 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 1768 LogFlowFunc(("pThis=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pThis, GCPhysAddr, pv, cb, pv, cb)); 1769 #endif 1770 1771 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb); 1768 return lsilogicRegisterRead(pDevIns, pThis, off, (uint32_t *)pv); 1769 } 1770 1771 /** 1772 * @callback_method_impl{FNIOMMMIONEWWRITE} 1773 */ 1774 static DECLCALLBACK(VBOXSTRICTRC) 1775 lsilogicDiagnosticWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb) 1776 { 1777 RT_NOREF(pDevIns, pvUser, off, pv, cb); 1778 LogFlowFunc(("pThis=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI), off, pv, cb, pv, cb)); 1772 1779 return VINF_SUCCESS; 1773 1780 } 1774 1781 1775 PDMBOTHCBDECL(int) lsilogicDiagnosticRead(PPDMDEVINS pDevIns, void *pvUser, 1776 RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 1777 { 1778 #ifdef LOG_ENABLED 1779 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 1780 LogFlowFunc(("pThis=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pThis, GCPhysAddr, pv, cb, pv, cb)); 1781 #endif 1782 1783 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb); 1782 /** 1783 * @callback_method_impl{FNIOMMMIONEWREAD} 1784 */ 1785 static DECLCALLBACK(VBOXSTRICTRC) lsilogicDiagnosticRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb) 1786 { 1787 RT_NOREF(pDevIns, pvUser, off, pv, cb); 1788 LogFlowFunc(("pThis=%#p off=%RGp pv=%#p{%.*Rhxs} cb=%u\n", PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI), off, pv, cb, pv, cb)); 1784 1789 return VINF_SUCCESS; 1785 1790 } … … 3801 3806 * @callback_method_impl{FNIOMIOPORTIN, Legacy ISA port.} 3802 3807 */ 3803 static DECLCALLBACK(int) lsilogicR3IsaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 3808 static DECLCALLBACK(VBOXSTRICTRC) 3809 lsilogicR3IsaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb) 3804 3810 { 3805 3811 RT_NOREF(pvUser, cb); 3806 3812 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 3807 3813 3808 Assert(cb == 1); 3809 3810 uint8_t iRegister = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3811 ? Port - LSILOGIC_BIOS_IO_PORT 3812 : Port - LSILOGIC_SAS_BIOS_IO_PORT; 3813 int rc = vboxscsiReadRegister(&pThis->VBoxSCSI, iRegister, pu32); 3814 3815 Log2(("%s: pu32=%p:{%.*Rhxs} iRegister=%d rc=%Rrc\n", 3816 __FUNCTION__, pu32, 1, pu32, iRegister, rc)); 3814 ASSERT_GUEST(cb == 1); 3815 3816 int rc = vboxscsiReadRegister(&pThis->VBoxSCSI, offPort, pu32); 3817 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register read status: %Rrc\n", rc)); 3818 3819 Log2(("%s: pu32=%p:{%.*Rhxs} offPort=%d rc=%Rrc\n", __FUNCTION__, pu32, 1, pu32, offPort, rc)); 3817 3820 3818 3821 return rc; … … 3888 3891 3889 3892 /** 3890 * @callback_method_impl{FNIOMIOPORTOUT, Legacy ISA port.} 3891 */ 3892 static DECLCALLBACK(int) lsilogicR3IsaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 3893 * @callback_method_impl{FNIOMIOPORTNEWOUT, Legacy ISA port.} 3894 */ 3895 static DECLCALLBACK(VBOXSTRICTRC) 3896 lsilogicR3IsaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb) 3893 3897 { 3894 3898 RT_NOREF(pvUser, cb); 3895 3899 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 3896 Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x Port=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32,Port));3897 3898 A ssert(cb == 1);3900 Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x offPort=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, offPort)); 3901 3902 ASSERT_GUEST(cb == 1); 3899 3903 3900 3904 /* … … 3905 3909 return VINF_SUCCESS; 3906 3910 3907 uint8_t iRegister = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3908 ? Port - LSILOGIC_BIOS_IO_PORT 3909 : Port - LSILOGIC_SAS_BIOS_IO_PORT; 3910 int rc = vboxscsiWriteRegister(&pThis->VBoxSCSI, iRegister, (uint8_t)u32); 3911 int rc = vboxscsiWriteRegister(&pThis->VBoxSCSI, offPort, (uint8_t)u32); 3912 if (rc == VERR_MORE_DATA) 3913 { 3914 ASMAtomicXchgBool(&pThis->fBiosReqPending, true); 3915 /* Notify the worker thread that there are pending requests. */ 3916 LogFlowFunc(("Signal event semaphore\n")); 3917 rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtProcess); 3918 AssertRC(rc); 3919 } 3920 else 3921 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register write status: %Rrc\n", rc)); 3922 3923 return VINF_SUCCESS; 3924 } 3925 3926 /** 3927 * @callback_method_impl{FNIOMIOPORTNEWOUTSTRING, 3928 * Port I/O Handler for primary port range OUT string operations.} 3929 */ 3930 static DECLCALLBACK(VBOXSTRICTRC) lsilogicR3IsaIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, 3931 uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb) 3932 { 3933 RT_NOREF(pvUser); 3934 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 3935 Log2(("#%d %s: pvUser=%#p cb=%d offPort=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, offPort)); 3936 3937 int rc = vboxscsiWriteString(pDevIns, &pThis->VBoxSCSI, offPort, pbSrc, pcTransfers, cb); 3911 3938 if (rc == VERR_MORE_DATA) 3912 3939 { … … 3917 3944 AssertRC(rc); 3918 3945 } 3919 else if (RT_FAILURE(rc))3920 AssertMsg Failed(("Writing BIOS register failed%Rrc\n", rc));3946 else 3947 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register write status: %Rrc\n", rc)); 3921 3948 3922 3949 return VINF_SUCCESS; … … 3924 3951 3925 3952 /** 3926 * @callback_method_impl{FNIOMIOPORT OUTSTRING,3927 * Port I/O Handler for primary port range OUTstring operations.}3928 */ 3929 static DECLCALLBACK( int) lsilogicR3IsaIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORTPort,3930 uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)3953 * @callback_method_impl{FNIOMIOPORTINSTRING, 3954 * Port I/O Handler for primary port range IN string operations.} 3955 */ 3956 static DECLCALLBACK(VBOXSTRICTRC) lsilogicR3IsaIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, 3957 uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb) 3931 3958 { 3932 3959 RT_NOREF(pvUser); 3933 3960 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 3934 Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port)); 3935 3936 uint8_t iRegister = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3937 ? Port - LSILOGIC_BIOS_IO_PORT 3938 : Port - LSILOGIC_SAS_BIOS_IO_PORT; 3939 int rc = vboxscsiWriteString(pDevIns, &pThis->VBoxSCSI, iRegister, pbSrc, pcTransfers, cb); 3940 if (rc == VERR_MORE_DATA) 3941 { 3942 ASMAtomicXchgBool(&pThis->fBiosReqPending, true); 3943 /* Notify the worker thread that there are pending requests. */ 3944 LogFlowFunc(("Signal event semaphore\n")); 3945 rc = PDMDevHlpSUPSemEventSignal(pThis->CTX_SUFF(pDevIns), pThis->hEvtProcess); 3946 AssertRC(rc); 3947 } 3948 else if (RT_FAILURE(rc)) 3949 AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc)); 3950 3951 return VINF_SUCCESS; 3952 } 3953 3954 /** 3955 * @callback_method_impl{FNIOMIOPORTINSTRING, 3956 * Port I/O Handler for primary port range IN string operations.} 3957 */ 3958 static DECLCALLBACK(int) lsilogicR3IsaIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, 3959 uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb) 3960 { 3961 RT_NOREF(pvUser); 3962 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 3963 LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port)); 3964 3965 uint8_t iRegister = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3966 ? Port - LSILOGIC_BIOS_IO_PORT 3967 : Port - LSILOGIC_SAS_BIOS_IO_PORT; 3968 return vboxscsiReadString(pDevIns, &pThis->VBoxSCSI, iRegister, pbDst, pcTransfers, cb); 3969 } 3970 3971 /** 3972 * @callback_method_impl{FNPCIIOREGIONMAP} 3973 */ 3974 static DECLCALLBACK(int) lsilogicR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, 3975 RTGCPHYS GCPhysAddress, RTGCPHYS cb, 3976 PCIADDRESSSPACE enmType) 3977 { 3978 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 3979 int rc = VINF_SUCCESS; 3980 const char *pcszCtrl = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3981 ? "LsiLogic" 3982 : "LsiLogicSas"; 3983 const char *pcszDiag = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI 3984 ? "LsiLogicDiag" 3985 : "LsiLogicSasDiag"; 3986 RT_NOREF(pPciDev); 3987 3988 Log2(("%s: registering area at GCPhysAddr=%RGp cb=%RGp\n", __FUNCTION__, GCPhysAddress, cb)); 3989 3990 AssertMsg( (enmType == PCI_ADDRESS_SPACE_MEM && cb >= LSILOGIC_PCI_SPACE_MEM_SIZE) 3991 || (enmType == PCI_ADDRESS_SPACE_IO && cb >= LSILOGIC_PCI_SPACE_IO_SIZE), 3992 ("PCI region type and size do not match\n")); 3993 Assert(pPciDev == pDevIns->apPciDevs[0]); 3994 3995 if (enmType == PCI_ADDRESS_SPACE_MEM && iRegion == 1) 3996 { 3997 /* 3998 * Non-4-byte read access to LSILOGIC_REG_REPLY_QUEUE may cause real strange behavior 3999 * because the data is part of a physical guest address. But some drivers use 1-byte 4000 * access to scan for SCSI controllers. So, we simplify our code by telling IOM to 4001 * read DWORDs. 4002 * 4003 * Regarding writes, we couldn't find anything specific in the specs about what should 4004 * happen. So far we've ignored unaligned writes and assumed the missing bytes of 4005 * byte and word access to be zero. We suspect that IOMMMIO_FLAGS_WRITE_ONLY_DWORD 4006 * or IOMMMIO_FLAGS_WRITE_DWORD_ZEROED would be the most appropriate here, but since we 4007 * don't have real hw to test one, the old behavior is kept exactly like it used to be. 4008 */ 4009 /** @todo Check out unaligned writes and non-dword writes on real LsiLogic 4010 * hardware. */ 4011 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 4012 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_PASSTHRU, 4013 lsilogicMMIOWrite, lsilogicMMIORead, pcszCtrl); 4014 if (RT_FAILURE(rc)) 4015 return rc; 4016 4017 if (pThis->fR0Enabled) 4018 { 4019 rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/, 4020 "lsilogicMMIOWrite", "lsilogicMMIORead"); 4021 if (RT_FAILURE(rc)) 4022 return rc; 4023 } 4024 4025 if (pThis->fGCEnabled) 4026 { 4027 rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/, 4028 "lsilogicMMIOWrite", "lsilogicMMIORead"); 4029 if (RT_FAILURE(rc)) 4030 return rc; 4031 } 4032 4033 pThis->GCPhysMMIOBase = GCPhysAddress; 4034 } 4035 else if (enmType == PCI_ADDRESS_SPACE_MEM && iRegion == 2) 4036 { 4037 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 4038 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 4039 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, 4040 lsilogicDiagnosticWrite, lsilogicDiagnosticRead, pcszDiag); 4041 if (RT_FAILURE(rc)) 4042 return rc; 4043 4044 if (pThis->fR0Enabled) 4045 { 4046 rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/, 4047 "lsilogicDiagnosticWrite", "lsilogicDiagnosticRead"); 4048 if (RT_FAILURE(rc)) 4049 return rc; 4050 } 4051 4052 if (pThis->fGCEnabled) 4053 { 4054 rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/, 4055 "lsilogicDiagnosticWrite", "lsilogicDiagnosticRead"); 4056 if (RT_FAILURE(rc)) 4057 return rc; 4058 } 4059 } 4060 else if (enmType == PCI_ADDRESS_SPACE_IO) 4061 { 4062 rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress, LSILOGIC_PCI_SPACE_IO_SIZE, 4063 NULL, lsilogicIOPortWrite, lsilogicIOPortRead, NULL, NULL, pcszCtrl); 4064 if (RT_FAILURE(rc)) 4065 return rc; 4066 4067 if (pThis->fR0Enabled) 4068 { 4069 rc = PDMDevHlpIOPortRegisterR0(pDevIns, (RTIOPORT)GCPhysAddress, LSILOGIC_PCI_SPACE_IO_SIZE, 4070 0, "lsilogicIOPortWrite", "lsilogicIOPortRead", NULL, NULL, pcszCtrl); 4071 if (RT_FAILURE(rc)) 4072 return rc; 4073 } 4074 4075 if (pThis->fGCEnabled) 4076 { 4077 rc = PDMDevHlpIOPortRegisterRC(pDevIns, (RTIOPORT)GCPhysAddress, LSILOGIC_PCI_SPACE_IO_SIZE, 4078 0, "lsilogicIOPortWrite", "lsilogicIOPortRead", NULL, NULL, pcszCtrl); 4079 if (RT_FAILURE(rc)) 4080 return rc; 4081 } 4082 4083 pThis->IOPortBase = (RTIOPORT)GCPhysAddress; 4084 } 4085 else 4086 AssertMsgFailed(("Invalid enmType=%d iRegion=%d\n", enmType, iRegion)); 4087 3961 LogFlowFunc(("#%d %s: pvUser=%#p cb=%d offPort=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, offPort)); 3962 3963 int rc = vboxscsiReadString(pDevIns, &pThis->VBoxSCSI, offPort, pbDst, pcTransfers, cb); 3964 AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register read status: %Rrc\n", rc)); 4088 3965 return rc; 4089 3966 } … … 4107 3984 */ 4108 3985 pHlp->pfnPrintf(pHlp, 4109 "%s#%d: port=% RTiopmmio=%RGp max-devices=%u GC=%RTbool R0=%RTbool\n",3986 "%s#%d: port=%04x mmio=%RGp max-devices=%u GC=%RTbool R0=%RTbool\n", 4110 3987 pDevIns->pReg->szName, 4111 3988 pDevIns->iInstance, 4112 pThis->IOPortBase, pThis->GCPhysMMIOBase, 3989 PDMDevHlpIoPortGetMappingAddress(pDevIns, pThis->hIoPortsReg), 3990 PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmioReg), 4113 3991 pThis->cDeviceStates, 4114 3992 pThis->fGCEnabled ? true : false, … … 5261 5139 pThis->fBiosReqPending = false; 5262 5140 RTListInit(&pThis->ListMemRegns); 5141 pThis->hMmioReg = NIL_IOMMMIOHANDLE; 5142 pThis->hMmioDiag = NIL_IOMMMIOHANDLE; 5143 pThis->hIoPortsReg = NIL_IOMIOPORTHANDLE; 5144 pThis->hIoPortsBios = NIL_IOMIOPORTHANDLE; 5263 5145 5264 5146 /* … … 5426 5308 # endif 5427 5309 5428 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, LSILOGIC_PCI_SPACE_IO_SIZE, PCI_ADDRESS_SPACE_IO, lsilogicR3Map); 5429 if (RT_FAILURE(rc)) 5430 return rc; 5431 5432 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1, LSILOGIC_PCI_SPACE_MEM_SIZE, PCI_ADDRESS_SPACE_MEM, lsilogicR3Map); 5433 if (RT_FAILURE(rc)) 5434 return rc; 5435 5436 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, LSILOGIC_PCI_SPACE_MEM_SIZE, PCI_ADDRESS_SPACE_MEM, lsilogicR3Map); 5437 if (RT_FAILURE(rc)) 5438 return rc; 5310 /* Region #0: I/O ports. */ 5311 rc = PDMDevHlpPCIIORegionCreateIo(pDevIns, 0 /*iPciRegion*/, LSILOGIC_PCI_SPACE_IO_SIZE, 5312 lsilogicIOPortWrite, lsilogicIOPortRead, NULL /*pvUser*/, 5313 pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI ? "LsiLogic" : "LsiLogicSas", 5314 NULL /*paExtDesc*/, &pThis->hIoPortsReg); 5315 AssertRCReturn(rc, rc); 5316 5317 /* Region #1: MMIO. 5318 * 5319 * Non-4-byte read access to LSILOGIC_REG_REPLY_QUEUE may cause real strange behavior 5320 * because the data is part of a physical guest address. But some drivers use 1-byte 5321 * access to scan for SCSI controllers. So, we simplify our code by telling IOM to 5322 * read DWORDs. 5323 * 5324 * Regarding writes, we couldn't find anything specific in the specs about what should 5325 * happen. So far we've ignored unaligned writes and assumed the missing bytes of 5326 * byte and word access to be zero. We suspect that IOMMMIO_FLAGS_WRITE_ONLY_DWORD 5327 * or IOMMMIO_FLAGS_WRITE_DWORD_ZEROED would be the most appropriate here, but since we 5328 * don't have real hw to test one, the old behavior is kept exactly like it used to be. 5329 */ 5330 /** @todo Check out unaligned writes and non-dword writes on real LsiLogic 5331 * hardware. */ 5332 rc = PDMDevHlpPCIIORegionCreateMmio(pDevIns, 1 /*iPciRegion*/, LSILOGIC_PCI_SPACE_MEM_SIZE, PCI_ADDRESS_SPACE_MEM, 5333 lsilogicMMIOWrite, lsilogicMMIORead, NULL /*pvUser*/, 5334 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_PASSTHRU, 5335 pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI ? "LsiLogic" : "LsiLogicSas", 5336 &pThis->hMmioReg); 5337 AssertRCReturn(rc, rc); 5338 5339 /* Region #2: MMIO - Diag. */ 5340 rc = PDMDevHlpPCIIORegionCreateMmio(pDevIns, 2 /*iPciRegion*/, LSILOGIC_PCI_SPACE_MEM_SIZE, PCI_ADDRESS_SPACE_MEM, 5341 lsilogicDiagnosticWrite, lsilogicDiagnosticRead, NULL /*pvUser*/, 5342 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, 5343 pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI ? "LsiLogicDiag" : "LsiLogicSasDiag", 5344 &pThis->hMmioDiag); 5345 AssertRCReturn(rc, rc); 5439 5346 5440 5347 /* … … 5547 5454 pThis->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIANOTIFY); 5548 5455 } 5549 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER) 5550 { 5551 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc)); 5552 return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot attach to status driver")); 5553 } 5456 else 5457 AssertMsgReturn(rc == VERR_PDM_NO_ATTACHED_DRIVER, 5458 ("Failed to attach to status driver. rc=%Rrc\n", rc), 5459 PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot attach to status driver"))); 5554 5460 5555 5461 /* Initialize the SCSI emulation for the BIOS. */ … … 5564 5470 { 5565 5471 if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI) 5566 rc = PDMDevHlpI OPortRegister(pDevIns, LSILOGIC_BIOS_IO_PORT, 4, NULL,5567 lsilogicR3IsaIOPortWrite, lsilogicR3IsaIOPortRead,5568 lsilogicR3IsaIOPortWriteStr, lsilogicR3IsaIOPortReadStr,5569 "LsiLogic BIOS");5472 rc = PDMDevHlpIoPortCreateExAndMap(pDevIns, LSILOGIC_BIOS_IO_PORT, 4, 5473 lsilogicR3IsaIOPortWrite, lsilogicR3IsaIOPortRead, 5474 lsilogicR3IsaIOPortWriteStr, lsilogicR3IsaIOPortReadStr, NULL /*pvUser*/, 5475 "LsiLogic BIOS", NULL /*paExtDesc*/, &pThis->hIoPortsBios); 5570 5476 else if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SAS) 5571 rc = PDMDevHlpI OPortRegister(pDevIns, LSILOGIC_SAS_BIOS_IO_PORT, 4, NULL,5572 lsilogicR3IsaIOPortWrite, lsilogicR3IsaIOPortRead,5573 lsilogicR3IsaIOPortWriteStr, lsilogicR3IsaIOPortReadStr,5574 "LsiLogic SAS BIOS");5477 rc = PDMDevHlpIoPortCreateExAndMap(pDevIns, LSILOGIC_SAS_BIOS_IO_PORT, 4, 5478 lsilogicR3IsaIOPortWrite, lsilogicR3IsaIOPortRead, 5479 lsilogicR3IsaIOPortWriteStr, lsilogicR3IsaIOPortReadStr, NULL /*pvUser*/, 5480 "LsiLogic SAS BIOS", NULL /*paExtDesc*/, &pThis->hIoPortsBios); 5575 5481 else 5576 AssertMsgFailed(("Invalid controller type %d\n", pThis->enmCtrlType)); 5577 5578 if (RT_FAILURE(rc)) 5579 return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot register legacy I/O handlers")); 5482 AssertMsgFailedReturn(("Invalid controller type %d\n", pThis->enmCtrlType), VERR_INTERNAL_ERROR_3); 5483 AssertRCReturn(rc, PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot register legacy I/O handlers"))); 5580 5484 } 5581 5485 … … 5607 5511 } 5608 5512 5609 #endif /* IN_RING3 */ 5513 #else /* !IN_RING3 */ 5514 5515 /** 5516 * @callback_method_impl{PDMDEVREGR0,pfnConstruct} 5517 */ 5518 static DECLCALLBACK(int) lsilogicRZConstruct(PPDMDEVINS pDevIns) 5519 { 5520 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 5521 PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI); 5522 5523 int rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->hIoPortsReg, lsilogicIOPortWrite, lsilogicIOPortRead, NULL /*pvUser*/); 5524 AssertRCReturn(rc, rc); 5525 5526 rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmioReg, lsilogicMMIOWrite, lsilogicMMIORead, NULL /*pvUser*/); 5527 AssertRCReturn(rc, rc); 5528 5529 rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmioDiag, lsilogicDiagnosticWrite, lsilogicDiagnosticRead, NULL /*pvUser*/); 5530 AssertRCReturn(rc, rc); 5531 5532 return VINF_SUCCESS; 5533 } 5534 5535 #endif /* !IN_RING3 */ 5610 5536 5611 5537 /** … … 5655 5581 #elif defined(IN_RING0) 5656 5582 /* .pfnEarlyConstruct = */ NULL, 5657 /* .pfnConstruct = */ NULL,5583 /* .pfnConstruct = */ lsilogicRZConstruct, 5658 5584 /* .pfnDestruct = */ NULL, 5659 5585 /* .pfnFinalDestruct = */ NULL, … … 5668 5594 /* .pfnReserved7 = */ NULL, 5669 5595 #elif defined(IN_RC) 5670 /* .pfnConstruct = */ NULL,5596 /* .pfnConstruct = */ lsilogicRZConstruct, 5671 5597 /* .pfnReserved0 = */ NULL, 5672 5598 /* .pfnReserved1 = */ NULL, … … 5730 5656 #elif defined(IN_RING0) 5731 5657 /* .pfnEarlyConstruct = */ NULL, 5732 /* .pfnConstruct = */ NULL,5658 /* .pfnConstruct = */ lsilogicRZConstruct, 5733 5659 /* .pfnDestruct = */ NULL, 5734 5660 /* .pfnFinalDestruct = */ NULL, … … 5743 5669 /* .pfnReserved7 = */ NULL, 5744 5670 #elif defined(IN_RC) 5745 /* .pfnConstruct = */ NULL,5671 /* .pfnConstruct = */ lsilogicRZConstruct, 5746 5672 /* .pfnReserved0 = */ NULL, 5747 5673 /* .pfnReserved1 = */ NULL, -
trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp
r81765 r81773 79 79 * Reads a register value. 80 80 * 81 * @ret urns VBox status code.81 * @retval VINF_SUCCESS 82 82 * @param pVBoxSCSI Pointer to the SCSI state. 83 83 * @param iRegister Index of the register to read. … … 145 145 * Writes to a register. 146 146 * 147 * @ret urns VBox status code.147 * @retval VINF_SUCCESS on success. 148 148 * @retval VERR_MORE_DATA if a command is ready to be sent to the SCSI driver. 149 * 149 150 * @param pVBoxSCSI Pointer to the SCSI state. 150 151 * @param iRegister Index of the register to write to. … … 350 351 } 351 352 353 /** 354 * @retval VINF_SUCCESS 355 */ 352 356 int vboxscsiReadString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister, 353 357 uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb) … … 375 379 * Also ignore attempts to read more data than is available. 376 380 */ 377 int rc = VINF_SUCCESS;378 381 uint32_t cbTransfer = *pcTransfers * cb; 379 382 if (pVBoxSCSI->cbBufLeft > 0) … … 405 408 *pcTransfers = 0; 406 409 407 return rc; 408 } 409 410 return VINF_SUCCESS; 411 } 412 413 /** 414 * @retval VINF_SUCCESS 415 * @retval VERR_MORE_DATA 416 */ 410 417 int vboxscsiWriteString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister, 411 418 uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)
Note:
See TracChangeset
for help on using the changeset viewer.