2 Basic serial IO abstraction 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>
16 // ---------------------------------------------
17 // UART Register Offsets
18 // ---------------------------------------------
19 #define BAUD_LOW_OFFSET 0x00
20 #define BAUD_HIGH_OFFSET 0x01
21 #define IER_OFFSET 0x01
22 #define LCR_SHADOW_OFFSET 0x01
23 #define FCR_SHADOW_OFFSET 0x02
24 #define IR_CONTROL_OFFSET 0x02
25 #define FCR_OFFSET 0x02
26 #define EIR_OFFSET 0x02
27 #define BSR_OFFSET 0x03
28 #define LCR_OFFSET 0x03
29 #define MCR_OFFSET 0x04
30 #define LSR_OFFSET 0x05
31 #define MSR_OFFSET 0x06
33 // ---------------------------------------------
34 // UART Register Bit Defines
35 // ---------------------------------------------
36 #define LSR_TXRDY 0x20U
37 #define LSR_RXDA 0x01U
39 #define ENABLE_FIFO 0x01U
40 #define CLEAR_FIFOS 0x06U
42 // IO Port Base for the UART
46 The constructor function initializes the UART.
48 @param ImageHandle The firmware allocated handle for the EFI image.
49 @param SystemTable A pointer to the EFI System Table.
51 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
56 GdbSerialLibConstructor (
57 IN EFI_HANDLE ImageHandle
,
58 IN EFI_SYSTEM_TABLE
*SystemTable
66 gPort
= (UINTN
)PcdGet32 (PcdGdbUartPort
);
68 BaudRate
= PcdGet64 (PcdGdbBaudRate
);
69 Parity
= PcdGet8 (PcdGdbParity
);
70 DataBits
= PcdGet8 (PcdGdbDataBits
);
71 StopBits
= PcdGet8 (PcdGdbStopBits
);
73 return GdbSerialInit (BaudRate
, Parity
, DataBits
, StopBits
);
77 Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,
78 data buts, and stop bits on a serial device. This call is optional as the serial
79 port will be set up with defaults base on PCD values.
81 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the
82 device's default interface speed.
83 @param Parity The type of parity to use on this serial device. A Parity value of
84 DefaultParity will use the device's default parity value.
85 @param DataBits The number of data bits to use on the serial device. A DataBits
86 value of 0 will use the device's default data bit setting.
87 @param StopBits The number of stop bits to use on this serial device. A StopBits
88 value of DefaultStopBits will use the device's default number of
91 @retval EFI_SUCCESS The device was configured.
92 @retval EFI_DEVICE_ERROR The serial device could not be configured.
110 // We assume the UART has been turned on to decode gPort address range
116 Data
= (UINT8
)(DataBits
- (UINT8
)5);
119 // Calculate divisor for baud generator
121 Divisor
= 115200/(UINTN
)BaudRate
;
124 // Set communications format
126 OutputData
= (UINT8
)((DLAB
<< 7) | ((BreakSet
<< 6) | ((Parity
<< 3) | ((StopBits
<< 2) | Data
))));
127 IoWrite8 (gPort
+ LCR_OFFSET
, OutputData
);
130 // Configure baud rate
132 IoWrite8 (gPort
+ BAUD_HIGH_OFFSET
, (UINT8
)(Divisor
>> 8));
133 IoWrite8 (gPort
+ BAUD_LOW_OFFSET
, (UINT8
)(Divisor
& 0xff));
136 // Switch back to bank 0
138 OutputData
= (UINT8
)((~DLAB
<<7)|((BreakSet
<<6)|((Parity
<<3)|((StopBits
<<2)| Data
))));
139 IoWrite8 (gPort
+ LCR_OFFSET
, OutputData
);
141 // Not sure this is the right place to enable the FIFOs....
142 // We probably need the FIFO enabled to not drop input
143 IoWrite8 (gPort
+ FCR_SHADOW_OFFSET
, ENABLE_FIFO
);
145 // Configure the UART hardware here
146 return RETURN_SUCCESS
;
150 Check to see if a character is available from GDB. Do not read the character as that is
151 done via GdbGetChar().
153 @return TRUE - Character available
154 @return FALSE - Character not available
165 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
167 return ((Data
& LSR_RXDA
) == LSR_RXDA
);
171 Get a character from GDB. This function must be able to run in interrupt context.
173 @return A character from GDB
185 // Wait for the serial port to be ready
187 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
188 } while ((Data
& LSR_RXDA
) == 0);
190 Char
= IoRead8 (gPort
);
192 // Make this an DEBUG_INFO after we get everything debugged.
193 DEBUG ((DEBUG_ERROR
, "<%c<", Char
));
198 Send a character to GDB. This function must be able to run in interrupt context.
201 @param Char Send a character to GDB
212 // Make this an DEBUG_INFO after we get everything debugged.
213 DEBUG ((DEBUG_ERROR
, ">%c>", Char
));
215 // Wait for the serial port to be ready
217 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
218 } while ((Data
& LSR_TXRDY
) == 0);
220 IoWrite8 (gPort
, Char
);
224 Send an ASCII string to GDB. This function must be able to run in interrupt context.
227 @param String Send a string to GDB
235 while (*String
!= '\0') {
236 GdbPutChar (*String
);