1 /** @file
2 Serial I/O Port library functions with no library constructor/destructor
3
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5
6
7 This program and the accompanying materials are licensed and made available under
8
9 the terms and conditions of the BSD License that accompanies this distribution.
10
11 The full text of the license may be found at
12
13 http://opensource.org/licenses/bsd-license.php.
14
15
16
17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20
21
22
23 This software and associated documentation
24 (if any) is furnished under a license and may only be used or
25 copied in accordance with the terms of the license. Except as
26 permitted by such license, no part of this software or
27 documentation may be reproduced, stored in a retrieval system, or
28 transmitted in any form or by any means without the express written
29 consent of Intel Corporation.
30
31 Module Name: SerialPortLib.c
32
33 **/
34
35 #include "PlatformSerialPortLib.h"
36
37 UINT16 gComBase = 0x3f8;
38 UINTN gBps = 115200;
39 UINT8 gData = 8;
40 UINT8 gStop = 1;
41 UINT8 gParity = 0;
42 UINT8 gBreakSet = 0;
43
44 /**
45 Initialize Serial Port
46
47 The Baud Rate Divisor registers are programmed and the LCR
48 is used to configure the communications format. Hard coded
UARTInitialize(VOID)49 UART config comes from globals in DebugSerialPlatform lib.
50
51 @param None
52
53 @retval None
54
55 **/
56 RETURN_STATUS
57 EFIAPI
58 UARTInitialize (
59 VOID
60 )
61 {
62 UINTN Divisor;
63 UINT8 OutputData;
64 UINT8 Data;
65
66 //
67 // Map 5..8 to 0..3
68 //
69 Data = (UINT8) (gData - (UINT8) 5);
70
71 //
72 // Calculate divisor for baud generator
73 //
74 Divisor = 115200 / gBps;
75
76 //
77 // Set communications format
78 //
79 OutputData = (UINT8) ((DLAB << 7) | ((gBreakSet << 6) | ((gParity << 3) | ((gStop << 2) | Data))));
80 IoWrite8 (gComBase + LCR_OFFSET, OutputData);
81
82 //
83 // Configure baud rate
84 //
85 IoWrite8 (gComBase + BAUD_HIGH_OFFSET, (UINT8) (Divisor >> 8));
86 IoWrite8 (gComBase + BAUD_LOW_OFFSET, (UINT8) (Divisor & 0xff));
87
88 //
89 // Switch back to bank 0
90 //
91 OutputData = (UINT8) ((~DLAB << 7) | ((gBreakSet << 6) | ((gParity << 3) | ((gStop << 2) | Data))));
92 IoWrite8 (gComBase + LCR_OFFSET, OutputData);
93
94 return RETURN_SUCCESS;
95 }
96
97 /**
SerialPortInitialize(VOID)98 Common function to initialize UART Serial device and USB Serial device.
99
100 @param None
101
102 @retval None
103
104 **/
105 RETURN_STATUS
106 EFIAPI
107 SerialPortInitialize (
108 VOID
109 )
110 {
111
112 UARTInitialize ();
113
114
115 return RETURN_SUCCESS;
116 }
117
118 /**
119 Write data to serial device.
120
121 If the buffer is NULL, then return 0;
122 if NumberOfBytes is zero, then return 0.
123
UARTDbgOut(IN UINT8 * Buffer,IN UINTN NumberOfBytes)124 @param Buffer Point of data buffer which need to be writed.
125 @param NumberOfBytes Number of output bytes which are cached in Buffer.
126
127 @retval 0 Write data failed.
128 @retval !0 Actual number of bytes writed to serial device.
129
130 **/
131 UINTN
132 EFIAPI
133 UARTDbgOut (
134 IN UINT8 *Buffer,
135 IN UINTN NumberOfBytes
136 )
137 {
138 UINTN Result;
139 UINT8 Data;
140
141 if (NULL == Buffer) {
142 return 0;
143 }
144
145 Result = NumberOfBytes;
146
147 while (NumberOfBytes--) {
148 //
149 // Wait for the serial port to be ready.
150 //
151 do {
152 Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) + LSR_OFFSET);
153 } while ((Data & LSR_TXRDY) == 0);
154 IoWrite8 ((UINT16) PcdGet64 (PcdSerialRegisterBase), *Buffer++);
155 }
156
157 return Result;
158 }
159
SerialPortWrite(IN UINT8 * Buffer,IN UINTN NumberOfBytes)160 /**
161 Common function to write data to UART Serial device and USB Serial device.
162
163 @param Buffer Point of data buffer which need to be writed.
164 @param NumberOfBytes Number of output bytes which are cached in Buffer.
165
166 **/
167 UINTN
168 EFIAPI
169 SerialPortWrite (
170 IN UINT8 *Buffer,
171 IN UINTN NumberOfBytes
172 )
173 {
174 if (FeaturePcdGet (PcdStatusCodeUseIsaSerial)) {
175 UARTDbgOut (Buffer, NumberOfBytes);
176 }
177
178 return RETURN_SUCCESS;
179 }
180
181 /**
182 Read data from serial device and save the datas in buffer.
183
184 If the buffer is NULL, then return 0;
185 if NumberOfBytes is zero, then return 0.
186
UARTDbgIn(OUT UINT8 * Buffer,IN UINTN NumberOfBytes)187 @param Buffer Point of data buffer which need to be writed.
188 @param NumberOfBytes Number of output bytes which are cached in Buffer.
189
190 @retval 0 Read data failed.
191 @retval !0 Actual number of bytes raed to serial device.
192
193 **/
194 UINTN
195 EFIAPI
196 UARTDbgIn (
197 OUT UINT8 *Buffer,
198 IN UINTN NumberOfBytes
199 )
200 {
201 UINTN Result;
202 UINT8 Data;
203
204 if (NULL == Buffer) {
205 return 0;
206 }
207
208 Result = NumberOfBytes;
209
210 while (NumberOfBytes--) {
211 //
212 // Wait for the serial port to be ready.
213 //
214 do {
215 Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) + LSR_OFFSET);
216 } while ((Data & LSR_RXDA) == 0);
217
218 *Buffer++ = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase));
219 }
220
221 return Result;
222 }
223
SerialPortRead(OUT UINT8 * Buffer,IN UINTN NumberOfBytes)224 /**
225 Common function to Read data from UART serial device, USB serial device and save the datas in buffer.
226
227 @param Buffer Point of data buffer which need to be writed.
228 @param NumberOfBytes Number of output bytes which are cached in Buffer.
229
230 **/
231 UINTN
232 EFIAPI
233 SerialPortRead (
234 OUT UINT8 *Buffer,
235 IN UINTN NumberOfBytes
236 )
237 {
238 if (FeaturePcdGet (PcdStatusCodeUseIsaSerial)) {
239 UARTDbgIn (Buffer, NumberOfBytes);
240 }
241
242 return RETURN_SUCCESS;
243 }
244
245
246 /**
247 Polls a serial device to see if there is any data waiting to be read.
248
249 Polls aserial device to see if there is any data waiting to be read.
SerialPortPoll(VOID)250 If there is data waiting to be read from the serial device, then TRUE is returned.
251 If there is no data waiting to be read from the serial device, then FALSE is returned.
252
253 @retval TRUE Data is waiting to be read from the serial device.
254 @retval FALSE There is no data waiting to be read from the serial device.
255
256 **/
257 BOOLEAN
258 EFIAPI
259 SerialPortPoll (
260 VOID
261 )
262 {
263 UINT8 Data;
264
265 //
266 // Read the serial port status.
267 //
268 Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) + LSR_OFFSET);
269
270 return (BOOLEAN) ((Data & LSR_RXDA) != 0);
271 }
272