VirtualBox

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

Last change on this file since 74441 was 73636, checked in by vboxsync, 6 years ago

Devices/Serial: Fix Widows guests, the THRE empty interrupt status is only returned once to the guest every time it occurs

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