X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EmbeddedPkg%2FGdbStub%2FGdbStubInternal.h;fp=EmbeddedPkg%2FGdbStub%2FGdbStubInternal.h;h=5f15420f02e8852aef2c4d21d7c2e7c96a42bd92;hp=ac04d7b9a53bd9e6f66e475168a9fda3f6b0334d;hb=1e57a46299244793beb27e74be171d1540606999;hpb=5767f22fca7c337cdc113e14b411c1fd0ea7bd53 diff --git a/EmbeddedPkg/GdbStub/GdbStubInternal.h b/EmbeddedPkg/GdbStub/GdbStubInternal.h index ac04d7b9a5..5f15420f02 100644 --- a/EmbeddedPkg/GdbStub/GdbStubInternal.h +++ b/EmbeddedPkg/GdbStub/GdbStubInternal.h @@ -1,746 +1,746 @@ -/** @file - Private include file for GDB stub - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -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 + Private include file for GDB stub + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +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