VirtualBox

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

Last change on this file since 74942 was 74919, checked in by vboxsync, 6 years ago

Serial: Make sure the data is periodically removed from the TX queue even if there is no driver connected to the device

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.1 KB
Line 
1/* $Id: UartCore.h 74919 2018-10-18 13:12:30Z 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 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19#ifndef ___UartCore_h
20#define ___UartCore_h
21
22#include <VBox/types.h>
23#include <VBox/vmm/pdmdev.h>
24#include <VBox/vmm/pdmserialifs.h>
25#include <VBox/vmm/ssm.h>
26#include <iprt/assert.h>
27
28RT_C_DECLS_BEGIN
29
30/*********************************************************************************************************************************
31* Defined Constants And Macros *
32*********************************************************************************************************************************/
33
34/** The current serial code saved state version. */
35#define UART_SAVED_STATE_VERSION 7
36/** Saved state version before the TX timer for the connected device case was added. */
37#define UART_SAVED_STATE_VERSION_PRE_UNCONNECTED_TX_TIMER 6
38/** Saved state version of the legacy code which got replaced after 5.2. */
39#define UART_SAVED_STATE_VERSION_LEGACY_CODE 5
40/** Includes some missing bits from the previous saved state. */
41#define UART_SAVED_STATE_VERSION_MISSING_BITS 4
42/** Saved state version when only the 16450 variant was implemented. */
43#define UART_SAVED_STATE_VERSION_16450 3
44
45/** Maximum size of a FIFO. */
46#define UART_FIFO_LENGTH_MAX 128
47
48
49/*********************************************************************************************************************************
50* Structures and Typedefs *
51*********************************************************************************************************************************/
52
53/** Pointer to the UART core state. */
54typedef struct UARTCORE *PUARTCORE;
55
56
57/**
58 * UART core IRQ request callback to let the core instance raise/clear interrupt requests.
59 *
60 * @returns nothing.
61 * @param pDevIns The owning device instance.
62 * @param pThis The UART core instance.
63 * @param iLUN The LUN associated with the UART core.
64 * @param iLvl The interrupt level.
65 */
66typedef DECLCALLBACK(void) FNUARTCOREIRQREQ(PPDMDEVINS pDevIns, PUARTCORE pThis, unsigned iLUN, int iLvl);
67/** Pointer to a UART core IRQ request callback. */
68typedef FNUARTCOREIRQREQ *PFNUARTCOREIRQREQ;
69
70
71/**
72 * UART type.
73 */
74typedef enum UARTTYPE
75{
76 /** Invalid UART type. */
77 UARTTYPE_INVALID = 0,
78 /** 16450 UART type. */
79 UARTTYPE_16450,
80 /** 16550A UART type. */
81 UARTTYPE_16550A,
82 /** 16750 UART type. */
83 UARTTYPE_16750,
84 /** 32bit hack. */
85 UARTTYPE_32BIT_HACK = 0x7fffffff
86} UARTTYPE;
87
88
89/**
90 * UART FIFO.
91 */
92typedef struct UARTFIFO
93{
94 /** Fifo size configured. */
95 uint8_t cbMax;
96 /** Current amount of bytes used. */
97 uint8_t cbUsed;
98 /** Next index to write to. */
99 uint8_t offWrite;
100 /** Next index to read from. */
101 uint8_t offRead;
102 /** The interrupt trigger level (only used for the receive FIFO). */
103 uint8_t cbItl;
104 /** The data in the FIFO. */
105 uint8_t abBuf[UART_FIFO_LENGTH_MAX];
106 /** Alignment to a 4 byte boundary. */
107 uint8_t au8Alignment0[3];
108} UARTFIFO;
109/** Pointer to a FIFO. */
110typedef UARTFIFO *PUARTFIFO;
111
112
113/**
114 * UART core device.
115 *
116 * @implements PDMIBASE
117 * @implements PDMISERIALPORT
118 */
119typedef struct UARTCORE
120{
121 /** Access critical section. */
122 PDMCRITSECT CritSect;
123 /** Pointer to the device instance - R3 Ptr. */
124 PPDMDEVINSR3 pDevInsR3;
125 /** Pointer to the device instance - R0 Ptr. */
126 PPDMDEVINSR0 pDevInsR0;
127 /** Pointer to the device instance - RC Ptr. */
128 PPDMDEVINSRC pDevInsRC;
129 /** The LUN on the owning device instance for this core. */
130 uint32_t iLUN;
131 /** LUN\#0: The base interface. */
132 PDMIBASE IBase;
133 /** LUN\#0: The serial port interface. */
134 PDMISERIALPORT ISerialPort;
135 /** Pointer to the attached base driver. */
136 R3PTRTYPE(PPDMIBASE) pDrvBase;
137 /** Pointer to the attached serial driver. */
138 R3PTRTYPE(PPDMISERIALCONNECTOR) pDrvSerial;
139 /** Configuration flags. */
140 uint32_t fFlags;
141 /** The selected UART type. */
142 UARTTYPE enmType;
143
144 /** R3 timer pointer for the character timeout indication. */
145 PTMTIMERR3 pTimerRcvFifoTimeoutR3;
146 /** R3 timer pointer for the send loop if no driver is connected. */
147 PTMTIMERR3 pTimerTxUnconnectedR3;
148 /** R3 interrupt request callback of the owning device. */
149 R3PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR3;
150 /** R0 timer pointer fo the character timeout indication. */
151 PTMTIMERR0 pTimerRcvFifoTimeoutR0;
152 /** R0 timer pointer for the send loop if no driver is connected. */
153 PTMTIMERR0 pTimerTxUnconnectedR0;
154 /** R0 interrupt request callback of the owning device. */
155 R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR0;
156 /** RC timer pointer fo the character timeout indication. */
157 PTMTIMERRC pTimerRcvFifoTimeoutRC;
158 /** RC timer pointer for the send loop if no driver is connected. */
159 PTMTIMERRC pTimerTxUnconnectedRC;
160 /** RC interrupt request callback of the owning device. */
161 RCPTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqRC;
162 /** Alignment */
163 uint32_t u32Alignment;
164
165 /** The divisor register (DLAB = 1). */
166 uint16_t uRegDivisor;
167 /** The Receiver Buffer Register (RBR, DLAB = 0). */
168 uint8_t uRegRbr;
169 /** The Transmitter Holding Register (THR, DLAB = 0). */
170 uint8_t uRegThr;
171 /** The Interrupt Enable Register (IER, DLAB = 0). */
172 uint8_t uRegIer;
173 /** The Interrupt Identification Register (IIR). */
174 uint8_t uRegIir;
175 /** The FIFO Control Register (FCR). */
176 uint8_t uRegFcr;
177 /** The Line Control Register (LCR). */
178 uint8_t uRegLcr;
179 /** The Modem Control Register (MCR). */
180 uint8_t uRegMcr;
181 /** The Line Status Register (LSR). */
182 uint8_t uRegLsr;
183 /** The Modem Status Register (MSR). */
184 uint8_t uRegMsr;
185 /** The Scratch Register (SCR). */
186 uint8_t uRegScr;
187
188 /** Flag whether a character timeout interrupt is pending
189 * (no symbols were inserted or removed from the receive FIFO
190 * during an 4 times the character transmit/receive period and the FIFO
191 * is not empty). */
192 bool fIrqCtiPending;
193 /** Flag whether the transmitter holding register went empty since last time the
194 * IIR register was read. This gets reset when IIR is read so the guest will get this
195 * interrupt ID only once. */
196 bool fThreEmptyPending;
197 /** Alignment. */
198 bool afAlignment[2];
199 /** The transmit FIFO. */
200 UARTFIFO FifoXmit;
201 /** The receive FIFO. */
202 UARTFIFO FifoRecv;
203
204 /** Time it takes to transmit/receive a single symbol in timer ticks. */
205 uint64_t cSymbolXferTicks;
206 /** Number of bytes available for reading from the layer below. */
207 volatile uint32_t cbAvailRdr;
208
209#if defined(IN_RC) || HC_ARCH_BITS == 32
210 uint32_t uAlignment;
211#endif
212} UARTCORE;
213
214AssertCompileSizeAlignment(UARTCORE, 8);
215
216
217#ifndef VBOX_DEVICE_STRUCT_TESTCASE
218
219/** Flag whether to yield the CPU on an LSR read. */
220#define UART_CORE_YIELD_ON_LSR_READ RT_BIT_32(0)
221
222/**
223 * Performs a register write to the given register offset.
224 *
225 * @returns VBox status code.
226 * @param pThis The UART core instance.
227 * @param uReg The register offset (byte offset) to start writing to.
228 * @param u32 The value to write.
229 * @param cb Number of bytes to write.
230 */
231DECLHIDDEN(int) uartRegWrite(PUARTCORE pThis, uint32_t uReg, uint32_t u32, size_t cb);
232
233/**
234 * Performs a register read from the given register offset.
235 *
236 * @returns VBox status code.
237 * @param pThis The UART core instance.
238 * @param uReg The register offset (byte offset) to start reading from.
239 * @param pu32 Where to store the read value.
240 * @param cb Number of bytes to read.
241 */
242DECLHIDDEN(int) uartRegRead(PUARTCORE pThis, uint32_t uReg, uint32_t *pu32, size_t cb);
243
244# ifdef IN_RING3
245/**
246 * Initializes the given UART core instance using the provided configuration.
247 *
248 * @returns VBox status code.
249 * @param pThis The UART core instance to initialize.
250 * @param pDevInsR3 The R3 device instance pointer.
251 * @param enmType The type of UART emulated.
252 * @param iLUN The LUN the UART should look for attached drivers.
253 * @param fFlags Additional flags controlling device behavior.
254 * @param pfnUartIrqReqR3 Pointer to the R3 interrupt request callback.
255 * @param pfnUartIrqReqR0 Pointer to the R0 interrupt request callback.
256 * @param pfnUartIrqReqRC Pointer to the RC interrupt request callback.
257 */
258DECLHIDDEN(int) uartR3Init(PUARTCORE pThis, PPDMDEVINS pDevInsR3, UARTTYPE enmType, unsigned iLUN, uint32_t fFlags,
259 R3PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR3, R0PTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqR0,
260 RCPTRTYPE(PFNUARTCOREIRQREQ) pfnUartIrqReqRC);
261
262/**
263 * Destroys the given UART core instance freeing all allocated resources.
264 *
265 * @returns nothing.
266 * @param pThis The UART core instance.
267 */
268DECLHIDDEN(void) uartR3Destruct(PUARTCORE pThis);
269
270/**
271 * Detaches any attached driver from the given UART core instance.
272 *
273 * @returns nothing.
274 * @param pThis The UART core instance.
275 */
276DECLHIDDEN(void) uartR3Detach(PUARTCORE pThis);
277
278/**
279 * Attaches the given UART core instance to the drivers at the given LUN.
280 *
281 * @returns VBox status code.
282 * @param pThis The UART core instance.
283 * @param iLUN The LUN being attached.
284 */
285DECLHIDDEN(int) uartR3Attach(PUARTCORE pThis, unsigned iLUN);
286
287/**
288 * Resets the given UART core instance.
289 *
290 * @returns nothing.
291 * @param pThis The UART core instance.
292 */
293DECLHIDDEN(void) uartR3Reset(PUARTCORE pThis);
294
295/**
296 * Relocates an RC pointers of the given UART core instance
297 *
298 * @returns nothing.
299 * @param pThis The UART core instance.
300 * @param offDelta The delta to relocate RC pointers with.
301 */
302DECLHIDDEN(void) uartR3Relocate(PUARTCORE pThis, RTGCINTPTR offDelta);
303
304/**
305 * Saves the UART state to the given SSM handle.
306 *
307 * @returns VBox status code.
308 * @param pThis The UART core instance.
309 * @param pSSM The SSM handle to save to.
310 */
311DECLHIDDEN(int) uartR3SaveExec(PUARTCORE pThis, PSSMHANDLE pSSM);
312
313/**
314 * Loads the UART state from the given SSM handle.
315 *
316 * @returns VBox status code.
317 * @param pThis The UART core instance.
318 * @param pSSM The SSM handle to load from.
319 * @param uVersion Saved state version.
320 * @param uPass The SSM pass the call is done in.
321 * @param puIrq Where to store the IRQ value for legacy
322 * saved states - optional.
323 * @param pPortBase Where to store the I/O port base for legacy
324 * saved states - optional.
325 */
326DECLHIDDEN(int) uartR3LoadExec(PUARTCORE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass,
327 uint8_t *puIrq, RTIOPORT *pPortBase);
328
329/**
330 * Called when loading the state completed, updates the parameters of any driver underneath.
331 *
332 * @returns VBox status code.
333 * @param pThis The UART core instance.
334 * @param pSSM The SSM handle.
335 */
336DECLHIDDEN(int) uartR3LoadDone(PUARTCORE pThis, PSSMHANDLE pSSM);
337
338# endif
339
340#endif
341
342RT_C_DECLS_END
343
344#endif
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use