VirtualBox

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

Last change on this file since 91968 was 85121, checked in by vboxsync, 4 years ago

iprt/cdefs.h: Refactored the typedef use of DECLCALLBACK as well as DECLCALLBACKMEMBER to wrap the whole expression, similar to the DECLR?CALLBACKMEMBER macros. This allows adding a throw() at the end when compiling with the VC++ compiler to indicate that the callbacks won't throw anything, so we can stop supressing the C5039 warning about passing functions that can potential throw C++ exceptions to extern C code that can't necessarily cope with such (unwind,++). Introduced a few _EX variations that allows specifying different/no calling convention too, as that's handy when dynamically resolving host APIs. Fixed numerous places missing DECLCALLBACK and such. Left two angry @todos regarding use of CreateThread. bugref:9794

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