2 Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system
3 running GDB. One consle for error information and another console for user input/output.
5 Basic packet format is $packet-data#checksum. So every comand has 4 bytes of overhead: $,
6 #, 0, 0. The 0 and 0 are the ascii characters for the checksum.
9 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
11 This program and the accompanying materials
12 are licensed and made available under the terms and conditions of the BSD License
13 which accompanies this distribution. The full text of the license may be found at
14 http://opensource.org/licenses/bsd-license.php
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 #include <GdbStubInternal.h>
24 // Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
25 // here we need to wait for the periodic callback to do this.
27 BOOLEAN gCtrlCBreakFlag
= FALSE
;
30 // If the periodic callback is called while we are processing an F packet we need
31 // to let the callback know to not read from the serail stream as it could steal
32 // characters from the F reponse packet
34 BOOLEAN gProcessingFPacket
= FALSE
;
37 Process a control-C break message.
39 Currently a place holder, remove the ASSERT when it gets implemented.
41 @param ErrNo Error infomration from the F reply packet or other source
46 GdbCtrlCBreakMessage (
50 // See D.10.5 of gdb.pdf
51 // This should look like a break message. Should look like SIGINT
53 /* TODO: Make sure if we should do anything with ErrNo */
54 //Turn on the global Ctrl-C flag.
55 gCtrlCBreakFlag
= TRUE
;
60 Parse the F reply packet and extract the return value and an ErrNo if it exists.
62 @param Packet Packet to parse like an F reply packet
63 @param ErrNo Buffer to hold Count bytes that were read
65 @retval -1 Error, not a valid F reply packet
66 @retval other Return the return code from the F reply packet
70 GdbParseFReplyPacket (
77 if (Packet
[0] != 'F') {
78 // A valid responce would be an F packet
82 RetCode
= AsciiStrHexToUintn (&Packet
[1]);
85 for (;*Packet
!= '\0' && *Packet
!= ','; Packet
++);
86 if (*Packet
== '\0') {
91 *ErrNo
= AsciiStrHexToUintn (++Packet
);
94 for (;*Packet
!= '\0' && *Packet
!= ','; Packet
++);
95 if (*Packet
== '\0') {
99 if (*(++Packet
) == 'C') {
100 GdbCtrlCBreakMessage (*ErrNo
);
108 Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
109 the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
111 @param FileDescriptor Device to talk to.
112 @param Buffer Buffer to hold Count bytes that were read
113 @param Count Number of bytes to transfer.
116 @retval {other} Number of bytes read.
121 IN INTN FileDescriptor
,
130 BOOLEAN ReceiveDone
= FALSE
;
133 // "Fread,XX,YYYYYYYY,XX
135 // XX - FileDescriptor in ASCII
136 // YYYYYYYY - Buffer address in ASCII
137 // XX - Count in ASCII
140 Size
= AsciiSPrint (Packet
, sizeof (Packet
), "Fread,%x,%x,%x", FileDescriptor
, Buffer
, Count
);
141 // Packet array is too small if you got this ASSERT
142 ASSERT (Size
< sizeof (Packet
));
144 gProcessingFPacket
= TRUE
;
146 Print ((CHAR16
*)L
"Packet sent..\n");
150 ReceivePacket (Packet
, sizeof (Packet
));
151 Print ((CHAR16
*)L
"Command received..%c\n", Packet
[0]);
153 // Process GDB commands
155 //Write memory command.
156 //M addr,length:XX...
158 WriteToMemory (Packet
);
161 //Fretcode, errno, Ctrl-C flag
162 //retcode - Count read
164 //Once target receives F reply packet that means the previous
165 //transactions are finished.
174 } while (ReceiveDone
== FALSE
);
176 RetCode
= GdbParseFReplyPacket (Packet
, &ErrNo
);
177 Print ((CHAR16
*)L
"RetCode: %x..ErrNo: %x..\n", RetCode
, ErrNo
);
180 //Send error to the host if there is any.
181 SendError ((UINT8
)ErrNo
);
184 gProcessingFPacket
= FALSE
;
191 Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
192 nothing was written. On error -1 is returned.
194 @param FileDescriptor Device to talk to.
195 @param Buffer Buffer to hold Count bytes that are to be written
196 @param Count Number of bytes to transfer.
199 @retval {other} Number of bytes written.
204 IN INTN FileDescriptor
,
205 OUT CONST VOID
*Buffer
,
213 BOOLEAN ReceiveDone
= FALSE
;
216 // #Fwrite,XX,YYYYYYYY,XX$SS
218 // XX - FileDescriptor in ASCII
219 // YYYYYYYY - Buffer address in ASCII
220 // XX - Count in ASCII
223 Size
= AsciiSPrint (Packet
, sizeof (Packet
), "Fwrite,%x,%x,%x", FileDescriptor
, Buffer
, Count
);
224 // Packet array is too small if you got this ASSERT
225 ASSERT (Size
< sizeof (Packet
));
228 Print ((CHAR16
*)L
"Packet sent..\n");
232 ReceivePacket (Packet
, sizeof (Packet
));
233 Print ((CHAR16
*)L
"Command received..%c\n", Packet
[0]);
235 // Process GDB commands
237 //Read memory command.
240 ReadFromMemory (Packet
);
243 //Fretcode, errno, Ctrl-C flag
244 //retcode - Count read
246 //Once target receives F reply packet that means the previous
247 //transactions are finished.
256 } while (ReceiveDone
== FALSE
);
258 RetCode
= GdbParseFReplyPacket (Packet
, &ErrNo
);
259 Print ((CHAR16
*)L
"RetCode: %x..ErrNo: %x..\n", RetCode
, ErrNo
);
261 //Send error to the host if there is any.
263 SendError((UINT8
)ErrNo
);
271 Reset the serial device.
273 @param This Protocol instance pointer.
275 @retval EFI_SUCCESS The device was reset.
276 @retval EFI_DEVICE_ERROR The serial device could not be reset.
282 IN EFI_SERIAL_IO_PROTOCOL
*This
290 Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
291 data buts, and stop bits on a serial device.
293 @param This Protocol instance pointer.
294 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
295 device's default interface speed.
296 @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the
297 serial interface. A ReceiveFifoDepth value of 0 will use
298 the device's dfault FIFO depth.
299 @param Timeout The requested time out for a single character in microseconds.
300 This timeout applies to both the transmit and receive side of the
301 interface. A Timeout value of 0 will use the device's default time
303 @param Parity The type of parity to use on this serial device. A Parity value of
304 DefaultParity will use the device's default parity value.
305 @param DataBits The number of data bits to use on the serial device. A DataBits
306 vaule of 0 will use the device's default data bit setting.
307 @param StopBits The number of stop bits to use on this serial device. A StopBits
308 value of DefaultStopBits will use the device's default number of
311 @retval EFI_SUCCESS The device was reset.
312 @retval EFI_DEVICE_ERROR The serial device could not be reset.
317 GdbSerialSetAttributes (
318 IN EFI_SERIAL_IO_PROTOCOL
*This
,
320 IN UINT32 ReceiveFifoDepth
,
322 IN EFI_PARITY_TYPE Parity
,
324 IN EFI_STOP_BITS_TYPE StopBits
327 return EFI_UNSUPPORTED
;
332 Set the control bits on a serial device
334 @param This Protocol instance pointer.
335 @param Control Set the bits of Control that are settable.
337 @retval EFI_SUCCESS The new control bits were set on the serial device.
338 @retval EFI_UNSUPPORTED The serial device does not support this operation.
339 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
344 GdbSerialSetControl (
345 IN EFI_SERIAL_IO_PROTOCOL
*This
,
349 return EFI_UNSUPPORTED
;
354 Retrieves the status of thecontrol bits on a serial device
356 @param This Protocol instance pointer.
357 @param Control A pointer to return the current Control signals from the serial device.
359 @retval EFI_SUCCESS The control bits were read from the serial device.
360 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
365 GdbSerialGetControl (
366 IN EFI_SERIAL_IO_PROTOCOL
*This
,
370 return EFI_UNSUPPORTED
;
375 Writes data to a serial device.
377 @param This Protocol instance pointer.
378 @param BufferSize On input, the size of the Buffer. On output, the amount of
379 data actually written.
380 @param Buffer The buffer of data to write
382 @retval EFI_SUCCESS The data was written.
383 @retval EFI_DEVICE_ERROR The device reported an error.
384 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
390 IN EFI_SERIAL_IO_PROTOCOL
*This
,
391 IN OUT UINTN
*BufferSize
,
395 GDB_SERIAL_DEV
*SerialDev
;
398 SerialDev
= GDB_SERIAL_DEV_FROM_THIS (This
);
400 Return
= GdbWrite (SerialDev
->OutFileDescriptor
, Buffer
, *BufferSize
);
401 if (Return
== (UINTN
)-1) {
402 return EFI_DEVICE_ERROR
;
405 if (Return
!= *BufferSize
) {
406 *BufferSize
= Return
;
413 Writes data to a serial device.
415 @param This Protocol instance pointer.
416 @param BufferSize On input, the size of the Buffer. On output, the amount of
417 data returned in Buffer.
418 @param Buffer The buffer to return the data into.
420 @retval EFI_SUCCESS The data was read.
421 @retval EFI_DEVICE_ERROR The device reported an error.
422 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
429 IN EFI_SERIAL_IO_PROTOCOL
*This
,
430 IN OUT UINTN
*BufferSize
,
434 GDB_SERIAL_DEV
*SerialDev
;
437 SerialDev
= GDB_SERIAL_DEV_FROM_THIS (This
);
439 Return
= GdbRead (SerialDev
->InFileDescriptor
, Buffer
, *BufferSize
);
440 if (Return
== (UINTN
)-1) {
441 return EFI_DEVICE_ERROR
;
444 if (Return
!= *BufferSize
) {
445 *BufferSize
= Return
;
453 // Template used to initailize the GDB Serial IO protocols
455 GDB_SERIAL_DEV gdbSerialDevTemplate
= {
456 GDB_SERIAL_DEV_SIGNATURE
,
460 SERIAL_IO_INTERFACE_REVISION
,
462 GdbSerialSetAttributes
,
473 1, // RceiveFifoDepth
481 HARDWARE_DEVICE_PATH
,
484 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
) + sizeof (UINT32
)),
485 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
) + sizeof (UINT32
)) >> 8)
488 EFI_SERIAL_IO_PROTOCOL_GUID
492 END_DEVICE_PATH_TYPE
,
493 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
495 (UINT8
) (sizeof (EFI_DEVICE_PATH_PROTOCOL
)),
496 (UINT8
) (sizeof (EFI_DEVICE_PATH_PROTOCOL
) >> 8)
506 Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
508 These console show up on the remote system running GDB
512 GdbInitializeSerialConsole (
517 GDB_SERIAL_DEV
*StdOutSerialDev
;
518 GDB_SERIAL_DEV
*StdErrSerialDev
;
520 // Use the template to make a copy of the Serial Console private data structure.
521 StdOutSerialDev
= AllocateCopyPool (sizeof (GDB_SERIAL_DEV
), &gdbSerialDevTemplate
);
522 ASSERT (StdOutSerialDev
!= NULL
);
524 // Fixup pointer after the copy
525 StdOutSerialDev
->SerialIo
.Mode
= &StdOutSerialDev
->SerialMode
;
527 StdErrSerialDev
= AllocateCopyPool (sizeof (GDB_SERIAL_DEV
), &gdbSerialDevTemplate
);
528 ASSERT (StdErrSerialDev
!= NULL
);
530 // Fixup pointer and modify stuff that is different for StdError
531 StdErrSerialDev
->SerialIo
.Mode
= &StdErrSerialDev
->SerialMode
;
532 StdErrSerialDev
->DevicePath
.Index
= 1;
533 StdErrSerialDev
->OutFileDescriptor
= GDB_STDERR
;
535 // Make a new handle with Serial IO protocol and its device path on it.
536 Status
= gBS
->InstallMultipleProtocolInterfaces (
537 &StdOutSerialDev
->Handle
,
538 &gEfiSerialIoProtocolGuid
, &StdOutSerialDev
->SerialIo
,
539 &gEfiDevicePathProtocolGuid
, &StdOutSerialDev
->DevicePath
,
542 ASSERT_EFI_ERROR (Status
);
544 // Make a new handle with Serial IO protocol and its device path on it.
545 Status
= gBS
->InstallMultipleProtocolInterfaces (
546 &StdErrSerialDev
->Handle
,
547 &gEfiSerialIoProtocolGuid
, &StdErrSerialDev
->SerialIo
,
548 &gEfiDevicePathProtocolGuid
, &StdErrSerialDev
->DevicePath
,
551 ASSERT_EFI_ERROR (Status
);