2 Basic serial IO abstaction for GDB
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/GdbSerialLib.h>
18 #include <Library/PcdLib.h>
19 #include <Library/IoLib.h>
20 #include <Library/DebugLib.h>
23 //---------------------------------------------
24 // UART Register Offsets
25 //---------------------------------------------
26 #define BAUD_LOW_OFFSET 0x00
27 #define BAUD_HIGH_OFFSET 0x01
28 #define IER_OFFSET 0x01
29 #define LCR_SHADOW_OFFSET 0x01
30 #define FCR_SHADOW_OFFSET 0x02
31 #define IR_CONTROL_OFFSET 0x02
32 #define FCR_OFFSET 0x02
33 #define EIR_OFFSET 0x02
34 #define BSR_OFFSET 0x03
35 #define LCR_OFFSET 0x03
36 #define MCR_OFFSET 0x04
37 #define LSR_OFFSET 0x05
38 #define MSR_OFFSET 0x06
40 //---------------------------------------------
41 // UART Register Bit Defines
42 //---------------------------------------------
43 #define LSR_TXRDY 0x20
46 #define ENABLE_FIFO 0x01
47 #define CLEAR_FIFOS 0x06
51 // IO Port Base for the UART
56 The constructor function initializes the UART.
58 @param ImageHandle The firmware allocated handle for the EFI image.
59 @param SystemTable A pointer to the EFI System Table.
61 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
66 GdbSerialLibConstructor (
67 IN EFI_HANDLE ImageHandle
,
68 IN EFI_SYSTEM_TABLE
*SystemTable
76 gPort
= (UINTN
)PcdGet32 (PcdGdbUartPort
);
78 BaudRate
= PcdGet64 (PcdGdbBaudRate
);
79 Parity
= PcdGet8 (PcdGdbParity
);
80 DataBits
= PcdGet8 (PcdGdbDataBits
);
81 StopBits
= PcdGet8 (PcdGdbStopBits
);
83 return GdbSerialInit (BaudRate
, Parity
, DataBits
, StopBits
);
89 Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
90 data buts, and stop bits on a serial device. This call is optional as the serial
91 port will be set up with defaults base on PCD values.
93 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
94 device's default interface speed.
95 @param Parity The type of parity to use on this serial device. A Parity value of
96 DefaultParity will use the device's default parity value.
97 @param DataBits The number of data bits to use on the serial device. A DataBits
98 vaule of 0 will use the device's default data bit setting.
99 @param StopBits The number of stop bits to use on this serial device. A StopBits
100 value of DefaultStopBits will use the device's default number of
103 @retval EFI_SUCCESS The device was configured.
104 @retval EFI_DEVICE_ERROR The serial device could not be coonfigured.
122 // We assume the UART has been turned on to decode gPort address range
128 Data
= (UINT8
) (DataBits
- (UINT8
)5);
131 // Calculate divisor for baud generator
133 Divisor
= 115200/(UINTN
)BaudRate
;
136 // Set communications format
138 OutputData
= (UINT8
)((DLAB
<< 7) | ((BreakSet
<< 6) | ((Parity
<< 3) | ((StopBits
<< 2) | Data
))));
139 IoWrite8 (gPort
+ LCR_OFFSET
, OutputData
);
142 // Configure baud rate
144 IoWrite8 (gPort
+ BAUD_HIGH_OFFSET
, (UINT8
)(Divisor
>> 8));
145 IoWrite8 (gPort
+ BAUD_LOW_OFFSET
, (UINT8
)(Divisor
& 0xff));
149 // Switch back to bank 0
151 OutputData
= (UINT8
)((~DLAB
<<7)|((BreakSet
<<6)|((Parity
<<3)|((StopBits
<<2)| Data
))));
152 IoWrite8 (gPort
+ LCR_OFFSET
, OutputData
);
154 // Not sure this is the right place to enable the FIFOs....
155 // We probably need the FIFO enabled to not drop input
156 IoWrite8 (gPort
+ FCR_SHADOW_OFFSET
, ENABLE_FIFO
);
159 // Configure the UART hardware here
160 return RETURN_SUCCESS
;
165 Check to see if a character is available from GDB. Do not read the character as that is
166 done via GdbGetChar().
168 @return TRUE - Character available
169 @return FALSE - Character not available
180 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
182 return ((Data
& LSR_RXDA
) == LSR_RXDA
);
187 Get a character from GDB. This function must be able to run in interrupt context.
189 @return A character from GDB
201 // Wait for the serial port to be ready
203 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
204 } while ((Data
& LSR_RXDA
) == 0);
206 Char
= IoRead8 (gPort
);
208 // Make this an EFI_D_INFO after we get everything debugged.
209 DEBUG ((EFI_D_ERROR
, "<%c<", Char
));
215 Send a character to GDB. This function must be able to run in interrupt context.
218 @param Char Send a character to GDB
230 // Make this an EFI_D_INFO after we get everything debugged.
231 DEBUG ((EFI_D_ERROR
, ">%c>", Char
));
233 // Wait for the serial port to be ready
235 Data
= IoRead8 (gPort
+ LSR_OFFSET
);
236 } while ((Data
& LSR_TXRDY
) == 0);
238 IoWrite8 (gPort
, Char
);
242 Send an ASCII string to GDB. This function must be able to run in interrupt context.
245 @param String Send a string to GDB
254 while (*String
!= '\0') {
255 GdbPutChar (*String
);