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 This program and the accompanying materials are licensed and made available under 8 the terms and conditions of the BSD License that accompanies this distribution. 10 The full text of the license may be found at 12 http://opensource.org/licenses/bsd-license.php. 14 16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 20 22 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 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 /** 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 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 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 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 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. 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