Changeset 77411 in vbox
- Timestamp:
- Feb 21, 2019 3:57:31 PM (6 years ago)
- Location:
- trunk/src/VBox/Devices/Serial
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/UartCore.cpp
r76553 r77411 706 706 static void uartR3XferReset(PUARTCORE pThis) 707 707 { 708 TMTimerStop(pThis->CTX_SUFF(pTimerRcvFifoTimeout)); 709 TMTimerStop(pThis->CTX_SUFF(pTimerTxUnconnected)); 708 710 pThis->uRegLsr = UART_REG_LSR_THRE | UART_REG_LSR_TEMT; 709 711 pThis->fThreEmptyPending = false; … … 779 781 780 782 /** 783 * Transmits the given byte. 784 * 785 * @returns VBox status code. 786 * @param pThis The serial port instance. 787 * @param bVal Byte to transmit. 788 */ 789 static int uartXmit(PUARTCORE pThis, uint8_t bVal) 790 { 791 int rc = VINF_SUCCESS; 792 793 if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN) 794 { 795 #ifndef IN_RING3 796 if (!uartFifoUsedGet(&pThis->FifoXmit)) 797 rc = VINF_IOM_R3_IOPORT_WRITE; 798 else 799 { 800 uartFifoPut(&pThis->FifoXmit, true /*fOvrWr*/, bVal); 801 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT); 802 } 803 #else 804 uartFifoPut(&pThis->FifoXmit, true /*fOvrWr*/, bVal); 805 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT); 806 pThis->fThreEmptyPending = false; 807 uartIrqUpdate(pThis); 808 if (uartFifoUsedGet(&pThis->FifoXmit) == 1) 809 { 810 if ( pThis->pDrvSerial 811 && !(pThis->uRegMcr & UART_REG_MCR_LOOP)) 812 { 813 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial); 814 if (RT_FAILURE(rc2)) 815 LogRelMax(10, ("Serial#%d: Failed to send data with %Rrc\n", pThis->pDevInsR3->iInstance, rc2)); 816 } 817 else 818 TMTimerSetRelative(pThis->CTX_SUFF(pTimerTxUnconnected), pThis->cSymbolXferTicks, NULL); 819 } 820 #endif 821 } 822 else 823 { 824 /* Notify the lower driver about available data only if the register was empty before. */ 825 if (pThis->uRegLsr & UART_REG_LSR_THRE) 826 { 827 #ifndef IN_RING3 828 rc = VINF_IOM_R3_IOPORT_WRITE; 829 #else 830 pThis->uRegThr = bVal; 831 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT); 832 pThis->fThreEmptyPending = false; 833 uartIrqUpdate(pThis); 834 if ( pThis->pDrvSerial 835 && !(pThis->uRegMcr & UART_REG_MCR_LOOP)) 836 { 837 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial); 838 if (RT_FAILURE(rc2)) 839 LogRelMax(10, ("Serial#%d: Failed to send data with %Rrc\n", pThis->pDevInsR3->iInstance, rc2)); 840 } 841 else 842 TMTimerSetRelative(pThis->CTX_SUFF(pTimerTxUnconnected), pThis->cSymbolXferTicks, NULL); 843 #endif 844 } 845 else 846 pThis->uRegThr = bVal; 847 } 848 849 return rc; 850 } 851 852 853 /** 781 854 * Write handler for the THR/DLL register (depending on the DLAB bit in LCR). 782 855 * … … 803 876 } 804 877 else 805 { 806 if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN) 807 { 808 #ifndef IN_RING3 809 if (!uartFifoUsedGet(&pThis->FifoXmit)) 810 rc = VINF_IOM_R3_IOPORT_WRITE; 811 else 812 { 813 uartFifoPut(&pThis->FifoXmit, true /*fOvrWr*/, uVal); 814 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT); 815 } 816 #else 817 uartFifoPut(&pThis->FifoXmit, true /*fOvrWr*/, uVal); 818 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT); 819 pThis->fThreEmptyPending = false; 820 uartIrqUpdate(pThis); 821 if ( pThis->pDrvSerial 822 && uartFifoUsedGet(&pThis->FifoXmit) == 1) 823 { 824 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial); 825 if (RT_FAILURE(rc2)) 826 LogRelMax(10, ("Serial#%d: Failed to send data with %Rrc\n", pThis->pDevInsR3->iInstance, rc2)); 827 } 828 #endif 829 } 830 else 831 { 832 /* Notify the lower driver about available data only if the register was empty before. */ 833 if (pThis->uRegLsr & UART_REG_LSR_THRE) 834 { 835 #ifndef IN_RING3 836 rc = VINF_IOM_R3_IOPORT_WRITE; 837 #else 838 pThis->uRegThr = uVal; 839 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT); 840 pThis->fThreEmptyPending = false; 841 uartIrqUpdate(pThis); 842 if (pThis->pDrvSerial) 843 { 844 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial); 845 if (RT_FAILURE(rc2)) 846 LogRelMax(10, ("Serial#%d: Failed to send data with %Rrc\n", pThis->pDevInsR3->iInstance, rc2)); 847 } 848 else 849 TMTimerSetRelative(pThis->CTX_SUFF(pTimerTxUnconnected), pThis->cSymbolXferTicks, NULL); 850 #endif 851 } 852 else 853 pThis->uRegThr = uVal; 854 } 855 } 878 rc = uartXmit(pThis, uVal); 856 879 857 880 return rc; … … 1431 1454 PUARTCORE pThis = (PUARTCORE)pvUser; 1432 1455 PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED); 1433 uint8_t b Ignore= 0;1456 uint8_t bVal = 0; 1434 1457 size_t cbRead = 0; 1435 uartR3TxQueueCopyFrom(pThis, &bIgnore, sizeof(uint8_t), &cbRead); 1458 uartR3TxQueueCopyFrom(pThis, &bVal, sizeof(bVal), &cbRead); 1459 if (pThis->uRegMcr & UART_REG_MCR_LOOP) 1460 { 1461 /* Loopback mode is active, feed in the data at the receiving end. */ 1462 uint32_t cbAvailOld = ASMAtomicAddU32(&pThis->cbAvailRdr, 1); 1463 if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN) 1464 { 1465 PUARTFIFO pFifo = &pThis->FifoRecv; 1466 if (uartFifoFreeGet(pFifo) > 0) 1467 { 1468 pFifo->abBuf[pFifo->offWrite] = bVal; 1469 pFifo->offWrite = (pFifo->offWrite + 1) % pFifo->cbMax; 1470 pFifo->cbUsed++; 1471 1472 UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_DR); 1473 if (pFifo->cbUsed < pFifo->cbItl) 1474 { 1475 pThis->fIrqCtiPending = false; 1476 TMTimerSetRelative(pThis->CTX_SUFF(pTimerRcvFifoTimeout), pThis->cSymbolXferTicks * 4, NULL); 1477 } 1478 uartIrqUpdate(pThis); 1479 } 1480 1481 ASMAtomicSubU32(&pThis->cbAvailRdr, 1); 1482 } 1483 else if (!cbAvailOld) 1484 { 1485 pThis->uRegRbr = bVal; 1486 UART_REG_SET(pThis->uRegLsr, UART_REG_LSR_DR); 1487 uartIrqUpdate(pThis); 1488 } 1489 } 1436 1490 if (cbRead == 1) 1437 1491 TMTimerSetRelative(pThis->CTX_SUFF(pTimerTxUnconnected), pThis->cSymbolXferTicks, NULL); -
trunk/src/VBox/Devices/Serial/UartCore.h
r76565 r77411 148 148 /** R3 timer pointer for the character timeout indication. */ 149 149 PTMTIMERR3 pTimerRcvFifoTimeoutR3; 150 /** R3 timer pointer for the send loop if no driver is connected . */150 /** R3 timer pointer for the send loop if no driver is connected/loopback mode is active. */ 151 151 PTMTIMERR3 pTimerTxUnconnectedR3; 152 152 /** R3 interrupt request callback of the owning device. */ … … 154 154 /** R0 timer pointer fo the character timeout indication. */ 155 155 PTMTIMERR0 pTimerRcvFifoTimeoutR0; 156 /** R0 timer pointer for the send loop if no driver is connected . */156 /** R0 timer pointer for the send loop if no driver is connected/loopback mode is active. */ 157 157 PTMTIMERR0 pTimerTxUnconnectedR0; 158 158 /** R0 interrupt request callback of the owning device. */ … … 160 160 /** RC timer pointer fo the character timeout indication. */ 161 161 PTMTIMERRC pTimerRcvFifoTimeoutRC; 162 /** RC timer pointer for the send loop if no driver is connected . */162 /** RC timer pointer for the send loop if no driver is connected/loopback mode is active. */ 163 163 PTMTIMERRC pTimerTxUnconnectedRC; 164 164 /** RC interrupt request callback of the owning device. */
Note:
See TracChangeset
for help on using the changeset viewer.