VirtualBox

Changeset 56413 in vbox


Ignore:
Timestamp:
Jun 14, 2015 3:43:56 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
101015
Message:

IOM,DevATA,Dev*SCSI: Redid the string I/O callbacks so the devices doesn't need to talk to PGM. (scsi bits are untested)

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/iem.h

    r56291 r56413  
    9494VMM_INT_DECL(void)   IEMNotifyIOPortRead(PVM pVM, RTIOPORT Port, size_t cbValue);
    9595VMM_INT_DECL(void)   IEMNotifyIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
    96 VMM_INT_DECL(void)   IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrDst, RTGCUINTREG cTransfers, size_t cbValue);
    97 VMM_INT_DECL(void)   IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrSrc, RTGCUINTREG cTransfers, size_t cbValue);
     96VMM_INT_DECL(void)   IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, void *pvDst, RTGCUINTREG cTransfers, size_t cbValue);
     97VMM_INT_DECL(void)   IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, void const *pvSrc, RTGCUINTREG cTransfers, size_t cbValue);
    9898#endif
    9999
  • trunk/include/VBox/vmm/iom.h

    r56072 r56413  
    164164 * @remarks Caller enters the device critical section.
    165165 */
    166 typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
     166typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb);
    167167/** Pointer to a FNIOMIOPORTIN(). */
    168168typedef FNIOMIOPORTIN *PFNIOMIOPORTIN;
     
    177177 * @param   pvUser      User argument.
    178178 * @param   uPort       Port number used for the IN operation.
    179  * @param   pGCPtrDst   Pointer to the destination buffer (GC, incremented appropriately).
    180  * @param   pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units.
     179 * @param   pbDst       Pointer to the destination buffer.
     180 * @param   pcTransfers Pointer to the number of transfer units to read, on
     181 *                      return remaining transfer units.
    181182 * @param   cb          Size of the transfer unit (1, 2 or 4 bytes).
    182183 * @remarks Caller enters the device critical section.
    183184 */
    184 typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb);
     185typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint8_t *pbDst,
     186                                              uint32_t *pcTransfers, unsigned cb);
    185187/** Pointer to a FNIOMIOPORTINSTRING(). */
    186188typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING;
     
    198200 * @remarks Caller enters the device critical section.
    199201 */
    200 typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
     202typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb);
    201203/** Pointer to a FNIOMIOPORTOUT(). */
    202204typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT;
     
    210212 * @param   pvUser      User argument.
    211213 * @param   uPort       Port number used for the OUT operation.
    212  * @param   pGCPtrSrc   Pointer to the source buffer (GC, incremented appropriately).
    213  * @param   pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units.
     214 * @param   pbSrc       Pointer to the source buffer.
     215 * @param   pcTransfers Pointer to the number of transfer units to write, on
     216 *                      return remaining transfer units.
    214217 * @param   cb          Size of the transfer unit (1, 2 or 4 bytes).
    215218 * @remarks Caller enters the device critical section.
    216219 */
    217 typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb);
     220typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, const uint8_t *pbSrc,
     221                                               uint32_t *pcTransfers, unsigned cb);
    218222/** Pointer to a FNIOMIOPORTOUTSTRING(). */
    219223typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING;
     
    271275VMMDECL(VBOXSTRICTRC)   IOMIOPortRead(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
    272276VMMDECL(VBOXSTRICTRC)   IOMIOPortWrite(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
    273 VMMDECL(VBOXSTRICTRC)   IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb);
    274 VMMDECL(VBOXSTRICTRC)   IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb);
     277VMMDECL(VBOXSTRICTRC)   IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, void *pvDst,
     278                                            uint32_t *pcTransfers, unsigned cb);
     279VMMDECL(VBOXSTRICTRC)   IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT uPort, void const *pvSrc,
     280                                             uint32_t *pcTransfers, unsigned cb);
    275281VMMDECL(VBOXSTRICTRC)   IOMInterpretINSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
    276282VMMDECL(VBOXSTRICTRC)   IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r56408 r56413  
    528528PDMBOTHCBDECL(int) ataIOPortWrite1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
    529529PDMBOTHCBDECL(int) ataIOPortRead1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *u32, unsigned cb);
    530 PDMBOTHCBDECL(int) ataIOPortWriteStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb);
    531 PDMBOTHCBDECL(int) ataIOPortReadStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb);
     530PDMBOTHCBDECL(int) ataIOPortWriteStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t const *pbSrc,
     531                                          uint32_t *pcTransfers, unsigned cb);
     532PDMBOTHCBDECL(int) ataIOPortReadStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t *pbDst,
     533                                         uint32_t *pcTransfers, unsigned cb);
    532534PDMBOTHCBDECL(int) ataIOPortWrite1Other(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
    533535PDMBOTHCBDECL(int) ataIOPortRead1Other(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *u32, unsigned cb);
     
    50205022}
    50215023
    5022 #ifndef IN_RING0 /** @todo do this in ring-0 as well - after IEM specific interface rewrite! */
    50235024
    50245025/**
     
    50265027 * @see FNIOMIOPORTINSTRING for details.
    50275028 */
    5028 PDMBOTHCBDECL(int) ataIOPortReadStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst,
    5029                                          PRTGCUINTREG pcTransfer, unsigned cb)
    5030 {
    5031     uint32_t       i = (uint32_t)(uintptr_t)pvUser;
     5029PDMBOTHCBDECL(int) ataIOPortReadStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t *pbDst,
     5030                                         uint32_t *pcTransfers, unsigned cb)
     5031{
     5032    uint32_t       i     = (uint32_t)(uintptr_t)pvUser;
    50325033    PCIATAState   *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
    5033     PATACONTROLLER pCtl = &pThis->aCts[i];
    5034     int            rc = VINF_SUCCESS;
     5034    PATACONTROLLER pCtl  = &pThis->aCts[i];
    50355035
    50365036    Assert(i < 2);
    50375037    Assert(Port == pCtl->IOPortBase1);
    5038 
    5039     rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
    5040     if (rc == VINF_SUCCESS)
    5041     {
    5042         ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
    5043         uint32_t    cTransAvailable;
    5044         uint32_t    cTransfer = *pcTransfer;
    5045         uint32_t    cbTransfer;
    5046         RTGCPTR     GCDst = *pGCPtrDst;
    5047         Assert(cb == 2 || cb == 4);
    5048 
    5049         cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
    5050 # ifndef IN_RING3
    5051         /* Deal with the unlikely case where no data (or not enough for the read length operation) is available; go back to ring 3. */
    5052         if (!cTransAvailable)
    5053         {
     5038    Assert(*pcTransfers > 0);
     5039
     5040    int rc;
     5041    if (cb == 2 || cb == 4)
     5042    {
     5043        rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
     5044        if (rc == VINF_SUCCESS)
     5045        {
     5046            ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
     5047
     5048            uint32_t const offStart = s->iIOBufferPIODataStart;
     5049            if (offStart < s->iIOBufferPIODataEnd)
     5050            {
     5051                /*
     5052                 * Figure how much we can copy.  Usually it's the same as the request.
     5053                 * The last transfer unit cannot be handled in RC, as it involves
     5054                 * thread communication.  In R0 we let the non-string callback handle it,
     5055                 * and ditto for overflows/dummy data.
     5056                 */
     5057                uint32_t cAvailable = (s->iIOBufferPIODataEnd - offStart) / cb;
     5058#ifndef IN_RING3
     5059                if (cAvailable > 0)
     5060                    cAvailable--;
     5061#endif
     5062                uint32_t const cRequested = *pcTransfers;
     5063                if (cAvailable > cRequested)
     5064                    cAvailable = cRequested;
     5065                uint32_t const cbTransfer = cAvailable * cb;
     5066                if (   offStart + cbTransfer <= s->cbIOBuffer
     5067                    && cbTransfer > 0)
     5068                {
     5069                    /*
     5070                     * Do the transfer.
     5071                     */
     5072                    uint8_t const *pbSrc = s->CTX_SUFF(pbIOBuffer) + offStart;
     5073                    memcpy(pbDst, pbSrc, cbTransfer);
     5074                    Log3(("%s: addr=%#x cb=%#x cbTransfer=%#x val=%.*Rhxd\n",
     5075                          __FUNCTION__, Port, cb, cbTransfer, cbTransfer, pbSrc));
     5076                    s->iIOBufferPIODataStart = offStart + cbTransfer;
     5077
     5078#ifdef IN_RING3
     5079                    if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
     5080                        ataHCPIOTransferFinish(pCtl, s);
     5081#endif
     5082                    *pcTransfers = cRequested - cAvailable;
     5083                }
     5084                else
     5085                    Log2(("%s: DUMMY/Overflow!\n", __FUNCTION__));
     5086            }
     5087            else
     5088            {
     5089                /*
     5090                 * Dummy read (shouldn't happen) return 0xff like the non-string handler.
     5091                 */
     5092                Log2(("%s: DUMMY data (%#x bytes)\n", __FUNCTION__, *pcTransfers * cb));
     5093                memset(pbDst, 0xff, *pcTransfers * cb);
     5094                *pcTransfers = 0;
     5095            }
     5096
    50545097            PDMCritSectLeave(&pCtl->lock);
    5055             return VINF_IOM_R3_IOPORT_READ;
    5056         }
    5057         /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
    5058         cTransAvailable--;
    5059 # endif /* !IN_RING3 */
    5060         /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
    5061          * They are not performance-critical and generally shouldn't occur at all. */
    5062         if (cTransAvailable > cTransfer)
    5063             cTransAvailable = cTransfer;
    5064         cbTransfer = cTransAvailable * cb;
    5065 
    5066         rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
    5067 # ifndef IN_RING3
    5068         /* Paranoia. */
    5069         if (RT_FAILURE(rc))
    5070         {
    5071             PDMCritSectLeave(&pCtl->lock);
    5072             AssertFailed();
    5073             return VINF_IOM_R3_IOPORT_READ;
    5074         }
    5075 # else
    5076         Assert(rc == VINF_SUCCESS);
    5077 # endif
    5078 
    5079         if (cbTransfer)
    5080             Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
    5081         s->iIOBufferPIODataStart += cbTransfer;
    5082         *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
    5083         *pcTransfer = cTransfer - cTransAvailable;
    5084 # ifdef IN_RING3
    5085         if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
    5086             ataHCPIOTransferFinish(pCtl, s);
    5087 # endif /* IN_RING3 */
    5088         PDMCritSectLeave(&pCtl->lock);
     5098        }
     5099    }
     5100    /*
     5101     * Let the non-string I/O callback handle 1 byte reads.
     5102     */
     5103    else
     5104    {
     5105        Log2(("%s: 1 byte read (%#x transfers)\n", *pcTransfers));
     5106        AssertFailed();
     5107        rc = VINF_SUCCESS;
    50895108    }
    50905109    return rc;
     
    50965115 * @see FNIOMIOPORTOUTSTRING for details.
    50975116 */
    5098 PDMBOTHCBDECL(int) ataIOPortWriteStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc,
    5099                                           PRTGCUINTREG pcTransfer, unsigned cb)
    5100 {
    5101     uint32_t       i = (uint32_t)(uintptr_t)pvUser;
     5117PDMBOTHCBDECL(int) ataIOPortWriteStr1Data(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t const *pbSrc,
     5118                                          uint32_t *pcTransfers, unsigned cb)
     5119{
     5120    uint32_t       i     = (uint32_t)(uintptr_t)pvUser;
    51025121    PCIATAState   *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
    5103     PATACONTROLLER pCtl = &pThis->aCts[i];
    5104     int            rc;
     5122    PATACONTROLLER pCtl  = &pThis->aCts[i];
    51055123
    51065124    Assert(i < 2);
    51075125    Assert(Port == pCtl->IOPortBase1);
    5108 
    5109     rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
    5110     if (rc == VINF_SUCCESS)
    5111     {
    5112         ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
    5113         uint32_t cTransfer = *pcTransfer;
    5114         uint32_t cbTransfer;
    5115         RTGCPTR GCSrc = *pGCPtrSrc;
    5116         Assert(cb == 2 || cb == 4);
    5117 
    5118         uint32_t cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
    5119 # ifndef IN_RING3
    5120         /* Deal with the unlikely case where no data (or not enough for the read length operation) is available; go back to ring 3. */
    5121         if (!cTransAvailable)
    5122         {
     5126    Assert(*pcTransfers > 0);
     5127
     5128    int rc;
     5129    if (cb == 2 || cb == 4)
     5130    {
     5131        rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
     5132        if (rc == VINF_SUCCESS)
     5133        {
     5134            ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
     5135
     5136            uint32_t const offStart = s->iIOBufferPIODataStart;
     5137            if (offStart < s->iIOBufferPIODataEnd)
     5138            {
     5139                /*
     5140                 * Figure how much we can copy.  Usually it's the same as the request.
     5141                 * The last transfer unit cannot be handled in RC, as it involves
     5142                 * thread communication.  In R0 we let the non-string callback handle it,
     5143                 * and ditto for overflows/dummy data.
     5144                 */
     5145                uint32_t cAvailable = (s->iIOBufferPIODataEnd - offStart) / cb;
     5146#ifndef IN_RING3
     5147                if (cAvailable)
     5148                    cAvailable--;
     5149#endif
     5150                uint32_t const cRequested = *pcTransfers;
     5151                if (cAvailable > cRequested)
     5152                    cAvailable = cRequested;
     5153                uint32_t const cbTransfer = cAvailable * cb;
     5154                if (   offStart + cbTransfer <= s->cbIOBuffer
     5155                    && cbTransfer)
     5156                {
     5157                    /*
     5158                     * Do the transfer.
     5159                     */
     5160                    void *pvDst = s->CTX_SUFF(pbIOBuffer) + offStart;
     5161                    memcpy(pvDst, pbSrc, cbTransfer);
     5162                    Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, pvDst));
     5163                    s->iIOBufferPIODataStart = offStart + cbTransfer;
     5164
     5165#ifdef IN_RING3
     5166                    if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
     5167                        ataHCPIOTransferFinish(pCtl, s);
     5168#endif
     5169                    *pcTransfers = cRequested - cAvailable;
     5170                }
     5171                else
     5172                    Log2(("%s: DUMMY/Overflow!\n", __FUNCTION__));
     5173            }
     5174            else
     5175            {
     5176                Log2(("%s: DUMMY data (%#x bytes)\n", __FUNCTION__, *pcTransfers * cb));
     5177                *pcTransfers = 0;
     5178            }
     5179
    51235180            PDMCritSectLeave(&pCtl->lock);
    5124             return VINF_IOM_R3_IOPORT_WRITE;
    5125         }
    5126         /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
    5127         cTransAvailable--;
    5128 # endif /* !IN_RING3 */
    5129         /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
    5130          * They are not performance-critical and generally shouldn't occur at all. */
    5131         if (cTransAvailable > cTransfer)
    5132             cTransAvailable = cTransfer;
    5133         cbTransfer = cTransAvailable * cb;
    5134 
    5135         rc = PGMPhysSimpleReadGCPtr(PDMDevHlpGetVMCPU(pDevIns), s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
    5136 # ifndef IN_RING3
    5137         /* Paranoia. */
    5138         if (RT_FAILURE(rc))
    5139         {
    5140             PDMCritSectLeave(&pCtl->lock);
    5141             AssertFailed();
    5142             return VINF_IOM_R3_IOPORT_WRITE;
    5143         }
    5144 # else
    5145         Assert(rc == VINF_SUCCESS);
    5146 # endif
    5147 
    5148         if (cbTransfer)
    5149             Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
    5150         s->iIOBufferPIODataStart += cbTransfer;
    5151         *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
    5152         *pcTransfer = cTransfer - cTransAvailable;
    5153 # ifdef IN_RING3
    5154         if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
    5155             ataHCPIOTransferFinish(pCtl, s);
    5156 # endif /* IN_RING3 */
    5157         PDMCritSectLeave(&pCtl->lock);
    5158     }
     5181        }
     5182    }
     5183    /*
     5184     * Let the non-string I/O callback handle 1 byte reads.
     5185     */
     5186    else
     5187    {
     5188        Log2(("%s: 1 byte write (%#x transfers)\n", *pcTransfers));
     5189        AssertFailed();
     5190        rc = VINF_SUCCESS;
     5191    }
     5192
    51595193    return rc;
    51605194}
    5161 
    5162 #endif /* !IN_RING0 */
    51635195
    51645196
     
    74917523        if (fR0Enabled)
    74927524        {
    7493 #if 1
     7525#if 0
    74947526            rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 1, (RTR0PTR)i,
    74957527                                           "ataIOPortWrite1Data", "ataIOPortRead1Data", NULL, NULL, "ATA I/O Base 1 - Data");
  • trunk/src/VBox/Devices/Storage/DevBusLogic.cpp

    r56292 r56413  
    25752575 * @see FNIOMIOPORTOUTSTRING for details.
    25762576 */
    2577 static DECLCALLBACK(int) buslogicR3BiosIoPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc,
    2578                                                       PRTGCUINTREG pcTransfer, unsigned cb)
     2577static DECLCALLBACK(int) buslogicR3BiosIoPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port,
     2578                                                      uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)
    25792579{
    25802580    PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    2581     int rc;
    2582 
    2583     Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",
    2584           pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
    2585 
    2586     rc = vboxscsiWriteString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),
    2587                              pGCPtrSrc, pcTransfer, cb);
     2581    Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
     2582
     2583    int rc = vboxscsiWriteString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), pbSrc, pcTransfers, cb);
    25882584    if (rc == VERR_MORE_DATA)
    25892585    {
     
    26012597 * @see FNIOMIOPORTINSTRING for details.
    26022598 */
    2603 static DECLCALLBACK(int) buslogicR3BiosIoPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst,
    2604                                                      PRTGCUINTREG pcTransfer, unsigned cb)
     2599static DECLCALLBACK(int) buslogicR3BiosIoPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port,
     2600                                                     uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb)
    26052601{
    26062602    PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    2607 
    2608     LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",
    2609                  pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
     2603    LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
    26102604
    26112605    return vboxscsiReadString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),
    2612                               pGCPtrDst, pcTransfer, cb);
     2606                              pbDst, pcTransfers, cb);
    26132607}
    26142608
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r56292 r56413  
    38523852 */
    38533853static DECLCALLBACK(int) lsilogicR3IsaIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port,
    3854                                                      PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
     3854                                                     uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)
    38553855{
    38563856    PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
     
    38603860                      ? Port - LSILOGIC_BIOS_IO_PORT
    38613861                      : Port - LSILOGIC_SAS_BIOS_IO_PORT;
    3862     int rc = vboxscsiWriteString(pDevIns, &pThis->VBoxSCSI, iRegister, pGCPtrSrc, pcTransfer, cb);
     3862    int rc = vboxscsiWriteString(pDevIns, &pThis->VBoxSCSI, iRegister, pbSrc, pcTransfers, cb);
    38633863    if (rc == VERR_MORE_DATA)
    38643864    {
     
    38763876 * Port I/O Handler for primary port range IN string operations.}
    38773877 */
    3878 static DECLCALLBACK(int) lsilogicR3IsaIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst,
    3879                                                   PRTGCUINTREG pcTransfer, unsigned cb)
     3878static DECLCALLBACK(int) lsilogicR3IsaIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port,
     3879                                                    uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb)
    38803880{
    38813881    PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    3882 
    3883     LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",
    3884                  pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
     3882    LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
    38853883
    38863884    uint8_t iRegister = pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SPI
    38873885                      ? Port - LSILOGIC_BIOS_IO_PORT
    38883886                      : Port - LSILOGIC_SAS_BIOS_IO_PORT;
    3889     return vboxscsiReadString(pDevIns, &pThis->VBoxSCSI, iRegister, pGCPtrDst, pcTransfer, cb);
     3887    return vboxscsiReadString(pDevIns, &pThis->VBoxSCSI, iRegister, pbDst, pcTransfers, cb);
    38903888}
    38913889
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp

    r56292 r56413  
    3939 * Resets the state.
    4040 */
    41 static void vboxscsiReset(PVBOXSCSI pVBoxSCSI)
    42 {
    43     pVBoxSCSI->regIdentify   = 0;
     41static void vboxscsiReset(PVBOXSCSI pVBoxSCSI, bool fEverything)
     42{
     43    if (fEverything)
     44    {
     45        pVBoxSCSI->regIdentify = 0;
     46        pVBoxSCSI->fBusy       = false;
     47    }
    4448    pVBoxSCSI->cbCDB         = 0;
    45     memset(pVBoxSCSI->abCDB, 0, sizeof(pVBoxSCSI->abCDB));
     49    RT_ZERO(pVBoxSCSI->abCDB);
    4650    pVBoxSCSI->iCDB          = 0;
    47     pVBoxSCSI->fBusy         = false;
    4851    pVBoxSCSI->rcCompletion  = 0;
    4952    pVBoxSCSI->uTargetDevice = 0;
     
    5255    if (pVBoxSCSI->pbBuf)
    5356        RTMemFree(pVBoxSCSI->pbBuf);
    54 
    5557    pVBoxSCSI->pbBuf         = NULL;
    5658    pVBoxSCSI->enmState      = VBOXSCSISTATE_NO_COMMAND;
     
    6668{
    6769    pVBoxSCSI->pbBuf = NULL;
    68     vboxscsiReset(pVBoxSCSI);
     70    vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
    6971
    7072    return VINF_SUCCESS;
     
    102104        {
    103105            /* If we're not in the 'command ready' state, there may not even be a buffer yet. */
    104             if ((pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY) && pVBoxSCSI->cbBuf > 0)
     106            if (   pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY
     107                && pVBoxSCSI->cbBuf > 0)
    105108            {
    106109                AssertMsg(pVBoxSCSI->pbBuf, ("pBuf is NULL\n"));
    107                 Assert(pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY);
    108110                Assert(!pVBoxSCSI->fBusy);
    109111                uVal = pVBoxSCSI->pbBuf[pVBoxSCSI->iBuf];
    110112                pVBoxSCSI->iBuf++;
    111113                pVBoxSCSI->cbBuf--;
     114
     115                /* When the guest reads the last byte from the data in buffer, clear
     116                   everything and reset command buffer. */
    112117                if (pVBoxSCSI->cbBuf == 0)
    113                 {
    114                     /** The guest read the last byte from the data in buffer.
    115                      *  Clear everything and reset command buffer.
    116                      */
    117                     RTMemFree(pVBoxSCSI->pbBuf);
    118                     pVBoxSCSI->pbBuf = NULL;
    119                     pVBoxSCSI->cbCDB = 0;
    120                     pVBoxSCSI->iCDB  = 0;
    121                     pVBoxSCSI->iBuf  = 0;
    122                     pVBoxSCSI->rcCompletion = 0;
    123                     pVBoxSCSI->uTargetDevice = 0;
    124                     pVBoxSCSI->enmState = VBOXSCSISTATE_NO_COMMAND;
    125                     memset(pVBoxSCSI->abCDB, 0, sizeof(pVBoxSCSI->abCDB));
    126                 }
     118                    vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
    127119            }
    128120            break;
     
    151143 *
    152144 * @returns VBox status code.
    153  *          VERR_MORE_DATA if a command is ready to be sent to the SCSI driver.
     145 * @retval  VERR_MORE_DATA if a command is ready to be sent to the SCSI driver.
    154146 * @param   pVBoxSCSI    Pointer to the SCSI state.
    155147 * @param   iRegister    Index of the register to write to.
     
    172164            {
    173165                if (uVal != VBOXSCSI_TXDIR_FROM_DEVICE && uVal != VBOXSCSI_TXDIR_TO_DEVICE)
    174                     vboxscsiReset(pVBoxSCSI);
     166                    vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
    175167                else
    176168                {
     
    181173            else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_CDB_SIZE_BUFHI)
    182174            {
    183                 uint8_t     cbCDB = uVal & 0x0F;
    184 
     175                uint8_t cbCDB = uVal & 0x0F;
    185176                if (cbCDB > VBOXSCSI_CDB_SIZE_MAX)
    186                     vboxscsiReset(pVBoxSCSI);
     177                    vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
    187178                else
    188179                {
     
    231222            break;
    232223        }
     224
    233225        case 1:
    234226        {
     
    237229            {
    238230                /* Reset the state */
    239                 vboxscsiReset(pVBoxSCSI);
    240             }
    241             else
     231                vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
     232            }
     233            else if (pVBoxSCSI->cbBuf > 0)
    242234            {
    243235                pVBoxSCSI->pbBuf[pVBoxSCSI->iBuf++] = uVal;
    244                 if (pVBoxSCSI->iBuf == pVBoxSCSI->cbBuf)
     236                pVBoxSCSI->cbBuf--;
     237                if (pVBoxSCSI->cbBuf == 0)
    245238                {
    246239                    rc = VERR_MORE_DATA;
     
    248241                }
    249242            }
    250             break;
    251         }
     243            /* else: Ignore extra data, request pending or something. */
     244            break;
     245        }
     246
    252247        case 2:
    253248        {
     
    255250            break;
    256251        }
     252
    257253        case 3:
    258254        {
    259255            /* Reset */
    260             vboxscsiReset(pVBoxSCSI);
    261             break;
    262         }
     256            vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
     257            break;
     258        }
     259
    263260        default:
    264261            AssertMsgFailed(("Invalid register to write to %u\n", iRegister));
     
    335332
    336333    if (pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_TO_DEVICE)
    337     {
    338         if (pVBoxSCSI->pbBuf)
    339             RTMemFree(pVBoxSCSI->pbBuf);
    340         pVBoxSCSI->pbBuf  = NULL;
    341         pVBoxSCSI->cbBuf = 0;
    342         pVBoxSCSI->cbCDB = 0;
    343         pVBoxSCSI->iCDB  = 0;
    344         pVBoxSCSI->iBuf  = 0;
    345         pVBoxSCSI->uTargetDevice = 0;
    346         pVBoxSCSI->enmState = VBOXSCSISTATE_NO_COMMAND;
    347         memset(pVBoxSCSI->abCDB, 0, sizeof(pVBoxSCSI->abCDB));
    348     }
     334        vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
    349335
    350336    pVBoxSCSI->rcCompletion = rcCompletion;
     
    356342
    357343int vboxscsiReadString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
    358                        RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
    359 {
    360     RTGCPTR  GCDst      = *pGCPtrDst;
    361     uint32_t cbTransfer = *pcTransfer * cb;
    362 
    363     LogFlowFunc(("pDevIns=%#p pVBoxSCSI=%#p iRegister=%d cTransfer=%u cb=%u\n",
    364                  pDevIns, pVBoxSCSI, iRegister, *pcTransfer, cb));
     344                       uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb)
     345{
     346    LogFlowFunc(("pDevIns=%#p pVBoxSCSI=%#p iRegister=%d cTransfers=%u cb=%u\n",
     347                 pDevIns, pVBoxSCSI, iRegister, *pcTransfers, cb));
     348
     349    /*
     350     * Check preconditions, fall back to non-string I/O handler.
     351     */
     352    Assert(*pcTransfers > 0);
    365353
    366354    /* Read string only valid for data in register. */
    367     AssertMsg(iRegister == 1, ("Hey only register 1 can be read from with string\n"));
     355    AssertMsgReturn(iRegister == 1, ("Hey! Only register 1 can be read from with string!\n"), VINF_SUCCESS);
    368356
    369357    /* Accesses without a valid buffer will be ignored. */
    370     if (!pVBoxSCSI->pbBuf)
    371         return VINF_SUCCESS;
    372 
    373     /* Also ignore attempts to read more data than is available. */
    374     Assert(cbTransfer <= pVBoxSCSI->cbBuf);
    375     if (cbTransfer > pVBoxSCSI->cbBuf)
    376         cbTransfer = pVBoxSCSI->cbBuf;  /* Ignore excess data (not supposed to happen). */
    377 
    378     int rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, pVBoxSCSI->pbBuf + pVBoxSCSI->iBuf, cbTransfer);
    379     AssertRC(rc);
    380 
    381     *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
    382     *pcTransfer = 0;
    383 
    384     /* Advance current buffer position. */
    385     pVBoxSCSI->iBuf  += cbTransfer;
    386     pVBoxSCSI->cbBuf -= cbTransfer;
    387 
    388     if (pVBoxSCSI->cbBuf == 0)
    389     {
    390         /** The guest read the last byte from the data in buffer.
    391          *  Clear everything and reset command buffer.
    392          */
    393         RTMemFree(pVBoxSCSI->pbBuf);
    394         pVBoxSCSI->pbBuf  = NULL;
    395         pVBoxSCSI->cbCDB = 0;
    396         pVBoxSCSI->iCDB  = 0;
    397         pVBoxSCSI->iBuf  = 0;
    398         pVBoxSCSI->uTargetDevice = 0;
    399         pVBoxSCSI->enmState = VBOXSCSISTATE_NO_COMMAND;
    400         memset(pVBoxSCSI->abCDB, 0, sizeof(pVBoxSCSI->abCDB));
    401     }
     358    AssertReturn(!pVBoxSCSI->pbBuf, VINF_SUCCESS);
     359
     360    /* Check state. */
     361    AssertReturn(pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY, VINF_SUCCESS);
     362    Assert(!pVBoxSCSI->fBusy);
     363
     364    /*
     365     * Also ignore attempts to read more data than is available.
     366     */
     367    int rc = VINF_SUCCESS;
     368    uint32_t cbTransfer = *pcTransfers * cb;
     369    if (pVBoxSCSI->cbBuf > 0) /* Think cbBufLeft, not cbBuf! */
     370    {
     371        Assert(cbTransfer <= pVBoxSCSI->cbBuf);
     372        if (cbTransfer > pVBoxSCSI->cbBuf)
     373        {
     374            memset(pbDst + pVBoxSCSI->cbBuf, 0xff, cbTransfer - pVBoxSCSI->cbBuf);
     375            cbTransfer = pVBoxSCSI->cbBuf;  /* Ignore excess data (not supposed to happen). */
     376        }
     377
     378        /* Copy the data and adance the buffer position. */
     379        memcpy(pbDst, pVBoxSCSI->pbBuf + pVBoxSCSI->iBuf, cbTransfer);
     380
     381        /* Advance current buffer position. */
     382        pVBoxSCSI->iBuf  += cbTransfer;
     383        pVBoxSCSI->cbBuf -= cbTransfer;
     384
     385        /* When the guest reads the last byte from the data in buffer, clear
     386           everything and reset command buffer. */
     387        if (pVBoxSCSI->cbBuf == 0)
     388            vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
     389    }
     390    else
     391    {
     392        AssertFailed();
     393        memset(pbDst, 0, cbTransfer);
     394    }
     395    *pcTransfers = 0;
    402396
    403397    return rc;
     
    405399
    406400int vboxscsiWriteString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
    407                         RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
    408 {
    409     RTGCPTR  GCSrc      = *pGCPtrSrc;
    410     uint32_t cbTransfer = *pcTransfer * cb;
    411 
     401                        uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)
     402{
     403    /*
     404     * Check preconditions, fall back to non-string I/O handler.
     405     */
     406    Assert(*pcTransfers > 0);
    412407    /* Write string only valid for data in/out register. */
    413     AssertMsg(iRegister == 1, ("Hey only register 1 can be written to with string\n"));
     408    AssertMsgReturn(iRegister == 1, ("Hey! Only register 1 can be written to with string!\n"), VINF_SUCCESS);
    414409
    415410    /* Accesses without a valid buffer will be ignored. */
    416     if (!pVBoxSCSI->pbBuf)
    417         return VINF_SUCCESS;
    418 
    419     Assert(cbTransfer <= pVBoxSCSI->cbBuf);
    420     if (cbTransfer > pVBoxSCSI->cbBuf)
    421         cbTransfer = pVBoxSCSI->cbBuf;  /* Ignore excess data (not supposed to happen). */
    422 
    423     int rc = PDMDevHlpPhysReadGCVirt(pDevIns, pVBoxSCSI->pbBuf + pVBoxSCSI->iBuf, GCSrc, cbTransfer);
    424     AssertRC(rc);
    425 
    426     /* Advance current buffer position. */
    427     pVBoxSCSI->iBuf  += cbTransfer;
    428     pVBoxSCSI->cbBuf -= cbTransfer;
    429 
    430     *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
    431     *pcTransfer = 0;
    432 
    433     ASMAtomicXchgBool(&pVBoxSCSI->fBusy, true);
    434     return VERR_MORE_DATA;
     411    AssertReturn(!pVBoxSCSI->pbBuf, VINF_SUCCESS);
     412
     413    /* State machine assumptions. */
     414    AssertReturn(pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY, VINF_SUCCESS);
     415    AssertReturn(pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_TO_DEVICE, VINF_SUCCESS);
     416
     417    /*
     418     * Ignore excess data (not supposed to happen).
     419     */
     420    int rc = VINF_SUCCESS;
     421    if (pVBoxSCSI->cbBuf > 0) /* Think cbBufLeft, not cbBuf! */
     422    {
     423        uint32_t cbTransfer = *pcTransfers * cb;
     424        if (cbTransfer > pVBoxSCSI->cbBuf) /* Think cbBufLeft, not cbBuf! */
     425        {
     426            /** @todo the non-string version of the code would cause a reset here. */
     427            cbTransfer = pVBoxSCSI->cbBuf;
     428        }
     429
     430        /* Copy the data and adance the buffer position. */
     431        memcpy(pVBoxSCSI->pbBuf + pVBoxSCSI->iBuf, pbSrc, cbTransfer);
     432        pVBoxSCSI->iBuf  += cbTransfer;
     433        pVBoxSCSI->cbBuf -= cbTransfer;
     434
     435        /* If we've reached the end, tell the caller to submit the command. */
     436        if (pVBoxSCSI->cbBuf == 0)
     437        {
     438            ASMAtomicXchgBool(&pVBoxSCSI->fBusy, true);
     439            rc = VERR_MORE_DATA;
     440        }
     441    }
     442    else
     443        AssertFailed();
     444    *pcTransfers = 0;
     445
     446    return rc;
    435447}
    436448
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.h

    r56292 r56413  
    111111    /** Pointer to the buffer holding the data. */
    112112    R3PTRTYPE(uint8_t *) pbBuf;
    113     /** Size of the buffer in bytes. */
     113    /** Size of the buffer in bytes.
     114     *
     115     * @todo r=bird: Misleading docs and member name.  This is actually not the
     116     *               buffer size, it's the number of bytes left to read/write in the
     117     *               buffer.  It is decremented when the guest (BIOS) accesses
     118     *               the buffer data. */
    114119    uint32_t             cbBuf;
    115120    /** Current position in the buffer (offBuf if you like). */
     
    138143void vboxscsiSetRequestRedo(PVBOXSCSI pVBoxSCSI, PPDMSCSIREQUEST pScsiRequest);
    139144int vboxscsiWriteString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
    140                         RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb);
     145                        uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb);
    141146int vboxscsiReadString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
    142                        RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb);
     147                       uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb);
    143148RT_C_DECLS_END
    144149#endif /* IN_RING3 */
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r56287 r56413  
    99959995
    99969996
    9997 VMM_INT_DECL(void)   IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrDst, RTGCUINTREG cTransfers, size_t cbValue)
     9997VMM_INT_DECL(void)   IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, void *pvDst, RTGCUINTREG cTransfers, size_t cbValue)
    99989998{
    99999999    AssertFailed();
     
    1000110001
    1000210002
    10003 VMM_INT_DECL(void)   IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrSrc, RTGCUINTREG cTransfers, size_t cbValue)
     10003VMM_INT_DECL(void)   IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, void const *pvSrc, RTGCUINTREG cTransfers, size_t cbValue)
    1000410004{
    1000510005    AssertFailed();
  • trunk/src/VBox/VMM/VMMAll/IOMAll.cpp

    r56403 r56413  
    236236 * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
    237237 * @param   Port        The port to read.
    238  * @param   pGCPtrDst   Pointer to the destination buffer (RC, incremented
    239  *                      appropriately).
     238 * @param   pvDst       Pointer to the destination buffer.
    240239 * @param   pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units.
    241240 * @param   cb          Size of the transfer unit (1, 2 or 4 bytes).
    242241 */
    243 VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port,
    244                                           PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb)
     242VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT uPort,
     243                                          void *pvDst, uint32_t *pcTransfers, unsigned cb)
    245244{
    246245    /* Take the IOM lock before performing any device I/O. */
     
    252251    AssertRC(rc2);
    253252#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
    254     IEMNotifyIOPortReadString(pVM, Port, *pGCPtrDst, *pcTransfers, cb);
     253    IEMNotifyIOPortReadString(pVM, uPort, pvDst, *pcTransfers, cb);
    255254#endif
    256255
    257256#ifdef LOG_ENABLED
    258     const RTGCUINTREG cTransfers = *pcTransfers;
     257    const uint32_t cTransfers = *pcTransfers;
    259258#endif
    260259#ifdef VBOX_WITH_STATISTICS
     
    263262     */
    264263    PIOMIOPORTSTATS pStats = pVCpu->iom.s.CTX_SUFF(pStatsLastRead);
    265     if (!pStats || pStats->Core.Key != Port)
    266     {
    267         pStats = (PIOMIOPORTSTATS)RTAvloIOPortGet(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortStatTree, Port);
     264    if (!pStats || pStats->Core.Key != uPort)
     265    {
     266        pStats = (PIOMIOPORTSTATS)RTAvloIOPortGet(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortStatTree, uPort);
    268267        if (pStats)
    269268            pVCpu->iom.s.CTX_SUFF(pStatsLastRead) = pStats;
     
    276275    CTX_SUFF(PIOMIOPORTRANGE) pRange = pVCpu->iom.s.CTX_SUFF(pRangeLastRead);
    277276    if (    !pRange
    278         ||   (unsigned)Port - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
    279     {
    280         pRange = iomIOPortGetRange(pVM, Port);
     277        ||   (unsigned)uPort - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
     278    {
     279        pRange = iomIOPortGetRange(pVM, uPort);
    281280        if (pRange)
    282281            pVCpu->iom.s.CTX_SUFF(pRangeLastRead) = pRange;
     
    314313        {
    315314            STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfIn), a);
    316             rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
     315            rcStrict = pfnInStrCallback(pDevIns, pvUser, uPort, (uint8_t *)pvDst, pcTransfers, cb);
    317316            STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfIn), a);
    318317        }
    319318        else
    320319#endif
    321             rcStrict = pfnInStrCallback(pDevIns, pvUser, Port, pGCPtrDst, pcTransfers, cb);
     320            rcStrict = pfnInStrCallback(pDevIns, pvUser, uPort, (uint8_t *)pvDst, pcTransfers, cb);
    322321        PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    323322
     
    330329# endif
    331330#endif
    332         Log3(("IOMIOPortReadStr: Port=%RTiop pGCPtrDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=%Rrc\n",
    333               Port, pGCPtrDst, pcTransfers, cTransfers, *pcTransfers, cb, VBOXSTRICTRC_VAL(rcStrict)));
     331        Log3(("IOMIOPortReadStr: uPort=%RTiop pvDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=%Rrc\n",
     332              uPort, pvDst, pcTransfers, cTransfers, *pcTransfers, cb, VBOXSTRICTRC_VAL(rcStrict)));
    334333        return rcStrict;
    335334    }
     
    339338     * Handler in ring-3?
    340339     */
    341     PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, Port);
     340    PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, uPort);
    342341    if (pRangeR3)
    343342    {
     
    359358#endif
    360359
    361     Log3(("IOMIOPortReadStr: Port=%RTiop pGCPtrDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
    362           Port, pGCPtrDst, pcTransfers, cTransfers, *pcTransfers, cb));
     360    Log3(("IOMIOPortReadStr: uPort=%RTiop pvDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
     361          uPort, pvDst, pcTransfers, cTransfers, *pcTransfers, cb));
    363362    IOM_UNLOCK_SHARED(pVM);
    364363    return VINF_SUCCESS;
     
    516515 * @param   pVM         Pointer to the VM.
    517516 * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
    518  * @param   Port        The port to write.
    519  * @param   pGCPtrSrc   Pointer to the source buffer (RC, incremented
    520  *                      appropriately).
    521  * @param   pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units.
     517 * @param   uPort       The port to write to.
     518 * @param   pvSrc       The guest page to read from.
     519 * @param   pcTransfers Pointer to the number of transfer units to write, on
     520 *                     return remaining transfer units.
    522521 * @param   cb          Size of the transfer unit (1, 2 or 4 bytes).
    523522 */
    524 VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port,
    525                                            PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb)
     523VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT uPort, void const *pvSrc,
     524                                           uint32_t *pcTransfers, unsigned cb)
    526525{
     526    Assert(cb == 1 || cb == 2 || cb == 4);
     527
    527528    /* Take the IOM lock before performing any device I/O. */
    528529    int rc2 = IOM_LOCK_SHARED(pVM);
     
    533534    AssertRC(rc2);
    534535#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
    535     IEMNotifyIOPortWriteString(pVM, Port, *pGCPtrSrc, *pcTransfers, cb);
     536    IEMNotifyIOPortWriteString(pVM, uPort, pvSrc, *pcTransfers, cb);
    536537#endif
    537538
    538539#ifdef LOG_ENABLED
    539     const RTGCUINTREG cTransfers = *pcTransfers;
     540    const uint32_t cTransfers = *pcTransfers;
    540541#endif
    541542#ifdef VBOX_WITH_STATISTICS
     
    544545     */
    545546    PIOMIOPORTSTATS     pStats = pVCpu->iom.s.CTX_SUFF(pStatsLastWrite);
    546     if (!pStats || pStats->Core.Key != Port)
    547     {
    548         pStats = (PIOMIOPORTSTATS)RTAvloIOPortGet(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortStatTree, Port);
     547    if (!pStats || pStats->Core.Key != uPort)
     548    {
     549        pStats = (PIOMIOPORTSTATS)RTAvloIOPortGet(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortStatTree, uPort);
    549550        if (pStats)
    550551            pVCpu->iom.s.CTX_SUFF(pStatsLastWrite) = pStats;
     
    557558    CTX_SUFF(PIOMIOPORTRANGE) pRange = pVCpu->iom.s.CTX_SUFF(pRangeLastWrite);
    558559    if (    !pRange
    559         ||   (unsigned)Port - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
    560     {
    561         pRange = iomIOPortGetRange(pVM, Port);
     560        ||   (unsigned)uPort - (unsigned)pRange->Port >= (unsigned)pRange->cPorts)
     561    {
     562        pRange = iomIOPortGetRange(pVM, uPort);
    562563        if (pRange)
    563564            pVCpu->iom.s.CTX_SUFF(pRangeLastWrite) = pRange;
     
    595596        {
    596597            STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfOut), a);
    597             rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
     598            rcStrict = pfnOutStrCallback(pDevIns, pvUser, uPort, (uint8_t const *)pvSrc, pcTransfers, cb);
    598599            STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfOut), a);
    599600        }
    600601        else
    601602#endif
    602             rcStrict = pfnOutStrCallback(pDevIns, pvUser, Port, pGCPtrSrc, pcTransfers, cb);
     603            rcStrict = pfnOutStrCallback(pDevIns, pvUser, uPort, (uint8_t const *)pvSrc, pcTransfers, cb);
    603604        PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    604605
     
    611612# endif
    612613#endif
    613         Log3(("IOMIOPortWriteStr: Port=%RTiop pGCPtrSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rcStrict=%Rrc\n",
    614               Port, pGCPtrSrc, pcTransfers, cTransfers, *pcTransfers, cb, VBOXSTRICTRC_VAL(rcStrict)));
     614        Log3(("IOMIOPortWriteStr: uPort=%RTiop pvSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rcStrict=%Rrc\n",
     615              uPort, pvSrc, pcTransfers, cTransfers, *pcTransfers, cb, VBOXSTRICTRC_VAL(rcStrict)));
    615616        return rcStrict;
    616617    }
     
    620621     * Handler in ring-3?
    621622     */
    622     PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, Port);
     623    PIOMIOPORTRANGER3 pRangeR3 = iomIOPortGetRangeR3(pVM, uPort);
    623624    if (pRangeR3)
    624625    {
     
    640641#endif
    641642
    642     Log3(("IOMIOPortWriteStr: Port=%RTiop pGCPtrSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
    643           Port, pGCPtrSrc, pcTransfers, cTransfers, *pcTransfers, cb));
     643    Log3(("IOMIOPortWriteStr: uPort=%RTiop pvSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
     644          uPort, pvSrc, pcTransfers, cTransfers, *pcTransfers, cb));
    644645    IOM_UNLOCK_SHARED(pVM);
    645646    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r56080 r56413  
    23392339    if (cTransfers > 1)
    23402340    {
    2341         /* If the device supports string transfers, ask it to do as
    2342          * much as it wants. The rest is done with single-word transfers. */
    2343         const RTGCUINTREG cTransfersOrg = cTransfers;
    2344         rcStrict = IOMIOPortReadString(pVM, pVCpu, uPort, &GCPtrDst, &cTransfers, cbTransfer);
    2345         AssertRC(VBOXSTRICTRC_VAL(rcStrict)); Assert(cTransfers <= cTransfersOrg);
    2346         pRegFrame->rdi  = ((pRegFrame->rdi + (cTransfersOrg - cTransfers) * cbTransfer) & fAddrMask)
    2347                         | (pRegFrame->rdi & ~fAddrMask);
    2348     }
    2349 
     2341        /*
     2342         * Work the string page by page, letting the device handle as much
     2343         * as it likes via the string I/O interface.
     2344         */
     2345        for (;;)
     2346        {
     2347            PGMPAGEMAPLOCK Lock;
     2348            void          *pvDst;
     2349            rc2 = PGMPhysGCPtr2CCPtr(pVCpu, GCPtrDst, &pvDst, &Lock);
     2350            if (RT_SUCCESS(rc2))
     2351            {
     2352                uint32_t cMaxThisTime = (PAGE_SIZE - (GCPtrDst & PAGE_OFFSET_MASK)) / cbTransfer;
     2353                if (cMaxThisTime > cTransfers)
     2354                    cMaxThisTime      = cTransfers;
     2355                if (!cMaxThisTime)
     2356                    break;
     2357                uint32_t cThisTime    = cMaxThisTime;
     2358
     2359                rcStrict = IOMIOPortReadString(pVM, pVCpu, uPort, pvDst, &cThisTime, cbTransfer);
     2360                AssertRC(VBOXSTRICTRC_VAL(rcStrict));
     2361                Assert(cThisTime <= cMaxThisTime); /* cThisTime is now how many transfers we have left. */
     2362
     2363                /* If not supported do IOMIOPortRead. */
     2364/** @todo this code should move to IOMIOPortReadString! */
     2365                if (   cThisTime > 0
     2366                    && rcStrict == VINF_SUCCESS)
     2367                {
     2368                    pvDst = (uint8_t *)pvDst + (cMaxThisTime - cThisTime) * cbTransfer;
     2369                    do
     2370                    {
     2371                        uint32_t u32Value = 0;
     2372                        rcStrict = IOMIOPortRead(pVM, pVCpu, uPort, &u32Value, cbTransfer);
     2373                        if (IOM_SUCCESS(rcStrict))
     2374                        {
     2375                            switch (cbTransfer)
     2376                            {
     2377                                case 4: *(uint32_t *)pvDst =           u32Value; pvDst = (uint8_t *)pvDst + 4; break;
     2378                                case 2: *(uint16_t *)pvDst = (uint16_t)u32Value; pvDst = (uint8_t *)pvDst + 2; break;
     2379                                case 1: *(uint8_t  *)pvDst = (uint8_t )u32Value; pvDst = (uint8_t *)pvDst + 1; break;
     2380                                default: AssertFailedReturn(VERR_IOM_IOPORT_IPE_3);
     2381                            }
     2382                            cThisTime--;
     2383                        }
     2384                    } while (   cThisTime > 0
     2385                             && rcStrict == VINF_SUCCESS);
     2386                }
     2387
     2388                PGMPhysReleasePageMappingLock(pVM, &Lock);
     2389
     2390                uint32_t const cActual  = cMaxThisTime - cThisTime;
     2391                uint32_t const cbActual = cActual * cbTransfer;
     2392                cTransfers    -= cActual;
     2393                pRegFrame->rdi = ((pRegFrame->rdi + cbActual) & fAddrMask)
     2394                               | (pRegFrame->rdi & ~fAddrMask);
     2395                GCPtrDst       = (GCPtrDst + cbActual) & fAddrMask;
     2396
     2397                if (   cThisTime
     2398                    || !cTransfers
     2399                    || rcStrict != VINF_SUCCESS
     2400                    || (GCPtrDst & PAGE_OFFSET_MASK))
     2401                    break;
     2402            }
     2403            else
     2404            {
     2405                Log(("IOMInterpretOUTSEx: PGMPhysGCPtr2CCPtr %#RGv -> %Rrc\n", GCPtrDst, rc2));
     2406                break;
     2407            }
     2408        }
     2409    }
     2410
     2411    /*
     2412     * Single transfer / unmapped memory fallback.
     2413     */
    23502414#ifdef IN_RC
    23512415    MMGCRamRegisterTrapHandler(pVM);
     
    23952459 *
    23962460 * @param   pVM             The virtual machine.
    2397  * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
     2461 * @param   pVCpu           Pointer to the virtual CPU structure of the caller.
    23982462 * @param   pRegFrame       Pointer to CPUMCTXCORE guest registers structure.
    23992463 * @param   uPort           IO Port
     
    24012465 * @param   enmAddrMode     The address mode.
    24022466 * @param   cbTransfer      Size of transfer unit
     2467 *
     2468 * @remarks This API will probably be relaced by IEM before long, so no use in
     2469 *          optimizing+fixing stuff too much here.
    24032470 */
    24042471VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix,
     
    24582525    {
    24592526        /*
    2460          * If the device supports string transfers, ask it to do as
    2461          * much as it wants. The rest is done with single-word transfers.
     2527         * Work the string page by page, letting the device handle as much
     2528         * as it likes via the string I/O interface.
    24622529         */
    2463         const RTGCUINTREG cTransfersOrg = cTransfers;
    2464         rcStrict = IOMIOPortWriteString(pVM, pVCpu, uPort, &GCPtrSrc, &cTransfers, cbTransfer);
    2465         AssertRC(VBOXSTRICTRC_VAL(rcStrict)); Assert(cTransfers <= cTransfersOrg);
    2466         pRegFrame->rsi  = ((pRegFrame->rsi + (cTransfersOrg - cTransfers) * cbTransfer) & fAddrMask)
    2467                         | (pRegFrame->rsi & ~fAddrMask);
    2468     }
    2469 
     2530        for (;;)
     2531        {
     2532            PGMPAGEMAPLOCK Lock;
     2533            void const    *pvSrc;
     2534            rc2 = PGMPhysGCPtr2CCPtrReadOnly(pVCpu, GCPtrSrc, &pvSrc, &Lock);
     2535            if (RT_SUCCESS(rc2))
     2536            {
     2537                uint32_t cMaxThisTime = (PAGE_SIZE - (GCPtrSrc & PAGE_OFFSET_MASK)) / cbTransfer;
     2538                if (cMaxThisTime > cTransfers)
     2539                    cMaxThisTime      = cTransfers;
     2540                if (!cMaxThisTime)
     2541                    break;
     2542                uint32_t cThisTime    = cMaxThisTime;
     2543
     2544                rcStrict = IOMIOPortWriteString(pVM, pVCpu, uPort, pvSrc, &cThisTime, cbTransfer);
     2545                AssertRC(VBOXSTRICTRC_VAL(rcStrict));
     2546                Assert(cThisTime <= cMaxThisTime); /* cThisTime is now how many transfers we have left. */
     2547
     2548                /* If not supported do IOMIOPortWrite. */
     2549/** @todo this code should move to IOMIOPortReadString! */
     2550                if (   cThisTime > 0
     2551                    && rcStrict == VINF_SUCCESS)
     2552                {
     2553                    pvSrc = (uint8_t const *)pvSrc + (cMaxThisTime - cThisTime) * cbTransfer;
     2554                    do
     2555                    {
     2556                        uint32_t u32Value;
     2557                        switch (cbTransfer)
     2558                        {
     2559                            case 4: u32Value = *(uint32_t *)pvSrc; pvSrc = (uint8_t const *)pvSrc + 4; break;
     2560                            case 2: u32Value = *(uint16_t *)pvSrc; pvSrc = (uint8_t const *)pvSrc + 2; break;
     2561                            case 1: u32Value = *(uint8_t *)pvSrc;  pvSrc = (uint8_t const *)pvSrc + 1; break;
     2562                            default: AssertFailedReturn(VERR_IOM_IOPORT_IPE_3);
     2563                        }
     2564                        rcStrict = IOMIOPortWrite(pVM, pVCpu, uPort, u32Value, cbTransfer);
     2565                        if (IOM_SUCCESS(rcStrict))
     2566                            cThisTime--;
     2567                    } while (   cThisTime > 0
     2568                             && rcStrict == VINF_SUCCESS);
     2569                }
     2570
     2571                PGMPhysReleasePageMappingLock(pVM, &Lock);
     2572
     2573                uint32_t const cActual  = cMaxThisTime - cThisTime;
     2574                uint32_t const cbActual = cActual * cbTransfer;
     2575                cTransfers    -= cActual;
     2576                pRegFrame->rsi = ((pRegFrame->rsi + cbActual) & fAddrMask)
     2577                               | (pRegFrame->rsi & ~fAddrMask);
     2578                GCPtrSrc       = (GCPtrSrc + cbActual) & fAddrMask;
     2579
     2580                if (   cThisTime
     2581                    || !cTransfers
     2582                    || rcStrict != VINF_SUCCESS
     2583                    || (GCPtrSrc & PAGE_OFFSET_MASK))
     2584                    break;
     2585            }
     2586            else
     2587            {
     2588                Log(("IOMInterpretOUTSEx: PGMPhysGCPtr2CCPtrReadOnly %#RGv -> %Rrc\n", GCPtrSrc, rc2));
     2589                break;
     2590            }
     2591        }
     2592    }
     2593
     2594    /*
     2595     * Single transfer / unmapped memory fallback.
     2596     */
    24702597#ifdef IN_RC
    24712598    MMGCRamRegisterTrapHandler(pVM);
  • trunk/src/VBox/VMM/VMMR3/IOM.cpp

    r56287 r56413  
    132132static DECLCALLBACK(void) iomR3IOPortInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    133133static DECLCALLBACK(void) iomR3MMIOInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    134 static DECLCALLBACK(int) iomR3IOPortDummyIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
    135 static DECLCALLBACK(int) iomR3IOPortDummyOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
    136 static DECLCALLBACK(int) iomR3IOPortDummyInStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb);
    137 static DECLCALLBACK(int) iomR3IOPortDummyOutStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb);
     134static FNIOMIOPORTIN        iomR3IOPortDummyIn;
     135static FNIOMIOPORTOUT       iomR3IOPortDummyOut;
     136static FNIOMIOPORTINSTRING  iomR3IOPortDummyInStr;
     137static FNIOMIOPORTOUTSTRING iomR3IOPortDummyOutStr;
    138138
    139139#ifdef VBOX_WITH_STATISTICS
     
    12011201
    12021202/**
    1203  * Dummy Port I/O Handler for string IN operations.
    1204  *
    1205  * @returns VBox status code.
    1206  *
    1207  * @param   pDevIns     The device instance.
    1208  * @param   pvUser      User argument.
    1209  * @param   Port        Port number used for the string IN operation.
    1210  * @param   pGCPtrDst   Pointer to the destination buffer (GC, incremented appropriately).
    1211  * @param   pcTransfer  Pointer to the number of transfer units to read, on return remaining transfer units.
    1212  * @param   cb          Size of the transfer unit (1, 2 or 4 bytes).
    1213  */
    1214 static DECLCALLBACK(int) iomR3IOPortDummyInStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst,
    1215                                                PRTGCUINTREG pcTransfer, unsigned cb)
    1216 {
    1217     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pGCPtrDst); NOREF(pcTransfer); NOREF(cb);
     1203 * @callback_method_impl{FNIOMIOPORTINSTRING,
     1204 *      Dummy Port I/O Handler for string IN operations.}
     1205 */
     1206static DECLCALLBACK(int) iomR3IOPortDummyInStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t *pbDst,
     1207                                               uint32_t *pcTransfer, unsigned cb)
     1208{
     1209    NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pbDst); NOREF(pcTransfer); NOREF(cb);
    12181210    return VINF_SUCCESS;
    12191211}
     
    12391231
    12401232/**
    1241  * Dummy Port I/O Handler for string OUT operations.
    1242  *
    1243  * @returns VBox status code.
    1244  *
    1245  * @param   pDevIns     The device instance.
    1246  * @param   pvUser      User argument.
    1247  * @param   Port        Port number used for the string OUT operation.
    1248  * @param   pGCPtrSrc   Pointer to the source buffer (GC, incremented appropriately).
    1249  * @param   pcTransfer  Pointer to the number of transfer units to write, on return remaining transfer units.
    1250  * @param   cb          Size of the transfer unit (1, 2 or 4 bytes).
    1251  */
    1252 static DECLCALLBACK(int) iomR3IOPortDummyOutStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc,
    1253                                                 PRTGCUINTREG pcTransfer, unsigned cb)
    1254 {
    1255     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pGCPtrSrc); NOREF(pcTransfer); NOREF(cb);
     1233 * @callback_method_impl{FNIOMIOPORTOUTSTRING,
     1234 *      Dummy Port I/O Handler for string OUT operations.}
     1235 */
     1236static DECLCALLBACK(int) iomR3IOPortDummyOutStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t const *pbSrc,
     1237                                                uint32_t *pcTransfer, unsigned cb)
     1238{
     1239    NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pbSrc); NOREF(pcTransfer); NOREF(cb);
    12561240    return VINF_SUCCESS;
    12571241}
Note: See TracChangeset for help on using the changeset viewer.

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