Changeset 73243 in vbox for trunk/src/VBox/Devices/Serial
- Timestamp:
- Jul 19, 2018 3:08:34 PM (7 years ago)
- Location:
- trunk/src/VBox/Devices/Serial
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/DevSerialNew.cpp
r73135 r73243 125 125 126 126 127 /** 128 * Returns the matching UART type from the given string. 129 * 130 * @returns UART type based on the given string or UARTTYPE_INVALID if an invalid type was passed. 131 * @param pszUartType The UART type. 132 */ 133 static UARTTYPE serialR3GetUartTypeFromString(const char *pszUartType) 134 { 135 if (!RTStrCmp(pszUartType, "15450")) 136 return UARTTYPE_16450; 137 else if (!RTStrCmp(pszUartType, "15550A")) 138 return UARTTYPE_16550A; 139 else if (!RTStrCmp(pszUartType, "16750")) 140 return UARTTYPE_16750; 141 142 AssertLogRelMsgFailedReturn(("Unknown UART type \"%s\" specified", pszUartType), 143 UARTTYPE_INVALID); 144 } 145 146 127 147 /* -=-=-=-=-=-=-=-=- PDMDEVREG -=-=-=-=-=-=-=-=- */ 128 148 … … 209 229 "R0Enabled\0" 210 230 "YieldOnLSRRead\0" 211 " Enable16550A\0"231 "UartType\0" 212 232 )) 213 233 { … … 263 283 N_("Configuration error: Failed to get the \"IOBase\" value")); 264 284 265 bool f16550AEnabled = true; 266 rc = CFGMR3QueryBoolDef(pCfg, "Enable16550A", &f16550AEnabled, true); 267 if (RT_FAILURE(rc)) 268 return PDMDEV_SET_ERROR(pDevIns, rc, 269 N_("Configuration error: Failed to get the \"Enable16550A\" value")); 285 char *pszUartType; 286 rc = CFGMR3QueryStringAllocDef(pCfg, "UartType", &pszUartType, "16550A"); 287 if (RT_FAILURE(rc)) 288 return PDMDEV_SET_ERROR(pDevIns, rc, 289 N_("Configuration error: failed to read \"UartType\" as string")); 290 291 UARTTYPE enmUartType = serialR3GetUartTypeFromString(pszUartType); 292 293 if (enmUartType != UARTTYPE_INVALID) 294 LogRel(("Serial#%d: emulating %s (IOBase: %04x IRQ: %u)\n", 295 pDevIns->iInstance, pszUartType, uIoBase, uIrq)); 296 297 MMR3HeapFree(pszUartType); 298 299 if (enmUartType == UARTTYPE_INVALID) 300 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER, 301 N_("Configuration error: \"UartType\" contains invalid type")); 270 302 271 303 pThis->uIrq = uIrq; 272 304 pThis->PortBase = uIoBase; 273 274 LogRel(("Serial#%d: emulating %s (IOBase: %04x IRQ: %u)\n",275 pDevIns->iInstance, f16550AEnabled ? "16550A" : "16450", uIoBase, uIrq));276 305 277 306 /* … … 330 359 331 360 /* Init the UART core structure. */ 332 rc = uartR3Init(&pThis->UartCore, pDevIns, f16550AEnabled ? UARTTYPE_16550A : UARTTYPE_16450, 0,361 rc = uartR3Init(&pThis->UartCore, pDevIns, enmUartType, 0, 333 362 fYieldOnLSRRead ? UART_CORE_YIELD_ON_LSR_READ : 0, serialIrqReq, pfnSerialIrqReqR0, pfnSerialIrqReqRC); 334 363 -
trunk/src/VBox/Devices/Serial/DrvCharNew.cpp
r72117 r73243 231 231 AssertRC(rc); 232 232 233 ASMAtomicSubZ(&pThis->cbAvailWr, cbFetched); 234 pThis->cbTxUsed += cbFetched; 233 if (cbFetched > 0) 234 { 235 ASMAtomicSubZ(&pThis->cbAvailWr, cbFetched); 236 pThis->cbTxUsed += cbFetched; 237 } 238 else 239 { 240 /* The guest reset the send queue and there is no data available anymore. */ 241 pThis->cbAvailWr = 0; 242 } 235 243 } 236 244 -
trunk/src/VBox/Devices/Serial/DrvHostSerialNew.cpp
r72132 r73243 400 400 AssertRC(rc); 401 401 402 ASMAtomicSubZ(&pThis->cbAvailWr, cbFetched); 403 pThis->cbTxUsed += cbFetched; 404 } 405 406 size_t cbProcessed = 0; 407 rc = RTSerialPortWriteNB(pThis->hSerialPort, &pThis->abTxBuf[0], pThis->cbTxUsed, &cbProcessed); 408 if (RT_SUCCESS(rc)) 409 { 410 pThis->cbTxUsed -= cbProcessed; 411 if (pThis->cbTxUsed) 402 if (cbFetched > 0) 412 403 { 413 /* Move the data in the TX buffer to the front to fill the end again. */414 memmove(&pThis->abTxBuf[0], &pThis->abTxBuf[cbProcessed], pThis->cbTxUsed);404 ASMAtomicSubZ(&pThis->cbAvailWr, cbFetched); 405 pThis->cbTxUsed += cbFetched; 415 406 } 416 407 else 417 pThis->pDrvSerialPort->pfnDataSentNotify(pThis->pDrvSerialPort); 418 STAM_COUNTER_ADD(&pThis->StatBytesWritten, cbProcessed); 408 { 409 /* The guest reset the send queue and there is no data available anymore. */ 410 pThis->cbAvailWr = 0; 411 } 419 412 } 420 else 413 414 if (pThis->cbTxUsed) 421 415 { 422 LogRelMax(10, ("HostSerial#%d: Sending data failed even though the serial port is marked as writeable (rc=%Rrc)\n", 423 pThis->pDrvIns->iInstance, rc)); 424 break; 416 size_t cbProcessed = 0; 417 rc = RTSerialPortWriteNB(pThis->hSerialPort, &pThis->abTxBuf[0], pThis->cbTxUsed, &cbProcessed); 418 if (RT_SUCCESS(rc)) 419 { 420 pThis->cbTxUsed -= cbProcessed; 421 if (pThis->cbTxUsed) 422 { 423 /* Move the data in the TX buffer to the front to fill the end again. */ 424 memmove(&pThis->abTxBuf[0], &pThis->abTxBuf[cbProcessed], pThis->cbTxUsed); 425 } 426 else 427 pThis->pDrvSerialPort->pfnDataSentNotify(pThis->pDrvSerialPort); 428 STAM_COUNTER_ADD(&pThis->StatBytesWritten, cbProcessed); 429 } 430 else 431 { 432 LogRelMax(10, ("HostSerial#%d: Sending data failed even though the serial port is marked as writeable (rc=%Rrc)\n", 433 pThis->pDrvIns->iInstance, rc)); 434 break; 435 } 425 436 } 426 437 } -
trunk/src/VBox/Devices/Serial/UartCore.cpp
r73135 r73243 23 23 *********************************************************************************************************************************/ 24 24 #define LOG_GROUP LOG_GROUP_DEV_SERIAL 25 #include <VBox/vmm/tm.h> 25 26 #include <iprt/uuid.h> 26 27 #include <iprt/assert.h> … … 50 51 /** Enable modem status interrupt. */ 51 52 # define UART_REG_IER_EDSSI RT_BIT(3) 53 /** Sleep mode enable. */ 54 # define UART_REG_IER_SLEEP_MODE_EN RT_BIT(4) 55 /** Low power mode enable. */ 56 # define UART_REG_IER_LP_MODE_EN RT_BIT(5) 52 57 /** Mask of writeable bits. */ 53 58 # define UART_REG_IER_MASK_WR 0x0f 59 /** Mask of writeable bits for 16750+. */ 60 # define UART_REG_IER_MASK_WR_16750 0x3f 54 61 55 62 /** The IIR register index (from the base of the port range). */ … … 71 78 /** Modem Status interrupt. */ 72 79 # define UART_REG_IIR_ID_MS 0x0 80 /** 64 byte FIFOs enabled (15750+ only). */ 81 # define UART_REG_IIR_64BYTE_FIFOS_EN RT_BIT(5) 73 82 /** FIFOs enabled. */ 74 83 # define UART_REG_IIR_FIFOS_EN 0xc0 … … 86 95 /** DMA Mode Select. */ 87 96 # define UART_REG_FCR_DMA_MODE_SEL RT_BIT(3) 97 /** 64 Byte FIFO enable (15750+ only). */ 98 # define UART_REG_FCR_64BYTE_FIFO_EN RT_BIT(5) 88 99 /** Receiver level interrupt trigger. */ 89 100 # define UART_REG_FCR_RCV_LVL_IRQ_MASK 0xc0 … … 101 112 # define UART_REG_FCR_MASK_WR 0xcf 102 113 /** Mask of sticky bits. */ 103 # define UART_REG_FCR_MASK_STICKY 0x c9114 # define UART_REG_FCR_MASK_STICKY 0xe9 104 115 105 116 /** The LCR register index (from the base of the port range). */ … … 134 145 /** Loopback connection. */ 135 146 # define UART_REG_MCR_LOOP RT_BIT(4) 136 /** Mask of writeable bits. */ 147 /** Flow Control Enable (15750+ only). */ 148 # define UART_REG_MCR_AFE RT_BIT(5) 149 /** Mask of writeable bits (15450 and 15550A). */ 137 150 # define UART_REG_MCR_MASK_WR 0x1f 151 /** Mask of writeable bits (15750+). */ 152 # define UART_REG_MCR_MASK_WR_15750 0x3f 138 153 139 154 /** The LSR register index (from the base of the port range). */ … … 198 213 * Global Variables * 199 214 *********************************************************************************************************************************/ 215 200 216 #ifdef IN_RING3 217 /** 218 * FIFO ITL levels. 219 */ 220 static struct 221 { 222 /** ITL level for a 16byte FIFO. */ 223 uint8_t cbItl16; 224 /** ITL level for a 64byte FIFO. */ 225 uint8_t cbItl64; 226 } s_aFifoItl[] = 227 { 228 /* cbItl16 cbItl64 */ 229 { 1, 1 }, 230 { 4, 16 }, 231 { 8, 32 }, 232 { 14, 56 } 233 }; 234 235 201 236 /** 202 237 * String versions of the parity enum. … … 258 293 && (pThis->uRegIer & UART_REG_IER_ELSI)) 259 294 uRegIirNew = UART_REG_IIR_ID_SET(UART_REG_IIR_ID_RCL); 295 else if ( (pThis->uRegIer & UART_REG_IER_ERBFI) 296 && pThis->fIrqCtiPending) 297 uRegIirNew = UART_REG_IIR_ID_SET(UART_REG_IIR_ID_CTI); 260 298 else if ( (pThis->uRegLsr & UART_REG_LSR_DR) 261 299 && (pThis->uRegIer & UART_REG_IER_ERBFI) … … 270 308 uRegIirNew = UART_REG_IIR_ID_SET(UART_REG_IIR_ID_MS); 271 309 272 /** @todo Character timeout indication for FIFO mode. */273 274 310 LogFlowFunc((" uRegIirNew=%#x uRegIir=%#x\n", uRegIirNew, pThis->uRegIir)); 275 311 … … 291 327 if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN) 292 328 uRegIirNew |= UART_REG_IIR_FIFOS_EN; 329 if (pThis->uRegFcr & UART_REG_FCR_64BYTE_FIFO_EN) 330 uRegIirNew |= UART_REG_IIR_64BYTE_FIFOS_EN; 293 331 294 332 pThis->uRegIir = uRegIirNew; … … 319 357 DECLINLINE(size_t) uartFifoFreeGet(PUARTFIFO pFifo) 320 358 { 321 return UART_FIFO_LENGTH- pFifo->cbUsed;359 return pFifo->cbMax - pFifo->cbUsed; 322 360 } 323 361 … … 333 371 DECLINLINE(bool) uartFifoPut(PUARTFIFO pFifo, bool fOvrWr, uint8_t bData) 334 372 { 335 if (fOvrWr || pFifo->cbUsed < UART_FIFO_LENGTH)373 if (fOvrWr || pFifo->cbUsed < pFifo->cbMax) 336 374 { 337 375 pFifo->abBuf[pFifo->offWrite] = bData; 338 pFifo->offWrite = (pFifo->offWrite + 1) % UART_FIFO_LENGTH;376 pFifo->offWrite = (pFifo->offWrite + 1) % pFifo->cbMax; 339 377 } 340 378 341 379 bool fOverFlow = false; 342 if (pFifo->cbUsed < UART_FIFO_LENGTH)380 if (pFifo->cbUsed < pFifo->cbMax) 343 381 pFifo->cbUsed++; 344 382 else … … 346 384 fOverFlow = true; 347 385 if (fOvrWr) /* Advance the read position to account for the lost character. */ 348 pFifo->offRead = (pFifo->offRead + 1) % UART_FIFO_LENGTH;386 pFifo->offRead = (pFifo->offRead + 1) % pFifo->cbMax; 349 387 } 350 388 … … 366 404 { 367 405 bRet = pFifo->abBuf[pFifo->offRead]; 368 pFifo->offRead = (pFifo->offRead + 1) % UART_FIFO_LENGTH;406 pFifo->offRead = (pFifo->offRead + 1) % pFifo->cbMax; 369 407 pFifo->cbUsed--; 370 408 } … … 390 428 while (cbCopy) 391 429 { 392 size_t cbThisCopy = RT_MIN(cbCopy, (uint8_t)( UART_FIFO_LENGTH- pFifo->offRead));430 size_t cbThisCopy = RT_MIN(cbCopy, (uint8_t)(pFifo->cbMax - pFifo->offRead)); 393 431 memcpy(pbDst, &pFifo->abBuf[pFifo->offRead], cbThisCopy); 394 432 395 pFifo->offRead = (pFifo->offRead + cbThisCopy) % UART_FIFO_LENGTH;433 pFifo->offRead = (pFifo->offRead + cbThisCopy) % pFifo->cbMax; 396 434 pFifo->cbUsed -= cbThisCopy; 397 435 pbDst += cbThisCopy; … … 420 458 while (cbCopy) 421 459 { 422 size_t cbThisCopy = RT_MIN(cbCopy, (uint8_t)( UART_FIFO_LENGTH- pFifo->offWrite));460 size_t cbThisCopy = RT_MIN(cbCopy, (uint8_t)(pFifo->cbMax - pFifo->offWrite)); 423 461 memcpy(&pFifo->abBuf[pFifo->offWrite], pbSrc, cbThisCopy); 424 462 425 pFifo->offWrite = (pFifo->offWrite + cbThisCopy) % UART_FIFO_LENGTH;463 pFifo->offWrite = (pFifo->offWrite + cbThisCopy) % pFifo->cbMax; 426 464 pFifo->cbUsed += cbThisCopy; 427 465 pbSrc += cbThisCopy; … … 474 512 uint32_t uBps = 115200 / pThis->uRegDivisor; /* This is for PC compatible serial port with a 1.8432 MHz crystal. */ 475 513 unsigned cDataBits = UART_REG_LCR_WLS_GET(pThis->uRegLcr) + 5; 514 uint32_t cFrameBits = cDataBits; 476 515 PDMSERIALSTOPBITS enmStopBits = PDMSERIALSTOPBITS_ONE; 477 516 PDMSERIALPARITY enmParity = PDMSERIALPARITY_NONE; … … 480 519 { 481 520 enmStopBits = cDataBits == 5 ? PDMSERIALSTOPBITS_ONEPOINTFIVE : PDMSERIALSTOPBITS_TWO; 521 cFrameBits += 2; 482 522 } 523 else 524 cFrameBits++; 483 525 484 526 if (pThis->uRegLcr & UART_REG_LCR_PEN) … … 504 546 pThis->uRegLcr & (UART_REG_LCR_EPS | UART_REG_LCR_PAR_STICK))); 505 547 } 548 549 cFrameBits++; 506 550 } 551 552 uint64_t uTimerFreq = TMTimerGetFreq(pThis->CTX_SUFF(pTimerRcvFifoTimeout)); 553 pThis->cSymbolXferTicks = (uTimerFreq / uBps) * cFrameBits; 507 554 508 555 LogFlowFunc(("Changing parameters to: %u,%s,%u,%s\n", … … 513 560 LogRelMax(10, ("Serial#%d: Failed to change parameters to %u,%s,%u,%s -> %Rrc\n", 514 561 pThis->pDevInsR3->iInstance, uBps, s_aszParity[enmParity], cDataBits, s_aszStopBits[enmStopBits], rc)); 562 563 /* Changed parameters will flush all receive queues, so there won't be any data to read even if indicated. */ 564 ASMAtomicWriteU32(&pThis->cbAvailRdr, 0); 565 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_DR); 515 566 } 516 567 } … … 558 609 while (cbFilled < cbFill) 559 610 { 560 size_t cbThisRead = RT_MIN(cbFill , (uint8_t)(UART_FIFO_LENGTH- pFifo->offWrite));611 size_t cbThisRead = RT_MIN(cbFill - cbFilled, (uint8_t)(pFifo->cbMax - pFifo->offWrite)); 561 612 size_t cbRead = 0; 562 613 int rc = pThis->pDrvSerial->pfnReadRdr(pThis->pDrvSerial, &pFifo->abBuf[pFifo->offWrite], cbThisRead, &cbRead); 563 614 /*Assert(RT_SUCCESS(rc) && cbRead == cbThisRead);*/ RT_NOREF(rc); 564 615 565 pFifo->offWrite = (pFifo->offWrite + cbRead) % UART_FIFO_LENGTH;616 pFifo->offWrite = (pFifo->offWrite + cbRead) % pFifo->cbMax; 566 617 pFifo->cbUsed += cbRead; 567 618 cbFilled += cbRead; … … 577 628 } 578 629 630 Assert(cbFilled <= pThis->cbAvailRdr); 579 631 ASMAtomicSubU32(&pThis->cbAvailRdr, cbFilled); 580 632 } … … 609 661 static void uartR3DataFetch(PUARTCORE pThis) 610 662 { 611 if (pThis->uRegFcr %UART_REG_FCR_FIFO_EN)663 if (pThis->uRegFcr & UART_REG_FCR_FIFO_EN) 612 664 uartR3RecvFifoFill(pThis); 613 665 else … … 713 765 else 714 766 { 715 pThis->uRegIer = uVal & UART_REG_IER_MASK_WR; 767 if (pThis->enmType < UARTTYPE_16750) 768 pThis->uRegIer = uVal & UART_REG_IER_MASK_WR; 769 else 770 pThis->uRegIer = uVal & UART_REG_IER_MASK_WR_16750; 716 771 uartIrqUpdate(pThis); 717 772 } … … 730 785 DECLINLINE(int) uartRegFcrWrite(PUARTCORE pThis, uint8_t uVal) 731 786 { 787 #ifndef IN_RING3 788 RT_NOREF(pThis, uVal); 789 return VINF_IOM_R3_IOPORT_WRITE; 790 #else 732 791 int rc = VINF_SUCCESS; 733 734 792 if ( pThis->enmType >= UARTTYPE_16550A 735 793 && uVal != pThis->uRegFcr) … … 741 799 uartFifoClear(&pThis->FifoRecv); 742 800 743 /* Fill in the next data. */ 744 if (ASMAtomicReadU32(&pThis->cbAvailRdr)) 745 { 746 #ifndef IN_RING3 747 rc = VINF_IOM_R3_IOPORT_WRITE; 748 #else 749 uartR3DataFetch(pThis); 750 #endif 751 } 801 /* 802 * If the FIFO is about to be enabled and the DR bit is ready we have an unacknowledged 803 * byte in the RBR register which will be lost so we have to adjust the available bytes. 804 */ 805 if ( ASMAtomicReadU32(&pThis->cbAvailRdr) > 0 806 && (pThis->uRegFcr & UART_REG_FCR_FIFO_EN)) 807 ASMAtomicDecU32(&pThis->cbAvailRdr); 808 809 /* Clear the DR bit too. */ 810 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_DR); 752 811 } 753 812 … … 755 814 { 756 815 if (uVal & UART_REG_FCR_RCV_FIFO_RST) 816 { 817 TMTimerStop(pThis->CTX_SUFF(pTimerRcvFifoTimeout)); 818 pThis->fIrqCtiPending = false; 757 819 uartFifoClear(&pThis->FifoRecv); 820 } 758 821 if (uVal & UART_REG_FCR_XMIT_FIFO_RST) 759 822 uartFifoClear(&pThis->FifoXmit); 760 823 824 /* 825 * The 64byte FIFO enable bit is only changeable for 16750 826 * and if the DLAB bit in LCR is set. 827 */ 828 if ( pThis->enmType < UARTTYPE_16750 829 || !(pThis->uRegLcr & UART_REG_LCR_DLAB)) 830 uVal &= ~UART_REG_FCR_64BYTE_FIFO_EN; 831 else /* Use previous value. */ 832 uVal |= pThis->uRegFcr & UART_REG_FCR_64BYTE_FIFO_EN; 833 834 if (uVal & UART_REG_FCR_64BYTE_FIFO_EN) 835 { 836 pThis->FifoRecv.cbMax = 64; 837 pThis->FifoXmit.cbMax = 64; 838 } 839 else 840 { 841 pThis->FifoRecv.cbMax = 16; 842 pThis->FifoXmit.cbMax = 16; 843 } 844 761 845 if (uVal & UART_REG_FCR_FIFO_EN) 762 846 { 763 switch (UART_REG_FCR_RCV_LVL_IRQ_GET(uVal)) 764 { 765 case UART_REG_FCR_RCV_LVL_IRQ_1: 766 pThis->FifoRecv.cbItl = 1; 767 break; 768 case UART_REG_FCR_RCV_LVL_IRQ_4: 769 pThis->FifoRecv.cbItl = 4; 770 break; 771 case UART_REG_FCR_RCV_LVL_IRQ_8: 772 pThis->FifoRecv.cbItl = 8; 773 break; 774 case UART_REG_FCR_RCV_LVL_IRQ_14: 775 pThis->FifoRecv.cbItl = 14; 776 break; 777 default: 778 /* Should never occur as all cases are handled earlier. */ 779 AssertMsgFailed(("Impossible to hit!\n")); 780 } 847 uint8_t idxItl = UART_REG_FCR_RCV_LVL_IRQ_GET(uVal); 848 if (uVal & UART_REG_FCR_64BYTE_FIFO_EN) 849 pThis->FifoRecv.cbItl = s_aFifoItl[idxItl].cbItl64; 850 else 851 pThis->FifoRecv.cbItl = s_aFifoItl[idxItl].cbItl16; 781 852 } 782 853 … … 785 856 uartIrqUpdate(pThis); 786 857 } 858 859 /* Fill in the next data. */ 860 if (ASMAtomicReadU32(&pThis->cbAvailRdr)) 861 uartR3DataFetch(pThis); 787 862 } 788 863 789 864 return rc; 865 #endif 790 866 } 791 867 … … 837 913 int rc = VINF_SUCCESS; 838 914 839 uVal &= UART_REG_MCR_MASK_WR; 915 if (pThis->enmType < UARTTYPE_16750) 916 uVal &= UART_REG_MCR_MASK_WR; 917 else 918 uVal &= UART_REG_MCR_MASK_WR_15750; 840 919 if (pThis->uRegMcr != uVal) 841 920 { … … 913 992 { 914 993 *puVal = uartFifoGet(&pThis->FifoRecv); 994 pThis->fIrqCtiPending = false; 915 995 if (!pThis->FifoRecv.cbUsed) 996 { 997 TMTimerStop(pThis->CTX_SUFF(pTimerRcvFifoTimeout)); 916 998 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_DR); 999 } 1000 else 1001 { 1002 uint64_t tsCtiFire = TMTimerGet(pThis->CTX_SUFF(pTimerRcvFifoTimeout)) + pThis->cSymbolXferTicks * 4; 1003 TMTimerSet(pThis->CTX_SUFF(pTimerRcvFifoTimeout), tsCtiFire); 1004 } 917 1005 uartIrqUpdate(pThis); 918 1006 } … … 924 1012 if (pThis->uRegLsr & UART_REG_LSR_DR) 925 1013 { 1014 Assert(pThis->cbAvailRdr); 926 1015 uint32_t cbAvail = ASMAtomicDecU32(&pThis->cbAvailRdr); 927 1016 if (!cbAvail) … … 1097 1186 DECLHIDDEN(int) uartRegWrite(PUARTCORE pThis, uint32_t uReg, uint32_t u32, size_t cb) 1098 1187 { 1188 AssertMsgReturn(cb == 1, ("uReg=%#x cb=%d u32=%#x\n", uReg, cb, u32), VINF_SUCCESS); 1189 1099 1190 int rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_R3_IOPORT_WRITE); 1100 1191 if (rc != VINF_SUCCESS) … … 1104 1195 LogFlowFunc(("pThis=%#p uReg=%u{%s} u32=%#x cb=%u\n", 1105 1196 pThis, uReg, uartRegIdx2Str(pThis, idxReg, true /*fWrite*/), u32, cb)); 1106 1107 AssertMsgReturn(cb == 1, ("uReg=%#x cb=%d u32=%#x\n", uReg, cb, u32), VINF_SUCCESS);1108 1197 1109 1198 uint8_t uVal = (uint8_t)u32; … … 1186 1275 1187 1276 #ifdef IN_RING3 1277 1278 /* -=-=-=-=-=-=-=-=- Timer callbacks -=-=-=-=-=-=-=-=- */ 1279 1280 /** 1281 * @callback_method_impl{FNTMTIMERDEV, Fifo timer function.} 1282 */ 1283 static DECLCALLBACK(void) uartR3RcvFifoTimeoutTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 1284 { 1285 RT_NOREF(pDevIns, pTimer); 1286 PUARTCORE pThis = (PUARTCORE)pvUser; 1287 Assert(PDMCritSectIsOwner(&pThis->CritSect)); 1288 if (pThis->FifoRecv.cbUsed) 1289 { 1290 pThis->fIrqCtiPending = true; 1291 uartIrqUpdate(pThis); 1292 } 1293 } 1294 1188 1295 1189 1296 /* -=-=-=-=-=-=-=-=- PDMISERIALPORT on LUN#0 -=-=-=-=-=-=-=-=- */ … … 1266 1373 else 1267 1374 { 1268 AssertMsgFailed(("There is no data to read!\n")); 1375 /* 1376 * This can happen if there was data in the FIFO when the connection was closed, 1377 * idicate this condition to the lower driver by returning 0 bytes. 1378 */ 1269 1379 *pcbRead = 0; 1270 1380 } … … 1324 1434 { 1325 1435 RT_NOREF(offDelta); 1326 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pThis->pDevInsR3); 1436 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pThis->pDevInsR3); 1437 pThis->pTimerRcvFifoTimeoutRC = TMTimerRCPtr(pThis->pTimerRcvFifoTimeoutR3); 1327 1438 } 1328 1439 … … 1330 1441 DECLHIDDEN(void) uartR3Reset(PUARTCORE pThis) 1331 1442 { 1332 pThis->uRegDivisor = 0x0c; /* Default to 9600 Baud. */ 1333 pThis->uRegRbr = 0; 1334 pThis->uRegThr = 0; 1335 pThis->uRegIer = 0; 1336 pThis->uRegIir = UART_REG_IIR_IP_NO_INT; 1337 pThis->uRegFcr = 0; 1338 pThis->uRegLcr = 0; /* 5 data bits, no parity, 1 stop bit. */ 1339 pThis->uRegMcr = 0; 1340 pThis->uRegLsr = UART_REG_LSR_THRE | UART_REG_LSR_TEMT; 1341 pThis->uRegMsr = 0; /* Updated below. */ 1342 pThis->uRegScr = 0; 1343 1443 pThis->uRegDivisor = 0x0c; /* Default to 9600 Baud. */ 1444 pThis->uRegRbr = 0; 1445 pThis->uRegThr = 0; 1446 pThis->uRegIer = 0; 1447 pThis->uRegIir = UART_REG_IIR_IP_NO_INT; 1448 pThis->uRegFcr = 0; 1449 pThis->uRegLcr = 0; /* 5 data bits, no parity, 1 stop bit. */ 1450 pThis->uRegMcr = 0; 1451 pThis->uRegLsr = UART_REG_LSR_THRE | UART_REG_LSR_TEMT; 1452 pThis->uRegMsr = 0; /* Updated below. */ 1453 pThis->uRegScr = 0; 1454 pThis->fIrqCtiPending = false; 1455 1456 /* Standard FIFO size for 15550A. */ 1457 pThis->FifoXmit.cbMax = 16; 1458 pThis->FifoRecv.cbMax = 16; 1344 1459 uartFifoClear(&pThis->FifoXmit); 1345 1460 uartFifoClear(&pThis->FifoRecv); … … 1438 1553 pThis->ISerialPort.pfnNotifyBrk = uartR3NotifyBrk; 1439 1554 1440 rc = PDMDevHlpCritSectInit(pDevInsR3, &pThis->CritSect, RT_SRC_POS, "Serial#%d", iLUN); 1555 rc = PDMDevHlpCritSectInit(pDevInsR3, &pThis->CritSect, RT_SRC_POS, "Uart{%s#%d}#%d", 1556 pDevInsR3->pReg->szName, pDevInsR3->iInstance, iLUN); 1441 1557 AssertRCReturn(rc, rc); 1442 1558 … … 1467 1583 } 1468 1584 1585 /* 1586 * Create the receive FIFO character timeout indicator timer. 1587 */ 1588 rc = PDMDevHlpTMTimerCreate(pDevInsR3, TMCLOCK_VIRTUAL, uartR3RcvFifoTimeoutTimer, pThis, 1589 TMTIMER_FLAGS_NO_CRIT_SECT, "UART Rcv FIFO Timer", 1590 &pThis->pTimerRcvFifoTimeoutR3); 1591 AssertRCReturn(rc, rc); 1592 1593 rc = TMR3TimerSetCritSect(pThis->pTimerRcvFifoTimeoutR3, &pThis->CritSect); 1594 AssertRCReturn(rc, rc); 1595 1596 pThis->pTimerRcvFifoTimeoutR0 = TMTimerR0Ptr(pThis->pTimerRcvFifoTimeoutR3); 1597 pThis->pTimerRcvFifoTimeoutRC = TMTimerRCPtr(pThis->pTimerRcvFifoTimeoutR3); 1598 1469 1599 uartR3Reset(pThis); 1470 1600 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Serial/UartCore.h
r73136 r73243 20 20 #define ___UartCore_h 21 21 22 #include <VBox/types.h> 22 23 #include <VBox/vmm/pdmdev.h> 23 24 #include <VBox/vmm/pdmserialifs.h> … … 30 31 *********************************************************************************************************************************/ 31 32 32 /** Size of a FIFO. */33 #define UART_FIFO_LENGTH 1633 /** Maximum size of a FIFO. */ 34 #define UART_FIFO_LENGTH_MAX 128 34 35 35 36 … … 67 68 /** 16550A UART type. */ 68 69 UARTTYPE_16550A, 69 /** 32bit hack. */ 70 /** 16750 UART type. */ 71 UARTTYPE_16750, 72 /** 32bit hack. */ 70 73 UARTTYPE_32BIT_HACK = 0x7fffffff 71 74 } UARTTYPE; … … 77 80 typedef struct UARTFIFO 78 81 { 82 /** Fifo size configured. */ 83 uint8_t cbMax; 79 84 /** Current amount of bytes used. */ 80 85 uint8_t cbUsed; … … 86 91 uint8_t cbItl; 87 92 /** The data in the FIFO. */ 88 uint8_t abBuf[UART_FIFO_LENGTH]; 93 uint8_t abBuf[UART_FIFO_LENGTH_MAX]; 94 /** Alignment to a 4 byte boundary. */ 95 uint8_t au8Alignment0[3]; 89 96 } UARTFIFO; 90 97 /** Pointer to a FIFO. */ … … 123 130 UARTTYPE enmType; 124 131 132 /** R3 timer pointer fo the character timeout indication. */ 133 PTMTIMERR3 pTimerRcvFifoTimeoutR3; 125 134 /** R3 interrupt request callback of the owning device. */ 126 135 R3PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR3; 136 /** R0 timer pointer fo the character timeout indication. */ 137 PTMTIMERR0 pTimerRcvFifoTimeoutR0; 127 138 /** R0 interrupt request callback of the owning device. */ 128 139 R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR0; 129 /** RC interrupt request callback of the owning device. */ 140 /** RC timer pointer fo the character timeout indication. */ 141 PTMTIMERRC pTimerRcvFifoTimeoutRC; 142 /** RC interrupt request callback of the owning device. */ 130 143 RCPTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqRC; 131 144 … … 153 166 uint8_t uRegScr; 154 167 155 /** The transmit FIFO. */ 168 /** Flag whether a character timeout interrupt is pending 169 * (no symbols were inserted or removed from the receive FIFO 170 * during an 4 times the character transmit/receive period and the FIFO 171 * is not empty). */ 172 bool fIrqCtiPending; 173 /** Alignment. */ 174 bool afAlignment[3]; 175 /** The transmit FIFO. */ 156 176 UARTFIFO FifoXmit; 157 177 /** The receive FIFO. */ 158 178 UARTFIFO FifoRecv; 159 179 180 /** Time it takes to transmit/receive a single symbol in timer ticks. */ 181 uint64_t cSymbolXferTicks; 160 182 /** Number of bytes available for reading from the layer below. */ 161 183 volatile uint32_t cbAvailRdr;
Note:
See TracChangeset
for help on using the changeset viewer.