-/** @file
- Private include file for GDB stub
-
- 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.
-
-**/
-
-#ifndef __GDB_STUB_INTERNAL__
-#define __GDB_STUB_INTERNAL__
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/PcdLib.h>
-#include <Library/GdbSerialLib.h>
-#include <Library/PrintLib.h>
-
-#include <Protocol/DebugSupport.h>
-#include <Protocol/SerialIo.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/LoadedImage.h>
-#include <Guid/DebugImageInfoTable.h>
-#include <IndustryStandard/PeImage.h>
-
-extern CONST CHAR8 mHexToStr[];
-
-// maximum size of input and output buffers
-// This value came from the show remote command of the gdb we tested against
-#define MAX_BUF_SIZE 2000
-
-// maximum size of address buffer
-#define MAX_ADDR_SIZE 32
-
-// maximum size of register number buffer
-#define MAX_REG_NUM_BUF_SIZE 32
-
-// maximum size of length buffer
-#define MAX_LENGTH_SIZE 32
-
-// maximum size of T signal members
-#define MAX_T_SIGNAL_SIZE 64
-
-// the mask used to clear all the cache
-#define TF_BIT 0x00000100
-
-
-//
-// GDB Signal definitions - generic names for interrupts
-//
-#define GDB_SIGILL 4 // Illegal instruction
-#define GDB_SIGTRAP 5 // Trace Trap (Breakpoint and SingleStep)
-#define GDB_SIGEMT 7 // Emulator Trap
-#define GDB_SIGFPE 8 // Floating point exception
-#define GDB_SIGSEGV 11 // Setgment violation, page fault
-
-
-//
-// GDB File I/O Error values, zero means no error
-// Includes all general GDB Unix like error values
-//
-#define GDB_EBADMEMADDRBUFSIZE 11 // the buffer that stores memory Address to be read from/written to is not the right size
-#define GDB_EBADMEMLENGBUFSIZE 12 // the buffer that stores Length is not the right size
-#define GDB_EBADMEMLENGTH 13 // Length, the given number of bytes to read or write, is not the right size
-#define GDB_EBADMEMDATA 14 // one of the bytes or nibbles of the memory is leess than 0
-#define GDB_EBADMEMDATASIZE 15 // the memory data, 'XX..', is too short or too long
-#define GDB_EBADBUFSIZE 21 // the buffer created is not the correct size
-#define GDB_EINVALIDARG 31 // argument is invalid
-#define GDB_ENOSPACE 41 //
-#define GDB_EINVALIDBRKPOINTTYPE 51 // the breakpoint type is not recognized
-#define GDB_EINVALIDREGNUM 61 // given register number is not valid: either <0 or >=Number of Registers
-#define GDB_EUNKNOWN 255 // unknown
-
-
-//
-// These devices are open by GDB so we can just read and write to them
-//
-#define GDB_STDIN 0x00
-#define GDB_STDOUT 0x01
-#define GDB_STDERR 0x02
-
-//
-//Define Register size for different architectures
-//
-#if defined (MDE_CPU_IA32)
-#define REG_SIZE 32
-#elif defined (MDE_CPU_X64)
-#define REG_SIZE 64
-#elif defined (MDE_CPU_ARM)
-#define REG_SIZE 32
-#endif
-
-#define GDB_SERIAL_DEV_SIGNATURE SIGNATURE_32 ('g', 'd', 'b', 's')
-
-typedef struct {
- VENDOR_DEVICE_PATH VendorDevice;
- UINT32 Index; // Suport more than one
- EFI_DEVICE_PATH_PROTOCOL End;
-} GDB_SERIAL_DEVICE_PATH;
-
-//
-// Name: SERIAL_DEV
-// Purpose: To provide device specific information
-// Fields:
-// Signature UINTN: The identity of the serial device
-// SerialIo SERIAL_IO_PROTOCOL: Serial I/O protocol interface
-// SerialMode SERIAL_IO_MODE:
-// DevicePath EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device
-//
-typedef struct {
- UINTN Signature;
- EFI_HANDLE Handle;
- EFI_SERIAL_IO_PROTOCOL SerialIo;
- EFI_SERIAL_IO_MODE SerialMode;
- GDB_SERIAL_DEVICE_PATH DevicePath;
- INTN InFileDescriptor;
- INTN OutFileDescriptor;
-} GDB_SERIAL_DEV;
-
-
-#define GDB_SERIAL_DEV_FROM_THIS(a) CR (a, GDB_SERIAL_DEV, SerialIo, GDB_SERIAL_DEV_SIGNATURE)
-
-
-typedef struct {
- EFI_EXCEPTION_TYPE Exception;
- UINT8 SignalNo;
-} EFI_EXCEPTION_TYPE_ENTRY;
-
-
-#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
-
-//
-// Byte packed structure for DR6
-// 32-bits on IA-32
-// 64-bits on X64. The upper 32-bits on X64 are reserved
-//
-typedef union {
- struct {
- UINT32 B0:1; // Breakpoint condition detected
- UINT32 B1:1; // Breakpoint condition detected
- UINT32 B2:1; // Breakpoint condition detected
- UINT32 B3:1; // Breakpoint condition detected
- UINT32 Reserved_1:9; // Reserved
- UINT32 BD:1; // Debug register access detected
- UINT32 BS:1; // Single step
- UINT32 BT:1; // Task switch
- UINT32 Reserved_2:16; // Reserved
- } Bits;
- UINTN UintN;
-} IA32_DR6;
-
-//
-// Byte packed structure for DR7
-// 32-bits on IA-32
-// 64-bits on X64. The upper 32-bits on X64 are reserved
-//
-typedef union {
- struct {
- UINT32 L0:1; // Local breakpoint enable
- UINT32 G0:1; // Global breakpoint enable
- UINT32 L1:1; // Local breakpoint enable
- UINT32 G1:1; // Global breakpoint enable
- UINT32 L2:1; // Local breakpoint enable
- UINT32 G2:1; // Global breakpoint enable
- UINT32 L3:1; // Local breakpoint enable
- UINT32 G3:1; // Global breakpoint enable
- UINT32 LE:1; // Local exact breakpoint enable
- UINT32 GE:1; // Global exact breakpoint enable
- UINT32 Reserved_1:3; // Reserved
- UINT32 GD:1; // Global detect enable
- UINT32 Reserved_2:2; // Reserved
- UINT32 RW0:2; // Read/Write field
- UINT32 LEN0:2; // Length field
- UINT32 RW1:2; // Read/Write field
- UINT32 LEN1:2; // Length field
- UINT32 RW2:2; // Read/Write field
- UINT32 LEN2:2; // Length field
- UINT32 RW3:2; // Read/Write field
- UINT32 LEN3:2; // Length field
- } Bits;
- UINTN UintN;
-} IA32_DR7;
-
-#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */
-
-typedef enum {
- InstructionExecution, //Hardware breakpoint
- DataWrite, //watch
- DataRead, //rwatch
- DataReadWrite, //awatch
- SoftwareBreakpoint, //Software breakpoint
- NotSupported
-} BREAK_TYPE;
-
-//
-// Array of exception types that need to be hooked by the debugger
-//
-extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[];
-
-//
-// 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.
-//
-extern BOOLEAN gCtrlCBreakFlag;
-
-//
-// 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
-//
-extern BOOLEAN gProcessingFPacket;
-
-
-// The offsets of registers SystemContext.
-// The fields in the array are in the gdb ordering.
-//
-extern UINTN gRegisterOffsets[];
-
-/**
- Return the number of entries in the gExceptionType[]
-
- @retval UINTN, the number of entries in the gExceptionType[] array.
- **/
-UINTN
-MaxEfiException (
- VOID
- );
-
-
-/**
- Return the number of entries in the gRegisters[]
-
- @retval UINTN, the number of entries (registers) in the gRegisters[] array.
- **/
-UINTN
-MaxRegisterCount (
- VOID
- );
-
-
-/**
- Check to see if the ISA is supported.
- ISA = Instruction Set Architecture
-
- @retval TRUE if Isa is supported,
- FALSE otherwise.
- **/
-BOOLEAN
-CheckIsa (
- IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
- );
-
-
-/**
- Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
-
- @param SystemContext Register content at time of the exception
- @param GdbExceptionType GDB exception type
- **/
-
-VOID
-GdbSendTSignal (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINT8 GdbExceptionType
- );
-
-
-/**
- Translates the EFI mapping to GDB mapping
-
- @param EFIExceptionType EFI Exception that is being processed
- @retval UINTN that corresponds to EFIExceptionType's GDB exception type number
- **/
-UINT8
-ConvertEFItoGDBtype (
- IN EFI_EXCEPTION_TYPE EFIExceptionType
- );
-
-
-/**
- Empties the given buffer
- @param *Buf pointer to the first element in buffer to be emptied
- **/
-VOID
-EmptyBuffer (
- IN CHAR8 *Buf
- );
-
-
-/**
- Converts an 8-bit Hex Char into a INTN.
-
- @param Char - the hex character to be converted into UINTN
- @retval a INTN, from 0 to 15, that corressponds to Char
- -1 if Char is not a hex character
- **/
-INTN
-HexCharToInt (
- IN CHAR8 Char
- );
-
-
-/** 'E NN'
- Send an error with the given error number after converting to hex.
- The error number is put into the buffer in hex. '255' is the biggest errno we can send.
- ex: 162 will be sent as A2.
-
- @param errno the error number that will be sent
- **/
-VOID
-EFIAPI
-SendError (
- IN UINT8 ErrorNum
- );
-
-
-/**
- Send 'OK' when the function is done executing successfully.
- **/
-VOID
-SendSuccess (
- VOID
- );
-
-
-/**
- Send empty packet to specify that particular command/functionality is not supported.
- **/
-VOID
-SendNotSupported (
- VOID
- );
-
-/** ‘p n’
- Reads the n-th register's value into an output buffer and sends it as a packet
- @param SystemContext Register content at time of the exception
- @param InBuffer This is the input buffer received from gdb server
- **/
-VOID
-ReadNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘g’
- Reads the general registers into an output buffer and sends it as a packet
- @param SystemContext Register content at time of the exception
- **/
-VOID
-ReadGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/** ‘P n...=r...’
- Writes the new value of n-th register received into the input buffer to the n-th register
- @param SystemContext Register content at time of the exception
- @param InBuffer This is the input buffer received from gdb server
- **/
-VOID
-WriteNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘G XX...’
- Writes the new values received into the input buffer to the general registers
- @param SystemContext Register content at time of the exception
- @param InBuffer Pointer to the input buffer received from gdb server
- **/
-
-VOID
-WriteGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘m addr,length ’
- Find the Length of the area to read and the start addres. Finally, pass them to
- another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
- send it as a packet.
-
- @param *PacketData Pointer to Payload data for the packet
- **/
-VOID
-ReadFromMemory (
- IN CHAR8 *PacketData
- );
-
-
-/** ‘M addr,length :XX...’
- Find the Length of the area in bytes to write and the start addres. Finally, pass them to
- another function, TransferFromInBufToMem, that will write to that memory space the info in
- the input buffer.
-
- @param PacketData Pointer to Payload data for the packet
- **/
-VOID
-WriteToMemory (
- IN CHAR8 *PacketData
- );
-
-
-/** ‘c [addr ]’
- Continue. addr is Address to resume. If addr is omitted, resume at current
- Address.
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to PacketData
- **/
-
-VOID
-ContinueAtAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/** ‘s [addr ]’
- Single step. addr is the Address at which to resume. If addr is omitted, resume
- at same Address.
-
- @param SystemContext Register content at time of the exception
- @param PacketData Pointer to Payload data for the packet
- **/
-VOID
-SingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-/**
- Insert Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-AddSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-/**
- Remove Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-RemoveSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- ‘Z1, [addr], [length]’
- ‘Z2, [addr], [length]’
- ‘Z3, [addr], [length]’
- ‘Z4, [addr], [length]’
-
- Insert hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-InsertBreakPoint(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/**
- ‘z1, [addr], [length]’
- ‘z2, [addr], [length]’
- ‘z3, [addr], [length]’
- ‘z4, [addr], [length]’
-
- Remove hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-RemoveBreakPoint(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/**
- Exception Hanldler for GDB. It will be called for all exceptions
- registered via the gExceptionType[] array.
-
- @param ExceptionType Exception that is being processed
- @param SystemContext Register content at time of the exception
-
- **/
-VOID
-EFIAPI
-GdbExceptionHandler (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- Periodic callback for GDB. This function is used to catch a ctrl-c or other
- break in type command from GDB.
-
- @param SystemContext Register content at time of the call
-
- **/
-VOID
-EFIAPI
-GdbPeriodicCallBack (
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- Make two serail consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
-
- These console show up on the remote system running GDB
-
-**/
-
-VOID
-GdbInitializeSerialConsole (
- VOID
- );
-
-
-/**
- Send a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
- in an infinit loop. This is so if you unplug the debugger code just keeps running
-
- @param PacketData Payload data for the packet
-
- @retval Number of bytes of packet data sent.
-
-**/
-UINTN
-SendPacket (
- IN CHAR8 *PacketData
- );
-
-
-/**
- Receive a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
- (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
-
- If an ack '+' is not sent resend the packet
-
- @param PacketData Payload data for the packet
-
- @retval Number of bytes of packet data received.
-
- **/
-UINTN
-ReceivePacket (
- OUT CHAR8 *PacketData,
- IN UINTN PacketDataSize
- );
-
-
-/**
- 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
- );
-
-
-/**
- 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
- );
-
-UINTN *
-FindPointerToRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber
- );
-
-CHAR8 *
-BasicReadRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *OutBufPtr
- );
-
-VOID
-TransferFromInBufToMem (
- IN UINTN Length,
- IN UINT8 *Address,
- IN CHAR8 *NewData
- );
-
-VOID
-TransferFromMemToOutBufAndSend (
- IN UINTN Length,
- IN UINT8 *Address
- );
-
-CHAR8 *
-BasicWriteRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *InBufPtr
- );
-
-VOID
-PrintReg (
- EFI_SYSTEM_CONTEXT SystemContext
- );
-
-UINTN
-ParseBreakpointPacket (
- IN CHAR8 *PacketData,
- OUT UINTN *Type,
- OUT UINTN *Address,
- OUT UINTN *Length
- );
-
-UINTN
-GetBreakpointDataAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- );
-
-UINTN
-GetBreakpointDetected (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-BREAK_TYPE
-GetBreakpointType (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- );
-
-UINTN
-ConvertLengthData (
- IN UINTN Length
- );
-
-EFI_STATUS
-FindNextFreeDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- OUT UINTN *Register
- );
-
-EFI_STATUS
-EnableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type
- );
-
-EFI_STATUS
-FindMatchingDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type,
- OUT UINTN *Register
- );
-
-EFI_STATUS
-DisableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register
- );
-
-VOID
-InitializeProcessor (
- VOID
- );
-
-BOOLEAN
-ValidateAddress (
- IN VOID *Address
- );
-
-BOOLEAN
-ValidateException (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-#endif
+/** @file\r
+ Private include file for GDB stub\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
+#ifndef __GDB_STUB_INTERNAL__\r
+#define __GDB_STUB_INTERNAL__\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/GdbSerialLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+#include <Protocol/DebugSupport.h>\r
+#include <Protocol/SerialIo.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Guid/DebugImageInfoTable.h>\r
+#include <IndustryStandard/PeImage.h>\r
+\r
+extern CONST CHAR8 mHexToStr[];\r
+\r
+// maximum size of input and output buffers\r
+// This value came from the show remote command of the gdb we tested against\r
+#define MAX_BUF_SIZE 2000\r
+\r
+// maximum size of address buffer\r
+#define MAX_ADDR_SIZE 32\r
+\r
+// maximum size of register number buffer\r
+#define MAX_REG_NUM_BUF_SIZE 32\r
+\r
+// maximum size of length buffer\r
+#define MAX_LENGTH_SIZE 32\r
+\r
+// maximum size of T signal members\r
+#define MAX_T_SIGNAL_SIZE 64\r
+\r
+// the mask used to clear all the cache\r
+#define TF_BIT 0x00000100\r
+\r
+\r
+//\r
+// GDB Signal definitions - generic names for interrupts\r
+//\r
+#define GDB_SIGILL 4 // Illegal instruction\r
+#define GDB_SIGTRAP 5 // Trace Trap (Breakpoint and SingleStep)\r
+#define GDB_SIGEMT 7 // Emulator Trap\r
+#define GDB_SIGFPE 8 // Floating point exception\r
+#define GDB_SIGSEGV 11 // Segment violation, page fault\r
+\r
+\r
+//\r
+// GDB File I/O Error values, zero means no error\r
+// Includes all general GDB Unix like error values\r
+//\r
+#define GDB_EBADMEMADDRBUFSIZE 11 // the buffer that stores memory Address to be read from/written to is not the right size\r
+#define GDB_EBADMEMLENGBUFSIZE 12 // the buffer that stores Length is not the right size\r
+#define GDB_EBADMEMLENGTH 13 // Length, the given number of bytes to read or write, is not the right size\r
+#define GDB_EBADMEMDATA 14 // one of the bytes or nibbles of the memory is leess than 0\r
+#define GDB_EBADMEMDATASIZE 15 // the memory data, 'XX..', is too short or too long\r
+#define GDB_EBADBUFSIZE 21 // the buffer created is not the correct size\r
+#define GDB_EINVALIDARG 31 // argument is invalid\r
+#define GDB_ENOSPACE 41 //\r
+#define GDB_EINVALIDBRKPOINTTYPE 51 // the breakpoint type is not recognized\r
+#define GDB_EINVALIDREGNUM 61 // given register number is not valid: either <0 or >=Number of Registers\r
+#define GDB_EUNKNOWN 255 // unknown\r
+\r
+\r
+//\r
+// These devices are open by GDB so we can just read and write to them\r
+//\r
+#define GDB_STDIN 0x00\r
+#define GDB_STDOUT 0x01\r
+#define GDB_STDERR 0x02\r
+\r
+//\r
+//Define Register size for different architectures\r
+//\r
+#if defined (MDE_CPU_IA32)\r
+#define REG_SIZE 32\r
+#elif defined (MDE_CPU_X64)\r
+#define REG_SIZE 64\r
+#elif defined (MDE_CPU_ARM)\r
+#define REG_SIZE 32\r
+#endif\r
+\r
+#define GDB_SERIAL_DEV_SIGNATURE SIGNATURE_32 ('g', 'd', 'b', 's')\r
+\r
+typedef struct {\r
+ VENDOR_DEVICE_PATH VendorDevice;\r
+ UINT32 Index; // Suport more than one\r
+ EFI_DEVICE_PATH_PROTOCOL End;\r
+} GDB_SERIAL_DEVICE_PATH;\r
+\r
+//\r
+// Name: SERIAL_DEV\r
+// Purpose: To provide device specific information\r
+// Fields:\r
+// Signature UINTN: The identity of the serial device\r
+// SerialIo SERIAL_IO_PROTOCOL: Serial I/O protocol interface\r
+// SerialMode SERIAL_IO_MODE:\r
+// DevicePath EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device\r
+//\r
+typedef struct {\r
+ UINTN Signature;\r
+ EFI_HANDLE Handle;\r
+ EFI_SERIAL_IO_PROTOCOL SerialIo;\r
+ EFI_SERIAL_IO_MODE SerialMode;\r
+ GDB_SERIAL_DEVICE_PATH DevicePath;\r
+ INTN InFileDescriptor;\r
+ INTN OutFileDescriptor;\r
+} GDB_SERIAL_DEV;\r
+\r
+\r
+#define GDB_SERIAL_DEV_FROM_THIS(a) CR (a, GDB_SERIAL_DEV, SerialIo, GDB_SERIAL_DEV_SIGNATURE)\r
+\r
+\r
+typedef struct {\r
+ EFI_EXCEPTION_TYPE Exception;\r
+ UINT8 SignalNo;\r
+} EFI_EXCEPTION_TYPE_ENTRY;\r
+\r
+\r
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)\r
+\r
+//\r
+// Byte packed structure for DR6\r
+// 32-bits on IA-32\r
+// 64-bits on X64. The upper 32-bits on X64 are reserved\r
+//\r
+typedef union {\r
+ struct {\r
+ UINT32 B0:1; // Breakpoint condition detected\r
+ UINT32 B1:1; // Breakpoint condition detected\r
+ UINT32 B2:1; // Breakpoint condition detected\r
+ UINT32 B3:1; // Breakpoint condition detected\r
+ UINT32 Reserved_1:9; // Reserved\r
+ UINT32 BD:1; // Debug register access detected\r
+ UINT32 BS:1; // Single step\r
+ UINT32 BT:1; // Task switch\r
+ UINT32 Reserved_2:16; // Reserved\r
+ } Bits;\r
+ UINTN UintN;\r
+} IA32_DR6;\r
+\r
+//\r
+// Byte packed structure for DR7\r
+// 32-bits on IA-32\r
+// 64-bits on X64. The upper 32-bits on X64 are reserved\r
+//\r
+typedef union {\r
+ struct {\r
+ UINT32 L0:1; // Local breakpoint enable\r
+ UINT32 G0:1; // Global breakpoint enable\r
+ UINT32 L1:1; // Local breakpoint enable\r
+ UINT32 G1:1; // Global breakpoint enable\r
+ UINT32 L2:1; // Local breakpoint enable\r
+ UINT32 G2:1; // Global breakpoint enable\r
+ UINT32 L3:1; // Local breakpoint enable\r
+ UINT32 G3:1; // Global breakpoint enable\r
+ UINT32 LE:1; // Local exact breakpoint enable\r
+ UINT32 GE:1; // Global exact breakpoint enable\r
+ UINT32 Reserved_1:3; // Reserved\r
+ UINT32 GD:1; // Global detect enable\r
+ UINT32 Reserved_2:2; // Reserved\r
+ UINT32 RW0:2; // Read/Write field\r
+ UINT32 LEN0:2; // Length field\r
+ UINT32 RW1:2; // Read/Write field\r
+ UINT32 LEN1:2; // Length field\r
+ UINT32 RW2:2; // Read/Write field\r
+ UINT32 LEN2:2; // Length field\r
+ UINT32 RW3:2; // Read/Write field\r
+ UINT32 LEN3:2; // Length field\r
+ } Bits;\r
+ UINTN UintN;\r
+} IA32_DR7;\r
+\r
+#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */\r
+\r
+typedef enum {\r
+ InstructionExecution, //Hardware breakpoint\r
+ DataWrite, //watch\r
+ DataRead, //rwatch\r
+ DataReadWrite, //awatch\r
+ SoftwareBreakpoint, //Software breakpoint\r
+ NotSupported\r
+} BREAK_TYPE;\r
+\r
+//\r
+// Array of exception types that need to be hooked by the debugger\r
+//\r
+extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[];\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
+extern BOOLEAN gCtrlCBreakFlag;\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
+extern BOOLEAN gProcessingFPacket;\r
+\r
+\r
+// The offsets of registers SystemContext.\r
+// The fields in the array are in the gdb ordering.\r
+//\r
+extern UINTN gRegisterOffsets[];\r
+\r
+/**\r
+ Return the number of entries in the gExceptionType[]\r
+\r
+ @retval UINTN, the number of entries in the gExceptionType[] array.\r
+ **/\r
+UINTN\r
+MaxEfiException (\r
+ VOID\r
+ );\r
+\r
+\r
+/**\r
+ Return the number of entries in the gRegisters[]\r
+\r
+ @retval UINTN, the number of entries (registers) in the gRegisters[] array.\r
+ **/\r
+UINTN\r
+MaxRegisterCount (\r
+ VOID\r
+ );\r
+\r
+\r
+/**\r
+ Check to see if the ISA is supported.\r
+ ISA = Instruction Set Architecture\r
+\r
+ @retval TRUE if Isa is supported,\r
+ FALSE otherwise.\r
+ **/\r
+BOOLEAN\r
+CheckIsa (\r
+ IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa\r
+ );\r
+\r
+\r
+/**\r
+ Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ @param GdbExceptionType GDB exception type\r
+ **/\r
+\r
+VOID\r
+GdbSendTSignal (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINT8 GdbExceptionType\r
+ );\r
+\r
+\r
+/**\r
+ Translates the EFI mapping to GDB mapping\r
+\r
+ @param EFIExceptionType EFI Exception that is being processed\r
+ @retval UINTN that corresponds to EFIExceptionType's GDB exception type number\r
+ **/\r
+UINT8\r
+ConvertEFItoGDBtype (\r
+ IN EFI_EXCEPTION_TYPE EFIExceptionType\r
+ );\r
+\r
+\r
+/**\r
+ Empties the given buffer\r
+ @param *Buf pointer to the first element in buffer to be emptied\r
+ **/\r
+VOID\r
+EmptyBuffer (\r
+ IN CHAR8 *Buf\r
+ );\r
+\r
+\r
+/**\r
+ Converts an 8-bit Hex Char into a INTN.\r
+\r
+ @param Char - the hex character to be converted into UINTN\r
+ @retval a INTN, from 0 to 15, that corressponds to Char\r
+ -1 if Char is not a hex character\r
+ **/\r
+INTN\r
+HexCharToInt (\r
+ IN CHAR8 Char\r
+ );\r
+\r
+\r
+/** 'E NN'\r
+ Send an error with the given error number after converting to hex.\r
+ The error number is put into the buffer in hex. '255' is the biggest errno we can send.\r
+ ex: 162 will be sent as A2.\r
+\r
+ @param errno the error number that will be sent\r
+ **/\r
+VOID\r
+EFIAPI\r
+SendError (\r
+ IN UINT8 ErrorNum\r
+ );\r
+\r
+\r
+/**\r
+ Send 'OK' when the function is done executing successfully.\r
+ **/\r
+VOID\r
+SendSuccess (\r
+ VOID\r
+ );\r
+\r
+\r
+/**\r
+ Send empty packet to specify that particular command/functionality is not supported.\r
+ **/\r
+VOID\r
+SendNotSupported (\r
+ VOID\r
+ );\r
+\r
+/** ‘p n’\r
+ Reads the n-th register's value into an output buffer and sends it as a packet\r
+ @param SystemContext Register content at time of the exception\r
+ @param InBuffer This is the input buffer received from gdb server\r
+ **/\r
+VOID\r
+ReadNthRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN CHAR8 *InBuffer\r
+ );\r
+\r
+\r
+/** ‘g’\r
+ Reads the general registers into an output buffer and sends it as a packet\r
+ @param SystemContext Register content at time of the exception\r
+ **/\r
+VOID\r
+ReadGeneralRegisters (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+\r
+/** ‘P n...=r...’\r
+ Writes the new value of n-th register received into the input buffer to the n-th register\r
+ @param SystemContext Register content at time of the exception\r
+ @param InBuffer This is the input buffer received from gdb server\r
+ **/\r
+VOID\r
+WriteNthRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN CHAR8 *InBuffer\r
+ );\r
+\r
+\r
+/** ‘G XX...’\r
+ Writes the new values received into the input buffer to the general registers\r
+ @param SystemContext Register content at time of the exception\r
+ @param InBuffer Pointer to the input buffer received from gdb server\r
+ **/\r
+\r
+VOID\r
+WriteGeneralRegisters (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN CHAR8 *InBuffer\r
+ );\r
+\r
+\r
+/** ‘m addr,length ’\r
+ Find the Length of the area to read and the start addres. Finally, pass them to\r
+ another function, TransferFromMemToOutBufAndSend, that will read from that memory space and\r
+ send it as a packet.\r
+\r
+ @param *PacketData Pointer to Payload data for the packet\r
+ **/\r
+VOID\r
+ReadFromMemory (\r
+ IN CHAR8 *PacketData\r
+ );\r
+\r
+\r
+/** ‘M addr,length :XX...’\r
+ Find the Length of the area in bytes to write and the start addres. Finally, pass them to\r
+ another function, TransferFromInBufToMem, that will write to that memory space the info in\r
+ the input buffer.\r
+\r
+ @param PacketData Pointer to Payload data for the packet\r
+ **/\r
+VOID\r
+WriteToMemory (\r
+ IN CHAR8 *PacketData\r
+ );\r
+\r
+\r
+/** ‘c [addr ]’\r
+ Continue. addr is Address to resume. If addr is omitted, resume at current\r
+ Address.\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ @param *PacketData Pointer to PacketData\r
+ **/\r
+\r
+VOID\r
+ContinueAtAddress (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN CHAR8 *PacketData\r
+ );\r
+\r
+\r
+/** ‘s [addr ]’\r
+ Single step. addr is the Address at which to resume. If addr is omitted, resume\r
+ at same Address.\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ @param PacketData Pointer to Payload data for the packet\r
+ **/\r
+VOID\r
+SingleStep (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN CHAR8 *PacketData\r
+ );\r
+\r
+/**\r
+ Insert Single Step in the SystemContext\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ **/\r
+VOID\r
+AddSingleStep (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+/**\r
+ Remove Single Step in the SystemContext\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ **/\r
+VOID\r
+RemoveSingleStep (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+\r
+/**\r
+ ‘Z1, [addr], [length]’\r
+ ‘Z2, [addr], [length]’\r
+ ‘Z3, [addr], [length]’\r
+ ‘Z4, [addr], [length]’\r
+\r
+ Insert hardware breakpoint/watchpoint at address addr of size length\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ @param *PacketData Pointer to the Payload data for the packet\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InsertBreakPoint(\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN CHAR8 *PacketData\r
+ );\r
+\r
+\r
+/**\r
+ ‘z1, [addr], [length]’\r
+ ‘z2, [addr], [length]’\r
+ ‘z3, [addr], [length]’\r
+ ‘z4, [addr], [length]’\r
+\r
+ Remove hardware breakpoint/watchpoint at address addr of size length\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ @param *PacketData Pointer to the Payload data for the packet\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RemoveBreakPoint(\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN CHAR8 *PacketData\r
+ );\r
+\r
+\r
+/**\r
+ Exception Hanldler for GDB. It will be called for all exceptions\r
+ registered via the gExceptionType[] array.\r
+\r
+ @param ExceptionType Exception that is being processed\r
+ @param SystemContext Register content at time of the exception\r
+\r
+ **/\r
+VOID\r
+EFIAPI\r
+GdbExceptionHandler (\r
+ IN EFI_EXCEPTION_TYPE ExceptionType,\r
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+\r
+/**\r
+ Periodic callback for GDB. This function is used to catch a ctrl-c or other\r
+ break in type command from GDB.\r
+\r
+ @param SystemContext Register content at time of the call\r
+\r
+ **/\r
+VOID\r
+EFIAPI\r
+GdbPeriodicCallBack (\r
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+\r
+/**\r
+ Make two serail 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
+\r
+VOID\r
+GdbInitializeSerialConsole (\r
+ VOID\r
+ );\r
+\r
+\r
+/**\r
+ Send a GDB Remote Serial Protocol Packet\r
+\r
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',\r
+ the packet teminating character '#' and the two digit checksum.\r
+\r
+ If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up\r
+ in an infinit loop. This is so if you unplug the debugger code just keeps running\r
+\r
+ @param PacketData Payload data for the packet\r
+\r
+ @retval Number of bytes of packet data sent.\r
+\r
+**/\r
+UINTN\r
+SendPacket (\r
+ IN CHAR8 *PacketData\r
+ );\r
+\r
+\r
+/**\r
+ Receive a GDB Remote Serial Protocol Packet\r
+\r
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',\r
+ the packet teminating character '#' and the two digit checksum.\r
+\r
+ If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.\r
+ (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)\r
+\r
+ If an ack '+' is not sent resend the packet\r
+\r
+ @param PacketData Payload data for the packet\r
+\r
+ @retval Number of bytes of packet data received.\r
+\r
+ **/\r
+UINTN\r
+ReceivePacket (\r
+ OUT CHAR8 *PacketData,\r
+ IN UINTN PacketDataSize\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
+\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
+UINTN *\r
+FindPointerToRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN RegNumber\r
+ );\r
+\r
+CHAR8 *\r
+BasicReadRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN RegNumber,\r
+ IN CHAR8 *OutBufPtr\r
+ );\r
+\r
+VOID\r
+TransferFromInBufToMem (\r
+ IN UINTN Length,\r
+ IN UINT8 *Address,\r
+ IN CHAR8 *NewData\r
+ );\r
+\r
+VOID\r
+TransferFromMemToOutBufAndSend (\r
+ IN UINTN Length,\r
+ IN UINT8 *Address\r
+ );\r
+\r
+CHAR8 *\r
+BasicWriteRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN RegNumber,\r
+ IN CHAR8 *InBufPtr\r
+ );\r
+\r
+VOID\r
+PrintReg (\r
+ EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+UINTN\r
+ParseBreakpointPacket (\r
+ IN CHAR8 *PacketData,\r
+ OUT UINTN *Type,\r
+ OUT UINTN *Address,\r
+ OUT UINTN *Length\r
+ );\r
+\r
+UINTN\r
+GetBreakpointDataAddress (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN BreakpointNumber\r
+ );\r
+\r
+UINTN\r
+GetBreakpointDetected (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+BREAK_TYPE\r
+GetBreakpointType (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN BreakpointNumber\r
+ );\r
+\r
+UINTN\r
+ConvertLengthData (\r
+ IN UINTN Length\r
+ );\r
+\r
+EFI_STATUS\r
+FindNextFreeDebugRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ OUT UINTN *Register\r
+ );\r
+\r
+EFI_STATUS\r
+EnableDebugRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN Register,\r
+ IN UINTN Address,\r
+ IN UINTN Length,\r
+ IN UINTN Type\r
+ );\r
+\r
+EFI_STATUS\r
+FindMatchingDebugRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN Address,\r
+ IN UINTN Length,\r
+ IN UINTN Type,\r
+ OUT UINTN *Register\r
+ );\r
+\r
+EFI_STATUS\r
+DisableDebugRegister (\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN UINTN Register\r
+ );\r
+\r
+VOID\r
+InitializeProcessor (\r
+ VOID\r
+ );\r
+\r
+BOOLEAN\r
+ValidateAddress (\r
+ IN VOID *Address\r
+ );\r
+\r
+BOOLEAN\r
+ValidateException (\r
+ IN EFI_EXCEPTION_TYPE ExceptionType,\r
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+#endif\r