1 /** @file
2 Basic serial IO abstaction for GDB
3
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
5
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
10
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.
13
14 **/
15
16 #include <Uefi.h>
17 #include <Library/GdbSerialLib.h>
18 #include <Library/PcdLib.h>
19 #include <Library/IoLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22
23 #include <Protocol/DebugPort.h>
24
25
26 EFI_DEBUGPORT_PROTOCOL *gDebugPort = NULL;
27 UINTN gTimeOut = 0;
28
29 /**
30 The constructor function initializes the UART.
31
32 @param ImageHandle The firmware allocated handle for the EFI image.
33 @param SystemTable A pointer to the EFI System Table.
34
35 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
36
37 **/
38 RETURN_STATUS
39 EFIAPI
GdbSerialLibDebugPortConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)40 GdbSerialLibDebugPortConstructor (
41 IN EFI_HANDLE ImageHandle,
42 IN EFI_SYSTEM_TABLE *SystemTable
43 )
44 {
45 EFI_STATUS Status;
46
47 Status = gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **)&gDebugPort);
48 if (!EFI_ERROR (Status)) {
49 gTimeOut = PcdGet32 (PcdGdbMaxPacketRetryCount);
50 gDebugPort->Reset (gDebugPort);
51 }
52
53 return Status;
54 }
55
56
57
58 /**
59 Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
60 data buts, and stop bits on a serial device. This call is optional as the serial
61 port will be set up with defaults base on PCD values.
62
63 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
64 device's default interface speed.
65 @param Parity The type of parity to use on this serial device. A Parity value of
66 DefaultParity will use the device's default parity value.
67 @param DataBits The number of data bits to use on the serial device. A DataBits
68 vaule of 0 will use the device's default data bit setting.
69 @param StopBits The number of stop bits to use on this serial device. A StopBits
70 value of DefaultStopBits will use the device's default number of
71 stop bits.
72
73 @retval EFI_SUCCESS The device was configured.
74 @retval EFI_DEVICE_ERROR The serial device could not be coonfigured.
75
76 **/
77 RETURN_STATUS
78 EFIAPI
GdbSerialInit(IN UINT64 BaudRate,IN UINT8 Parity,IN UINT8 DataBits,IN UINT8 StopBits)79 GdbSerialInit (
80 IN UINT64 BaudRate,
81 IN UINT8 Parity,
82 IN UINT8 DataBits,
83 IN UINT8 StopBits
84 )
85 {
86 EFI_STATUS Status;
87
88 Status = gDebugPort->Reset (gDebugPort);
89 return Status;
90 }
91
92
93 /**
94 Check to see if a character is available from GDB. Do not read the character as that is
95 done via GdbGetChar().
96
97 @return TRUE - Character available
98 @return FALSE - Character not available
99
100 **/
101 BOOLEAN
102 EFIAPI
GdbIsCharAvailable(VOID)103 GdbIsCharAvailable (
104 VOID
105 )
106 {
107 EFI_STATUS Status;
108
109 Status = gDebugPort->Poll (gDebugPort);
110
111 return (Status == EFI_SUCCESS ? TRUE : FALSE);
112 }
113
114
115 /**
116 Get a character from GDB. This function must be able to run in interrupt context.
117
118 @return A character from GDB
119
120 **/
121 CHAR8
122 EFIAPI
GdbGetChar(VOID)123 GdbGetChar (
124 VOID
125 )
126 {
127 EFI_STATUS Status;
128 CHAR8 Char;
129 UINTN BufferSize;
130
131 do {
132 BufferSize = sizeof (Char);
133 Status = gDebugPort->Read (gDebugPort, gTimeOut, &BufferSize, &Char);
134 } while (EFI_ERROR (Status) || BufferSize != sizeof (Char));
135
136 return Char;
137 }
138
139
140 /**
141 Send a character to GDB. This function must be able to run in interrupt context.
142
143
144 @param Char Send a character to GDB
145
146 **/
147
148 VOID
149 EFIAPI
GdbPutChar(IN CHAR8 Char)150 GdbPutChar (
151 IN CHAR8 Char
152 )
153 {
154 EFI_STATUS Status;
155 UINTN BufferSize;
156
157 do {
158 BufferSize = sizeof (Char);
159 Status = gDebugPort->Write (gDebugPort, gTimeOut, &BufferSize, &Char);
160 } while (EFI_ERROR (Status) || BufferSize != sizeof (Char));
161
162 return;
163 }
164
165 /**
166 Send an ASCII string to GDB. This function must be able to run in interrupt context.
167
168
169 @param String Send a string to GDB
170
171 **/
172
173 VOID
GdbPutString(IN CHAR8 * String)174 GdbPutString (
175 IN CHAR8 *String
176 )
177 {
178 // We could performance enhance this function by calling gDebugPort->Write ()
179 while (*String != '\0') {
180 GdbPutChar (*String);
181 String++;
182 }
183 }
184
185
186
187
188