-/** @file
- Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system
- running GDB. One consle for error information and another console for user input/output.
-
- Basic packet format is $packet-data#checksum. So every comand has 4 bytes of overhead: $,
- #, 0, 0. The 0 and 0 are the ascii characters for the checksum.
-
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <GdbStubInternal.h>
-
-//
-// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
-// here we need to wait for the periodic callback to do this.
-//
-BOOLEAN gCtrlCBreakFlag = FALSE;
-
-//
-// If the periodic callback is called while we are processing an F packet we need
-// to let the callback know to not read from the serail stream as it could steal
-// characters from the F reponse packet
-//
-BOOLEAN gProcessingFPacket = FALSE;
-
-/**
- Process a control-C break message.
-
- Currently a place holder, remove the ASSERT when it gets implemented.
-
- @param ErrNo Error infomration from the F reply packet or other source
-
-**/
-
-VOID
-GdbCtrlCBreakMessage (
- IN UINTN ErrNo
- )
-{
- // See D.10.5 of gdb.pdf
- // This should look like a break message. Should look like SIGINT
-
- /* TODO: Make sure if we should do anything with ErrNo */
- //Turn on the global Ctrl-C flag.
- gCtrlCBreakFlag = TRUE;
-}
-
-
-/**
- Parse the F reply packet and extract the return value and an ErrNo if it exists.
-
- @param Packet Packet to parse like an F reply packet
- @param ErrNo Buffer to hold Count bytes that were read
-
- @retval -1 Error, not a valid F reply packet
- @retval other Return the return code from the F reply packet
-
-**/
-INTN
-GdbParseFReplyPacket (
- IN CHAR8 *Packet,
- OUT UINTN *ErrNo
- )
-{
- INTN RetCode;
-
- if (Packet[0] != 'F') {
- // A valid responce would be an F packet
- return -1;
- }
-
- RetCode = AsciiStrHexToUintn (&Packet[1]);
-
- // Find 1st comma
- for (;*Packet != '\0' && *Packet != ','; Packet++);
- if (*Packet == '\0') {
- *ErrNo = 0;
- return RetCode;
- }
-
- *ErrNo = AsciiStrHexToUintn (++Packet);
-
- // Find 2nd comma
- for (;*Packet != '\0' && *Packet != ','; Packet++);
- if (*Packet == '\0') {
- return RetCode;
- }
-
- if (*(++Packet) == 'C') {
- GdbCtrlCBreakMessage (*ErrNo);
- }
-
- return RetCode;
-}
-
-
-/**
- Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
- the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that were read
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes read.
-
-**/
-INTN
-GdbRead (
- IN INTN FileDescriptor,
- OUT VOID *Buffer,
- IN UINTN Count
- )
-{
- CHAR8 Packet[128];
- UINTN Size;
- INTN RetCode;
- UINTN ErrNo;
- BOOLEAN ReceiveDone = FALSE;
-
- // Send:
- // "Fread,XX,YYYYYYYY,XX
- //
- // XX - FileDescriptor in ASCII
- // YYYYYYYY - Buffer address in ASCII
- // XX - Count in ASCII
- // SS - check sum
- //
- Size = AsciiSPrint (Packet, sizeof (Packet), "Fread,%x,%x,%x", FileDescriptor, Buffer, Count);
- // Packet array is too small if you got this ASSERT
- ASSERT (Size < sizeof (Packet));
-
- gProcessingFPacket = TRUE;
- SendPacket (Packet);
- Print ((CHAR16 *)L"Packet sent..\n");
-
- do {
- // Reply:
- ReceivePacket (Packet, sizeof (Packet));
- Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
-
- // Process GDB commands
- switch (Packet[0]) {
- //Write memory command.
- //M addr,length:XX...
- case 'M':
- WriteToMemory (Packet);
- break;
-
- //Fretcode, errno, Ctrl-C flag
- //retcode - Count read
- case 'F':
- //Once target receives F reply packet that means the previous
- //transactions are finished.
- ReceiveDone = TRUE;
- break;
-
- //Send empty buffer
- default :
- SendNotSupported();
- break;
- }
- } while (ReceiveDone == FALSE);
-
- RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
- Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
-
- if (ErrNo > 0) {
- //Send error to the host if there is any.
- SendError ((UINT8)ErrNo);
- }
-
- gProcessingFPacket = FALSE;
-
- return RetCode;
-}
-
-
-/**
- Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
- nothing was written. On error -1 is returned.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that are to be written
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes written.
-
-**/
-INTN
-GdbWrite (
- IN INTN FileDescriptor,
- OUT CONST VOID *Buffer,
- IN UINTN Count
- )
-{
- CHAR8 Packet[128];
- UINTN Size;
- INTN RetCode;
- UINTN ErrNo;
- BOOLEAN ReceiveDone = FALSE;
-
- // Send:
- // #Fwrite,XX,YYYYYYYY,XX$SS
- //
- // XX - FileDescriptor in ASCII
- // YYYYYYYY - Buffer address in ASCII
- // XX - Count in ASCII
- // SS - check sum
- //
- Size = AsciiSPrint (Packet, sizeof (Packet), "Fwrite,%x,%x,%x", FileDescriptor, Buffer, Count);
- // Packet array is too small if you got this ASSERT
- ASSERT (Size < sizeof (Packet));
-
- SendPacket (Packet);
- Print ((CHAR16 *)L"Packet sent..\n");
-
- do {
- // Reply:
- ReceivePacket (Packet, sizeof (Packet));
- Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
-
- // Process GDB commands
- switch (Packet[0]) {
- //Read memory command.
- //m addr,length.
- case 'm':
- ReadFromMemory (Packet);
- break;
-
- //Fretcode, errno, Ctrl-C flag
- //retcode - Count read
- case 'F':
- //Once target receives F reply packet that means the previous
- //transactions are finished.
- ReceiveDone = TRUE;
- break;
-
- //Send empty buffer
- default :
- SendNotSupported();
- break;
- }
- } while (ReceiveDone == FALSE);
-
- RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
- Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
-
- //Send error to the host if there is any.
- if (ErrNo > 0) {
- SendError((UINT8)ErrNo);
- }
-
- return RetCode;
-}
-
-
-/**
- Reset the serial device.
-
- @param This Protocol instance pointer.
-
- @retval EFI_SUCCESS The device was reset.
- @retval EFI_DEVICE_ERROR The serial device could not be reset.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialReset (
- IN EFI_SERIAL_IO_PROTOCOL *This
- )
-{
- return EFI_SUCCESS;
-}
-
-
-/**
- Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
- data buts, and stop bits on a serial device.
-
- @param This Protocol instance pointer.
- @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
- device's default interface speed.
- @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the
- serial interface. A ReceiveFifoDepth value of 0 will use
- the device's dfault FIFO depth.
- @param Timeout The requested time out for a single character in microseconds.
- This timeout applies to both the transmit and receive side of the
- interface. A Timeout value of 0 will use the device's default time
- out value.
- @param Parity The type of parity to use on this serial device. A Parity value of
- DefaultParity will use the device's default parity value.
- @param DataBits The number of data bits to use on the serial device. A DataBits
- vaule of 0 will use the device's default data bit setting.
- @param StopBits The number of stop bits to use on this serial device. A StopBits
- value of DefaultStopBits will use the device's default number of
- stop bits.
-
- @retval EFI_SUCCESS The device was reset.
- @retval EFI_DEVICE_ERROR The serial device could not be reset.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialSetAttributes (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN UINT64 BaudRate,
- IN UINT32 ReceiveFifoDepth,
- IN UINT32 Timeout,
- IN EFI_PARITY_TYPE Parity,
- IN UINT8 DataBits,
- IN EFI_STOP_BITS_TYPE StopBits
- )
-{
- return EFI_UNSUPPORTED;
-}
-
-
-/**
- Set the control bits on a serial device
-
- @param This Protocol instance pointer.
- @param Control Set the bits of Control that are settable.
-
- @retval EFI_SUCCESS The new control bits were set on the serial device.
- @retval EFI_UNSUPPORTED The serial device does not support this operation.
- @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialSetControl (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN UINT32 Control
- )
-{
- return EFI_UNSUPPORTED;
-}
-
-
-/**
- Retrieves the status of thecontrol bits on a serial device
-
- @param This Protocol instance pointer.
- @param Control A pointer to return the current Control signals from the serial device.
-
- @retval EFI_SUCCESS The control bits were read from the serial device.
- @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialGetControl (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- OUT UINT32 *Control
- )
-{
- return EFI_UNSUPPORTED;
-}
-
-
-/**
- Writes data to a serial device.
-
- @param This Protocol instance pointer.
- @param BufferSize On input, the size of the Buffer. On output, the amount of
- data actually written.
- @param Buffer The buffer of data to write
-
- @retval EFI_SUCCESS The data was written.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_TIMEOUT The data write was stopped due to a timeout.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialWrite (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- IN VOID *Buffer
- )
-{
- GDB_SERIAL_DEV *SerialDev;
- UINTN Return;
-
- SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
-
- Return = GdbWrite (SerialDev->OutFileDescriptor, Buffer, *BufferSize);
- if (Return == (UINTN)-1) {
- return EFI_DEVICE_ERROR;
- }
-
- if (Return != *BufferSize) {
- *BufferSize = Return;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Writes data to a serial device.
-
- @param This Protocol instance pointer.
- @param BufferSize On input, the size of the Buffer. On output, the amount of
- data returned in Buffer.
- @param Buffer The buffer to return the data into.
-
- @retval EFI_SUCCESS The data was read.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_TIMEOUT The data write was stopped due to a timeout.
-
-**/
-
-EFI_STATUS
-EFIAPI
-GdbSerialRead (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
-{
- GDB_SERIAL_DEV *SerialDev;
- UINTN Return;
-
- SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
-
- Return = GdbRead (SerialDev->InFileDescriptor, Buffer, *BufferSize);
- if (Return == (UINTN)-1) {
- return EFI_DEVICE_ERROR;
- }
-
- if (Return != *BufferSize) {
- *BufferSize = Return;
- }
-
- return EFI_SUCCESS;
-}
-
-
-//
-// Template used to initailize the GDB Serial IO protocols
-//
-GDB_SERIAL_DEV gdbSerialDevTemplate = {
- GDB_SERIAL_DEV_SIGNATURE,
- NULL,
-
- { // SerialIo
- SERIAL_IO_INTERFACE_REVISION,
- GdbSerialReset,
- GdbSerialSetAttributes,
- GdbSerialSetControl,
- GdbSerialGetControl,
- GdbSerialWrite,
- GdbSerialRead,
- NULL
- },
- { // SerialMode
- 0, // ControlMask
- 0, // Timeout
- 0, // BaudRate
- 1, // RceiveFifoDepth
- 0, // DataBits
- 0, // Parity
- 0 // StopBits
- },
- {
- {
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- {
- (UINT8) (sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)),
- (UINT8) ((sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)) >> 8)
- },
- EFI_SERIAL_IO_PROTOCOL_GUID,
- },
- 0,
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)),
- (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL) >> 8)
- }
- },
- },
- GDB_STDIN,
- GDB_STDOUT
-};
-
-
-/**
- Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
-
- These console show up on the remote system running GDB
-
-**/
-VOID
-GdbInitializeSerialConsole (
- VOID
- )
-{
- EFI_STATUS Status;
- GDB_SERIAL_DEV *StdOutSerialDev;
- GDB_SERIAL_DEV *StdErrSerialDev;
-
- // Use the template to make a copy of the Serial Console private data structure.
- StdOutSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
- ASSERT (StdOutSerialDev != NULL);
-
- // Fixup pointer after the copy
- StdOutSerialDev->SerialIo.Mode = &StdOutSerialDev->SerialMode;
-
- StdErrSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
- ASSERT (StdErrSerialDev != NULL);
-
- // Fixup pointer and modify stuff that is different for StdError
- StdErrSerialDev->SerialIo.Mode = &StdErrSerialDev->SerialMode;
- StdErrSerialDev->DevicePath.Index = 1;
- StdErrSerialDev->OutFileDescriptor = GDB_STDERR;
-
- // Make a new handle with Serial IO protocol and its device path on it.
- Status = gBS->InstallMultipleProtocolInterfaces (
- &StdOutSerialDev->Handle,
- &gEfiSerialIoProtocolGuid, &StdOutSerialDev->SerialIo,
- &gEfiDevicePathProtocolGuid, &StdOutSerialDev->DevicePath,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- // Make a new handle with Serial IO protocol and its device path on it.
- Status = gBS->InstallMultipleProtocolInterfaces (
- &StdErrSerialDev->Handle,
- &gEfiSerialIoProtocolGuid, &StdErrSerialDev->SerialIo,
- &gEfiDevicePathProtocolGuid, &StdErrSerialDev->DevicePath,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-}
-
+/** @file\r
+ Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system\r
+ running GDB. One consle for error information and another console for user input/output.\r
+\r
+ Basic packet format is $packet-data#checksum. So every comand has 4 bytes of overhead: $,\r
+ #, 0, 0. The 0 and 0 are the ascii characters for the checksum.\r
+\r
+\r
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <GdbStubInternal.h>\r
+\r
+//\r
+// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c\r
+// here we need to wait for the periodic callback to do this.\r
+//\r
+BOOLEAN gCtrlCBreakFlag = FALSE;\r
+\r
+//\r
+// If the periodic callback is called while we are processing an F packet we need\r
+// to let the callback know to not read from the serail stream as it could steal\r
+// characters from the F reponse packet\r
+//\r
+BOOLEAN gProcessingFPacket = FALSE;\r
+\r
+/**\r
+ Process a control-C break message.\r
+\r
+ Currently a place holder, remove the ASSERT when it gets implemented.\r
+\r
+ @param ErrNo Error infomration from the F reply packet or other source\r
+\r
+**/\r
+\r
+VOID\r
+GdbCtrlCBreakMessage (\r
+ IN UINTN ErrNo\r
+ )\r
+{\r
+ // See D.10.5 of gdb.pdf\r
+ // This should look like a break message. Should look like SIGINT\r
+\r
+ /* TODO: Make sure if we should do anything with ErrNo */\r
+ //Turn on the global Ctrl-C flag.\r
+ gCtrlCBreakFlag = TRUE;\r
+}\r
+\r
+\r
+/**\r
+ Parse the F reply packet and extract the return value and an ErrNo if it exists.\r
+\r
+ @param Packet Packet to parse like an F reply packet\r
+ @param ErrNo Buffer to hold Count bytes that were read\r
+\r
+ @retval -1 Error, not a valid F reply packet\r
+ @retval other Return the return code from the F reply packet\r
+\r
+**/\r
+INTN\r
+GdbParseFReplyPacket (\r
+ IN CHAR8 *Packet,\r
+ OUT UINTN *ErrNo\r
+ )\r
+{\r
+ INTN RetCode;\r
+\r
+ if (Packet[0] != 'F') {\r
+ // A valid responce would be an F packet\r
+ return -1;\r
+ }\r
+\r
+ RetCode = AsciiStrHexToUintn (&Packet[1]);\r
+\r
+ // Find 1st comma\r
+ for (;*Packet != '\0' && *Packet != ','; Packet++);\r
+ if (*Packet == '\0') {\r
+ *ErrNo = 0;\r
+ return RetCode;\r
+ }\r
+\r
+ *ErrNo = AsciiStrHexToUintn (++Packet);\r
+\r
+ // Find 2nd comma\r
+ for (;*Packet != '\0' && *Packet != ','; Packet++);\r
+ if (*Packet == '\0') {\r
+ return RetCode;\r
+ }\r
+\r
+ if (*(++Packet) == 'C') {\r
+ GdbCtrlCBreakMessage (*ErrNo);\r
+ }\r
+\r
+ return RetCode;\r
+}\r
+\r
+\r
+/**\r
+ Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates\r
+ the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.\r
+\r
+ @param FileDescriptor Device to talk to.\r
+ @param Buffer Buffer to hold Count bytes that were read\r
+ @param Count Number of bytes to transfer.\r
+\r
+ @retval -1 Error\r
+ @retval {other} Number of bytes read.\r
+\r
+**/\r
+INTN\r
+GdbRead (\r
+ IN INTN FileDescriptor,\r
+ OUT VOID *Buffer,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ CHAR8 Packet[128];\r
+ UINTN Size;\r
+ INTN RetCode;\r
+ UINTN ErrNo;\r
+ BOOLEAN ReceiveDone = FALSE;\r
+\r
+ // Send:\r
+ // "Fread,XX,YYYYYYYY,XX\r
+ //\r
+ // XX - FileDescriptor in ASCII\r
+ // YYYYYYYY - Buffer address in ASCII\r
+ // XX - Count in ASCII\r
+ // SS - check sum\r
+ //\r
+ Size = AsciiSPrint (Packet, sizeof (Packet), "Fread,%x,%x,%x", FileDescriptor, Buffer, Count);\r
+ // Packet array is too small if you got this ASSERT\r
+ ASSERT (Size < sizeof (Packet));\r
+\r
+ gProcessingFPacket = TRUE;\r
+ SendPacket (Packet);\r
+ Print ((CHAR16 *)L"Packet sent..\n");\r
+\r
+ do {\r
+ // Reply:\r
+ ReceivePacket (Packet, sizeof (Packet));\r
+ Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);\r
+\r
+ // Process GDB commands\r
+ switch (Packet[0]) {\r
+ //Write memory command.\r
+ //M addr,length:XX...\r
+ case 'M':\r
+ WriteToMemory (Packet);\r
+ break;\r
+\r
+ //Fretcode, errno, Ctrl-C flag\r
+ //retcode - Count read\r
+ case 'F':\r
+ //Once target receives F reply packet that means the previous\r
+ //transactions are finished.\r
+ ReceiveDone = TRUE;\r
+ break;\r
+\r
+ //Send empty buffer\r
+ default :\r
+ SendNotSupported();\r
+ break;\r
+ }\r
+ } while (ReceiveDone == FALSE);\r
+\r
+ RetCode = GdbParseFReplyPacket (Packet, &ErrNo);\r
+ Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);\r
+\r
+ if (ErrNo > 0) {\r
+ //Send error to the host if there is any.\r
+ SendError ((UINT8)ErrNo);\r
+ }\r
+\r
+ gProcessingFPacket = FALSE;\r
+\r
+ return RetCode;\r
+}\r
+\r
+\r
+/**\r
+ Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates\r
+ nothing was written. On error -1 is returned.\r
+\r
+ @param FileDescriptor Device to talk to.\r
+ @param Buffer Buffer to hold Count bytes that are to be written\r
+ @param Count Number of bytes to transfer.\r
+\r
+ @retval -1 Error\r
+ @retval {other} Number of bytes written.\r
+\r
+**/\r
+INTN\r
+GdbWrite (\r
+ IN INTN FileDescriptor,\r
+ OUT CONST VOID *Buffer,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ CHAR8 Packet[128];\r
+ UINTN Size;\r
+ INTN RetCode;\r
+ UINTN ErrNo;\r
+ BOOLEAN ReceiveDone = FALSE;\r
+\r
+ // Send:\r
+ // #Fwrite,XX,YYYYYYYY,XX$SS\r
+ //\r
+ // XX - FileDescriptor in ASCII\r
+ // YYYYYYYY - Buffer address in ASCII\r
+ // XX - Count in ASCII\r
+ // SS - check sum\r
+ //\r
+ Size = AsciiSPrint (Packet, sizeof (Packet), "Fwrite,%x,%x,%x", FileDescriptor, Buffer, Count);\r
+ // Packet array is too small if you got this ASSERT\r
+ ASSERT (Size < sizeof (Packet));\r
+\r
+ SendPacket (Packet);\r
+ Print ((CHAR16 *)L"Packet sent..\n");\r
+\r
+ do {\r
+ // Reply:\r
+ ReceivePacket (Packet, sizeof (Packet));\r
+ Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);\r
+\r
+ // Process GDB commands\r
+ switch (Packet[0]) {\r
+ //Read memory command.\r
+ //m addr,length.\r
+ case 'm':\r
+ ReadFromMemory (Packet);\r
+ break;\r
+\r
+ //Fretcode, errno, Ctrl-C flag\r
+ //retcode - Count read\r
+ case 'F':\r
+ //Once target receives F reply packet that means the previous\r
+ //transactions are finished.\r
+ ReceiveDone = TRUE;\r
+ break;\r
+\r
+ //Send empty buffer\r
+ default :\r
+ SendNotSupported();\r
+ break;\r
+ }\r
+ } while (ReceiveDone == FALSE);\r
+\r
+ RetCode = GdbParseFReplyPacket (Packet, &ErrNo);\r
+ Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);\r
+\r
+ //Send error to the host if there is any.\r
+ if (ErrNo > 0) {\r
+ SendError((UINT8)ErrNo);\r
+ }\r
+\r
+ return RetCode;\r
+}\r
+\r
+\r
+/**\r
+ Reset the serial device.\r
+\r
+ @param This Protocol instance pointer.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The serial device could not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GdbSerialReset (\r
+ IN EFI_SERIAL_IO_PROTOCOL *This\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,\r
+ data buts, and stop bits on a serial device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the\r
+ device's default interface speed.\r
+ @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the\r
+ serial interface. A ReceiveFifoDepth value of 0 will use\r
+ the device's dfault FIFO depth.\r
+ @param Timeout The requested time out for a single character in microseconds.\r
+ This timeout applies to both the transmit and receive side of the\r
+ interface. A Timeout value of 0 will use the device's default time\r
+ out value.\r
+ @param Parity The type of parity to use on this serial device. A Parity value of\r
+ DefaultParity will use the device's default parity value.\r
+ @param DataBits The number of data bits to use on the serial device. A DataBits\r
+ vaule of 0 will use the device's default data bit setting.\r
+ @param StopBits The number of stop bits to use on this serial device. A StopBits\r
+ value of DefaultStopBits will use the device's default number of\r
+ stop bits.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The serial device could not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GdbSerialSetAttributes (\r
+ IN EFI_SERIAL_IO_PROTOCOL *This,\r
+ IN UINT64 BaudRate,\r
+ IN UINT32 ReceiveFifoDepth,\r
+ IN UINT32 Timeout,\r
+ IN EFI_PARITY_TYPE Parity,\r
+ IN UINT8 DataBits,\r
+ IN EFI_STOP_BITS_TYPE StopBits\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Set the control bits on a serial device\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Control Set the bits of Control that are settable.\r
+\r
+ @retval EFI_SUCCESS The new control bits were set on the serial device.\r
+ @retval EFI_UNSUPPORTED The serial device does not support this operation.\r
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GdbSerialSetControl (\r
+ IN EFI_SERIAL_IO_PROTOCOL *This,\r
+ IN UINT32 Control\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Retrieves the status of thecontrol bits on a serial device\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Control A pointer to return the current Control signals from the serial device.\r
+\r
+ @retval EFI_SUCCESS The control bits were read from the serial device.\r
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GdbSerialGetControl (\r
+ IN EFI_SERIAL_IO_PROTOCOL *This,\r
+ OUT UINT32 *Control\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Writes data to a serial device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param BufferSize On input, the size of the Buffer. On output, the amount of\r
+ data actually written.\r
+ @param Buffer The buffer of data to write\r
+\r
+ @retval EFI_SUCCESS The data was written.\r
+ @retval EFI_DEVICE_ERROR The device reported an error.\r
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GdbSerialWrite (\r
+ IN EFI_SERIAL_IO_PROTOCOL *This,\r
+ IN OUT UINTN *BufferSize,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ GDB_SERIAL_DEV *SerialDev;\r
+ UINTN Return;\r
+\r
+ SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);\r
+\r
+ Return = GdbWrite (SerialDev->OutFileDescriptor, Buffer, *BufferSize);\r
+ if (Return == (UINTN)-1) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (Return != *BufferSize) {\r
+ *BufferSize = Return;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Writes data to a serial device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param BufferSize On input, the size of the Buffer. On output, the amount of\r
+ data returned in Buffer.\r
+ @param Buffer The buffer to return the data into.\r
+\r
+ @retval EFI_SUCCESS The data was read.\r
+ @retval EFI_DEVICE_ERROR The device reported an error.\r
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.\r
+\r
+**/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GdbSerialRead (\r
+ IN EFI_SERIAL_IO_PROTOCOL *This,\r
+ IN OUT UINTN *BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ GDB_SERIAL_DEV *SerialDev;\r
+ UINTN Return;\r
+\r
+ SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);\r
+\r
+ Return = GdbRead (SerialDev->InFileDescriptor, Buffer, *BufferSize);\r
+ if (Return == (UINTN)-1) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (Return != *BufferSize) {\r
+ *BufferSize = Return;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+//\r
+// Template used to initailize the GDB Serial IO protocols\r
+//\r
+GDB_SERIAL_DEV gdbSerialDevTemplate = {\r
+ GDB_SERIAL_DEV_SIGNATURE,\r
+ NULL,\r
+\r
+ { // SerialIo\r
+ SERIAL_IO_INTERFACE_REVISION,\r
+ GdbSerialReset,\r
+ GdbSerialSetAttributes,\r
+ GdbSerialSetControl,\r
+ GdbSerialGetControl,\r
+ GdbSerialWrite,\r
+ GdbSerialRead,\r
+ NULL\r
+ },\r
+ { // SerialMode\r
+ 0, // ControlMask\r
+ 0, // Timeout\r
+ 0, // BaudRate\r
+ 1, // RceiveFifoDepth\r
+ 0, // DataBits\r
+ 0, // Parity\r
+ 0 // StopBits\r
+ },\r
+ {\r
+ {\r
+ {\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_VENDOR_DP,\r
+ {\r
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)),\r
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)) >> 8)\r
+ },\r
+ },\r
+ EFI_SERIAL_IO_PROTOCOL_GUID\r
+ },\r
+ 0,\r
+ {\r
+ END_DEVICE_PATH_TYPE,\r
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ {\r
+ (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)),\r
+ (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL) >> 8)\r
+ }\r
+ },\r
+ },\r
+ GDB_STDIN,\r
+ GDB_STDOUT\r
+};\r
+\r
+\r
+/**\r
+ Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.\r
+\r
+ These console show up on the remote system running GDB\r
+\r
+**/\r
+VOID\r
+GdbInitializeSerialConsole (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ GDB_SERIAL_DEV *StdOutSerialDev;\r
+ GDB_SERIAL_DEV *StdErrSerialDev;\r
+\r
+ // Use the template to make a copy of the Serial Console private data structure.\r
+ StdOutSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);\r
+ ASSERT (StdOutSerialDev != NULL);\r
+\r
+ // Fixup pointer after the copy\r
+ StdOutSerialDev->SerialIo.Mode = &StdOutSerialDev->SerialMode;\r
+\r
+ StdErrSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);\r
+ ASSERT (StdErrSerialDev != NULL);\r
+\r
+ // Fixup pointer and modify stuff that is different for StdError\r
+ StdErrSerialDev->SerialIo.Mode = &StdErrSerialDev->SerialMode;\r
+ StdErrSerialDev->DevicePath.Index = 1;\r
+ StdErrSerialDev->OutFileDescriptor = GDB_STDERR;\r
+\r
+ // Make a new handle with Serial IO protocol and its device path on it.\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &StdOutSerialDev->Handle,\r
+ &gEfiSerialIoProtocolGuid, &StdOutSerialDev->SerialIo,\r
+ &gEfiDevicePathProtocolGuid, &StdOutSerialDev->DevicePath,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ // Make a new handle with Serial IO protocol and its device path on it.\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &StdErrSerialDev->Handle,\r
+ &gEfiSerialIoProtocolGuid, &StdErrSerialDev->SerialIo,\r
+ &gEfiDevicePathProtocolGuid, &StdErrSerialDev->DevicePath,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r