VirtualBox

Changeset 72132 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 6, 2018 7:40:10 PM (7 years ago)
Author:
vboxsync
Message:

DevSerialNew,DrvHostSerialNew: Some bugfixes

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Serial/DevSerialNew.cpp

    r72118 r72132  
    6464# define UART_REG_IIR_ID_MASK                0x0e
    6565/** Sets the interrupt identification to the given value. */
    66 # define UART_REG_IIR_ID_SET(a_Val)          (((a_Val) & UART_REG_IIR_ID_MASK) << 1)
     66# define UART_REG_IIR_ID_SET(a_Val)          (((a_Val) << 1) & UART_REG_IIR_ID_MASK)
    6767/** Receiver Line Status interrupt. */
    6868#  define UART_REG_IIR_ID_RCL                0x3
     
    304304static void serialIrqUpdate(PDEVSERIAL pThis)
    305305{
     306    LogFlowFunc(("pThis=%#p\n", pThis));
     307
    306308    /*
    307309     * The interrupt uses a priority scheme, only the interrupt with the
     
    327329    else if (   (pThis->uRegMsr & UART_REG_MSR_BITS_IIR_MS)
    328330             && (pThis->uRegIer & UART_REG_IER_EDSSI))
    329         uRegIirNew = UART_REG_IIR_ID_SET(UART_REG_MSR_BITS_IIR_MS);
     331        uRegIirNew = UART_REG_IIR_ID_SET(UART_REG_IIR_ID_MS);
    330332
    331333    /** @todo Character timeout indication for FIFO mode. */
    332334
    333     LogFlowFunc(("uRegIirNew=%#x uRegIir=%#x\n", uRegIirNew, pThis->uRegIir));
     335    LogFlowFunc(("    uRegIirNew=%#x uRegIir=%#x\n", uRegIirNew, pThis->uRegIir));
    334336
    335337    /* Change interrupt only if the interrupt status really changed from the previous value. */
    336338    if (uRegIirNew != (pThis->uRegIir & UART_REG_IIR_CHANGED_MASK))
    337339    {
     340        LogFlow(("    Interrupt source changed from %#x -> %#x (IRQ %d -> %d)\n",
     341                 pThis->uRegIir, uRegIirNew,
     342                 pThis->uRegIir == UART_REG_IIR_IP_NO_INT ? 0 : 1,
     343                 uRegIirNew == UART_REG_IIR_IP_NO_INT ? 0 : 1));
    338344        if (uRegIirNew == UART_REG_IIR_IP_NO_INT)
    339345            PDMDevHlpISASetIrqNoWait(pThis->CTX_SUFF(pDevIns), pThis->uIrq, 0);
     
    341347            PDMDevHlpISASetIrqNoWait(pThis->CTX_SUFF(pDevIns), pThis->uIrq, 1);
    342348    }
     349    else
     350        LogFlow(("    No change in interrupt source\n"));
    343351
    344352    if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN)
     
    482490#else
    483491                pThis->uRegThr = uVal;
    484                 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE);
     492                UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT);
    485493                if (pThis->pDrvSerial)
    486494                {
     
    756764
    757765
     766#ifdef LOG_ENABLED
     767/**
     768 * Converts the register index into a sensible memnonic.
     769 *
     770 * @returns Register memnonic.
     771 * @param   pThis               The serial port instance.
     772 * @param   idxReg              Register index.
     773 * @param   fWrite              Flag whether the register gets written.
     774 */
     775DECLINLINE(const char *) serialRegIdx2Str(PDEVSERIAL pThis, uint8_t idxReg, bool fWrite)
     776{
     777    const char *psz = "INV";
     778
     779    switch (idxReg)
     780    {
     781        /*case UART_REG_THR_DLL_INDEX:*/
     782        case UART_REG_RBR_DLL_INDEX:
     783            if (pThis->uRegLcr & UART_REG_LCR_DLAB)
     784                psz = "DLL";
     785            else if (fWrite)
     786                psz = "THR";
     787            else
     788                psz = "RBR";
     789            break;
     790        case UART_REG_IER_DLM_INDEX:
     791            if (pThis->uRegLcr & UART_REG_LCR_DLAB)
     792                psz = "DLM";
     793            else
     794                psz = "IER";
     795            break;
     796        /*case UART_REG_IIR_INDEX:*/
     797        case UART_REG_FCR_INDEX:
     798            if (fWrite)
     799                psz = "FCR";
     800            else
     801                psz = "IIR";
     802            break;
     803        case UART_REG_LCR_INDEX:
     804            psz = "LCR";
     805            break;
     806        case UART_REG_MCR_INDEX:
     807            psz = "MCR";
     808            break;
     809        case UART_REG_LSR_INDEX:
     810            psz = "LSR";
     811            break;
     812        case UART_REG_MSR_INDEX:
     813            psz = "MSR";
     814            break;
     815        case UART_REG_SCR_INDEX:
     816            psz = "SCR";
     817            break;
     818    }
     819
     820    return psz;
     821}
     822#endif
     823
    758824/* -=-=-=-=-=-=-=-=- I/O Port Access Handlers -=-=-=-=-=-=-=-=- */
    759825
     
    767833    RT_NOREF_PV(pvUser);
    768834
    769     LogFlowFunc(("pDevIns=%#p pvUser=%#p uPort=%RTiop u32=%#x cb=%u\n",
    770                  pDevIns, pvUser, uPort, u32, cb));
     835    uint8_t idxReg = uPort & 0x7;
     836    LogFlowFunc(("pDevIns=%#p pvUser=%#p uPort=%RTiop{%s} u32=%#x cb=%u\n",
     837                 pDevIns, pvUser, uPort, serialRegIdx2Str(pThis, idxReg, true /*fWrite*/), u32, cb));
    771838
    772839    AssertMsgReturn(cb == 1, ("uPort=%#x cb=%d u32=%#x\n", uPort, cb, u32), VINF_SUCCESS);
     
    774841    int rc = VINF_SUCCESS;
    775842    uint8_t uVal = (uint8_t)u32;
    776     switch (uPort & 0x7)
     843    switch (idxReg)
    777844    {
    778845        case UART_REG_THR_DLL_INDEX:
     
    815882        return VERR_IOM_IOPORT_UNUSED;
    816883
     884    uint8_t idxReg = uPort & 0x7;
    817885    int rc = VINF_SUCCESS;
    818     switch (uPort & 0x7)
     886    switch (idxReg)
    819887    {
    820888        case UART_REG_RBR_DLL_INDEX:
     
    846914    }
    847915
    848     LogFlowFunc(("pDevIns=%#p pvUser=%#p uPort=%RTiop u32=%#x cb=%u -> %Rrc\n",
    849                  pDevIns, pvUser, uPort, *pu32, cb, rc));
     916    LogFlowFunc(("pDevIns=%#p pvUser=%#p uPort=%RTiop{%s} u32=%#x cb=%u -> %Rrc\n",
     917                 pDevIns, pvUser, uPort, serialRegIdx2Str(pThis, idxReg, false /*fWrite*/), *pu32, cb, rc));
    850918    return rc;
    851919}
     
    862930static DECLCALLBACK(int) serialR3DataAvailRdrNotify(PPDMISERIALPORT pInterface, size_t cbAvail)
    863931{
     932    LogFlowFunc(("pInterface=%#p cbAvail=%zu\n", pInterface, cbAvail));
    864933    PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ISerialPort);
    865934
     
    869938    if (!cbAvailOld)
    870939    {
     940        LogFlow(("    cbAvailRdr=0 -> cbAvailRdr=%zu\n", cbAvail));
    871941        PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
    872942        size_t cbRead = 0;
     
    877947        PDMCritSectLeave(&pThis->CritSect);
    878948    }
     949    else
     950        LogFlow(("    cbAvailOld=%zu\n", cbAvailOld));
    879951    return VINF_SUCCESS;
    880952}
     
    886958static DECLCALLBACK(int) serialR3DataSentNotify(PPDMISERIALPORT pInterface)
    887959{
     960    LogFlowFunc(("pInterface=%#p\n", pInterface));
    888961    PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ISerialPort);
    889962
     
    902975static DECLCALLBACK(int) serialR3ReadWr(PPDMISERIALPORT pInterface, void *pvBuf, size_t cbRead, size_t *pcbRead)
    903976{
     977    LogFlowFunc(("pInterface=%#p pvBuf=%#p cbRead=%zu pcbRead=%#p\n", pInterface, pvBuf, cbRead, pcbRead));
    904978    PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ISerialPort);
    905979
     
    922996    }
    923997
     998    LogFlowFunc(("-> VINF_SUCCESS{*pcbRead=%zu}\n", *pcbRead));
    924999    PDMCritSectLeave(&pThis->CritSect);
    9251000    return VINF_SUCCESS;
     
    9321007static DECLCALLBACK(int) serialR3NotifyStsLinesChanged(PPDMISERIALPORT pInterface, uint32_t fNewStatusLines)
    9331008{
     1009    LogFlowFunc(("pInterface=%#p fNewStatusLines=%#x\n", pInterface, fNewStatusLines));
    9341010    PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ISerialPort);
    9351011
     
    9461022static DECLCALLBACK(int) serialR3NotifyBrk(PPDMISERIALPORT pInterface)
    9471023{
     1024    LogFlowFunc(("pInterface=%#p\n", pInterface));
    9481025    PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ISerialPort);
    9491026
  • trunk/src/VBox/Devices/Serial/DrvHostSerialNew.cpp

    r72117 r72132  
    4646 * Char driver instance data.
    4747 *
    48  * @implements  PDMICHARCONNECTOR
     48 * @implements  PDMISERIALCONNECTOR
    4949 */
    5050typedef struct DRVHOSTSERIAL
     
    7676    /** Current offset into the read buffer. */
    7777    volatile uint32_t           offRead;
     78    /** Current amount of data in the buffer. */
     79    volatile size_t             cbReadBuf;
    7880
    7981    /** Read/write statistics */
     
    103105DECLINLINE(size_t) drvHostSerialReadBufGetWrite(PDRVHOSTSERIAL pThis, void **ppv)
    104106{
    105     uint32_t offRead  = ASMAtomicReadU32(&pThis->offRead);
    106     uint32_t offWrite = ASMAtomicReadU32(&pThis->offWrite);
    107 
    108107    if (ppv)
    109         *ppv = &pThis->abReadBuf[offWrite];
    110 
    111     if (offWrite >= offRead)
    112         return sizeof(pThis->abReadBuf) - offWrite;
    113     else
    114         return offRead - offWrite - 1; /* Leave one byte free. */
     108        *ppv = &pThis->abReadBuf[pThis->offWrite];
     109
     110    size_t cbFree = sizeof(pThis->abReadBuf) - ASMAtomicReadZ(&pThis->cbReadBuf);
     111    if (cbFree)
     112        cbFree = RT_MIN(cbFree, sizeof(pThis->abReadBuf) - pThis->offWrite);
     113
     114    return cbFree;
    115115}
    116116
     
    125125DECLINLINE(size_t) drvHostSerialReadBufGetRead(PDRVHOSTSERIAL pThis, void **ppv)
    126126{
    127     uint32_t offRead  = ASMAtomicReadU32(&pThis->offRead);
    128     uint32_t offWrite = ASMAtomicReadU32(&pThis->offWrite);
    129 
    130127    if (ppv)
    131         *ppv = &pThis->abReadBuf[offRead];
    132 
    133     if (offWrite < offRead)
    134         return sizeof(pThis->abReadBuf) - offRead;
    135     else
    136         return offWrite - offRead;
     128        *ppv = &pThis->abReadBuf[pThis->offRead];
     129
     130    size_t cbUsed = ASMAtomicReadZ(&pThis->cbReadBuf);
     131    if (cbUsed)
     132        cbUsed = RT_MIN(cbUsed, sizeof(pThis->abReadBuf) - pThis->offRead);
     133
     134    return cbUsed;
    137135}
    138136
     
    150148    offWrite = (offWrite + cbAdv) % sizeof(pThis->abReadBuf);
    151149    ASMAtomicWriteU32(&pThis->offWrite, offWrite);
     150    ASMAtomicAddZ(&pThis->cbReadBuf, cbAdv);
    152151}
    153152
     
    165164    offRead = (offRead + cbAdv) % sizeof(pThis->abReadBuf);
    166165    ASMAtomicWriteU32(&pThis->offRead, offRead);
     166    ASMAtomicSubZ(&pThis->cbReadBuf, cbAdv);
    167167}
    168168
     
    228228
    229229    *pcbRead = cbReadAll;
     230    /* Kick the I/O thread if there is nothing to read to recalculate the poll flags. */
     231    if (!drvHostSerialReadBufGetRead(pThis, NULL))
     232        rc = RTSerialPortEvtPollInterrupt(pThis->hSerialPort);
    230233
    231234    STAM_COUNTER_ADD(&pThis->StatBytesRead, cbReadAll);
     
    549552     * Init basic data members and interfaces.
    550553     */
     554    pThis->pDrvIns                               = pDrvIns;
    551555    pThis->hSerialPort                           = NIL_RTSERIALPORT;
    552556    pThis->cbAvailWr                             = 0;
     
    554558    pThis->offWrite                              = 0;
    555559    pThis->offRead                               = 0;
     560    pThis->cbReadBuf                             = 0;
    556561    /* IBase. */
    557562    pDrvIns->IBase.pfnQueryInterface             = drvHostSerialQueryInterface;
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