EmbeddedPkg: Fix typos in comments
[mirror_edk2.git] / EmbeddedPkg / Library / GdbSerialLib / GdbSerialLib.c
CommitLineData
2ef2b01e
A
1/** @file\r
2 Basic serial IO abstaction for GDB\r
3\r
60274cca 4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
3402aac7 5\r
60274cca 6 This program and the accompanying materials\r
2ef2b01e
A
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <Uefi.h>\r
17#include <Library/GdbSerialLib.h>\r
18#include <Library/PcdLib.h>\r
19#include <Library/IoLib.h>\r
20#include <Library/DebugLib.h>\r
21\r
22\r
23//---------------------------------------------\r
24// UART Register Offsets\r
25//---------------------------------------------\r
26#define BAUD_LOW_OFFSET 0x00\r
27#define BAUD_HIGH_OFFSET 0x01\r
28#define IER_OFFSET 0x01\r
29#define LCR_SHADOW_OFFSET 0x01\r
30#define FCR_SHADOW_OFFSET 0x02\r
31#define IR_CONTROL_OFFSET 0x02\r
32#define FCR_OFFSET 0x02\r
33#define EIR_OFFSET 0x02\r
34#define BSR_OFFSET 0x03\r
35#define LCR_OFFSET 0x03\r
36#define MCR_OFFSET 0x04\r
37#define LSR_OFFSET 0x05\r
38#define MSR_OFFSET 0x06\r
39\r
40//---------------------------------------------\r
41// UART Register Bit Defines\r
42//---------------------------------------------\r
43#define LSR_TXRDY 0x20\r
44#define LSR_RXDA 0x01\r
45#define DLAB 0x01\r
46#define ENABLE_FIFO 0x01\r
47#define CLEAR_FIFOS 0x06\r
48\r
49\r
50\r
51// IO Port Base for the UART\r
52UINTN gPort;\r
53\r
54\r
55/**\r
56 The constructor function initializes the UART.\r
3402aac7 57\r
2ef2b01e
A
58 @param ImageHandle The firmware allocated handle for the EFI image.\r
59 @param SystemTable A pointer to the EFI System Table.\r
3402aac7 60\r
2ef2b01e
A
61 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
62\r
63**/\r
64RETURN_STATUS\r
65EFIAPI\r
66GdbSerialLibConstructor (\r
67 IN EFI_HANDLE ImageHandle,\r
68 IN EFI_SYSTEM_TABLE *SystemTable\r
69 )\r
70{\r
71 UINT64 BaudRate;\r
72 UINT8 DataBits;\r
73 UINT8 Parity;\r
74 UINT8 StopBits;\r
3402aac7 75\r
2ef2b01e 76 gPort = (UINTN)PcdGet32 (PcdGdbUartPort);\r
3402aac7 77\r
2ef2b01e
A
78 BaudRate = PcdGet64 (PcdGdbBaudRate);\r
79 Parity = PcdGet8 (PcdGdbParity);\r
80 DataBits = PcdGet8 (PcdGdbDataBits);\r
81 StopBits = PcdGet8 (PcdGdbStopBits);\r
82\r
83 return GdbSerialInit (BaudRate, Parity, DataBits, StopBits);\r
84}\r
85\r
86\r
87\r
88/**\r
3402aac7 89 Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,\r
2ef2b01e
A
90 data buts, and stop bits on a serial device. This call is optional as the serial\r
91 port will be set up with defaults base on PCD values.\r
92\r
93 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the\r
94 device's default interface speed.\r
95 @param Parity The type of parity to use on this serial device. A Parity value of\r
96 DefaultParity will use the device's default parity value.\r
97 @param DataBits The number of data bits to use on the serial device. A DataBits\r
98 vaule of 0 will use the device's default data bit setting.\r
99 @param StopBits The number of stop bits to use on this serial device. A StopBits\r
100 value of DefaultStopBits will use the device's default number of\r
101 stop bits.\r
102\r
103 @retval EFI_SUCCESS The device was configured.\r
104 @retval EFI_DEVICE_ERROR The serial device could not be coonfigured.\r
105\r
106**/\r
107RETURN_STATUS\r
108EFIAPI\r
109GdbSerialInit (\r
3402aac7
RC
110 IN UINT64 BaudRate,\r
111 IN UINT8 Parity,\r
112 IN UINT8 DataBits,\r
113 IN UINT8 StopBits\r
2ef2b01e
A
114 )\r
115{\r
116 UINTN Divisor;\r
117 UINT8 OutputData;\r
118 UINT8 Data;\r
119 UINT8 BreakSet = 0;\r
120\r
121 //\r
122 // We assume the UART has been turned on to decode gPort address range\r
123 //\r
3402aac7 124\r
2ef2b01e
A
125 //\r
126 // Map 5..8 to 0..3\r
127 //\r
128 Data = (UINT8) (DataBits - (UINT8)5);\r
129\r
130 //\r
131 // Calculate divisor for baud generator\r
132 //\r
3402aac7
RC
133 Divisor = 115200/(UINTN)BaudRate;\r
134\r
2ef2b01e
A
135 //\r
136 // Set communications format\r
137 //\r
138 OutputData = (UINT8)((DLAB << 7) | ((BreakSet << 6) | ((Parity << 3) | ((StopBits << 2) | Data))));\r
139 IoWrite8 (gPort + LCR_OFFSET, OutputData);\r
140\r
141 //\r
142 // Configure baud rate\r
143 //\r
144 IoWrite8 (gPort + BAUD_HIGH_OFFSET, (UINT8)(Divisor >> 8));\r
145 IoWrite8 (gPort + BAUD_LOW_OFFSET, (UINT8)(Divisor & 0xff));\r
146\r
147\r
148 //\r
149 // Switch back to bank 0\r
150 //\r
151 OutputData = (UINT8)((~DLAB<<7)|((BreakSet<<6)|((Parity<<3)|((StopBits<<2)| Data))));\r
152 IoWrite8 (gPort + LCR_OFFSET, OutputData);\r
153\r
154 // Not sure this is the right place to enable the FIFOs....\r
155 // We probably need the FIFO enabled to not drop input\r
156 IoWrite8 (gPort + FCR_SHADOW_OFFSET, ENABLE_FIFO);\r
157\r
158\r
159 // Configure the UART hardware here\r
160 return RETURN_SUCCESS;\r
161}\r
162\r
163\r
164/**\r
165 Check to see if a character is available from GDB. Do not read the character as that is\r
166 done via GdbGetChar().\r
167\r
4f0624e8
GL
168 @return TRUE - Character available\r
169 @return FALSE - Character not available\r
3402aac7 170\r
2ef2b01e
A
171**/\r
172BOOLEAN\r
173EFIAPI\r
174GdbIsCharAvailable (\r
175 VOID\r
3402aac7 176 )\r
2ef2b01e
A
177{\r
178 UINT8 Data;\r
3402aac7 179\r
2ef2b01e 180 Data = IoRead8 (gPort + LSR_OFFSET);\r
3402aac7 181\r
2ef2b01e
A
182 return ((Data & LSR_RXDA) == LSR_RXDA);\r
183}\r
184\r
185\r
186/**\r
187 Get a character from GDB. This function must be able to run in interrupt context.\r
188\r
189 @return A character from GDB\r
3402aac7 190\r
2ef2b01e
A
191**/\r
192CHAR8\r
193EFIAPI\r
194GdbGetChar (\r
195 VOID\r
196 )\r
197{\r
198 UINT8 Data;\r
199 CHAR8 Char;\r
200\r
201 // Wait for the serial port to be ready\r
202 do {\r
203 Data = IoRead8 (gPort + LSR_OFFSET);\r
204 } while ((Data & LSR_RXDA) == 0);\r
205\r
206 Char = IoRead8 (gPort);\r
3402aac7 207\r
2ef2b01e
A
208 // Make this an EFI_D_INFO after we get everything debugged.\r
209 DEBUG ((EFI_D_ERROR, "<%c<", Char));\r
210 return Char;\r
211}\r
212\r
213\r
214/**\r
215 Send a character to GDB. This function must be able to run in interrupt context.\r
216\r
217\r
218 @param Char Send a character to GDB\r
219\r
220**/\r
221\r
222VOID\r
223EFIAPI\r
224GdbPutChar (\r
225 IN CHAR8 Char\r
226 )\r
227{\r
228 UINT8 Data;\r
3402aac7 229\r
2ef2b01e
A
230 // Make this an EFI_D_INFO after we get everything debugged.\r
231 DEBUG ((EFI_D_ERROR, ">%c>", Char));\r
3402aac7 232\r
2ef2b01e
A
233 // Wait for the serial port to be ready\r
234 do {\r
235 Data = IoRead8 (gPort + LSR_OFFSET);\r
236 } while ((Data & LSR_TXRDY) == 0);\r
3402aac7 237\r
2ef2b01e
A
238 IoWrite8 (gPort, Char);\r
239}\r
240\r
241/**\r
242 Send an ASCII string to GDB. This function must be able to run in interrupt context.\r
243\r
244\r
245 @param String Send a string to GDB\r
246\r
247**/\r
248\r
249VOID\r
250GdbPutString (\r
251 IN CHAR8 *String\r
252 )\r
253{\r
254 while (*String != '\0') {\r
255 GdbPutChar (*String);\r
256 String++;\r
257 }\r
258}\r
259\r
260\r
261\r
262\r