Changeset 74919 in vbox for trunk/src/VBox/Devices/Serial
- Timestamp:
- Oct 18, 2018 1:12:30 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 125921
- Location:
- trunk/src/VBox/Devices/Serial
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/UartCore.cpp
r74446 r74919 731 731 } 732 732 733 } 734 735 736 /** 737 * Tries to copy the specified amount of data from the active TX queue (register or FIFO). 738 * 739 * @returns nothing. 740 * @param pThis The serial port instance. 741 * @param pvBuf Where to store the data. 742 * @param cbRead How much to read from the TX queue. 743 * @param pcbRead Where to store the amount of data read. 744 */ 745 static void uartR3TxQueueCopyFrom(PUARTCORE pThis, void *pvBuf, size_t cbRead, size_t *pcbRead) 746 { 747 if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN) 748 { 749 *pcbRead = uartFifoCopyTo(&pThis->FifoXmit, pvBuf, cbRead); 750 if (!pThis->FifoXmit.cbUsed) 751 { 752 UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_THRE); 753 pThis->fThreEmptyPending = true; 754 } 755 if (*pcbRead) 756 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_TEMT); 757 uartIrqUpdate(pThis); 758 } 759 else if (!(pThis->uRegLsr & UART_REG_LSR_THRE)) 760 { 761 *(uint8_t *)pvBuf = pThis->uRegThr; 762 *pcbRead = 1; 763 UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_THRE); 764 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_TEMT); 765 pThis->fThreEmptyPending = true; 766 uartIrqUpdate(pThis); 767 } 768 else 769 { 770 /* 771 * This can happen if there was data in the FIFO when the connection was closed, 772 * indicate this condition to the lower driver by returning 0 bytes. 773 */ 774 *pcbRead = 0; 775 } 733 776 } 734 777 #endif … … 803 846 LogRelMax(10, ("Serial#%d: Failed to send data with %Rrc\n", pThis->pDevInsR3->iInstance, rc2)); 804 847 } 848 else 849 TMTimerSetRelative(pThis->CTX_SUFF(pTimerTxUnconnected), pThis->cSymbolXferTicks, NULL); 805 850 #endif 806 851 } … … 1377 1422 } 1378 1423 1424 /** 1425 * @callback_method_impl{FNTMTIMERDEV, TX timer function when there is no driver connected for draining the THR/FIFO.} 1426 */ 1427 static DECLCALLBACK(void) uartR3TxUnconnectedTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 1428 { 1429 LogFlowFunc(("pDevIns=%#p pTimer=%#p pvUser=%#p\n", pDevIns, pTimer, pvUser)); 1430 RT_NOREF(pDevIns, pTimer); 1431 PUARTCORE pThis = (PUARTCORE)pvUser; 1432 PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED); 1433 uint8_t bIgnore = 0; 1434 size_t cbRead = 0; 1435 uartR3TxQueueCopyFrom(pThis, &bIgnore, sizeof(uint8_t), &cbRead); 1436 if (cbRead == 1) 1437 TMTimerSetRelative(pThis->CTX_SUFF(pTimerTxUnconnected), pThis->cSymbolXferTicks, NULL); 1438 PDMCritSectLeave(&pThis->CritSect); 1439 } 1440 1379 1441 1380 1442 /* -=-=-=-=-=-=-=-=- PDMISERIALPORT on LUN#0 -=-=-=-=-=-=-=-=- */ … … 1438 1500 1439 1501 PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED); 1440 if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN) 1441 { 1442 *pcbRead = uartFifoCopyTo(&pThis->FifoXmit, pvBuf, cbRead); 1443 if (!pThis->FifoXmit.cbUsed) 1444 { 1445 UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_THRE); 1446 pThis->fThreEmptyPending = true; 1447 } 1448 if (*pcbRead) 1449 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_TEMT); 1450 uartIrqUpdate(pThis); 1451 } 1452 else if (!(pThis->uRegLsr & UART_REG_LSR_THRE)) 1453 { 1454 *(uint8_t *)pvBuf = pThis->uRegThr; 1455 *pcbRead = 1; 1456 UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_THRE); 1457 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_TEMT); 1458 pThis->fThreEmptyPending = true; 1459 uartIrqUpdate(pThis); 1460 } 1461 else 1462 { 1463 /* 1464 * This can happen if there was data in the FIFO when the connection was closed, 1465 * idicate this condition to the lower driver by returning 0 bytes. 1466 */ 1467 *pcbRead = 0; 1468 } 1502 uartR3TxQueueCopyFrom(pThis, pvBuf, cbRead, pcbRead); 1469 1503 PDMCritSectLeave(&pThis->CritSect); 1470 1504 … … 1539 1573 SSMR3PutU8(pSSM, pThis->FifoRecv.cbItl); 1540 1574 1541 return TMR3TimerSave(pThis->pTimerRcvFifoTimeoutR3, pSSM); 1575 int rc = TMR3TimerSave(pThis->pTimerRcvFifoTimeoutR3, pSSM); 1576 if (RT_SUCCESS(rc)) 1577 rc = TMR3TimerSave(pThis->pTimerTxUnconnectedR3, pSSM); 1578 1579 return rc; 1542 1580 } 1543 1581 … … 1570 1608 1571 1609 TMR3TimerLoad(pThis->pTimerRcvFifoTimeoutR3, pSSM); 1610 if (uVersion > UART_SAVED_STATE_VERSION_PRE_UNCONNECTED_TX_TIMER) 1611 TMR3TimerLoad(pThis->pTimerTxUnconnectedR3, pSSM); 1572 1612 } 1573 1613 else … … 1665 1705 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pThis->pDevInsR3); 1666 1706 pThis->pTimerRcvFifoTimeoutRC = TMTimerRCPtr(pThis->pTimerRcvFifoTimeoutR3); 1707 pThis->pTimerTxUnconnectedRC = TMTimerRCPtr(pThis->pTimerTxUnconnectedR3); 1667 1708 } 1668 1709 … … 1810 1851 pThis->pTimerRcvFifoTimeoutRC = TMTimerRCPtr(pThis->pTimerRcvFifoTimeoutR3); 1811 1852 1853 /* 1854 * Create the transmit timer when no device is connected. 1855 */ 1856 rc = PDMDevHlpTMTimerCreate(pDevInsR3, TMCLOCK_VIRTUAL, uartR3TxUnconnectedTimer, pThis, 1857 TMTIMER_FLAGS_NO_CRIT_SECT, "UART TX uncon. Timer", 1858 &pThis->pTimerTxUnconnectedR3); 1859 AssertRCReturn(rc, rc); 1860 1861 rc = TMR3TimerSetCritSect(pThis->pTimerTxUnconnectedR3, &pThis->CritSect); 1862 AssertRCReturn(rc, rc); 1863 1864 pThis->pTimerTxUnconnectedR0 = TMTimerR0Ptr(pThis->pTimerTxUnconnectedR3); 1865 pThis->pTimerTxUnconnectedRC = TMTimerRCPtr(pThis->pTimerTxUnconnectedR3); 1866 1812 1867 uartR3Reset(pThis); 1813 1868 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Serial/UartCore.h
r73636 r74919 33 33 34 34 /** The current serial code saved state version. */ 35 #define UART_SAVED_STATE_VERSION 6 35 #define UART_SAVED_STATE_VERSION 7 36 /** Saved state version before the TX timer for the connected device case was added. */ 37 #define UART_SAVED_STATE_VERSION_PRE_UNCONNECTED_TX_TIMER 6 36 38 /** Saved state version of the legacy code which got replaced after 5.2. */ 37 #define UART_SAVED_STATE_VERSION_LEGACY_CODE 539 #define UART_SAVED_STATE_VERSION_LEGACY_CODE 5 38 40 /** Includes some missing bits from the previous saved state. */ 39 #define UART_SAVED_STATE_VERSION_MISSING_BITS 441 #define UART_SAVED_STATE_VERSION_MISSING_BITS 4 40 42 /** Saved state version when only the 16450 variant was implemented. */ 41 #define UART_SAVED_STATE_VERSION_16450 343 #define UART_SAVED_STATE_VERSION_16450 3 42 44 43 45 /** Maximum size of a FIFO. */ … … 140 142 UARTTYPE enmType; 141 143 142 /** R3 timer pointer fo the character timeout indication. */144 /** R3 timer pointer for the character timeout indication. */ 143 145 PTMTIMERR3 pTimerRcvFifoTimeoutR3; 146 /** R3 timer pointer for the send loop if no driver is connected. */ 147 PTMTIMERR3 pTimerTxUnconnectedR3; 144 148 /** R3 interrupt request callback of the owning device. */ 145 149 R3PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR3; 146 150 /** R0 timer pointer fo the character timeout indication. */ 147 151 PTMTIMERR0 pTimerRcvFifoTimeoutR0; 152 /** R0 timer pointer for the send loop if no driver is connected. */ 153 PTMTIMERR0 pTimerTxUnconnectedR0; 148 154 /** R0 interrupt request callback of the owning device. */ 149 155 R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR0; 150 156 /** RC timer pointer fo the character timeout indication. */ 151 157 PTMTIMERRC pTimerRcvFifoTimeoutRC; 152 /** RC interrupt request callback of the owning device. */ 158 /** RC timer pointer for the send loop if no driver is connected. */ 159 PTMTIMERRC pTimerTxUnconnectedRC; 160 /** RC interrupt request callback of the owning device. */ 153 161 RCPTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqRC; 162 /** Alignment */ 163 uint32_t u32Alignment; 154 164 155 165 /** The divisor register (DLAB = 1). */ … … 187 197 /** Alignment. */ 188 198 bool afAlignment[2]; 189 199 /** The transmit FIFO. */ 190 200 UARTFIFO FifoXmit; 191 201 /** The receive FIFO. */
Note:
See TracChangeset
for help on using the changeset viewer.