diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/VBox/Devices/Serial/UartCore.h | |
parent | Initial commit. (diff) | |
download | virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.tar.xz virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/Serial/UartCore.h')
-rw-r--r-- | src/VBox/Devices/Serial/UartCore.h | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/src/VBox/Devices/Serial/UartCore.h b/src/VBox/Devices/Serial/UartCore.h new file mode 100644 index 00000000..a8e038a5 --- /dev/null +++ b/src/VBox/Devices/Serial/UartCore.h @@ -0,0 +1,293 @@ +/* $Id: UartCore.h $ */ +/** @file + * UartCore - UART (16550A up to 16950) emulation. + * + * The documentation for this device was taken from the PC16550D spec from TI. + */ + +/* + * Copyright (C) 2018-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#ifndef VBOX_INCLUDED_SRC_Serial_UartCore_h +#define VBOX_INCLUDED_SRC_Serial_UartCore_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <VBox/types.h> +#include <VBox/vmm/pdmdev.h> +#include <VBox/vmm/pdmserialifs.h> +#include <VBox/vmm/ssm.h> +#include <iprt/assert.h> + +RT_C_DECLS_BEGIN + +/********************************************************************************************************************************* +* Defined Constants And Macros * +*********************************************************************************************************************************/ + +/** The current serial code saved state version. */ +#define UART_SAVED_STATE_VERSION 7 +/** Saved state version before the TX timer for the connected device case was added. */ +#define UART_SAVED_STATE_VERSION_PRE_UNCONNECTED_TX_TIMER 6 +/** Saved state version of the legacy code which got replaced after 5.2. */ +#define UART_SAVED_STATE_VERSION_LEGACY_CODE 5 +/** Includes some missing bits from the previous saved state. */ +#define UART_SAVED_STATE_VERSION_MISSING_BITS 4 +/** Saved state version when only the 16450 variant was implemented. */ +#define UART_SAVED_STATE_VERSION_16450 3 + +/** Maximum size of a FIFO. */ +#define UART_FIFO_LENGTH_MAX 128 + + +/********************************************************************************************************************************* +* Structures and Typedefs * +*********************************************************************************************************************************/ + +/** Pointer to the UART core state. */ +typedef struct UARTCORE *PUARTCORE; + + +/** + * UART core IRQ request callback to let the core instance raise/clear interrupt requests. + * + * @returns nothing. + * @param pDevIns The owning device instance. + * @param pThis The shared UART core instance data. + * @param iLUN The LUN associated with the UART core. + * @param iLvl The interrupt level. + */ +typedef DECLCALLBACKTYPE(void, FNUARTCOREIRQREQ,(PPDMDEVINS pDevIns, PUARTCORE pThis, unsigned iLUN, int iLvl)); +/** Pointer to a UART core IRQ request callback. */ +typedef FNUARTCOREIRQREQ *PFNUARTCOREIRQREQ; + + +/** + * UART type. + */ +typedef enum UARTTYPE +{ + /** Invalid UART type. */ + UARTTYPE_INVALID = 0, + /** 16450 UART type. */ + UARTTYPE_16450, + /** 16550A UART type. */ + UARTTYPE_16550A, + /** 16750 UART type. */ + UARTTYPE_16750, + /** 32bit hack. */ + UARTTYPE_32BIT_HACK = 0x7fffffff +} UARTTYPE; + + +/** + * UART FIFO. + */ +typedef struct UARTFIFO +{ + /** Fifo size configured. */ + uint8_t cbMax; + /** Current amount of bytes used. */ + uint8_t cbUsed; + /** Next index to write to. */ + uint8_t offWrite; + /** Next index to read from. */ + uint8_t offRead; + /** The interrupt trigger level (only used for the receive FIFO). */ + uint8_t cbItl; + /** The data in the FIFO. */ + uint8_t abBuf[UART_FIFO_LENGTH_MAX]; + /** Alignment to a 4 byte boundary. */ + uint8_t au8Alignment0[3]; +} UARTFIFO; +/** Pointer to a FIFO. */ +typedef UARTFIFO *PUARTFIFO; + + +/** + * Shared UART core device state. + * + * @implements PDMIBASE + * @implements PDMISERIALPORT + */ +typedef struct UARTCORE +{ + /** Access critical section. */ + PDMCRITSECT CritSect; + /** The LUN on the owning device instance for this core. */ + uint32_t iLUN; + /** Configuration flags. */ + uint32_t fFlags; + /** The selected UART type. */ + UARTTYPE enmType; + + /** The divisor register (DLAB = 1). */ + uint16_t uRegDivisor; + /** The Receiver Buffer Register (RBR, DLAB = 0). */ + uint8_t uRegRbr; + /** The Transmitter Holding Register (THR, DLAB = 0). */ + uint8_t uRegThr; + /** The Interrupt Enable Register (IER, DLAB = 0). */ + uint8_t uRegIer; + /** The Interrupt Identification Register (IIR). */ + uint8_t uRegIir; + /** The FIFO Control Register (FCR). */ + uint8_t uRegFcr; + /** The Line Control Register (LCR). */ + uint8_t uRegLcr; + /** The Modem Control Register (MCR). */ + uint8_t uRegMcr; + /** The Line Status Register (LSR). */ + uint8_t uRegLsr; + /** The Modem Status Register (MSR). */ + uint8_t uRegMsr; + /** The Scratch Register (SCR). */ + uint8_t uRegScr; + + /** Timer handle for the character timeout indication. */ + TMTIMERHANDLE hTimerRcvFifoTimeout; + /** Timer handle for the send loop if no driver is connected/loopback mode is active. */ + TMTIMERHANDLE hTimerTxUnconnected; + + /** Flag whether a character timeout interrupt is pending + * (no symbols were inserted or removed from the receive FIFO + * during an 4 times the character transmit/receive period and the FIFO + * is not empty). */ + bool fIrqCtiPending; + /** Flag whether the transmitter holding register went empty since last time the + * IIR register was read. This gets reset when IIR is read so the guest will get this + * interrupt ID only once. */ + bool fThreEmptyPending; + /** Explicit alignment. */ + bool afAlignment1[2]; + /** The transmit FIFO. */ + UARTFIFO FifoXmit; + /** The receive FIFO. */ + UARTFIFO FifoRecv; + + /** Time it takes to transmit/receive a single symbol in timer ticks. */ + uint64_t cSymbolXferTicks; + /** Number of bytes available for reading from the layer below. */ + volatile uint32_t cbAvailRdr; + /** Explicit alignment. */ + uint32_t u32Alignment2; +} UARTCORE; +AssertCompileSizeAlignment(UARTCORE, 8); + + +/** + * Ring-3 UART core device state. + * + * @implements PDMIBASE + * @implements PDMISERIALPORT + */ +typedef struct UARTCORER3 +{ + /** The LUN on the owning device instance for this core. */ + uint32_t iLUN; + uint32_t u32Padding; + /** LUN\#0: The base interface. */ + PDMIBASE IBase; + /** LUN\#0: The serial port interface. */ + PDMISERIALPORT ISerialPort; + /** Pointer to the attached base driver. */ + R3PTRTYPE(PPDMIBASE) pDrvBase; + /** Pointer to the attached serial driver. */ + R3PTRTYPE(PPDMISERIALCONNECTOR) pDrvSerial; + + /** Interrupt request callback of the owning device. */ + R3PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq; + + /** Pointer to the shared data - for timers callbacks and interface methods + * only. */ + R3PTRTYPE(PUARTCORE) pShared; + /** Pointer to the device instance - only for getting our bearings in + * interface methods. */ + PPDMDEVINS pDevIns; +} UARTCORER3; +/** Pointer to the core ring-3 UART device state. */ +typedef UARTCORER3 *PUARTCORER3; + + +/** + * Ring-0 UART core device state. + */ +typedef struct UARTCORER0 +{ + /** Interrupt request callback of the owning device. */ + R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq; +} UARTCORER0; +/** Pointer to the core ring-0 UART device state. */ +typedef UARTCORER0 *PUARTCORER0; + + +/** + * Raw-mode UART core device state. + */ +typedef struct UARTCORERC +{ + /** Interrupt request callback of the owning device. */ + R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq; +} UARTCORERC; +/** Pointer to the core raw-mode UART device state. */ +typedef UARTCORERC *PUARTCORERC; + + +/** Current context UAR core device state. */ +typedef CTX_SUFF(UARTCORE) UARTCORECC; +/** Pointer to the current context UAR core device state. */ +typedef CTX_SUFF(PUARTCORE) PUARTCORECC; + + +#ifndef VBOX_DEVICE_STRUCT_TESTCASE + +/** Flag whether to yield the CPU on an LSR read. */ +#define UART_CORE_YIELD_ON_LSR_READ RT_BIT_32(0) + +DECLHIDDEN(VBOXSTRICTRC) uartRegWrite(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, + uint32_t uReg, uint32_t u32, size_t cb); +DECLHIDDEN(VBOXSTRICTRC) uartRegRead(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, + uint32_t uReg, uint32_t *pu32, size_t cb); + +# ifdef IN_RING3 +DECLHIDDEN(int) uartR3Init(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, + UARTTYPE enmType, unsigned iLUN, uint32_t fFlags, PFNUARTCOREIRQREQ pfnUartIrqReq); +DECLHIDDEN(void) uartR3Destruct(PPDMDEVINS pDevIns, PUARTCORE pThis); +DECLHIDDEN(void) uartR3Detach(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC); +DECLHIDDEN(int) uartR3Attach(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, unsigned iLUN); +DECLHIDDEN(void) uartR3Reset(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC); +DECLHIDDEN(int) uartR3SaveExec(PPDMDEVINS pDevIns, PUARTCORE pThis, PSSMHANDLE pSSM); +DECLHIDDEN(int) uartR3LoadExec(PPDMDEVINS pDevIns, PUARTCORE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass, + uint8_t *puIrq, RTIOPORT *pPortBase); +DECLHIDDEN(int) uartR3LoadDone(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, PSSMHANDLE pSSM); + +# endif /* IN_RING3 */ +# if !defined(IN_RING3) || defined(DOXYGEN_RUNNING) +DECLHIDDEN(int) uartRZInit(PUARTCORECC pThisCC, PFNUARTCOREIRQREQ pfnUartIrqReq); +# endif + +#endif + +RT_C_DECLS_END + +#endif /* !VBOX_INCLUDED_SRC_Serial_UartCore_h */ |