VirtualBox

Changeset 73636 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 13, 2018 1:07:26 PM (6 years ago)
Author:
vboxsync
Message:

Devices/Serial: Fix Widows guests, the THRE empty interrupt status is only returned once to the guest every time it occurs

Location:
trunk/src/VBox/Devices
Files:
3 edited

Legend:

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

    r73528 r73636  
    6969/** Sets the interrupt identification to the given value. */
    7070# define UART_REG_IIR_ID_SET(a_Val)          (((a_Val) << 1) & UART_REG_IIR_ID_MASK)
     71/** Gets the interrupt identification from the given IIR register value. */
     72# define UART_REG_IIR_ID_GET(a_Val)          (((a_Val) >> 1) & UART_REG_IIR_ID_MASK)
    7173/** Receiver Line Status interrupt. */
    7274#  define UART_REG_IIR_ID_RCL                0x3
     
    303305        uRegIirNew = UART_REG_IIR_ID_SET(UART_REG_IIR_ID_RDA);
    304306    else if (   (pThis->uRegLsr & UART_REG_LSR_THRE)
    305              && (pThis->uRegIer & UART_REG_IER_ETBEI))
     307             && pThis->fThreEmptyPending)
    306308        uRegIirNew = UART_REG_IIR_ID_SET(UART_REG_IIR_ID_THRE);
    307309    else if (   (pThis->uRegMsr & UART_REG_MSR_BITS_IIR_MS)
     
    689691{
    690692    pThis->uRegLsr = UART_REG_LSR_THRE | UART_REG_LSR_TEMT;
     693    pThis->fThreEmptyPending = false;
    691694
    692695    uartFifoClear(&pThis->FifoXmit);
     
    749752            uartFifoPut(&pThis->FifoXmit, true /*fOvrWr*/, uVal);
    750753            UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT);
     754            pThis->fThreEmptyPending = false;
    751755            uartIrqUpdate(pThis);
    752756            if (pThis->pDrvSerial)
     
    768772                pThis->uRegThr = uVal;
    769773                UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT);
     774                pThis->fThreEmptyPending = false;
    770775                uartIrqUpdate(pThis);
    771776                if (pThis->pDrvSerial)
     
    11161121{
    11171122    *puVal = pThis->uRegIir;
     1123    /* Reset the THRE empty interrupt id when this gets returned to the guest (see table 3 UART Reset configuration). */
     1124    if (UART_REG_IIR_ID_GET(pThis->uRegIir) == UART_REG_IIR_ID_THRE)
     1125    {
     1126        pThis->fThreEmptyPending = false;
     1127        uartIrqUpdate(pThis);
     1128    }
    11181129    return VINF_SUCCESS;
    11191130}
     
    14061417        *pcbRead = uartFifoCopyTo(&pThis->FifoXmit, pvBuf, cbRead);
    14071418        if (!pThis->FifoXmit.cbUsed)
     1419        {
    14081420            UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_THRE);
     1421            pThis->fThreEmptyPending = true;
     1422        }
    14091423        if (*pcbRead)
    14101424            UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_TEMT);
     
    14171431        UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_THRE);
    14181432        UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_TEMT);
     1433        pThis->fThreEmptyPending = true;
    14191434        uartIrqUpdate(pThis);
    14201435    }
     
    14931508    SSMR3PutU8(pSSM,   pThis->uRegScr);
    14941509    SSMR3PutBool(pSSM, pThis->fIrqCtiPending);
     1510    SSMR3PutBool(pSSM, pThis->fThreEmptyPending);
    14951511    SSMR3PutU8(pSSM,   pThis->FifoXmit.cbMax);
    14961512    SSMR3PutU8(pSSM,   pThis->FifoXmit.cbItl);
     
    15221538        SSMR3GetU8(pSSM,   &pThis->uRegScr);
    15231539        SSMR3GetBool(pSSM, &pThis->fIrqCtiPending);
     1540        SSMR3GetBool(pSSM, &pThis->fThreEmptyPending);
    15241541        SSMR3GetU8(pSSM,   &pThis->FifoXmit.cbMax);
    15251542        SSMR3GetU8(pSSM,   &pThis->FifoXmit.cbItl);
     
    15381555
    15391556        int      uIrq;
     1557        int32_t  iTmp;
    15401558        uint32_t PortBase;
    15411559
     
    15501568        if (uVersion > UART_SAVED_STATE_VERSION_16450)
    15511569            SSMR3GetU8(pSSM, &pThis->uRegFcr);
    1552         SSMR3Skip(pSSM, sizeof(int32_t));
     1570        SSMR3GetS32(pSSM, &iTmp);
     1571        pThis->fThreEmptyPending = RT_BOOL(iTmp);
    15531572        SSMR3GetS32(pSSM, &uIrq);
    15541573        SSMR3Skip(pSSM, sizeof(int32_t));
     
    16381657    pThis->uRegScr        = 0;
    16391658    pThis->fIrqCtiPending = false;
     1659    pThis->fThreEmptyPending = false;
    16401660
    16411661    /* Standard FIFO size for 15550A. */
  • trunk/src/VBox/Devices/Serial/UartCore.h

    r73259 r73636  
    181181     * is not empty). */
    182182    bool                            fIrqCtiPending;
     183    /** Flag whether the transmitter holding register went empty since last time the
     184     * IIR register was read. This gets reset when IIR is read so the guest will get this
     185     * interrupt ID only once. */
     186    bool                            fThreEmptyPending;
    183187    /** Alignment. */
    184     bool                            afAlignment[3];
     188    bool                            afAlignment[2];
    185189        /** The transmit FIFO. */
    186190    UARTFIFO                        FifoXmit;
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r73243 r73636  
    13501350    GEN_CHECK_OFF(UARTCORE, uRegScr);
    13511351    GEN_CHECK_OFF(UARTCORE, fIrqCtiPending);
     1352    GEN_CHECK_OFF(UARTCORE, fThreEmptyPending);
    13521353    GEN_CHECK_OFF(UARTCORE, FifoXmit);
    13531354    GEN_CHECK_OFF(UARTCORE, FifoRecv);
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