VirtualBox

Changeset 56404 in vbox


Ignore:
Timestamp:
Jun 13, 2015 6:39:47 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
101005
Message:

DevATA: Read final PIO transfer unit in ring-0.

Location:
trunk/src/VBox
Files:
2 edited

Legend:

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

    r56402 r56404  
    575575}
    576576
    577 #ifdef IN_RING3
    578 
     577#if defined(IN_RING3) || defined(IN_RING0)
     578
     579# ifdef IN_RING3
    579580typedef void (*PBeginTransferFunc)(ATADevState *);
    580581typedef bool (*PSourceSinkFunc)(ATADevState *);
     
    609610static bool atapiR3PassthroughSS(ATADevState *);
    610611static bool atapiR3ReadDVDStructureSS(ATADevState *);
     612# endif /* IN_RING3 */
    611613
    612614/**
     
    623625} ATAFNBT;
    624626
     627# ifdef IN_RING3
    625628/**
    626629 * Array of end transfer functions, the index is ATAFNET.
     
    635638    atapiR3PassthroughCmdBT,
    636639};
     640# endif /* IN_RING3 */
    637641
    638642/**
     
    669673} ATAFNSS;
    670674
     675# ifdef IN_RING3
    671676/**
    672677 * Array of source/sink functions, the index is ATAFNSS.
     
    701706    atapiR3ReadDVDStructureSS
    702707};
     708# endif /* IN_RING3 */
    703709
    704710
     
    708714static const ATARequest g_ataResetCRequest = { ATA_AIO_RESET_CLEARED,  { { 0, 0, 0, 0, 0 } } };
    709715
     716# ifdef IN_RING3
    710717static void ataR3AsyncIOClearRequests(PATACONTROLLER pCtl)
    711718{
     
    719726    AssertRC(rc);
    720727}
    721 
    722 
    723 static void ataR3AsyncIOPutRequest(PATACONTROLLER pCtl, const ATARequest *pReq)
     728# endif /* IN_RING3 */
     729
     730static void ataHCAsyncIOPutRequest(PATACONTROLLER pCtl, const ATARequest *pReq)
    724731{
    725732    int rc = PDMCritSectEnter(&pCtl->AsyncIORequestLock, VINF_SUCCESS);
     
    742749}
    743750
     751# ifdef IN_RING3
    744752
    745753static const ATARequest *ataR3AsyncIOGetCurrentRequest(PATACONTROLLER pCtl)
     
    909917     */
    910918    Log2(("%s: Ctl#%d: message to async I/O thread, new request\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    911     ataR3AsyncIOPutRequest(pCtl, &Req);
     919    ataHCAsyncIOPutRequest(pCtl, &Req);
    912920}
    913921
     
    938946    ataSetStatus(s, ATA_STAT_BUSY);
    939947    Log2(("%s: Ctl#%d: message to async I/O thread, abort command on LUN#%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->iLUN));
    940     ataR3AsyncIOPutRequest(pCtl, &Req);
    941 }
    942 
    943 
    944 static void ataR3SetIRQ(ATADevState *s)
     948    ataHCAsyncIOPutRequest(pCtl, &Req);
     949}
     950# endif /* IN_RING3 */
     951
     952static void ataHCSetIRQ(ATADevState *s)
    945953{
    946954    PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
     
    968976}
    969977
    970 #endif /* IN_RING3 */
     978#endif /* IN_RING0 || IN_RING3 */
    971979
    972980static void ataUnsetIRQ(ATADevState *s)
     
    990998}
    991999
    992 #ifdef IN_RING3
    993 
    994 static void ataR3PIOTransferStart(ATADevState *s, uint32_t start, uint32_t size)
     1000#if defined(IN_RING0) || defined(IN_RING3)
     1001
     1002static void ataHCPIOTransferStart(ATADevState *s, uint32_t start, uint32_t size)
    9951003{
    9961004    Log2(("%s: LUN#%d start %d size %d\n", __FUNCTION__, s->iLUN, start, size));
     
    10021010
    10031011
    1004 static void ataR3PIOTransferStop(ATADevState *s)
     1012static void ataHCPIOTransferStop(ATADevState *s)
    10051013{
    10061014    Log2(("%s: LUN#%d\n", __FUNCTION__, s->iLUN));
     
    10091017        s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
    10101018        Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
    1011         ataR3SetIRQ(s);
     1019        ataHCSetIRQ(s);
    10121020        s->fATAPITransfer = false;
    10131021    }
     
    10211029
    10221030
    1023 static void ataR3PIOTransferLimitATAPI(ATADevState *s)
     1031static void ataHCPIOTransferLimitATAPI(ATADevState *s)
    10241032{
    10251033    uint32_t cbLimit, cbTransfer;
     
    10451053}
    10461054
     1055# ifdef IN_RING3
    10471056
    10481057static uint32_t ataR3GetNSectors(ATADevState *s)
     
    40084017                ataR3CmdError(s, ABRT_ERR);
    40094018                ataUnsetStatus(s, ATA_STAT_READY);
    4010                 ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4019                ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    40114020            }
    40124021            break;
     
    40174026        case ATA_INITIALIZE_DEVICE_PARAMETERS:
    40184027            ataR3CmdOK(s, ATA_STAT_SEEK);
    4019             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4028            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    40204029            break;
    40214030        case ATA_SET_MULTIPLE_MODE:
     
    40324041                ataR3CmdOK(s, 0);
    40334042            }
    4034             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4043            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    40354044            break;
    40364045        case ATA_READ_VERIFY_SECTORS_EXT:
     
    40404049            /* do sector number check ? */
    40414050            ataR3CmdOK(s, ATA_STAT_SEEK);
    4042             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4051            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    40434052            break;
    40444053        case ATA_READ_SECTORS_EXT:
     
    41004109            ataR3SetSector(s, s->cTotalSectors - 1);
    41014110            ataR3CmdOK(s, 0);
    4102             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4111            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41034112            break;
    41044113        case ATA_SEEK: /* Used by the SCO OpenServer. Command is marked as obsolete */
    41054114            ataR3CmdOK(s, 0);
    4106             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4115            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41074116            break;
    41084117        case ATA_READ_NATIVE_MAX_ADDRESS:
    41094118            ataR3SetSector(s, RT_MIN(s->cTotalSectors, 1 << 28) - 1);
    41104119            ataR3CmdOK(s, 0);
    4111             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4120            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41124121            break;
    41134122        case ATA_CHECK_POWER_MODE:
    41144123            s->uATARegNSector = 0xff; /* drive active or idle */
    41154124            ataR3CmdOK(s, 0);
    4116             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4125            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41174126            break;
    41184127        case ATA_SET_FEATURES:
     
    41254134                    Log2(("%s: write cache enable\n", __FUNCTION__));
    41264135                    ataR3CmdOK(s, ATA_STAT_SEEK);
    4127                     ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4136                    ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41284137                    break;
    41294138                case 0xaa: /* read look-ahead enable */
    41304139                    Log2(("%s: read look-ahead enable\n", __FUNCTION__));
    41314140                    ataR3CmdOK(s, ATA_STAT_SEEK);
    4132                     ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4141                    ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41334142                    break;
    41344143                case 0x55: /* read look-ahead disable */
    41354144                    Log2(("%s: read look-ahead disable\n", __FUNCTION__));
    41364145                    ataR3CmdOK(s, ATA_STAT_SEEK);
    4137                     ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4146                    ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41384147                    break;
    41394148                case 0xcc: /* reverting to power-on defaults enable */
    41404149                    Log2(("%s: revert to power-on defaults enable\n", __FUNCTION__));
    41414150                    ataR3CmdOK(s, ATA_STAT_SEEK);
    4142                     ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4151                    ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41434152                    break;
    41444153                case 0x66: /* reverting to power-on defaults disable */
    41454154                    Log2(("%s: revert to power-on defaults disable\n", __FUNCTION__));
    41464155                    ataR3CmdOK(s, ATA_STAT_SEEK);
    4147                     ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4156                    ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41484157                    break;
    41494158                case 0x82: /* write cache disable */
     
    41704179                    }
    41714180                    ataR3CmdOK(s, ATA_STAT_SEEK);
    4172                     ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4181                    ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41734182                    break;
    41744183                }
     
    41924201        case ATA_STANDBY_IMMEDIATE:
    41934202            ataR3CmdOK(s, 0);
    4194             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4203            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    41954204            break;
    41964205        case ATA_IDLE_IMMEDIATE:
     
    42004209        case ATA_SLEEP:
    42014210            ataR3CmdOK(s, 0);
    4202             ataR3SetIRQ(s);
     4211            ataHCSetIRQ(s);
    42034212            break;
    42044213            /* ATAPI commands */
     
    42094218            {
    42104219                ataR3CmdError(s, ABRT_ERR);
    4211                 ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4220                ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    42124221            }
    42134222            break;
     
    42434252            if (s->fATAPI)
    42444253                ataUnsetStatus(s, ATA_STAT_READY);
    4245             ataR3SetIRQ(s); /* Shortcut, do not use AIO thread. */
     4254            ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */
    42464255            break;
    42474256    }
    42484257}
    42494258
    4250 #endif /* IN_RING3 */
     4259# endif /* IN_RING3 */
     4260#endif /* IN_RING0 || IN_RING3 */
    42514261
    42524262/*
     
    43894399        if (pCtl->iSelectedIf)  /* Device 1 selected, Device 0 responding for it. */
    43904400        {
    4391             if (!pCtl->aIfs[0].pDrvBlock)   /* @todo: this case should never get here! */
     4401            if (!pCtl->aIfs[0].pDrvBlock)   /** @todo this case should never get here! */
    43924402            {
    43934403                Log2(("%s: addr=%#x: no device on channel\n", __FUNCTION__, addr));
     
    45194529                val = s->uATARegStatus;
    45204530#else /* !IN_RING3 */
    4521                 /* Cannot yield CPU in guest context. And switching to host
    4522                  * context for each and every busy status is too costly,
     4531                /* Cannot yield CPU in raw-mode and ring-0 context.  And switching
     4532                 * to host context for each and every busy status is too costly,
    45234533                 * especially on SMP systems where we don't gain much by
    45244534                 * yielding the CPU to someone else. */
     
    46104620
    46114621        /* Issue the reset request now. */
    4612         ataR3AsyncIOPutRequest(pCtl, &g_ataResetARequest);
     4622        ataHCAsyncIOPutRequest(pCtl, &g_ataResetARequest);
    46134623#else /* !IN_RING3 */
    46144624        AssertMsgFailed(("RESET handling is too complicated for GC\n"));
     
    46274637            Log2(("%s: ignored setting HOB\n", __FUNCTION__));
    46284638        }
    4629         ataR3AsyncIOPutRequest(pCtl, &g_ataResetCRequest);
     4639        ataHCAsyncIOPutRequest(pCtl, &g_ataResetCRequest);
    46304640#else /* !IN_RING3 */
    46314641        AssertMsgFailed(("RESET handling is too complicated for GC\n"));
     
    46694679}
    46704680
    4671 #ifdef IN_RING3
    4672 
    4673 static void ataR3PIOTransfer(PATACONTROLLER pCtl)
     4681#if defined(IN_RING0) || defined(IN_RING3)
     4682
     4683static void ataHCPIOTransfer(PATACONTROLLER pCtl)
    46744684{
    46754685    ATADevState *s;
     
    46804690    if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
    46814691    {
     4692# ifdef IN_RING3
    46824693        LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "loading" : "storing"));
    46834694        /* Any guest OS that triggers this case has a pathetic ATA driver.
     
    46994710            s->iIOBufferEnd = s->cbElementaryTransfer;
    47004711        }
     4712# else
     4713        AssertReleaseFailed();
     4714# endif
    47014715    }
    47024716    if (s->cbTotalTransfer)
    47034717    {
    47044718        if (s->fATAPITransfer)
    4705             ataR3PIOTransferLimitATAPI(s);
     4719            ataHCPIOTransferLimitATAPI(s);
    47064720
    47074721        if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
     
    47124726             s->cbTotalTransfer, s->cbElementaryTransfer,
    47134727             s->iIOBufferCur, s->iIOBufferEnd));
    4714         ataR3PIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
     4728        ataHCPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
    47154729        s->cbTotalTransfer -= s->cbElementaryTransfer;
    47164730        s->iIOBufferCur += s->cbElementaryTransfer;
     
    47204734    }
    47214735    else
    4722         ataR3PIOTransferStop(s);
    4723 }
    4724 
    4725 
    4726 DECLINLINE(void) ataR3PIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
     4736        ataHCPIOTransferStop(s);
     4737}
     4738
     4739
     4740DECLINLINE(void) ataHCPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
    47274741{
    47284742    /* Do not interfere with RESET processing if the PIO transfer finishes
     
    47454759
    47464760        Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    4747         ataR3AsyncIOPutRequest(pCtl, &g_ataPIORequest);
     4761        ataHCAsyncIOPutRequest(pCtl, &g_ataPIORequest);
    47484762    }
    47494763    else
     
    47604774            /* There is more to transfer, happens usually for large ATAPI
    47614775             * reads - the protocol limits the chunk size to 65534 bytes. */
    4762             ataR3PIOTransfer(pCtl);
    4763             ataR3SetIRQ(s);
     4776            ataHCPIOTransfer(pCtl);
     4777            ataHCSetIRQ(s);
    47644778        }
    47654779        else
     
    47674781            Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    47684782            /* Finish PIO transfer. */
    4769             ataR3PIOTransfer(pCtl);
     4783            ataHCPIOTransfer(pCtl);
    47704784            Assert(!pCtl->fRedo);
    47714785        }
     
    47734787}
    47744788
    4775 #endif /* IN_RING3 */
     4789#endif /* IN_RING0 || IN_RING3 */
     4790
     4791/**
     4792 * Fallback for ataCopyPioData124 that handles unaligned and out of bounds cases.
     4793 *
     4794 * @param   pIf         The device interface to work with.
     4795 * @param   pbDst       The destination buffer.
     4796 * @param   pbSrc       The source buffer.
     4797 * @param   cbCopy      The number of bytes to copy, either 1, 2 or 4 bytes.
     4798 */
     4799DECL_NO_INLINE(static, void) ataCopyPioData124Slow(ATADevState *pIf, uint8_t *pbDst, const uint8_t *pbSrc, uint32_t cbCopy)
     4800{
     4801    uint32_t const offStart = pIf->iIOBufferPIODataStart;
     4802    uint32_t const offNext  = offStart + cbCopy;
     4803
     4804    if (offStart + cbCopy > pIf->cbIOBuffer)
     4805    {
     4806        Log(("%s: cbCopy=%#x offStart=%#x cbIOBuffer=%#x offNext=%#x (iIOBufferPIODataEnd=%#x)\n",
     4807             __FUNCTION__, cbCopy, offStart, pIf->cbIOBuffer, offNext, pIf->iIOBufferPIODataEnd));
     4808        if (offStart < pIf->cbIOBuffer)
     4809            cbCopy = pIf->cbIOBuffer - offStart;
     4810        else
     4811            cbCopy = 0;
     4812    }
     4813
     4814    switch (cbCopy)
     4815    {
     4816        case 4: pbDst[3] = pbSrc[3]; /* fall thru */
     4817        case 3: pbDst[2] = pbSrc[2]; /* fall thru */
     4818        case 2: pbDst[1] = pbSrc[1]; /* fall thru */
     4819        case 1: pbDst[0] = pbSrc[0]; /* fall thru */
     4820        case 0: break;
     4821        default: AssertFailed(); /* impossible */
     4822    }
     4823
     4824    pIf->iIOBufferPIODataStart = offNext;
     4825
     4826}
     4827
     4828
     4829/**
     4830 * Work for ataDataWrite & ataDataRead that copies data without using memcpy.
     4831 *
     4832 * This also updates pIf->iIOBufferPIODataStart.
     4833 *
     4834 * The two buffers are either stack (32-bit aligned) or somewhere within
     4835 * pIf->pbIOBuffer.
     4836 *
     4837 * @param   pIf         The device interface to work with.
     4838 * @param   pbDst       The destination buffer.
     4839 * @param   pbSrc       The source buffer.
     4840 * @param   cbCopy      The number of bytes to copy, either 1, 2 or 4 bytes.
     4841 */
     4842DECLINLINE(void) ataCopyPioData124(ATADevState *pIf, uint8_t *pbDst, const uint8_t *pbSrc, uint32_t cbCopy)
     4843{
     4844    /*
     4845     * Quick bounds checking can be done by checking that the pbIOBuffer offset
     4846     * (iIOBufferPIODataStart) is aligned at the transfer size (which is ASSUMED
     4847     * to be 1, 2 or 4).  However, since we're paranoid and don't currently
     4848     * trust iIOBufferPIODataEnd to be within bounds, we current check against the
     4849     * IO buffer size too.
     4850     */
     4851    Assert(cbCopy == 1 || cbCopy == 2 || cbCopy == 4);
     4852    uint32_t const offStart = pIf->iIOBufferPIODataStart;
     4853    if (RT_LIKELY(   !(offStart & (cbCopy - 1))
     4854                  && offStart + cbCopy <= pIf->cbIOBuffer))
     4855    {
     4856        switch (cbCopy)
     4857        {
     4858            case 4: *(uint32_t *)pbDst = *(uint32_t const *)pbSrc; break;
     4859            case 2: *(uint16_t *)pbDst = *(uint16_t const *)pbSrc; break;
     4860            case 1: *pbDst = *pbSrc; break;
     4861        }
     4862        pIf->iIOBufferPIODataStart = offStart + cbCopy;
     4863    }
     4864    else
     4865        ataCopyPioData124Slow(pIf, pbDst, pbSrc, cbCopy);
     4866}
    47764867
    47774868static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
    47784869{
    47794870    ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
    4780     uint8_t *p;
    47814871
    47824872    if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
    47834873    {
    47844874        Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
    4785         p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
    4786 #ifndef IN_RING3
    4787         /* All but the last transfer unit is simple enough for GC, but
    4788          * sending a request to the async IO thread is too complicated. */
     4875        uint8_t *pbDst = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
     4876
     4877#ifdef IN_RC
     4878        /* Raw-mode: The ataHCPIOTransfer following the last transfer unit
     4879           requires I/O thread signalling, we must go to ring-3 for that. */
    47894880        if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
    4790         {
    4791             memcpy(p, pbBuf, cbSize);
    4792             s->iIOBufferPIODataStart += cbSize;
    4793         }
     4881            ataCopyPioData124(s, pbDst, pbBuf, cbSize);
    47944882        else
    47954883            return VINF_IOM_R3_IOPORT_WRITE;
    4796 #else  /* IN_RING3 */
    4797         memcpy(p, pbBuf, cbSize);
    4798         s->iIOBufferPIODataStart += cbSize;
     4884
     4885#elif defined(IN_RING0)
     4886        /* Ring-0: We can do I/O thread signalling here, however for paranoid reasons
     4887           triggered by a special case in ataHCPIOTransferFinish, we take extra care here. */
     4888        if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
     4889            ataCopyPioData124(s, pbDst, pbBuf, cbSize);
     4890        else if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE) /* paranoia */
     4891        {
     4892            ataCopyPioData124(s, pbDst, pbBuf, cbSize);
     4893            ataHCPIOTransferFinish(pCtl, s);
     4894        }
     4895        else
     4896        {
     4897            Log(("%s: Unexpected\n",__FUNCTION__));
     4898            return VINF_IOM_R3_IOPORT_WRITE;
     4899        }
     4900
     4901#else  /* IN_RING 3*/
     4902        ataCopyPioData124(s, pbDst, pbBuf, cbSize);
    47994903        if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
    4800             ataR3PIOTransferFinish(pCtl, s);
    4801 #endif /* IN_RING3 */
     4904            ataHCPIOTransferFinish(pCtl, s);
     4905#endif /* IN_RING 3*/
    48024906    }
    48034907    else
     
    48104914{
    48114915    ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
    4812     uint8_t *p;
    48134916
    48144917    if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
    48154918    {
    48164919        Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
    4817         p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
    4818 #ifndef IN_RING3
     4920        uint8_t const *pbSrc = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
     4921
     4922#ifdef IN_RC
    48194923        /* All but the last transfer unit is simple enough for RC, but
    48204924         * sending a request to the async IO thread is too complicated. */
    48214925        if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
    4822         {
    4823             memcpy(pbBuf, p, cbSize);
    4824             s->iIOBufferPIODataStart += cbSize;
    4825         }
     4926            ataCopyPioData124(s, pbBuf, pbSrc, cbSize);
    48264927        else
    48274928            return VINF_IOM_R3_IOPORT_READ;
     4929
     4930#elif defined(IN_RING0)
     4931        /* Ring-0: We can do I/O thread signalling here.  However there is one
     4932           case in ataHCPIOTransfer that does a LogRel and would (but not from
     4933           here) call directly into the driver code.  We detect that odd case
     4934           here cand return to ring-3 to handle it. */
     4935        if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
     4936            ataCopyPioData124(s, pbBuf, pbSrc, cbSize);
     4937        else if (   s->cbTotalTransfer == 0
     4938                 || s->iSourceSink != ATAFN_SS_NULL
     4939                 || s->iIOBufferCur <= s->iIOBufferEnd)
     4940        {
     4941            ataCopyPioData124(s, pbBuf, pbSrc, cbSize);
     4942            ataHCPIOTransferFinish(pCtl, s);
     4943        }
     4944        else
     4945        {
     4946            Log(("%s: Unexpected\n",__FUNCTION__));
     4947            return VINF_IOM_R3_IOPORT_READ;
     4948        }
     4949
    48284950#else  /* IN_RING3 */
    4829         memcpy(pbBuf, p, cbSize);
    4830         s->iIOBufferPIODataStart += cbSize;
     4951        ataCopyPioData124(s, pbBuf, pbSrc, cbSize);
    48314952        if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
    4832             ataR3PIOTransferFinish(pCtl, s);
     4953            ataHCPIOTransferFinish(pCtl, s);
    48334954#endif /* IN_RING3 */
    48344955    }
     
    52165337                             * request. Occurs very rarely, not worth optimizing. */
    52175338                            LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    5218                             ataR3AsyncIOPutRequest(pCtl, pReq);
     5339                            ataHCAsyncIOPutRequest(pCtl, pReq);
    52195340                            break;
    52205341                        }
     
    52445365                        {
    52455366                            Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    5246                             ataR3AsyncIOPutRequest(pCtl, &g_ataDMARequest);
     5367                            ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest);
    52475368                        }
    52485369                    }
     
    52525373                        /* Finish DMA transfer. */
    52535374                        ataR3DMATransferStop(s);
    5254                         ataR3SetIRQ(s);
     5375                        ataHCSetIRQ(s);
    52555376                        pCtl->uAsyncIOState = ATA_AIO_NEW;
    52565377                    }
     
    52605381                    if (s->cbTotalTransfer)
    52615382                    {
    5262                         ataR3PIOTransfer(pCtl);
     5383                        ataHCPIOTransfer(pCtl);
    52635384                        Assert(!pCtl->fRedo);
    52645385                        if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
    5265                             ataR3SetIRQ(s);
     5386                            ataHCSetIRQ(s);
    52665387
    52675388                        if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
     
    52885409                        Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
    52895410                        /* Finish PIO transfer. */
    5290                         ataR3PIOTransfer(pCtl);
     5411                        ataHCPIOTransfer(pCtl);
    52915412                        Assert(!pCtl->fRedo);
    52925413                        if (!s->fATAPITransfer)
    5293                             ataR3SetIRQ(s);
     5414                            ataHCSetIRQ(s);
    52945415                        pCtl->uAsyncIOState = ATA_AIO_NEW;
    52955416                    }
     
    53205441                {
    53215442                    LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
    5322                     ataR3AsyncIOPutRequest(pCtl, &g_ataDMARequest);
     5443                    ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest);
    53235444                    break;
    53245445                }
     
    53485469                    s->fATAPITransfer = false;
    53495470                }
    5350                 ataR3SetIRQ(s);
     5471                ataHCSetIRQ(s);
    53515472                pCtl->uAsyncIOState = ATA_AIO_NEW;
    53525473                break;
     
    53655486                    {
    53665487                        LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
    5367                         ataR3AsyncIOPutRequest(pCtl, &g_ataPIORequest);
     5488                        ataHCAsyncIOPutRequest(pCtl, &g_ataPIORequest);
    53685489                        break;
    53695490                    }
     
    53885509                if (s->cbTotalTransfer)
    53895510                {
    5390                     ataR3PIOTransfer(pCtl);
    5391                     ataR3SetIRQ(s);
     5511                    ataHCPIOTransfer(pCtl);
     5512                    ataHCSetIRQ(s);
    53925513
    53935514                    if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
     
    54135534                {
    54145535                    /* Finish PIO transfer. */
    5415                     ataR3PIOTransfer(pCtl);
     5536                    ataHCPIOTransfer(pCtl);
    54165537                    if (    !pCtl->fChainedTransfer
    54175538                        &&  !s->fATAPITransfer
    54185539                        &&  s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
    54195540                    {
    5420                             ataR3SetIRQ(s);
     5541                            ataHCSetIRQ(s);
    54215542                    }
    54225543                    pCtl->uAsyncIOState = ATA_AIO_NEW;
     
    54265547            case ATA_AIO_RESET_ASSERTED:
    54275548                pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
    5428                 ataR3PIOTransferStop(&pCtl->aIfs[0]);
    5429                 ataR3PIOTransferStop(&pCtl->aIfs[1]);
     5549                ataHCPIOTransferStop(&pCtl->aIfs[0]);
     5550                ataHCPIOTransferStop(&pCtl->aIfs[1]);
    54305551                /* Do not change the DMA registers, they are not affected by the
    54315552                 * ATA controller reset logic. It should be sufficient to issue a
     
    54715592                    /* Stop any pending DMA transfer. */
    54725593                    s->fDMA = false;
    5473                     ataR3PIOTransferStop(s);
     5594                    ataHCPIOTransferStop(s);
    54745595                    ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
    54755596                    ataSetStatus(s, ATA_STAT_READY);
    5476                     ataR3SetIRQ(s);
     5597                    ataHCSetIRQ(s);
    54775598                }
    54785599                break;
     
    56005721        {
    56015722            Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    5602             ataR3AsyncIOPutRequest(pCtl, &g_ataDMARequest);
     5723            ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest);
    56035724        }
    56045725#else /* !IN_RING3 */
     
    59426063        PDMCritSectLeave(&pCtl->lock);
    59436064    }
     6065
    59446066    return rc;
    59456067}
     
    60076129# ifdef IN_RING3
    60086130        if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
    6009             ataR3PIOTransferFinish(pCtl, s);
     6131            ataHCPIOTransferFinish(pCtl, s);
    60106132# endif /* IN_RING3 */
    60116133    }
     
    60766198# ifdef IN_RING3
    60776199        if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
    6078             ataR3PIOTransferFinish(pCtl, s);
     6200            ataHCPIOTransferFinish(pCtl, s);
    60796201# endif /* IN_RING3 */
    60806202    }
     
    69117033        ataR3AsyncIOClearRequests(&pThis->aCts[i]);
    69127034        Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
    6913         ataR3AsyncIOPutRequest(&pThis->aCts[i], &g_ataResetARequest);
    6914         ataR3AsyncIOPutRequest(&pThis->aCts[i], &g_ataResetCRequest);
     7035        ataHCAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetARequest);
     7036        ataHCAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetCRequest);
    69157037
    69167038        PDMCritSectLeave(&pThis->aCts[i].lock);
     
    73057427    {
    73067428        rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTHCPTR)(uintptr_t)i,
    7307                                      ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
     7429                                     ataIOPortWrite1, ataIOPortRead1,
     7430                                     ataIOPortWriteStr1, ataIOPortReadStr1,
     7431                                     "ATA I/O Base 1");
    73087432        if (RT_FAILURE(rc))
    73097433            return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers"));
     
    73127436        {
    73137437            rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
    7314                                            "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
     7438                                           "ataIOPortWrite1", "ataIOPortRead1",
     7439                                           "ataIOPortWriteStr1", "ataIOPortReadStr1",
     7440                                           "ATA I/O Base 1");
    73157441            if (RT_FAILURE(rc))
    73167442                return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)"));
  • trunk/src/VBox/VMM/VMMR0/VMMR0.def

    r55980 r56404  
    2424    PDMCritSectIsOwner
    2525    PDMCritSectLeave
     26    PDMHCCritSectScheduleExitEvent
    2627    PDMCritSectTryEnter
    2728    PDMCritSectTryEnterDebug
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