VirtualBox

source: vbox/trunk/src/VBox/Devices/Serial/UartCore.h@ 99404

Last change on this file since 99404 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1/* $Id: UartCore.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * UartCore - UART (16550A up to 16950) emulation.
4 *
5 * The documentation for this device was taken from the PC16550D spec from TI.
6 */
7
8/*
9 * Copyright (C) 2018-2023 Oracle and/or its affiliates.
10 *
11 * This file is part of VirtualBox base platform packages, as
12 * available from https://www.virtualbox.org.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation, in version 3 of the
17 * License.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <https://www.gnu.org/licenses>.
26 *
27 * SPDX-License-Identifier: GPL-3.0-only
28 */
29
30#ifndef VBOX_INCLUDED_SRC_Serial_UartCore_h
31#define VBOX_INCLUDED_SRC_Serial_UartCore_h
32#ifndef RT_WITHOUT_PRAGMA_ONCE
33# pragma once
34#endif
35
36#include <VBox/types.h>
37#include <VBox/vmm/pdmdev.h>
38#include <VBox/vmm/pdmserialifs.h>
39#include <VBox/vmm/ssm.h>
40#include <iprt/assert.h>
41
42RT_C_DECLS_BEGIN
43
44/*********************************************************************************************************************************
45* Defined Constants And Macros *
46*********************************************************************************************************************************/
47
48/** The current serial code saved state version. */
49#define UART_SAVED_STATE_VERSION 7
50/** Saved state version before the TX timer for the connected device case was added. */
51#define UART_SAVED_STATE_VERSION_PRE_UNCONNECTED_TX_TIMER 6
52/** Saved state version of the legacy code which got replaced after 5.2. */
53#define UART_SAVED_STATE_VERSION_LEGACY_CODE 5
54/** Includes some missing bits from the previous saved state. */
55#define UART_SAVED_STATE_VERSION_MISSING_BITS 4
56/** Saved state version when only the 16450 variant was implemented. */
57#define UART_SAVED_STATE_VERSION_16450 3
58
59/** Maximum size of a FIFO. */
60#define UART_FIFO_LENGTH_MAX 128
61
62
63/*********************************************************************************************************************************
64* Structures and Typedefs *
65*********************************************************************************************************************************/
66
67/** Pointer to the UART core state. */
68typedef struct UARTCORE *PUARTCORE;
69
70
71/**
72 * UART core IRQ request callback to let the core instance raise/clear interrupt requests.
73 *
74 * @returns nothing.
75 * @param pDevIns The owning device instance.
76 * @param pThis The shared UART core instance data.
77 * @param iLUN The LUN associated with the UART core.
78 * @param iLvl The interrupt level.
79 */
80typedef DECLCALLBACKTYPE(void, FNUARTCOREIRQREQ,(PPDMDEVINS pDevIns, PUARTCORE pThis, unsigned iLUN, int iLvl));
81/** Pointer to a UART core IRQ request callback. */
82typedef FNUARTCOREIRQREQ *PFNUARTCOREIRQREQ;
83
84
85/**
86 * UART type.
87 */
88typedef enum UARTTYPE
89{
90 /** Invalid UART type. */
91 UARTTYPE_INVALID = 0,
92 /** 16450 UART type. */
93 UARTTYPE_16450,
94 /** 16550A UART type. */
95 UARTTYPE_16550A,
96 /** 16750 UART type. */
97 UARTTYPE_16750,
98 /** 32bit hack. */
99 UARTTYPE_32BIT_HACK = 0x7fffffff
100} UARTTYPE;
101
102
103/**
104 * UART FIFO.
105 */
106typedef struct UARTFIFO
107{
108 /** Fifo size configured. */
109 uint8_t cbMax;
110 /** Current amount of bytes used. */
111 uint8_t cbUsed;
112 /** Next index to write to. */
113 uint8_t offWrite;
114 /** Next index to read from. */
115 uint8_t offRead;
116 /** The interrupt trigger level (only used for the receive FIFO). */
117 uint8_t cbItl;
118 /** The data in the FIFO. */
119 uint8_t abBuf[UART_FIFO_LENGTH_MAX];
120 /** Alignment to a 4 byte boundary. */
121 uint8_t au8Alignment0[3];
122} UARTFIFO;
123/** Pointer to a FIFO. */
124typedef UARTFIFO *PUARTFIFO;
125
126
127/**
128 * Shared UART core device state.
129 *
130 * @implements PDMIBASE
131 * @implements PDMISERIALPORT
132 */
133typedef struct UARTCORE
134{
135 /** Access critical section. */
136 PDMCRITSECT CritSect;
137 /** The LUN on the owning device instance for this core. */
138 uint32_t iLUN;
139 /** Configuration flags. */
140 uint32_t fFlags;
141 /** The selected UART type. */
142 UARTTYPE enmType;
143
144 /** The divisor register (DLAB = 1). */
145 uint16_t uRegDivisor;
146 /** The Receiver Buffer Register (RBR, DLAB = 0). */
147 uint8_t uRegRbr;
148 /** The Transmitter Holding Register (THR, DLAB = 0). */
149 uint8_t uRegThr;
150 /** The Interrupt Enable Register (IER, DLAB = 0). */
151 uint8_t uRegIer;
152 /** The Interrupt Identification Register (IIR). */
153 uint8_t uRegIir;
154 /** The FIFO Control Register (FCR). */
155 uint8_t uRegFcr;
156 /** The Line Control Register (LCR). */
157 uint8_t uRegLcr;
158 /** The Modem Control Register (MCR). */
159 uint8_t uRegMcr;
160 /** The Line Status Register (LSR). */
161 uint8_t uRegLsr;
162 /** The Modem Status Register (MSR). */
163 uint8_t uRegMsr;
164 /** The Scratch Register (SCR). */
165 uint8_t uRegScr;
166
167 /** Timer handle for the character timeout indication. */
168 TMTIMERHANDLE hTimerRcvFifoTimeout;
169 /** Timer handle for the send loop if no driver is connected/loopback mode is active. */
170 TMTIMERHANDLE hTimerTxUnconnected;
171
172 /** Flag whether a character timeout interrupt is pending
173 * (no symbols were inserted or removed from the receive FIFO
174 * during an 4 times the character transmit/receive period and the FIFO
175 * is not empty). */
176 bool fIrqCtiPending;
177 /** Flag whether the transmitter holding register went empty since last time the
178 * IIR register was read. This gets reset when IIR is read so the guest will get this
179 * interrupt ID only once. */
180 bool fThreEmptyPending;
181 /** Explicit alignment. */
182 bool afAlignment1[2];
183 /** The transmit FIFO. */
184 UARTFIFO FifoXmit;
185 /** The receive FIFO. */
186 UARTFIFO FifoRecv;
187
188 /** Time it takes to transmit/receive a single symbol in timer ticks. */
189 uint64_t cSymbolXferTicks;
190 /** Number of bytes available for reading from the layer below. */
191 volatile uint32_t cbAvailRdr;
192 /** Explicit alignment. */
193 uint32_t u32Alignment2;
194} UARTCORE;
195AssertCompileSizeAlignment(UARTCORE, 8);
196
197
198/**
199 * Ring-3 UART core device state.
200 *
201 * @implements PDMIBASE
202 * @implements PDMISERIALPORT
203 */
204typedef struct UARTCORER3
205{
206 /** The LUN on the owning device instance for this core. */
207 uint32_t iLUN;
208 uint32_t u32Padding;
209 /** LUN\#0: The base interface. */
210 PDMIBASE IBase;
211 /** LUN\#0: The serial port interface. */
212 PDMISERIALPORT ISerialPort;
213 /** Pointer to the attached base driver. */
214 R3PTRTYPE(PPDMIBASE) pDrvBase;
215 /** Pointer to the attached serial driver. */
216 R3PTRTYPE(PPDMISERIALCONNECTOR) pDrvSerial;
217
218 /** Interrupt request callback of the owning device. */
219 R3PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq;
220
221 /** Pointer to the shared data - for timers callbacks and interface methods
222 * only. */
223 R3PTRTYPE(PUARTCORE) pShared;
224 /** Pointer to the device instance - only for getting our bearings in
225 * interface methods. */
226 PPDMDEVINS pDevIns;
227} UARTCORER3;
228/** Pointer to the core ring-3 UART device state. */
229typedef UARTCORER3 *PUARTCORER3;
230
231
232/**
233 * Ring-0 UART core device state.
234 */
235typedef struct UARTCORER0
236{
237 /** Interrupt request callback of the owning device. */
238 R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq;
239} UARTCORER0;
240/** Pointer to the core ring-0 UART device state. */
241typedef UARTCORER0 *PUARTCORER0;
242
243
244/**
245 * Raw-mode UART core device state.
246 */
247typedef struct UARTCORERC
248{
249 /** Interrupt request callback of the owning device. */
250 R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq;
251} UARTCORERC;
252/** Pointer to the core raw-mode UART device state. */
253typedef UARTCORERC *PUARTCORERC;
254
255
256/** Current context UAR core device state. */
257typedef CTX_SUFF(UARTCORE) UARTCORECC;
258/** Pointer to the current context UAR core device state. */
259typedef CTX_SUFF(PUARTCORE) PUARTCORECC;
260
261
262#ifndef VBOX_DEVICE_STRUCT_TESTCASE
263
264/** Flag whether to yield the CPU on an LSR read. */
265#define UART_CORE_YIELD_ON_LSR_READ RT_BIT_32(0)
266
267DECLHIDDEN(VBOXSTRICTRC) uartRegWrite(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC,
268 uint32_t uReg, uint32_t u32, size_t cb);
269DECLHIDDEN(VBOXSTRICTRC) uartRegRead(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC,
270 uint32_t uReg, uint32_t *pu32, size_t cb);
271
272# ifdef IN_RING3
273DECLHIDDEN(int) uartR3Init(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC,
274 UARTTYPE enmType, unsigned iLUN, uint32_t fFlags, PFNUARTCOREIRQREQ pfnUartIrqReq);
275DECLHIDDEN(void) uartR3Destruct(PPDMDEVINS pDevIns, PUARTCORE pThis);
276DECLHIDDEN(void) uartR3Detach(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC);
277DECLHIDDEN(int) uartR3Attach(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, unsigned iLUN);
278DECLHIDDEN(void) uartR3Reset(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC);
279DECLHIDDEN(int) uartR3SaveExec(PPDMDEVINS pDevIns, PUARTCORE pThis, PSSMHANDLE pSSM);
280DECLHIDDEN(int) uartR3LoadExec(PPDMDEVINS pDevIns, PUARTCORE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass,
281 uint8_t *puIrq, RTIOPORT *pPortBase);
282DECLHIDDEN(int) uartR3LoadDone(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, PSSMHANDLE pSSM);
283
284# endif /* IN_RING3 */
285# if !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
286DECLHIDDEN(int) uartRZInit(PUARTCORECC pThisCC, PFNUARTCOREIRQREQ pfnUartIrqReq);
287# endif
288
289#endif
290
291RT_C_DECLS_END
292
293#endif /* !VBOX_INCLUDED_SRC_Serial_UartCore_h */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette