2 Basic serial IO abstaction for GDB
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/GdbSerialLib.h>
12 #include <Library/PcdLib.h>
13 #include <Library/IoLib.h>
14 #include <Library/DebugLib.h>
17 //---------------------------------------------
18 // UART Register Offsets
19 //---------------------------------------------
20 #define BAUD_LOW_OFFSET 0x00
21 #define BAUD_HIGH_OFFSET 0x01
22 #define IER_OFFSET 0x01
23 #define LCR_SHADOW_OFFSET 0x01
24 #define FCR_SHADOW_OFFSET 0x02
25 #define IR_CONTROL_OFFSET 0x02
26 #define FCR_OFFSET 0x02
27 #define EIR_OFFSET 0x02
28 #define BSR_OFFSET 0x03
29 #define LCR_OFFSET 0x03
30 #define MCR_OFFSET 0x04
31 #define LSR_OFFSET 0x05
32 #define MSR_OFFSET 0x06
34 //---------------------------------------------
35 // UART Register Bit Defines
36 //---------------------------------------------
37 #define LSR_TXRDY 0x20U
38 #define LSR_RXDA 0x01U
40 #define ENABLE_FIFO 0x01U
41 #define CLEAR_FIFOS 0x06U
45 // IO Port Base for the UART
50 The constructor function initializes the UART.
52 @param ImageHandle The firmware allocated handle for the EFI image.
53 @param SystemTable A pointer to the EFI System Table.
55 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
60 GdbSerialLibConstructor (
61 IN EFI_HANDLE ImageHandle
,
62 IN EFI_SYSTEM_TABLE
*SystemTable
70 gPort
= (UINTN
)PcdGet32 (PcdGdbUartPort
);
72 BaudRate
= PcdGet64 (PcdGdbBaudRate
);
73 Parity
= PcdGet8 (PcdGdbParity
);
74 DataBits
= PcdGet8 (PcdGdbDataBits
);
75 StopBits
= PcdGet8 (PcdGdbStopBits
);
77 return GdbSerialInit (BaudRate
, Parity
, DataBits
, StopBits
);
83 Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
84 data buts, and stop bits on a serial device. This call is optional as the serial
85 port will be set up with defaults base on PCD values.
87 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
88 device's default interface speed.
89 @param Parity The type of parity to use on this serial device. A Parity value of
90 DefaultParity will use the device's default parity value.
91 @param DataBits The number of data bits to use on the serial device. A DataBits
92 vaule of 0 will use the device's default data bit setting.
93 @param StopBits The number of stop bits to use on this serial device. A StopBits
94 value of DefaultStopBits will use the device's default number of
97 @retval EFI_SUCCESS The device was configured.
98 @retval EFI_DEVICE_ERROR The serial device could not be coonfigured.
116 // We assume the UART has been turned on to decode gPort address range
122 Data
= (UINT8
) (DataBits
- (UINT8
)5);
125 // Calculate divisor for baud generator
127 Divisor
= 115200/(UINTN
)BaudRate
;
130 // Set communications format
132 OutputData
= (UINT8
)((DLAB
<< 7) | ((BreakSet
<< 6) | ((Parity
<< 3) | ((StopBits
<< 2) | Data
))));
133 IoWrite8 (gPort
+ LCR_OFFSET
, OutputData
);
136 // Configure baud rate
138 IoWrite8 (gPort
+ BAUD_HIGH_OFFSET
, (UINT8
)(Divisor
>> 8));
139 IoWrite8 (gPort
+ BAUD_LOW_OFFSET
, (UINT8
)(Divisor
& 0xff));
143 // Switch back to bank 0
145 OutputData
= (UINT8
)((~DLAB
<<7)|((BreakSet
<<6)|((Parity
<<3)|((StopBits
<<2)| Data
))));
146 IoWrite8 (gPort
+ LCR_OFFSET
, OutputData
);
148 // Not sure this is the right place to enable the FIFOs....
149 // We probably need the FIFO enabled to not drop input
150 IoWrite8 (gPort
+ FCR_SHADOW_OFFSET
, ENABLE_FIFO
);
153 // Configure the UART hardware here
154 return RETURN_SUCCESS
;
159 Check to see if a character is available from GDB. Do not read the character as that is
160 done via GdbGetChar().
162 @return TRUE - Character available
163 @return FALSE - Character not available
174 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
176 return ((Data
& LSR_RXDA
) == LSR_RXDA
);
181 Get a character from GDB. This function must be able to run in interrupt context.
183 @return A character from GDB
195 // Wait for the serial port to be ready
197 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
198 } while ((Data
& LSR_RXDA
) == 0);
200 Char
= IoRead8 (gPort
);
202 // Make this an EFI_D_INFO after we get everything debugged.
203 DEBUG ((EFI_D_ERROR
, "<%c<", Char
));
209 Send a character to GDB. This function must be able to run in interrupt context.
212 @param Char Send a character to GDB
224 // Make this an EFI_D_INFO after we get everything debugged.
225 DEBUG ((EFI_D_ERROR
, ">%c>", Char
));
227 // Wait for the serial port to be ready
229 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
230 } while ((Data
& LSR_TXRDY
) == 0);
232 IoWrite8 (gPort
, Char
);
236 Send an ASCII string to GDB. This function must be able to run in interrupt context.
239 @param String Send a string to GDB
248 while (*String
!= '\0') {
249 GdbPutChar (*String
);