VirtualBox

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

Last change on this file since 103914 was 99739, checked in by vboxsync, 19 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void).

  • 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 99739 2023-05-11 01:01:08Z 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 * @param pDevIns The owning device instance.
75 * @param pThis The shared UART core instance data.
76 * @param iLUN The LUN associated with the UART core.
77 * @param iLvl The interrupt level.
78 */
79typedef DECLCALLBACKTYPE(void, FNUARTCOREIRQREQ,(PPDMDEVINS pDevIns, PUARTCORE pThis, unsigned iLUN, int iLvl));
80/** Pointer to a UART core IRQ request callback. */
81typedef FNUARTCOREIRQREQ *PFNUARTCOREIRQREQ;
82
83
84/**
85 * UART type.
86 */
87typedef enum UARTTYPE
88{
89 /** Invalid UART type. */
90 UARTTYPE_INVALID = 0,
91 /** 16450 UART type. */
92 UARTTYPE_16450,
93 /** 16550A UART type. */
94 UARTTYPE_16550A,
95 /** 16750 UART type. */
96 UARTTYPE_16750,
97 /** 32bit hack. */
98 UARTTYPE_32BIT_HACK = 0x7fffffff
99} UARTTYPE;
100
101
102/**
103 * UART FIFO.
104 */
105typedef struct UARTFIFO
106{
107 /** Fifo size configured. */
108 uint8_t cbMax;
109 /** Current amount of bytes used. */
110 uint8_t cbUsed;
111 /** Next index to write to. */
112 uint8_t offWrite;
113 /** Next index to read from. */
114 uint8_t offRead;
115 /** The interrupt trigger level (only used for the receive FIFO). */
116 uint8_t cbItl;
117 /** The data in the FIFO. */
118 uint8_t abBuf[UART_FIFO_LENGTH_MAX];
119 /** Alignment to a 4 byte boundary. */
120 uint8_t au8Alignment0[3];
121} UARTFIFO;
122/** Pointer to a FIFO. */
123typedef UARTFIFO *PUARTFIFO;
124
125
126/**
127 * Shared UART core device state.
128 *
129 * @implements PDMIBASE
130 * @implements PDMISERIALPORT
131 */
132typedef struct UARTCORE
133{
134 /** Access critical section. */
135 PDMCRITSECT CritSect;
136 /** The LUN on the owning device instance for this core. */
137 uint32_t iLUN;
138 /** Configuration flags. */
139 uint32_t fFlags;
140 /** The selected UART type. */
141 UARTTYPE enmType;
142
143 /** The divisor register (DLAB = 1). */
144 uint16_t uRegDivisor;
145 /** The Receiver Buffer Register (RBR, DLAB = 0). */
146 uint8_t uRegRbr;
147 /** The Transmitter Holding Register (THR, DLAB = 0). */
148 uint8_t uRegThr;
149 /** The Interrupt Enable Register (IER, DLAB = 0). */
150 uint8_t uRegIer;
151 /** The Interrupt Identification Register (IIR). */
152 uint8_t uRegIir;
153 /** The FIFO Control Register (FCR). */
154 uint8_t uRegFcr;
155 /** The Line Control Register (LCR). */
156 uint8_t uRegLcr;
157 /** The Modem Control Register (MCR). */
158 uint8_t uRegMcr;
159 /** The Line Status Register (LSR). */
160 uint8_t uRegLsr;
161 /** The Modem Status Register (MSR). */
162 uint8_t uRegMsr;
163 /** The Scratch Register (SCR). */
164 uint8_t uRegScr;
165
166 /** Timer handle for the character timeout indication. */
167 TMTIMERHANDLE hTimerRcvFifoTimeout;
168 /** Timer handle for the send loop if no driver is connected/loopback mode is active. */
169 TMTIMERHANDLE hTimerTxUnconnected;
170
171 /** Flag whether a character timeout interrupt is pending
172 * (no symbols were inserted or removed from the receive FIFO
173 * during an 4 times the character transmit/receive period and the FIFO
174 * is not empty). */
175 bool fIrqCtiPending;
176 /** Flag whether the transmitter holding register went empty since last time the
177 * IIR register was read. This gets reset when IIR is read so the guest will get this
178 * interrupt ID only once. */
179 bool fThreEmptyPending;
180 /** Explicit alignment. */
181 bool afAlignment1[2];
182 /** The transmit FIFO. */
183 UARTFIFO FifoXmit;
184 /** The receive FIFO. */
185 UARTFIFO FifoRecv;
186
187 /** Time it takes to transmit/receive a single symbol in timer ticks. */
188 uint64_t cSymbolXferTicks;
189 /** Number of bytes available for reading from the layer below. */
190 volatile uint32_t cbAvailRdr;
191 /** Explicit alignment. */
192 uint32_t u32Alignment2;
193} UARTCORE;
194AssertCompileSizeAlignment(UARTCORE, 8);
195
196
197/**
198 * Ring-3 UART core device state.
199 *
200 * @implements PDMIBASE
201 * @implements PDMISERIALPORT
202 */
203typedef struct UARTCORER3
204{
205 /** The LUN on the owning device instance for this core. */
206 uint32_t iLUN;
207 uint32_t u32Padding;
208 /** LUN\#0: The base interface. */
209 PDMIBASE IBase;
210 /** LUN\#0: The serial port interface. */
211 PDMISERIALPORT ISerialPort;
212 /** Pointer to the attached base driver. */
213 R3PTRTYPE(PPDMIBASE) pDrvBase;
214 /** Pointer to the attached serial driver. */
215 R3PTRTYPE(PPDMISERIALCONNECTOR) pDrvSerial;
216
217 /** Interrupt request callback of the owning device. */
218 R3PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq;
219
220 /** Pointer to the shared data - for timers callbacks and interface methods
221 * only. */
222 R3PTRTYPE(PUARTCORE) pShared;
223 /** Pointer to the device instance - only for getting our bearings in
224 * interface methods. */
225 PPDMDEVINS pDevIns;
226} UARTCORER3;
227/** Pointer to the core ring-3 UART device state. */
228typedef UARTCORER3 *PUARTCORER3;
229
230
231/**
232 * Ring-0 UART core device state.
233 */
234typedef struct UARTCORER0
235{
236 /** Interrupt request callback of the owning device. */
237 R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq;
238} UARTCORER0;
239/** Pointer to the core ring-0 UART device state. */
240typedef UARTCORER0 *PUARTCORER0;
241
242
243/**
244 * Raw-mode UART core device state.
245 */
246typedef struct UARTCORERC
247{
248 /** Interrupt request callback of the owning device. */
249 R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReq;
250} UARTCORERC;
251/** Pointer to the core raw-mode UART device state. */
252typedef UARTCORERC *PUARTCORERC;
253
254
255/** Current context UAR core device state. */
256typedef CTX_SUFF(UARTCORE) UARTCORECC;
257/** Pointer to the current context UAR core device state. */
258typedef CTX_SUFF(PUARTCORE) PUARTCORECC;
259
260
261#ifndef VBOX_DEVICE_STRUCT_TESTCASE
262
263/** Flag whether to yield the CPU on an LSR read. */
264#define UART_CORE_YIELD_ON_LSR_READ RT_BIT_32(0)
265
266DECLHIDDEN(VBOXSTRICTRC) uartRegWrite(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC,
267 uint32_t uReg, uint32_t u32, size_t cb);
268DECLHIDDEN(VBOXSTRICTRC) uartRegRead(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC,
269 uint32_t uReg, uint32_t *pu32, size_t cb);
270
271# ifdef IN_RING3
272DECLHIDDEN(int) uartR3Init(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC,
273 UARTTYPE enmType, unsigned iLUN, uint32_t fFlags, PFNUARTCOREIRQREQ pfnUartIrqReq);
274DECLHIDDEN(void) uartR3Destruct(PPDMDEVINS pDevIns, PUARTCORE pThis);
275DECLHIDDEN(void) uartR3Detach(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC);
276DECLHIDDEN(int) uartR3Attach(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, unsigned iLUN);
277DECLHIDDEN(void) uartR3Reset(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC);
278DECLHIDDEN(int) uartR3SaveExec(PPDMDEVINS pDevIns, PUARTCORE pThis, PSSMHANDLE pSSM);
279DECLHIDDEN(int) uartR3LoadExec(PPDMDEVINS pDevIns, PUARTCORE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass,
280 uint8_t *puIrq, RTIOPORT *pPortBase);
281DECLHIDDEN(int) uartR3LoadDone(PPDMDEVINS pDevIns, PUARTCORE pThis, PUARTCORECC pThisCC, PSSMHANDLE pSSM);
282
283# endif /* IN_RING3 */
284# if !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
285DECLHIDDEN(int) uartRZInit(PUARTCORECC pThisCC, PFNUARTCOREIRQREQ pfnUartIrqReq);
286# endif
287
288#endif
289
290RT_C_DECLS_END
291
292#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