VirtualBox

Changeset 81773 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 11, 2019 6:05:17 PM (5 years ago)
Author:
vboxsync
Message:

DevLsiLogicSCSI: Converted MMIO and I/O port handlers. bugref:9218

Location:
trunk/src/VBox/Devices/Storage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r81765 r81773  
    2626#include <VBox/vmm/pdmthread.h>
    2727#include <VBox/vmm/pdmcritsect.h>
     28#include <VBox/AssertGuest.h>
    2829#include <VBox/scsi.h>
    2930#include <VBox/sup.h>
     
    248249    /** The fault code of the I/O controller if we are in the fault state. */
    249250    uint16_t              u16IOCFaultCode;
    250 
    251     /** I/O port address the device is mapped to. */
    252     RTIOPORT              IOPortBase;
     251    uint16_t              u16Padding0b;
     252
    253253    /** MMIO address the device is mapped to. */
    254254    RTGCPHYS              GCPhysMMIOBase;
     
    367367    SUPSEMEVENT                      hEvtProcess;
    368368
     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;
    369377} LSILOGISCSI;
    370378
     
    12431251 * Writes a value to a register at a given offset.
    12441252 *
    1245  * @returns VBox status code.
     1253 * @returns Strict VBox status code.
     1254 * @param   pDevIns     The devie instance.
    12461255 * @param   pThis       Pointer to the LsiLogic device state.
    12471256 * @param   offReg      Offset of the register to write.
    12481257 * @param   u32         The value being written.
    12491258 */
    1250 static int lsilogicRegisterWrite(PLSILOGICSCSI pThis, uint32_t offReg, uint32_t u32)
     1259static VBOXSTRICTRC lsilogicRegisterWrite(PPDMDEVINS pDevIns, PLSILOGICSCSI pThis, uint32_t offReg, uint32_t u32)
    12511260{
    12521261    LogFlowFunc(("pThis=%#p offReg=%#x u32=%#x\n", pThis, offReg, u32));
     
    12551264        case LSILOGIC_REG_REPLY_QUEUE:
    12561265        {
    1257             int rc = PDMDevHlpCritSectEnter(pThis->CTX_SUFF(pDevIns), &pThis->ReplyFreeQueueWriteCritSect, VINF_IOM_R3_MMIO_WRITE);
     1266            int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->ReplyFreeQueueWriteCritSect, VINF_IOM_R3_MMIO_WRITE);
    12581267            if (rc != VINF_SUCCESS)
    12591268                return rc;
     
    12621271            pThis->uReplyFreeQueueNextEntryFreeWrite++;
    12631272            pThis->uReplyFreeQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries;
    1264             PDMDevHlpCritSectLeave(pThis->CTX_SUFF(pDevIns), &pThis->ReplyFreeQueueWriteCritSect);
     1273            PDMDevHlpCritSectLeave(pDevIns, &pThis->ReplyFreeQueueWriteCritSect);
    12651274            break;
    12661275        }
    12671276        case LSILOGIC_REG_REQUEST_QUEUE:
    12681277        {
    1269             int rc = PDMDevHlpCritSectEnter(pThis->CTX_SUFF(pDevIns), &pThis->RequestQueueCritSect, VINF_IOM_R3_MMIO_WRITE);
     1278            int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->RequestQueueCritSect, VINF_IOM_R3_MMIO_WRITE);
    12701279            if (rc != VINF_SUCCESS)
    12711280                return rc;
     
    12841293            uNextWrite %= pThis->cRequestQueueEntries;
    12851294            ASMAtomicWriteU32(&pThis->uRequestQueueNextEntryFreeWrite, uNextWrite);
    1286             PDMDevHlpCritSectLeave(pThis->CTX_SUFF(pDevIns), &pThis->RequestQueueCritSect);
     1295            PDMDevHlpCritSectLeave(pDevIns, &pThis->RequestQueueCritSect);
    12871296
    12881297            /* Send notification to R3 if there is not one sent already. Do this
     
    12931302                {
    12941303                    LogFlowFunc(("Signal event semaphore\n"));
    1295                     rc = PDMDevHlpSUPSemEventSignal(pThis->CTX_SUFF(pDevIns), pThis->hEvtProcess);
     1304                    rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtProcess);
    12961305                    AssertRC(rc);
    12971306                }
     
    15141523 *
    15151524 * @returns VBox status code.
     1525 * @param   pDevIns     The device instance.
    15161526 * @param   pThis       Pointer to the LsiLogic device state.
    15171527 * @param   offReg      Offset of the register to read.
    15181528 * @param   pu32        Where to store the content of the register.
    15191529 */
    1520 static int lsilogicRegisterRead(PLSILOGICSCSI pThis, uint32_t offReg, uint32_t *pu32)
     1530static VBOXSTRICTRC lsilogicRegisterRead(PPDMDEVINS pDevIns, PLSILOGICSCSI pThis, uint32_t offReg, uint32_t *pu32)
    15211531{
    15221532    int rc = VINF_SUCCESS;
     
    15291539        case LSILOGIC_REG_REPLY_QUEUE:
    15301540        {
    1531             rc = PDMDevHlpCritSectEnter(pThis->CTX_SUFF(pDevIns), &pThis->ReplyPostQueueCritSect, VINF_IOM_R3_MMIO_READ);
     1541            rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->ReplyPostQueueCritSect, VINF_IOM_R3_MMIO_READ);
    15321542            if (rc != VINF_SUCCESS)
    15331543                break;
     
    15491559                lsilogicClearInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_REPLY_INTR);
    15501560            }
    1551             PDMDevHlpCritSectLeave(pThis->CTX_SUFF(pDevIns), &pThis->ReplyPostQueueCritSect);
     1561            PDMDevHlpCritSectLeave(pDevIns, &pThis->ReplyPostQueueCritSect);
    15521562
    15531563            Log(("%s: Returning address %#x\n", __FUNCTION__, u32));
     
    16721682
    16731683/**
    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 */
     1686static DECLCALLBACK(VBOXSTRICTRC)
     1687lsilogicIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
    16771688{
    16781689    PLSILOGICSCSI   pThis  = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI);
    1679     uint32_t        offReg = uPort - pThis->IOPortBase;
    1680     int             rc;
     1690    VBOXSTRICTRC    rcStrict;
    16811691    RT_NOREF2(pvUser, cb);
    16821692
    1683     if (!(offReg & 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;
    16881698    }
    16891699    else
    16901700    {
    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 */
     1711static DECLCALLBACK(VBOXSTRICTRC)
     1712lsilogicIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb)
    17021713{
    17031714    PLSILOGICSCSI   pThis   = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI);
    1704     uint32_t        offReg  = uPort - pThis->IOPortBase;
    17051715    RT_NOREF_PV(pvUser);
    17061716    RT_NOREF_PV(cb);
    17071717
    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{FNIOMMMIOWRITE}
    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 */
     1728static DECLCALLBACK(VBOXSTRICTRC) lsilogicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
    17191729{
    17201730    PLSILOGICSCSI   pThis  = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI);
    1721     uint32_t        offReg = GCPhysAddr - pThis->GCPhysMMIOBase;
    17221731    uint32_t        u32;
    1723     int             rc;
    17241732    RT_NOREF_PV(pvUser);
    17251733
    1726     /* See comments in lsilogicR3Map regarding size and alignment. */
     1734    /* See comments in lsilogicR3Construct regarding size and alignment. */
    17271735    if (cb == 4)
    17281736        u32 = *(uint32_t const *)pv;
     
    17351743        else
    17361744            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);
    17421751    else
    17431752    {
    1744         Log(("lsilogicIOPortWrite: 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{FNIOMMMIOREAD}
    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 */
     1762static DECLCALLBACK(VBOXSTRICTRC) lsilogicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
    17541763{
    17551764    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.  */
    17581766    RT_NOREF2(pvUser, cb);
    17591767
    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 */
     1774static DECLCALLBACK(VBOXSTRICTRC)
     1775lsilogicDiagnosticWrite(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));
    17721779    return VINF_SUCCESS;
    17731780}
    17741781
    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 */
     1785static 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));
    17841789    return VINF_SUCCESS;
    17851790}
     
    38013806 * @callback_method_impl{FNIOMIOPORTIN, Legacy ISA port.}
    38023807 */
    3803 static DECLCALLBACK(int) lsilogicR3IsaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
     3808static DECLCALLBACK(VBOXSTRICTRC)
     3809lsilogicR3IsaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb)
    38043810{
    38053811    RT_NOREF(pvUser, cb);
    38063812    PLSILOGICSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PLSILOGICSCSI);
    38073813
    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));
    38173820
    38183821    return rc;
     
    38883891
    38893892/**
    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 */
     3895static DECLCALLBACK(VBOXSTRICTRC)
     3896lsilogicR3IsaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
    38933897{
    38943898    RT_NOREF(pvUser, cb);
    38953899    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     Assert(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);
    38993903
    39003904    /*
     
    39053909        return VINF_SUCCESS;
    39063910
    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 */
     3930static 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);
    39113938    if (rc == VERR_MORE_DATA)
    39123939    {
     
    39173944        AssertRC(rc);
    39183945    }
    3919     else if (RT_FAILURE(rc))
    3920         AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));
     3946    else
     3947        AssertMsg(rc == VINF_SUCCESS, ("Unexpected BIOS register write status: %Rrc\n", rc));
    39213948
    39223949    return VINF_SUCCESS;
     
    39243951
    39253952/**
    3926  * @callback_method_impl{FNIOMIOPORTOUTSTRING,
    3927  * Port I/O Handler for primary port range OUT string operations.}
    3928  */
    3929 static DECLCALLBACK(int) lsilogicR3IsaIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port,
    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 */
     3956static DECLCALLBACK(VBOXSTRICTRC) lsilogicR3IsaIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort,
     3957                                                             uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb)
    39313958{
    39323959    RT_NOREF(pvUser);
    39333960    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));
    40883965    return rc;
    40893966}
     
    41073984     */
    41083985    pHlp->pfnPrintf(pHlp,
    4109                     "%s#%d: port=%RTiop mmio=%RGp max-devices=%u GC=%RTbool R0=%RTbool\n",
     3986                    "%s#%d: port=%04x mmio=%RGp max-devices=%u GC=%RTbool R0=%RTbool\n",
    41103987                    pDevIns->pReg->szName,
    41113988                    pDevIns->iInstance,
    4112                     pThis->IOPortBase, pThis->GCPhysMMIOBase,
     3989                    PDMDevHlpIoPortGetMappingAddress(pDevIns, pThis->hIoPortsReg),
     3990                    PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmioReg),
    41133991                    pThis->cDeviceStates,
    41143992                    pThis->fGCEnabled ? true : false,
     
    52615139    pThis->fBiosReqPending = false;
    52625140    RTListInit(&pThis->ListMemRegns);
     5141    pThis->hMmioReg = NIL_IOMMMIOHANDLE;
     5142    pThis->hMmioDiag = NIL_IOMMMIOHANDLE;
     5143    pThis->hIoPortsReg = NIL_IOMIOPORTHANDLE;
     5144    pThis->hIoPortsBios = NIL_IOMIOPORTHANDLE;
    52635145
    52645146    /*
     
    54265308# endif
    54275309
    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);
    54395346
    54405347    /*
     
    55475454        pThis->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIANOTIFY);
    55485455    }
    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")));
    55545460
    55555461    /* Initialize the SCSI emulation for the BIOS. */
     
    55645470    {
    55655471        if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI)
    5566             rc = PDMDevHlpIOPortRegister(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);
    55705476        else if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SAS)
    5571             rc = PDMDevHlpIOPortRegister(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);
    55755481        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")));
    55805484    }
    55815485
     
    56075511}
    56085512
    5609 #endif /* IN_RING3 */
     5513#else  /* !IN_RING3 */
     5514
     5515/**
     5516 * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
     5517 */
     5518static 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 */
    56105536
    56115537/**
     
    56555581#elif defined(IN_RING0)
    56565582    /* .pfnEarlyConstruct = */      NULL,
    5657     /* .pfnConstruct = */           NULL,
     5583    /* .pfnConstruct = */           lsilogicRZConstruct,
    56585584    /* .pfnDestruct = */            NULL,
    56595585    /* .pfnFinalDestruct = */       NULL,
     
    56685594    /* .pfnReserved7 = */           NULL,
    56695595#elif defined(IN_RC)
    5670     /* .pfnConstruct = */           NULL,
     5596    /* .pfnConstruct = */           lsilogicRZConstruct,
    56715597    /* .pfnReserved0 = */           NULL,
    56725598    /* .pfnReserved1 = */           NULL,
     
    57305656#elif defined(IN_RING0)
    57315657    /* .pfnEarlyConstruct = */      NULL,
    5732     /* .pfnConstruct = */           NULL,
     5658    /* .pfnConstruct = */           lsilogicRZConstruct,
    57335659    /* .pfnDestruct = */            NULL,
    57345660    /* .pfnFinalDestruct = */       NULL,
     
    57435669    /* .pfnReserved7 = */           NULL,
    57445670#elif defined(IN_RC)
    5745     /* .pfnConstruct = */           NULL,
     5671    /* .pfnConstruct = */           lsilogicRZConstruct,
    57465672    /* .pfnReserved0 = */           NULL,
    57475673    /* .pfnReserved1 = */           NULL,
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp

    r81765 r81773  
    7979 * Reads a register value.
    8080 *
    81  * @returns VBox status code.
     81 * @retval  VINF_SUCCESS
    8282 * @param   pVBoxSCSI    Pointer to the SCSI state.
    8383 * @param   iRegister    Index of the register to read.
     
    145145 * Writes to a register.
    146146 *
    147  * @returns VBox status code.
     147 * @retval  VINF_SUCCESS on success.
    148148 * @retval  VERR_MORE_DATA if a command is ready to be sent to the SCSI driver.
     149 *
    149150 * @param   pVBoxSCSI    Pointer to the SCSI state.
    150151 * @param   iRegister    Index of the register to write to.
     
    350351}
    351352
     353/**
     354 * @retval VINF_SUCCESS
     355 */
    352356int vboxscsiReadString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
    353357                       uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb)
     
    375379     * Also ignore attempts to read more data than is available.
    376380     */
    377     int rc = VINF_SUCCESS;
    378381    uint32_t cbTransfer = *pcTransfers * cb;
    379382    if (pVBoxSCSI->cbBufLeft > 0)
     
    405408    *pcTransfers = 0;
    406409
    407     return rc;
    408 }
    409 
     410    return VINF_SUCCESS;
     411}
     412
     413/**
     414 * @retval VINF_SUCCESS
     415 * @retval VERR_MORE_DATA
     416 */
    410417int vboxscsiWriteString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
    411418                        uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette