From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:4864:20::436; helo=mail-wr1-x436.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 686352119C8AF for ; Wed, 12 Dec 2018 04:48:49 -0800 (PST) Received: by mail-wr1-x436.google.com with SMTP id r10so17554397wrs.10 for ; Wed, 12 Dec 2018 04:48:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KmJWMla1DqSL1pBGt556lJyZ8MfpcwwJr7OWyuN4T/s=; b=E/zCkhdHw8ImU6IgcMg7C9X+NYwxnZ8AHOqoWOV0nQD8YSchKC1kBP0bDu0NoKcyXl xMUYG9KYyS0xZIcyEHeC6MEwNwCBD9eaBt2R8G3tbqSSxWGLEPX8yy4a2skir2dvMQ7m 0/YZuxlLRVOd/NXb/WS+9E1ihHYY4KRmjaWSE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KmJWMla1DqSL1pBGt556lJyZ8MfpcwwJr7OWyuN4T/s=; b=Nmd56856RIlt+TZsaX+fdeFXZEMo0pGUMxxxTyHNkOvo5L6dX5W9BDv6EDJr+1pCsX eWy32fhkYu7iq8Lfo3xuo23BdawD/wt5AdXSQwqWhMxzLP5tJf7u/uZMd0YPwQpal1DW dPVNc1AR3PnuY/BNtoziDo0hMMCcTaxGB2AyntUWXGvn9btmfTZvtJREZQ3g4sWkqKkD s506maKe5hNq/k9Ie/N0WXF8jNWwNVy6AfK5ihSP2frOopp2Y3E2JFvV28QPSLoi2Ep0 IYGcK401DQnAH1xJuMqcU6/UtMgxCP2rBroXIpqRMpz+kMehGCXObA27MnrY6YudddKX CAfw== X-Gm-Message-State: AA+aEWYfBCCE72v0JVQrO/GzxIgT1j5ysa05FzR09Og97NEr1Dx8EJbA SVdhtCtl4/3/M6Z11XicSg5LMaWWMDh8Lw== X-Google-Smtp-Source: AFSGD/WXBb0fp6+SP1nz2OoXBdL/fB9C/EGFujzVHVnSAgf6tJ5oaJT4cjm6gFyKJJHw8sbDWB/3Nw== X-Received: by 2002:adf:d1d2:: with SMTP id m18mr17956887wri.138.1544618925516; Wed, 12 Dec 2018 04:48:45 -0800 (PST) Received: from harold.home ([2a01:cb1d:112:6f00:1db:abd7:f798:3277]) by smtp.gmail.com with ESMTPSA id 60sm31136325wrb.81.2018.12.12.04.48.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 12 Dec 2018 04:48:44 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org Date: Wed, 12 Dec 2018 13:48:42 +0100 Message-Id: <20181212124842.15968-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Subject: [PATCH] EmbeddedPkg: remove GdbDebugAgent library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Dec 2018 12:48:50 -0000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GdbDebugAgent library is unused and unmaintained, and now it turns out it doesn't build with Clang, so let's just get rid of it. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel --- BeagleBoardPkg/BeagleBoardPkg.dsc | 3 - EmbeddedPkg/EmbeddedPkg.dsc | 1 - EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf | 70 -- EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h | 728 --------------- EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c | 675 -------------- EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.c | 815 ----------------- EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c | 951 ------------------- EmbeddedPkg/Library/GdbDebugAgent/X64/Processor.c | 963 -------------------- EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S | 258 ------ EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm | 259 ------ EmbeddedPkg/Library/GdbDebugAgent/gdbnotes.txt | 15 - 11 files changed, 4738 deletions(-) diff --git a/BeagleBoardPkg/BeagleBoardPkg.dsc b/BeagleBoardPkg/BeagleBoardPkg.dsc index 348624a0389c..6dabfa905ae9 100644 --- a/BeagleBoardPkg/BeagleBoardPkg.dsc +++ b/BeagleBoardPkg/BeagleBoardPkg.dsc @@ -155,9 +155,6 @@ [LibraryClasses.common.SEC] # 1/123 faster than Stm or Vstm version BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf - # Uncomment to turn on GDB stub in SEC. - #DebugAgentLib|EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf - [LibraryClasses.common.PEI_CORE] PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index 9dc1b63dfb87..4d9e6399d575 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -237,7 +237,6 @@ [Components.common] EmbeddedPkg/Library/AcpiLib/AcpiLib.inf EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf EmbeddedPkg/Library/FdtLib/FdtLib.inf - EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf diff --git a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf b/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf deleted file mode 100644 index cfa8d8a761ca..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf +++ /dev/null @@ -1,70 +0,0 @@ -#/** @file -# Null instance of Debug Agent Library with empty functions. -# -# Copyright (c) 2010 - 2018, Intel Corporation. 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. -# -# -#**/ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = GdbDebugAgent - FILE_GUID = b9f10c17-6ca0-40b5-9b44-6253cfc7d24b - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = DebugAgentLib - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 EBC -# - -[Sources.common] - GdbDebugAgent.c - -[Sources.arm] - Arm/Processor.c - Arm/ExceptionSupport.ARMv6.S - Arm/ExceptionSupport.ARMv6.asm - -[Sources.X64] - Ia32/Processor.c - -[Sources.Ia32] - X64/Processor.c - - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - -[Packages.arm] - ArmPkg/ArmPkg.dec - -[LibraryClasses] - BaseLib - DebugLib - BaseMemoryLib - PcdLib - GdbSerialLib - CacheMaintenanceLib - DebugAgentTimerLib - -[FeaturePcd.common] - gEmbeddedTokenSpaceGuid.PcdGdbSerial - -[FixedPcd.common] - gEmbeddedTokenSpaceGuid.PcdGdbMaxPacketRetryCount - gEmbeddedTokenSpaceGuid.PcdGdbTimerPeriodMilliseconds - -[FixedPcd.arm] - gArmTokenSpaceGuid.PcdCpuVectorBaseAddress diff --git a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h b/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h deleted file mode 100644 index 7d85481c4be9..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h +++ /dev/null @@ -1,728 +0,0 @@ -/** @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 __GCC_DEBUG_AGENT_INTERNAL__ -#define __GCC_DEBUG_AGENT_INTERNAL__ - -#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_SIGINT 2 // Interrupt process via ctrl-c -#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 - - -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[]; - -// -// 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; - - -/** - Return the number of entries in the gExceptionType[] - - @retval UINTN, the number of entries in the gExceptionType[] array. - **/ -UINTN -MaxEfiException ( - 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 processed. - (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 - ); - -/** - 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 -ProcessorSendTSignal ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINT8 GdbExceptionType, - IN OUT CHAR8 *TSignalPtr, - IN UINTN SizeOfBuffer - ); - -/** - Check to see if this exception is related to ctrl-c handling. - - @param ExceptionType Exception that is being processed - @param SystemContext Register content at time of the exception - - @return TRUE This was a ctrl-c check that did not find a ctrl-c - @return FALSE This was not a ctrl-c check or some one hit ctrl-c - **/ -BOOLEAN -ProcessorControlC ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN OUT EFI_SYSTEM_CONTEXT SystemContext - ); - - -/** - Initialize debug agent. - - This function is used to set up debug enviroment. It may enable interrupts. - - @param[in] InitFlag Init flag is used to decide initialize process. - @param[in] Context Context needed according to InitFlag, it was optional. - -**/ -VOID -EFIAPI -DebugAgentHookExceptions ( - IN UINT32 InitFlag, - IN VOID *Context OPTIONAL - ); - - -#endif diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c b/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c deleted file mode 100644 index a43ff95d03a3..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c +++ /dev/null @@ -1,675 +0,0 @@ -/** @file - Processor specific parts of the GDB stub - - Copyright (c) 2008 - 2010, 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. - -**/ - - -#include -#include -#include - -// -// Externs from the exception handler assembly file -// -VOID -ExceptionHandlersStart ( - VOID - ); - -VOID -ExceptionHandlersEnd ( - VOID - ); - -VOID -CommonExceptionEntry ( - VOID - ); - -VOID -AsmCommonExceptionEntry ( - VOID - ); - - -// -// Array of exception types that need to be hooked by the debugger -// (efi, gdb) //efi number -// -EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = { - { EXCEPT_ARM_SOFTWARE_INTERRUPT, GDB_SIGTRAP }, - { EXCEPT_ARM_UNDEFINED_INSTRUCTION, GDB_SIGTRAP }, - { EXCEPT_ARM_PREFETCH_ABORT, GDB_SIGTRAP }, - { EXCEPT_ARM_DATA_ABORT, GDB_SIGTRAP }, // GDB_SIGEMT - { EXCEPT_ARM_RESERVED, GDB_SIGTRAP }, // GDB_SIGILL - { EXCEPT_ARM_FIQ, GDB_SIGINT } // Used for ctrl-c -}; - -// Shut up some annoying RVCT warnings -#ifdef __CC_ARM -#pragma diag_suppress 1296 -#endif - -UINTN gRegisterOffsets[] = { - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R0), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R1), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R2), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R3), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R4), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R5), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R6), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R7), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R8), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R9), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R10), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R11), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, R12), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, SP), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, LR), - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, PC), - 0x00000F01, // f0 - 0x00000F02, - 0x00000F03, - 0x00000F11, // f1 - 0x00000F12, - 0x00000F13, - 0x00000F21, // f2 - 0x00000F22, - 0x00000F23, - 0x00000F31, // f3 - 0x00000F32, - 0x00000F33, - 0x00000F41, // f4 - 0x00000F42, - 0x00000F43, - 0x00000F51, // f5 - 0x00000F52, - 0x00000F53, - 0x00000F61, // f6 - 0x00000F62, - 0x00000F63, - 0x00000F71, // f7 - 0x00000F72, - 0x00000F73, - 0x00000FFF, // fps - OFFSET_OF(EFI_SYSTEM_CONTEXT_ARM, CPSR) -}; - -// restore warnings for RVCT -#ifdef __CC_ARM -#pragma diag_default 1296 -#endif - - -/** - Return the number of entries in the gExceptionType[] - - @retval UINTN, the number of entries in the gExceptionType[] array. - **/ -UINTN -MaxEfiException ( - VOID - ) -{ - return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY); -} - - - - -/** - Check to see if the ISA is supported. - ISA = Instruction Set Architecture - - @retval TRUE if Isa is supported - -**/ -BOOLEAN -CheckIsa ( - IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa - ) -{ - if (Isa == IsaArm) { - return TRUE; - } else { - return FALSE; - } -} - - -/** - This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering - It is, by default, set to find the register pointer of the ARM member - @param SystemContext Register content at time of the exception - @param RegNumber The register to which we want to find a pointer - @retval the pointer to the RegNumber-th pointer - **/ -UINTN * -FindPointerToRegister( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber - ) -{ - UINT8 *TempPtr; - ASSERT(gRegisterOffsets[RegNumber] < 0xF00); - TempPtr = ((UINT8 *)SystemContext.SystemContextArm) + gRegisterOffsets[RegNumber]; - return (UINT32 *)TempPtr; -} - - -/** - Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr - @param SystemContext Register content at time of the exception - @param RegNumber the number of the register that we want to read - @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on. - @retval the pointer to the next character of the output buffer that is available to be written on. - **/ -CHAR8 * -BasicReadRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber, - IN CHAR8 *OutBufPtr - ) -{ - UINTN RegSize; - CHAR8 Char; - - if (gRegisterOffsets[RegNumber] > 0xF00) { - AsciiSPrint(OutBufPtr, 9, "00000000"); - OutBufPtr += 8; - return OutBufPtr; - } - - RegSize = 0; - while (RegSize < 32) { - Char = mHexToStr[(UINT8)((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)]; - if ((Char >= 'A') && (Char <= 'F')) { - Char = Char - 'A' + 'a'; - } - *OutBufPtr++ = Char; - - Char = mHexToStr[(UINT8)((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)]; - if ((Char >= 'A') && (Char <= 'F')) { - Char = Char - 'A' + 'a'; - } - *OutBufPtr++ = Char; - - RegSize = RegSize + 8; - } - return OutBufPtr; -} - - -/** - 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 Pointer to the input buffer received from gdb server - **/ -VOID -ReadNthRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN RegNumber; - CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq) - CHAR8 *OutBufPtr; // pointer to the output buffer - - RegNumber = AsciiStrHexToUintn (&InBuffer[1]); - - if (RegNumber >= (sizeof (gRegisterOffsets)/sizeof (UINTN))) { - SendError (GDB_EINVALIDREGNUM); - return; - } - - OutBufPtr = OutBuffer; - OutBufPtr = BasicReadRegister (SystemContext, RegNumber, OutBufPtr); - - *OutBufPtr = '\0'; // the end of the buffer - SendPacket(OutBuffer); -} - - -/** - Reads the general registers into an output buffer and sends it as a packet - @param SystemContext Register content at time of the exception - **/ -VOID -EFIAPI -ReadGeneralRegisters ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - UINTN Index; - // a UINT32 takes 8 ascii characters - CHAR8 OutBuffer[(sizeof (gRegisterOffsets) * 2) + 1]; - CHAR8 *OutBufPtr; - - // It is not safe to allocate pool here.... - OutBufPtr = OutBuffer; - for (Index = 0; Index < (sizeof (gRegisterOffsets)/sizeof (UINTN)); Index++) { - OutBufPtr = BasicReadRegister (SystemContext, Index, OutBufPtr); - } - - *OutBufPtr = '\0'; - SendPacket(OutBuffer); -} - - -/** - Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr - @param SystemContext Register content at time of the exception - @param RegNumber the number of the register that we want to write - @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on. - @retval the pointer to the next character of the input buffer that can be used - **/ -CHAR8 * -BasicWriteRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber, - IN CHAR8 *InBufPtr - ) -{ - UINTN RegSize; - UINTN TempValue; // the value transferred from a hex char - UINT32 NewValue; // the new value of the RegNumber-th Register - - if (gRegisterOffsets[RegNumber] > 0xF00) { - return InBufPtr + 8; - } - - NewValue = 0; - RegSize = 0; - while (RegSize < 32) { - TempValue = HexCharToInt(*InBufPtr++); - - if ((INTN)TempValue < 0) { - SendError (GDB_EBADMEMDATA); - return NULL; - } - - NewValue += (TempValue << (RegSize+4)); - TempValue = HexCharToInt(*InBufPtr++); - - if ((INTN)TempValue < 0) { - SendError (GDB_EBADMEMDATA); - return NULL; - } - - NewValue += (TempValue << RegSize); - RegSize = RegSize + 8; - } - *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue; - return InBufPtr; -} - - -/** ‘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 Ponter to the input buffer received from gdb server - **/ -VOID -WriteNthRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN RegNumber; - CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array - CHAR8 *RegNumBufPtr; - CHAR8 *InBufPtr; // pointer to the input buffer - - // find the register number to write - InBufPtr = &InBuffer[1]; - RegNumBufPtr = RegNumBuffer; - while (*InBufPtr != '=') { - *RegNumBufPtr++ = *InBufPtr++; - } - *RegNumBufPtr = '\0'; - RegNumber = AsciiStrHexToUintn (RegNumBuffer); - - // check if this is a valid Register Number - if (RegNumber >= (sizeof (gRegisterOffsets)/sizeof (UINTN))) { - SendError (GDB_EINVALIDREGNUM); - return; - } - InBufPtr++; // skips the '=' character - BasicWriteRegister (SystemContext, RegNumber, InBufPtr); - SendSuccess(); -} - - -/** ‘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 -EFIAPI -WriteGeneralRegisters ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN i; - CHAR8 *InBufPtr; /// pointer to the input buffer - UINTN MinLength; - UINTN RegisterCount = (sizeof (gRegisterOffsets)/sizeof (UINTN)); - - MinLength = (RegisterCount * 8) + 1; // 'G' plus the registers in ASCII format - - if (AsciiStrLen(InBuffer) < MinLength) { - //Bad message. Message is not the right length - SendError (GDB_EBADBUFSIZE); - return; - } - - InBufPtr = &InBuffer[1]; - - // Read the new values for the registers from the input buffer to an array, NewValueArray. - // The values in the array are in the gdb ordering - for(i = 0; i < RegisterCount; i++) { - InBufPtr = BasicWriteRegister (SystemContext, i, InBufPtr); - } - - SendSuccess (); -} - - - - -/** - Continue. addr is Address to resume. If addr is omitted, resume at current - Address. - - @param SystemContext Register content at time of the exception - **/ -VOID -EFIAPI -ContinueAtAddress ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - if (PacketData[1] != '\0') { - SystemContext.SystemContextArm->PC = AsciiStrHexToUintn(&PacketData[1]); - } -} - - -/** ‘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 - **/ -VOID -EFIAPI -SingleStep ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - SendNotSupported(); -} - - -VOID -EFIAPI -InsertBreakPoint ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - SendNotSupported (); -} - -VOID -EFIAPI -RemoveBreakPoint ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - SendNotSupported (); -} - - -/** - 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 -ProcessorSendTSignal ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINT8 GdbExceptionType, - IN OUT CHAR8 *TSignalPtr, - IN UINTN SizeOfBuffer - ) -{ - *TSignalPtr = '\0'; -} - -/** - FIQ state is only changed by FIQ exception. We don't want to take FIQ - ticks in the GDB stub. The stub disables FIQ on entry, but this is the - third instruction that executes in the execption handler. Thus we have - a crack we need to test for. - - @param PC PC of execption - - @return TRUE We are in the GDB stub exception preamble - @return FALSE We are not in GDB stub code - **/ -BOOLEAN -InFiqCrack ( - IN UINT32 PC - ) -{ - UINT64 VectorBase = PcdGet64 (PcdCpuVectorBaseAddress); - UINT32 Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart; - - if ((PC >= VectorBase) && (PC <= (VectorBase + Length))) { - return TRUE; - } - - return FALSE; -} - - -/** - Check to see if this exception is related to ctrl-c handling. - - In this scheme we dedicate FIQ to the ctrl-c handler so it is - independent of the rest of the system. - - SaveAndSetDebugTimerInterrupt () can be used to - - @param ExceptionType Exception that is being processed - @param SystemContext Register content at time of the exception - - @return TRUE This was a ctrl-c check that did not find a ctrl-c - @return FALSE This was not a ctrl-c check or some one hit ctrl-c - **/ -BOOLEAN -ProcessorControlC ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN OUT EFI_SYSTEM_CONTEXT SystemContext - ) -{ - CHAR8 Char; - BOOLEAN Return = TRUE; - - if (ExceptionType != EXCEPT_ARM_FIQ) { - // Skip it as it is not related to ctrl-c - return FALSE; - } - - if (InFiqCrack (SystemContext.SystemContextArm->PC)) { - // We are in our own interrupt preable, so skip this tick. - // We never want to let gdb see the debug stub running if we can help it - return FALSE; - } - - while (TRUE) { - if (!GdbIsCharAvailable ()) { - // - // No characters are pending so exit the loop - // - Return = TRUE; - break; - } - - Char = GdbGetChar (); - if (Char == 0x03) { - // - // We have a ctrl-c so exit and process exception for ctrl-c - // - Return = FALSE; - break; - } - } - - DebugAgentTimerEndOfInterrupt (); - - // Force an exit from the exception handler as we are done - return Return; -} - - -/** - Enable/Disable the interrupt of debug timer and return the interrupt state - prior to the operation. - - If EnableStatus is TRUE, enable the interrupt of debug timer. - If EnableStatus is FALSE, disable the interrupt of debug timer. - - @param[in] EnableStatus Enable/Disable. - - @retval TRUE Debug timer interrupt were enabled on entry to this call. - @retval FALSE Debug timer interrupt were disabled on entry to this call. - -**/ -BOOLEAN -EFIAPI -SaveAndSetDebugTimerInterrupt ( - IN BOOLEAN EnableStatus - ) -{ - BOOLEAN FiqEnabled; - - FiqEnabled = ArmGetFiqState (); - - if (EnableStatus) { - DebugAgentTimerSetPeriod (PcdGet32 (PcdGdbTimerPeriodMilliseconds)); - ArmEnableFiq (); - } else { - DebugAgentTimerSetPeriod (0); - ArmDisableFiq (); - } - - return FiqEnabled; -} - - - -VOID -GdbFPutString ( - IN CHAR8 *String - ); - -/** - Initialize debug agent. - - This function is used to set up debug environment to support source level debugging. - If certain Debug Agent Library instance has to save some private data in the stack, - this function must work on the mode that doesn't return to the caller, then - the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one - function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is - responsible to invoke the passing-in function at the end of InitializeDebugAgent(). - - If the parameter Function is not NULL, Debug Agent Library instance will invoke it by - passing in the Context to be its parameter. - - If Function() is NULL, Debug Agent Library instance will return after setup debug - environment. - - @param[in] InitFlag Init flag is used to decide the initialize process. - @param[in] Context Context needed according to InitFlag; it was optional. - @param[in] Function Continue function called by debug agent library; it was - optional. - -**/ -VOID -EFIAPI -InitializeDebugAgent ( - IN UINT32 InitFlag, - IN VOID *Context, OPTIONAL - IN DEBUG_AGENT_CONTINUE Function OPTIONAL - ) -{ - UINTN Offset; - UINTN Length; - BOOLEAN IrqEnabled; - UINT64 *VectorBase; - - - // - // Disable interrupts - // - IrqEnabled = ArmGetInterruptState (); - ArmDisableInterrupts (); - ArmDisableFiq (); - - // - // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress. - // - Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart; - - // - // Reserve space for the exception handlers - // - VectorBase = (UINT64 *)(UINTN)PcdGet64 (PcdCpuVectorBaseAddress); - - - // Copy our assembly code into the page that contains the exception vectors. - CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length); - - // - // Patch in the common Assembly exception handler - // - Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart; - *(UINTN *) (((UINT8 *)VectorBase) + Offset) = (UINTN)AsmCommonExceptionEntry; - - // Flush Caches since we updated executable stuff - InvalidateInstructionCacheRange ((VOID *)(UINTN)PcdGet64(PcdCpuVectorBaseAddress), Length); - - // setup a timer so gdb can break in via ctrl-c - DebugAgentTimerIntialize (); - - if (IrqEnabled) { - ArmEnableInterrupts (); - } - - if (Function != NULL) { - Function (Context); - } - - return; -} - diff --git a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.c b/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.c deleted file mode 100644 index 80aa4765c0ef..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.c +++ /dev/null @@ -1,815 +0,0 @@ -/** @file - Debug Agent library implementition with empty functions. - - Copyright (c) 2010, Intel Corporation. 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. - -**/ - -#include "GdbDebugAgent.h" - - -UINTN gMaxProcessorIndex = 0; - -// -// Buffers for basic gdb communication -// -CHAR8 gInBuffer[MAX_BUF_SIZE]; -CHAR8 gOutBuffer[MAX_BUF_SIZE]; - - -// -// Globals for returning XML from qXfer:libraries:read packet -// -UINTN gPacketqXferLibraryOffset = 0; -UINTN gEfiDebugImageTableEntry = 0; -CHAR8 gXferLibraryBuffer[2000]; - -GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - - -// add-symbol-file c:/work/edk2/Build/BeagleBoard/DEBUG_GCC48/ARM/BeagleBoardPkg/Sec/Sec/DEBUG/BeagleBoardSec.dll 0x80008360 -CHAR8 *qXferHack = ""; - -UINTN -gXferObjectReadResponse ( - IN CHAR8 Type, - IN CHAR8 *Str - ) -{ - CHAR8 *OutBufPtr; // pointer to the output buffer - CHAR8 Char; - UINTN Count; - - // responce starts with 'm' or 'l' if it is the end - OutBufPtr = gOutBuffer; - *OutBufPtr++ = Type; - Count = 1; - - // Binary data encoding - OutBufPtr = gOutBuffer; - while (*Str != '\0') { - Char = *Str++; - if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) { - // escape character - *OutBufPtr++ = 0x7d; - - Char ^= 0x20; - } - *OutBufPtr++ = Char; - Count++; - } - - *OutBufPtr = '\0' ; // the end of the buffer - SendPacket (gOutBuffer); - - return Count; -} - -/** - Process "qXfer:object:read:annex:offset,length" request. - - Returns an XML document that contains loaded libraries. In our case it is - infomration in the EFI Debug Inmage Table converted into an XML document. - - GDB will call with an arbitrary length (it can't know the real length and - will reply with chunks of XML that are easy for us to deal with. Gdb will - keep calling until we say we are done. XML doc looks like: - - - - - - - - Since we can not allocate memory in interupt context this module has - assumptions about how it will get called: - 1) Length will generally be max remote packet size (big enough) - 2) First Offset of an XML document read needs to be 0 - 3) This code will return back small chunks of the XML document on every read. - Each subseqent call will ask for the next available part of the document. - - Note: The only variable size element in the XML is: - " \n" and it is - based on the file path and name of the symbol file. If the symbol file name - is bigger than the max gdb remote packet size we could update this code - to respond back in chunks. - - @param Offset offset into special data area - @param Length number of bytes to read starting at Offset - - **/ -VOID -QxferLibrary ( - IN UINTN Offset, - IN UINTN Length - ) -{ - gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', "\n"); - gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', qXferHack); - gXferObjectReadResponse ('l', "\n"); - gPacketqXferLibraryOffset = 0; -} - -/** - Transfer length bytes of input buffer, starting at Address, to memory. - - @param length the number of the bytes to be transferred/written - @param *address the start address of the transferring/writing the memory - @param *new_data the new data to be written to memory - **/ - -VOID -TransferFromInBufToMem ( - IN UINTN Length, - IN unsigned char *Address, - IN CHAR8 *NewData - ) -{ - CHAR8 c1; - CHAR8 c2; - - while (Length-- > 0) { - c1 = (CHAR8)HexCharToInt (*NewData++); - c2 = (CHAR8)HexCharToInt (*NewData++); - - if ((c1 < 0) || (c2 < 0)) { - SendError (GDB_EBADMEMDATA); - return; - } - *Address++ = (UINT8)((c1 << 4) + c2); - } - - SendSuccess(); -} - - -/** - Transfer Length bytes of memory starting at Address to an output buffer, OutBuffer. This function will finally send the buffer - as a packet. - - @param Length the number of the bytes to be transferred/read - @param *address pointer to the start address of the transferring/reading the memory - **/ - -VOID -TransferFromMemToOutBufAndSend ( - IN UINTN Length, - IN unsigned char *Address - ) -{ - // there are Length bytes and every byte is represented as 2 hex chars - CHAR8 OutBuffer[MAX_BUF_SIZE]; - CHAR8 *OutBufPtr; // pointer to the output buffer - CHAR8 Char; - - OutBufPtr = OutBuffer; - while (Length > 0) { - - Char = mHexToStr[*Address >> 4]; - if ((Char >= 'A') && (Char <= 'F')) { - Char = Char - 'A' + 'a'; - } - *OutBufPtr++ = Char; - - Char = mHexToStr[*Address & 0x0f]; - if ((Char >= 'A') && (Char <= 'F')) { - Char = Char - 'A' + 'a'; - } - *OutBufPtr++ = Char; - - Address++; - Length--; - } - - *OutBufPtr = '\0' ; // the end of the buffer - SendPacket (OutBuffer); -} - - - -/** - 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 - ) -{ - UINT8 CheckSum; - UINTN Timeout; - CHAR8 *Ptr; - CHAR8 TestChar; - UINTN Count; - - Timeout = PcdGet32 (PcdGdbMaxPacketRetryCount); - - Count = 0; - do { - - Ptr = PacketData; - - if (Timeout-- == 0) { - // Only try a finite number of times so we don't get stuck in the loop - return Count; - } - - // Packet prefix - GdbPutChar ('$'); - - for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) { - GdbPutChar (*Ptr); - CheckSum = CheckSum + *Ptr; - } - - // Packet terminating character and checksum - GdbPutChar ('#'); - GdbPutChar (mHexToStr[CheckSum >> 4]); - GdbPutChar (mHexToStr[CheckSum & 0x0F]); - - TestChar = GdbGetChar (); - } while (TestChar != '+'); - - return Count; -} - -/** - 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 processed. - (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 - ) -{ - UINT8 CheckSum; - UINTN Index; - CHAR8 Char; - CHAR8 SumString[3]; - CHAR8 TestChar; - - ZeroMem (PacketData, PacketDataSize); - - for (;;) { - // wait for the start of a packet - TestChar = GdbGetChar (); - while (TestChar != '$') { - TestChar = GdbGetChar (); - }; - - retry: - for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) { - Char = GdbGetChar (); - if (Char == '$') { - goto retry; - } - if (Char == '#') { - break; - } - - PacketData[Index] = Char; - CheckSum = CheckSum + Char; - } - PacketData[Index] = '\0'; - - if (Index == PacketDataSize) { - continue; - } - - SumString[0] = GdbGetChar (); - SumString[1] = GdbGetChar (); - SumString[2] = '\0'; - - if (AsciiStrHexToUintn (SumString) == CheckSum) { - // Ack: Success - GdbPutChar ('+'); - - // Null terminate the callers string - PacketData[Index] = '\0'; - return Index; - } else { - // Ack: Failure - GdbPutChar ('-'); - } - } - - //return 0; -} - - -/** - Empties the given buffer - @param Buf pointer to the first element in buffer to be emptied - **/ -VOID -EmptyBuffer ( - IN CHAR8 *Buf - ) -{ - *Buf = '\0'; -} - - -/** - 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 - ) -{ - if ((Char >= 'A') && (Char <= 'F')) { - return Char - 'A' + 10; - } else if ((Char >= 'a') && (Char <= 'f')) { - return Char - 'a' + 10; - } else if ((Char >= '0') && (Char <= '9')) { - return Char - '0'; - } else { // if not a hex value, return a negative value - return -1; - } -} - - // 'E' + the biggest error number is 255, so its 2 hex digits + buffer end -CHAR8 *gError = "E__"; - -/** '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 - ) -{ - // - // Replace _, or old data, with current errno - // - gError[1] = mHexToStr [ErrorNum >> 4]; - gError[2] = mHexToStr [ErrorNum & 0x0f]; - - SendPacket (gError); // send buffer -} - - - -/** - Send 'OK' when the function is done executing successfully. - **/ -VOID -EFIAPI -SendSuccess ( - VOID - ) -{ - SendPacket ("OK"); // send buffer -} - - -/** - Send empty packet to specify that particular command/functionality is not supported. - **/ -VOID -EFIAPI -SendNotSupported ( - VOID - ) -{ - SendPacket (""); -} - - - - - -/** - 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 - ) -{ - UINTN i; - - for (i=0; i < MaxEfiException() ; i++) { - if (gExceptionType[i].Exception == EFIExceptionType) { - return gExceptionType[i].SignalNo; - } - } - return GDB_SIGTRAP; // this is a GDB trap -} - - -/** "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. - **/ - -VOID -EFIAPI -ReadFromMemory ( - CHAR8 *PacketData - ) -{ - UINTN Address; - UINTN Length; - CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars - CHAR8 *AddrBufPtr; // pointer to the address buffer - CHAR8 *InBufPtr; /// pointer to the input buffer - - AddrBufPtr = AddressBuffer; - InBufPtr = &PacketData[1]; - while (*InBufPtr != ',') { - *AddrBufPtr++ = *InBufPtr++; - } - *AddrBufPtr = '\0'; - - InBufPtr++; // this skips ',' in the buffer - - /* Error checking */ - if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) { - SendError (GDB_EBADMEMADDRBUFSIZE); - return; - } - - // 2 = 'm' + ',' - if (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - 2 >= MAX_LENGTH_SIZE) { - SendError (GDB_EBADMEMLENGTH); - return; - } - - Address = AsciiStrHexToUintn (AddressBuffer); - Length = AsciiStrHexToUintn (InBufPtr); - - TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address); -} - - -/** "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. - **/ -VOID -EFIAPI -WriteToMemory ( - IN CHAR8 *PacketData - ) -{ - UINTN Address; - UINTN Length; - UINTN MessageLength; - CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the Address in hex chars - CHAR8 LengthBuffer[MAX_LENGTH_SIZE]; // the buffer that will hold the Length in hex chars - CHAR8 *AddrBufPtr; // pointer to the Address buffer - CHAR8 *LengthBufPtr; // pointer to the Length buffer - CHAR8 *InBufPtr; /// pointer to the input buffer - - AddrBufPtr = AddressBuffer; - LengthBufPtr = LengthBuffer; - InBufPtr = &PacketData[1]; - - while (*InBufPtr != ',') { - *AddrBufPtr++ = *InBufPtr++; - } - *AddrBufPtr = '\0'; - - InBufPtr++; // this skips ',' in the buffer - - while (*InBufPtr != ':') { - *LengthBufPtr++ = *InBufPtr++; - } - *LengthBufPtr = '\0'; - - InBufPtr++; // this skips ':' in the buffer - - Address = AsciiStrHexToUintn (AddressBuffer); - Length = AsciiStrHexToUintn (LengthBuffer); - - /* Error checking */ - - //Check if Address is not too long. - if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) { - SendError (GDB_EBADMEMADDRBUFSIZE); - return; - } - - //Check if message length is not too long - if (AsciiStrLen(LengthBuffer) >= MAX_LENGTH_SIZE) { - SendError (GDB_EBADMEMLENGBUFSIZE); - return; - } - - // Check if Message is not too long/short. - // 3 = 'M' + ',' + ':' - MessageLength = (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - AsciiStrLen(LengthBuffer) - 3); - if (MessageLength != (2*Length)) { - //Message too long/short. New data is not the right size. - SendError (GDB_EBADMEMDATASIZE); - return; - } - TransferFromInBufToMem (Length, (unsigned char *)Address, InBufPtr); -} - -/** - Parses breakpoint packet data and captures Breakpoint type, Address and length. - In case of an error, function returns particular error code. Returning 0 meaning - no error. - - @param PacketData Pointer to the payload data for the packet. - @param Type Breakpoint type - @param Address Breakpoint address - @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte) - - @retval 1 Success - @retval {other} Particular error code - -**/ -UINTN -ParseBreakpointPacket ( - IN CHAR8 *PacketData, - OUT UINTN *Type, - OUT UINTN *Address, - OUT UINTN *Length - ) -{ - CHAR8 AddressBuffer[MAX_ADDR_SIZE]; - CHAR8 *AddressBufferPtr; - CHAR8 *PacketDataPtr; - - PacketDataPtr = &PacketData[1]; - AddressBufferPtr = AddressBuffer; - - *Type = AsciiStrHexToUintn (PacketDataPtr); - - //Breakpoint/watchpoint type should be between 0 to 4 - if (*Type > 4) { - return 22; //EINVAL: Invalid argument. - } - - //Skip ',' in the buffer. - while (*PacketDataPtr++ != ','); - - //Parse Address information - while (*PacketDataPtr != ',') { - *AddressBufferPtr++ = *PacketDataPtr++; - } - *AddressBufferPtr = '\0'; - - //Check if Address is not too long. - if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) { - return 40; //EMSGSIZE: Message size too long. - } - - *Address = AsciiStrHexToUintn (AddressBuffer); - - PacketDataPtr++; //This skips , in the buffer - - //Parse Length information - *Length = AsciiStrHexToUintn (PacketDataPtr); - - //Length should be 1, 2 or 4 bytes - if (*Length > 4) { - return 22; //EINVAL: Invalid argument - } - - return 0; //0 = No error -} - - - -/** - 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 - ) -{ - CHAR8 TSignalBuffer[128]; - CHAR8 *TSignalPtr; - - TSignalPtr = &TSignalBuffer[0]; - - //Construct TSignal packet - *TSignalPtr++ = 'T'; - - // - // replace _, or previous value, with Exception type - // - *TSignalPtr++ = mHexToStr [GdbExceptionType >> 4]; - *TSignalPtr++ = mHexToStr [GdbExceptionType & 0x0f]; - - ProcessorSendTSignal (SystemContext, GdbExceptionType, TSignalPtr, sizeof (TSignalBuffer) - 2); - - SendPacket (TSignalBuffer); -} - -VOID -GdbFWrite ( - IN UINTN Fd, - IN CHAR8 *Data, - IN UINTN DataSize - ) -{ - CHAR8 Buffer[128]; - - AsciiSPrint (Buffer, sizeof (Buffer), "Fwrite,%x,%x,%x", Fd, Data, DataSize); - SendPacket (Buffer); - - for( ; ; ) { - ReceivePacket (gInBuffer, MAX_BUF_SIZE); - - switch (gInBuffer[0]) { - case 'm': - ReadFromMemory (gInBuffer); - break; - - case 'M': - WriteToMemory (gInBuffer); - break; - - case 'F': - return; - } - } -} - - -VOID -GdbFPutString ( - IN CHAR8 *String - ) -{ - UINTN Len = AsciiStrSize (String); - - GdbFWrite (2, String, Len); -} - - -/** - 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 - ) -{ - UINT8 GdbExceptionType; - CHAR8 *Ptr; - - if (ProcessorControlC (ExceptionType, SystemContext)) { - // We tried to process a control C handler and there is nothing to do - return; - } - - GdbExceptionType = ConvertEFItoGDBtype (ExceptionType); - GdbSendTSignal (SystemContext, GdbExceptionType); - - for( ; ; ) { - ReceivePacket (gInBuffer, MAX_BUF_SIZE); - - switch (gInBuffer[0]) { - case '?': - GdbSendTSignal (SystemContext, GdbExceptionType); - break; - - case 'c': - ContinueAtAddress (SystemContext, gInBuffer); - return; - - case 'D': - // gdb wants to disconnect so return "OK" packet since. - SendSuccess (); - return; - - case 'g': - ReadGeneralRegisters (SystemContext); - break; - - case 'G': - WriteGeneralRegisters (SystemContext, gInBuffer); - break; - - case 'H': - //Return "OK" packet since we don't have more than one thread. - SendSuccess (); - break; - - case 'm': - ReadFromMemory (gInBuffer); - break; - - case 'M': - WriteToMemory (gInBuffer); - break; - - case 'P': - WriteNthRegister (SystemContext, gInBuffer); - break; - - // - // Still debugging this code. Not used in Darwin - // - case 'q': - // General Query Packets - if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) { - // return what we currently support, we don't parse what gdb suports - AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE); - SendPacket (gOutBuffer); - } else if (AsciiStrnCmp (gInBuffer, "qXfer:libraries:read::", 22) == 0) { - // ‘qXfer:libraries:read::offset,length - // gInBuffer[22] is offset string, ++Ptr is length string’ - for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++); - - // Not sure if multi-radix support is required. Currently only support decimal - QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr)); - } else if (AsciiStrnCmp (gInBuffer, "qOffsets", 8) == 0) { - AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "Text=1000;Data=f000;Bss=f000"); - SendPacket (gOutBuffer); - } else if (AsciiStrnCmp (gInBuffer, "qAttached", 9) == 0) { - // remote server attached to an existing process - SendPacket ("1"); - } else { - //Send empty packet - SendNotSupported (); - } - break; - - case 's': - SingleStep (SystemContext, gInBuffer); - return; - - case 'z': - RemoveBreakPoint (SystemContext, gInBuffer); - break; - - case 'Z': - InsertBreakPoint (SystemContext, gInBuffer); - break; - - default: - //Send empty packet - SendNotSupported (); - break; - } - } -} - - - - - diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c b/EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c deleted file mode 100644 index f1d7f3f1098a..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c +++ /dev/null @@ -1,951 +0,0 @@ -/** @file - Processor specific parts of the 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. - -**/ - -#include - -// -// Array of exception types that need to be hooked by the debugger -// {EFI mapping, GDB mapping} -// -EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = { - { EXCEPT_IA32_DIVIDE_ERROR, GDB_SIGFPE }, - { EXCEPT_IA32_DEBUG, GDB_SIGTRAP }, - { EXCEPT_IA32_NMI, GDB_SIGEMT }, - { EXCEPT_IA32_BREAKPOINT, GDB_SIGTRAP }, - { EXCEPT_IA32_OVERFLOW, GDB_SIGSEGV }, - { EXCEPT_IA32_BOUND, GDB_SIGSEGV }, - { EXCEPT_IA32_INVALID_OPCODE, GDB_SIGILL }, - { EXCEPT_IA32_DOUBLE_FAULT, GDB_SIGEMT }, - { EXCEPT_IA32_STACK_FAULT, GDB_SIGSEGV }, - { EXCEPT_IA32_GP_FAULT, GDB_SIGSEGV }, - { EXCEPT_IA32_PAGE_FAULT, GDB_SIGSEGV }, - { EXCEPT_IA32_FP_ERROR, GDB_SIGEMT }, - { EXCEPT_IA32_ALIGNMENT_CHECK, GDB_SIGEMT }, - { EXCEPT_IA32_MACHINE_CHECK, GDB_SIGEMT } -}; - - -// The offsets of registers SystemContext. -// The fields in the array are in the gdb ordering. -// -//16 regs -UINTN gRegisterOffsets[] = { - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eax), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ecx), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edx), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebx), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esp), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebp), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esi), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edi), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eip), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eflags), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Cs), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ss), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ds), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Es), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Fs), - OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Gs) -}; - - -//Debug only.. -VOID -PrintReg ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - Print ((CHAR16 *)L"EAX: %x ", SystemContext.SystemContextIa32->Eax); - Print ((CHAR16 *)L"ECX: %x ", SystemContext.SystemContextIa32->Ecx); - Print ((CHAR16 *)L"EDX: %x ", SystemContext.SystemContextIa32->Edx); - Print ((CHAR16 *)L"EBX: %x ", SystemContext.SystemContextIa32->Ebx); - Print ((CHAR16 *)L"ESP: %x ", SystemContext.SystemContextIa32->Esp); - Print ((CHAR16 *)L"EBP: %x ", SystemContext.SystemContextIa32->Ebp); - Print ((CHAR16 *)L"ESI: %x ", SystemContext.SystemContextIa32->Esi); - Print ((CHAR16 *)L"EDI: %x ", SystemContext.SystemContextIa32->Edi); - Print ((CHAR16 *)L"EIP: %x\n", SystemContext.SystemContextIa32->Eip); - Print ((CHAR16 *)L"EFlags: %x\n", SystemContext.SystemContextIa32->Eflags); -} - -//Debug only.. -VOID -PrintDRreg ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - Print ((CHAR16 *)L"DR0: %x ", SystemContext.SystemContextIa32->Dr0); - Print ((CHAR16 *)L"DR1: %x ", SystemContext.SystemContextIa32->Dr1); - Print ((CHAR16 *)L"DR2: %x ", SystemContext.SystemContextIa32->Dr2); - Print ((CHAR16 *)L"DR3: %x ", SystemContext.SystemContextIa32->Dr3); - Print ((CHAR16 *)L"DR6: %x ", SystemContext.SystemContextIa32->Dr6); - Print ((CHAR16 *)L"DR7: %x\n", SystemContext.SystemContextIa32->Dr7); -} - - -/** - Return the number of entries in the gExceptionType[] - - @retval UINTN, the number of entries in the gExceptionType[] array. - **/ -UINTN -MaxEfiException ( - VOID - ) -{ - return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY); -} - - -/** - 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 - ) -{ - return (BOOLEAN)(Isa == IsaIa32); -} - - -/** - This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering - It is, by default, set to find the register pointer of the IA32 member - - @param SystemContext Register content at time of the exception - @param RegNumber The register to which we want to find a pointer - @retval the pointer to the RegNumber-th pointer - **/ -UINTN * -FindPointerToRegister( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber - ) -{ - UINT8 *TempPtr; - TempPtr = ((UINT8 *)SystemContext.SystemContextIa32) + gRegisterOffsets[RegNumber]; - return (UINTN *)TempPtr; -} - - -/** - Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr - - @param SystemContext Register content at time of the exception - @param RegNumber the number of the register that we want to read - @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on. - @retval the pointer to the next character of the output buffer that is available to be written on. - **/ -CHAR8 * -BasicReadRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber, - IN CHAR8 *OutBufPtr - ) -{ - UINTN RegSize; - - RegSize = 0; - while (RegSize < REG_SIZE) { - *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)]; - *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)]; - RegSize = RegSize + 8; - } - return OutBufPtr; -} - - -/** ‘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 Pointer to the input buffer received from gdb server - **/ -VOID -EFIAPI -ReadNthRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN RegNumber; - CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq) - CHAR8 *OutBufPtr; // pointer to the output buffer - - RegNumber = AsciiStrHexToUintn (&InBuffer[1]); - - if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) { - SendError (GDB_EINVALIDREGNUM); - return; - } - - OutBufPtr = OutBuffer; - OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr); - - *OutBufPtr = '\0'; // the end of the buffer - SendPacket(OutBuffer); -} - - -/** ‘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 -EFIAPI -ReadGeneralRegisters ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - UINTN i; - CHAR8 OutBuffer[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq) - CHAR8 *OutBufPtr; // pointer to the output buffer - - OutBufPtr = OutBuffer; - for(i = 0 ; i < sizeof (gRegisterOffsets)/sizeof (UINTN) ; i++) { // there are only 16 registers to read - OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr); - } - - *OutBufPtr = '\0'; // the end of the buffer - SendPacket(OutBuffer); -} - - -/** - Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr - - @param SystemContext Register content at time of the exception - @param RegNumber the number of the register that we want to write - @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on. - @retval the pointer to the next character of the input buffer that can be used - **/ -CHAR8 * -BasicWriteRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber, - IN CHAR8 *InBufPtr - ) -{ - UINTN RegSize; - UINTN TempValue; // the value transferred from a hex char - UINT32 NewValue; // the new value of the RegNumber-th Register - - NewValue = 0; - RegSize = 0; - while (RegSize < REG_SIZE) { - TempValue = HexCharToInt(*InBufPtr++); - - if (TempValue < 0) { - SendError (GDB_EBADMEMDATA); - return NULL; - } - - NewValue += (TempValue << (RegSize+4)); - TempValue = HexCharToInt(*InBufPtr++); - - if (TempValue < 0) { - SendError (GDB_EBADMEMDATA); - return NULL; - } - - NewValue += (TempValue << RegSize); - RegSize = RegSize + 8; - } - *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue; - return InBufPtr; -} - - -/** ‘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 Ponter to the input buffer received from gdb server - **/ -VOID -EFIAPI -WriteNthRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN RegNumber; - CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array - CHAR8 *RegNumBufPtr; - CHAR8 *InBufPtr; // pointer to the input buffer - - // find the register number to write - InBufPtr = &InBuffer[1]; - RegNumBufPtr = RegNumBuffer; - while (*InBufPtr != '=') { - *RegNumBufPtr++ = *InBufPtr++; - } - *RegNumBufPtr = '\0'; - RegNumber = AsciiStrHexToUintn (RegNumBuffer); - - // check if this is a valid Register Number - if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) { - SendError (GDB_EINVALIDREGNUM); - return; - } - InBufPtr++; // skips the '=' character - BasicWriteRegister (SystemContext, RegNumber, InBufPtr); - SendSuccess(); -} - - -/** ‘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 -EFIAPI -WriteGeneralRegisters ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN i; - CHAR8 *InBufPtr; /// pointer to the input buffer - - // check to see if the buffer is the right size which is - // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129 - if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq) - //Bad message. Message is not the right length - SendError (GDB_EBADBUFSIZE); - return; - } - - InBufPtr = &InBuffer[1]; - - // Read the new values for the registers from the input buffer to an array, NewValueArray. - // The values in the array are in the gdb ordering - for(i=0; i < sizeof (gRegisterOffsets)/sizeof (UINTN); i++) { // there are only 16 registers to write - InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr); - } - - SendSuccess(); -} - -/** ‘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 - **/ -VOID -EFIAPI -ContinueAtAddress ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - if (PacketData[1] != '\0') { - SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]); - } -} - - -/** ‘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 - **/ -VOID -EFIAPI -SingleStep ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - SendNotSupported(); -} - - -/** - Returns breakpoint data address from DR0-DR3 based on the input breakpoint number - - @param SystemContext Register content at time of the exception - @param BreakpointNumber Breakpoint number - - @retval Address Data address from DR0-DR3 based on the breakpoint number. - -**/ -UINTN -GetBreakpointDataAddress ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN BreakpointNumber - ) -{ - UINTN Address; - - if (BreakpointNumber == 1) { - Address = SystemContext.SystemContextIa32->Dr0; - } else if (BreakpointNumber == 2) { - Address = SystemContext.SystemContextIa32->Dr1; - } else if (BreakpointNumber == 3) { - Address = SystemContext.SystemContextIa32->Dr2; - } else if (BreakpointNumber == 4) { - Address = SystemContext.SystemContextIa32->Dr3; - } else { - Address = 0; - } - - return Address; -} - - -/** - Returns currently detected breakpoint value based on the register DR6 B0-B3 field. - If no breakpoint is detected then it returns 0. - - @param SystemContext Register content at time of the exception - - @retval {1-4} Currently detected breakpoint value - @retval 0 No breakpoint detected. - -**/ -UINTN -GetBreakpointDetected ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - IA32_DR6 Dr6; - UINTN BreakpointNumber; - - Dr6.UintN = SystemContext.SystemContextIa32->Dr6; - - if (Dr6.Bits.B0 == 1) { - BreakpointNumber = 1; - } else if (Dr6.Bits.B1 == 1) { - BreakpointNumber = 2; - } else if (Dr6.Bits.B2 == 1) { - BreakpointNumber = 3; - } else if (Dr6.Bits.B3 == 1) { - BreakpointNumber = 4; - } else { - BreakpointNumber = 0; //No breakpoint detected - } - - return BreakpointNumber; -} - - -/** - Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite) - based on the Breakpoint number - - @param SystemContext Register content at time of the exception - @param BreakpointNumber Breakpoint number - - @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field - For unknown value, it returns NotSupported. - -**/ -BREAK_TYPE -GetBreakpointType ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN BreakpointNumber - ) -{ - IA32_DR7 Dr7; - BREAK_TYPE Type = NotSupported; //Default is NotSupported type - - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (BreakpointNumber == 1) { - Type = (BREAK_TYPE) Dr7.Bits.RW0; - } else if (BreakpointNumber == 2) { - Type = (BREAK_TYPE) Dr7.Bits.RW1; - } else if (BreakpointNumber == 3) { - Type = (BREAK_TYPE) Dr7.Bits.RW2; - } else if (BreakpointNumber == 4) { - Type = (BREAK_TYPE) Dr7.Bits.RW3; - } - - return Type; -} - - -/** - Parses Length and returns the length which DR7 LENn field accepts. - For example: If we receive 1-Byte length then we should return 0. - Zero gets written to DR7 LENn field. - - @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte) - - @retval Length Appropriate converted values which DR7 LENn field accepts. - -**/ -UINTN -ConvertLengthData ( - IN UINTN Length - ) -{ - if (Length == 1) { //1-Byte length - return 0; - } else if (Length == 2) { //2-Byte length - return 1; - } else if (Length == 4) { //4-Byte length - return 3; - } else { //Undefined or 8-byte length - return 2; - } -} - - -/** - Finds the next free debug register. If all the registers are occupied then - EFI_OUT_OF_RESOURCES is returned. - - @param SystemContext Register content at time of the exception - @param Register Register value (0 - 3 for the first free debug register) - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -FindNextFreeDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - OUT UINTN *Register - ) -{ - IA32_DR7 Dr7; - - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (Dr7.Bits.G0 == 0) { - *Register = 0; - } else if (Dr7.Bits.G1 == 0) { - *Register = 1; - } else if (Dr7.Bits.G2 == 0) { - *Register = 2; - } else if (Dr7.Bits.G3 == 0) { - *Register = 3; - } else { - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - - -/** - Enables the debug register. Writes Address value to appropriate DR0-3 register. - Sets LENn, Gn, RWn bits in DR7 register. - - @param SystemContext Register content at time of the exception - @param Register Register value (0 - 3) - @param Address Breakpoint address value - @param Type Breakpoint type (Instruction, Data write, Data read - or write etc.) - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -EnableDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN Register, - IN UINTN Address, - IN UINTN Length, - IN UINTN Type - ) -{ - IA32_DR7 Dr7; - - //Convert length data - Length = ConvertLengthData (Length); - - //For Instruction execution, length should be 0 - //(Ref. Intel reference manual 18.2.4) - if ((Type == 0) && (Length != 0)) { - return EFI_INVALID_PARAMETER; - } - - //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle - //software breakpoint. We should send empty packet in both these cases. - if ((Type == (BREAK_TYPE)DataRead) || - (Type == (BREAK_TYPE)SoftwareBreakpoint)) { - return EFI_UNSUPPORTED; - } - - //Read DR7 so appropriate Gn, RWn and LENn bits can be modified. - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (Register == 0) { - SystemContext.SystemContextIa32->Dr0 = Address; - Dr7.Bits.G0 = 1; - Dr7.Bits.RW0 = Type; - Dr7.Bits.LEN0 = Length; - } else if (Register == 1) { - SystemContext.SystemContextIa32->Dr1 = Address; - Dr7.Bits.G1 = 1; - Dr7.Bits.RW1 = Type; - Dr7.Bits.LEN1 = Length; - } else if (Register == 2) { - SystemContext.SystemContextIa32->Dr2 = Address; - Dr7.Bits.G2 = 1; - Dr7.Bits.RW2 = Type; - Dr7.Bits.LEN2 = Length; - } else if (Register == 3) { - SystemContext.SystemContextIa32->Dr3 = Address; - Dr7.Bits.G3 = 1; - Dr7.Bits.RW3 = Type; - Dr7.Bits.LEN3 = Length; - } else { - return EFI_INVALID_PARAMETER; - } - - //Update Dr7 with appropriate Gn, RWn and LENn bits - SystemContext.SystemContextIa32->Dr7 = Dr7.UintN; - - return EFI_SUCCESS; -} - - -/** - Returns register number 0 - 3 for the maching debug register. - This function compares incoming Address, Type, Length and - if there is a match then it returns the appropriate register number. - In case of mismatch, function returns EFI_NOT_FOUND message. - - @param SystemContext Register content at time of the exception - @param Address Breakpoint address value - @param Length Breakpoint length value - @param Type Breakpoint type (Instruction, Data write, - Data read or write etc.) - @param Register Register value to be returned - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -FindMatchingDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN Address, - IN UINTN Length, - IN UINTN Type, - OUT UINTN *Register - ) -{ - IA32_DR7 Dr7; - - //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle - //software breakpoint. We should send empty packet in both these cases. - if ((Type == (BREAK_TYPE)DataRead) || - (Type == (BREAK_TYPE)SoftwareBreakpoint)) { - return EFI_UNSUPPORTED; - } - - //Convert length data - Length = ConvertLengthData(Length); - - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if ((Dr7.Bits.G0 == 1) && - (Dr7.Bits.LEN0 == Length) && - (Dr7.Bits.RW0 == Type) && - (Address == SystemContext.SystemContextIa32->Dr0)) { - *Register = 0; - } else if ((Dr7.Bits.G1 == 1) && - (Dr7.Bits.LEN1 == Length) && - (Dr7.Bits.RW1 == Type) && - (Address == SystemContext.SystemContextIa32->Dr1)) { - *Register = 1; - } else if ((Dr7.Bits.G2 == 1) && - (Dr7.Bits.LEN2 == Length) && - (Dr7.Bits.RW2 == Type) && - (Address == SystemContext.SystemContextIa32->Dr2)) { - *Register = 2; - } else if ((Dr7.Bits.G3 == 1) && - (Dr7.Bits.LEN3 == Length) && - (Dr7.Bits.RW3 == Type) && - (Address == SystemContext.SystemContextIa32->Dr3)) { - *Register = 3; - } else { - Print ((CHAR16 *)L"No match found..\n"); - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - - -/** - Disables the particular debug register. - - @param SystemContext Register content at time of the exception - @param Register Register to be disabled - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -DisableDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN Register - ) -{ - IA32_DR7 Dr7; - UINTN Address = 0; - - //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off. - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (Register == 0) { - SystemContext.SystemContextIa32->Dr0 = Address; - Dr7.Bits.G0 = 0; - Dr7.Bits.RW0 = 0; - Dr7.Bits.LEN0 = 0; - } else if (Register == 1) { - SystemContext.SystemContextIa32->Dr1 = Address; - Dr7.Bits.G1 = 0; - Dr7.Bits.RW1 = 0; - Dr7.Bits.LEN1 = 0; - } else if (Register == 2) { - SystemContext.SystemContextIa32->Dr2 = Address; - Dr7.Bits.G2 = 0; - Dr7.Bits.RW2 = 0; - Dr7.Bits.LEN2 = 0; - } else if (Register == 3) { - SystemContext.SystemContextIa32->Dr3 = Address; - Dr7.Bits.G3 = 0; - Dr7.Bits.RW3 = 0; - Dr7.Bits.LEN3 = 0; - } else { - return EFI_INVALID_PARAMETER; - } - - //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off. - SystemContext.SystemContextIa32->Dr7 = Dr7.UintN; - - return EFI_SUCCESS; -} - - -/** - ‘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 - ) -{ - UINTN Type; - UINTN Address; - UINTN Length; - UINTN Register; - EFI_STATUS Status; - BREAK_TYPE BreakType = NotSupported; - UINTN ErrorCode; - - ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length); - if (ErrorCode > 0) { - SendError ((UINT8)ErrorCode); - return; - } - - switch (Type) { - - case 0: //Software breakpoint - BreakType = SoftwareBreakpoint; - break; - - case 1: //Hardware breakpoint - BreakType = InstructionExecution; - break; - - case 2: //Write watchpoint - BreakType = DataWrite; - break; - - case 3: //Read watchpoint - BreakType = DataRead; - break; - - case 4: //Access watchpoint - BreakType = DataReadWrite; - break; - - default : - Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type); - SendError (GDB_EINVALIDBRKPOINTTYPE); - return; - } - - // Find next free debug register - Status = FindNextFreeDebugRegister (SystemContext, &Register); - if (EFI_ERROR(Status)) { - Print ((CHAR16 *)L"No space left on device\n"); - SendError (GDB_ENOSPACE); - return; - } - - // Write Address, length data at particular DR register - Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType); - if (EFI_ERROR(Status)) { - if (Status == EFI_UNSUPPORTED) { - SendNotSupported(); - return; - } - - SendError (GDB_EINVALIDARG); - return; - } - - SendSuccess (); -} - - -/** - ‘z1, [addr], [length]’ - ‘z2, [addr], [length]’ - ‘z3, [addr], [length]’ - ‘z4, [addr], [length]’ - - Remove hardware breakpoint/watchpoint at address addr of size length - - @param *PacketData Pointer to the Payload data for the packet - -**/ -VOID -EFIAPI -RemoveBreakPoint ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - UINTN Type; - UINTN Address; - UINTN Length; - UINTN Register; - BREAK_TYPE BreakType = NotSupported; - EFI_STATUS Status; - UINTN ErrorCode; - - //Parse breakpoint packet data - ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length); - if (ErrorCode > 0) { - SendError ((UINT8)ErrorCode); - return; - } - - switch (Type) { - - case 0: //Software breakpoint - BreakType = SoftwareBreakpoint; - break; - - case 1: //Hardware breakpoint - BreakType = InstructionExecution; - break; - - case 2: //Write watchpoint - BreakType = DataWrite; - break; - - case 3: //Read watchpoint - BreakType = DataRead; - break; - - case 4: //Access watchpoint - BreakType = DataReadWrite; - break; - - default : - SendError (GDB_EINVALIDBRKPOINTTYPE); - return; - } - - //Find matching debug register - Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register); - if (EFI_ERROR(Status)) { - if (Status == EFI_UNSUPPORTED) { - SendNotSupported(); - return; - } - - SendError (GDB_ENOSPACE); - return; - } - - //Remove breakpoint - Status = DisableDebugRegister(SystemContext, Register); - if (EFI_ERROR(Status)) { - SendError (GDB_EINVALIDARG); - return; - } - - SendSuccess (); -} - - -/** - Initialize debug agent. - - This function is used to set up debug environment to support source level debugging. - If certain Debug Agent Library instance has to save some private data in the stack, - this function must work on the mode that doesn't return to the caller, then - the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one - function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is - responsible to invoke the passing-in function at the end of InitializeDebugAgent(). - - If the parameter Function is not NULL, Debug Agent Library instance will invoke it by - passing in the Context to be its parameter. - - If Function() is NULL, Debug Agent Library instance will return after setup debug - environment. - - @param[in] InitFlag Init flag is used to decide the initialize process. - @param[in] Context Context needed according to InitFlag; it was optional. - @param[in] Function Continue function called by debug agent library; it was - optional. - -**/ -VOID -EFIAPI -InitializeDebugAgent ( - IN UINT32 InitFlag, - IN VOID *Context, OPTIONAL - IN DEBUG_AGENT_CONTINUE Function OPTIONAL - ) -{ - // BugBug: Add the code to build an GDT/IDT - - if (Function != NULL) { - Function (Context); - } -} - diff --git a/EmbeddedPkg/Library/GdbDebugAgent/X64/Processor.c b/EmbeddedPkg/Library/GdbDebugAgent/X64/Processor.c deleted file mode 100644 index cbe50d78ec09..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/X64/Processor.c +++ /dev/null @@ -1,963 +0,0 @@ -/** @file - Processor specific parts of the 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. - -**/ - -#include - -// -// Array of exception types that need to be hooked by the debugger -// -EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = { - { EXCEPT_X64_DIVIDE_ERROR, GDB_SIGFPE }, - { EXCEPT_X64_DEBUG, GDB_SIGTRAP }, - { EXCEPT_X64_NMI, GDB_SIGEMT }, - { EXCEPT_X64_BREAKPOINT, GDB_SIGTRAP }, - { EXCEPT_X64_OVERFLOW, GDB_SIGSEGV }, - { EXCEPT_X64_BOUND, GDB_SIGSEGV }, - { EXCEPT_X64_INVALID_OPCODE, GDB_SIGILL }, - { EXCEPT_X64_DOUBLE_FAULT, GDB_SIGEMT }, - { EXCEPT_X64_STACK_FAULT, GDB_SIGSEGV }, - { EXCEPT_X64_GP_FAULT, GDB_SIGSEGV }, - { EXCEPT_X64_PAGE_FAULT, GDB_SIGSEGV }, - { EXCEPT_X64_FP_ERROR, GDB_SIGEMT }, - { EXCEPT_X64_ALIGNMENT_CHECK, GDB_SIGEMT }, - { EXCEPT_X64_MACHINE_CHECK, GDB_SIGEMT } -}; - - -// The offsets of registers SystemContextX64. -// The fields in the array are in the gdb ordering. -// HAVE TO DOUBLE-CHECK THE ORDER of the 24 regs -// -UINTN gRegisterOffsets[] = { - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rax), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rcx), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rdx), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rbx), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rsp), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rbp), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rsi), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rdi), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rip), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rflags), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Cs), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Ss), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Ds), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Es), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Fs), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Gs), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R8), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R9), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R10), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R11), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R12), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R13), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R14), - OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R15) -}; - - -/** - Return the number of entries in the gExceptionType[] - - @retval UINTN, the number of entries in the gExceptionType[] array. - **/ -UINTN -MaxEfiException ( - VOID - ) -{ - return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY); -} - - -/** - Return the number of entries in the gRegisters[] - - @retval UINTN, the number of entries (registers) in the gRegisters[] array. - **/ -UINTN -MaxRegisterCount ( - VOID - ) -{ - return sizeof (gRegisterOffsets)/sizeof (UINTN); -} - - -/** - Check to see if the ISA is supported. - ISA = Instruction Set Architecture - - @retval TRUE if Isa is supported -**/ -BOOLEAN -CheckIsa ( - IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa - ) -{ - return (BOOLEAN)(Isa == IsaX64); -} - - -/** - This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering - It is, by default, set to find the register pointer of the X64 member - @param SystemContext Register content at time of the exception - @param RegNumber The register to which we want to find a pointer - @retval the pointer to the RegNumber-th pointer - **/ -UINTN * -FindPointerToRegister( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber - ) -{ - UINT8 *TempPtr; - TempPtr = ((UINT8 *)SystemContext.SystemContextX64) + gRegisterOffsets[RegNumber]; - return (UINTN *)TempPtr; -} - - -/** - Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr - @param SystemContext Register content at time of the exception - @param RegNumber the number of the register that we want to read - @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on. - @retval the pointer to the next character of the output buffer that is available to be written on. - **/ -CHAR8 * -BasicReadRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber, - IN CHAR8 *OutBufPtr - ) -{ - UINTN RegSize; - - RegSize = 0; - while (RegSize < 64) { - *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)]; - *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)]; - RegSize = RegSize + 8; - } - return OutBufPtr; -} - - -/** ‘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 Pointer to the input buffer received from gdb server - **/ -VOID -ReadNthRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN RegNumber; - CHAR8 OutBuffer[17]; // 1 reg=16 hex chars, and the end '\0' (escape seq) - CHAR8 *OutBufPtr; // pointer to the output buffer - - RegNumber = AsciiStrHexToUintn (&InBuffer[1]); - - if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) { - SendError (GDB_EINVALIDREGNUM); - return; - } - - OutBufPtr = OutBuffer; - OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr); - - *OutBufPtr = '\0'; // the end of the buffer - SendPacket (OutBuffer); -} - - -/** ‘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 -EFIAPI -ReadGeneralRegisters ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - UINTN i; - CHAR8 OutBuffer[385]; // 24 regs, 16 hex chars each, and the end '\0' (escape seq) - CHAR8 *OutBufPtr; // pointer to the output buffer - - OutBufPtr = OutBuffer; - for(i = 0 ; i < MaxRegisterCount() ; i++) { // there are only 24 registers to read - OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr); - } - - *OutBufPtr = '\0'; // the end of the buffer - SendPacket (OutBuffer); -} - - -/** - Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr - - @param SystemContext Register content at time of the exception - @param RegNumber the number of the register that we want to write - @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on. - @retval the pointer to the next character of the input buffer that can be used - **/ -CHAR8 * -BasicWriteRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN RegNumber, - IN CHAR8 *InBufPtr - ) -{ - UINTN RegSize; - UINTN TempValue; // the value transferred from a hex char - UINT64 NewValue; // the new value of the RegNumber-th Register - - NewValue = 0; - RegSize = 0; - while (RegSize < 64) { - TempValue = HexCharToInt(*InBufPtr++); - - if (TempValue < 0) { - SendError (GDB_EBADMEMDATA); - return NULL; - } - - NewValue += (TempValue << (RegSize+4)); - TempValue = HexCharToInt(*InBufPtr++); - - if (TempValue < 0) { - SendError (GDB_EBADMEMDATA); - return NULL; - } - - NewValue += (TempValue << RegSize); - RegSize = RegSize + 8; - } - *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue; - return InBufPtr; -} - - -/** ‘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 Ponter to the input buffer received from gdb server - **/ -VOID -EFIAPI -WriteNthRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN RegNumber; - CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array - CHAR8 *RegNumBufPtr; - CHAR8 *InBufPtr; // pointer to the input buffer - - // find the register number to write - InBufPtr = &InBuffer[1]; - RegNumBufPtr = RegNumBuffer; - while (*InBufPtr != '=') { - *RegNumBufPtr++ = *InBufPtr++; - } - *RegNumBufPtr = '\0'; - RegNumber = AsciiStrHexToUintn (RegNumBuffer); - - // check if this is a valid Register Number - if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) { - SendError (GDB_EINVALIDREGNUM); - return; - } - InBufPtr++; // skips the '=' character - BasicWriteRegister (SystemContext, RegNumber, InBufPtr); - SendSuccess(); -} - - -/** ‘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 -EFIAPI -WriteGeneralRegisters ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *InBuffer - ) -{ - UINTN i; - CHAR8 *InBufPtr; /// pointer to the input buffer - - // check to see if the buffer is the right size which is - // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 385 - if (AsciiStrLen(InBuffer) != 385) { // 24 regs, 16 hex chars each, and the end '\0' (escape seq) - //Bad message. Message is not the right length - SendError (GDB_EBADBUFSIZE); - return; - } - - InBufPtr = &InBuffer[1]; - - // Read the new values for the registers from the input buffer to an array, NewValueArray. - // The values in the array are in the gdb ordering - for(i=0; i < MaxRegisterCount(); i++) { // there are only 16 registers to write - InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr); - } - - SendSuccess(); -} - - - /** - Insert Single Step in the SystemContext - - @param SystemContext Register content at time of the exception - **/ -VOID -AddSingleStep ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - SystemContext.SystemContextX64->Rflags |= TF_BIT; //Setting the TF bit. -} - - - -/** - Remove Single Step in the SystemContext - - @param SystemContext Register content at time of the exception - **/ -VOID -RemoveSingleStep ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - SystemContext.SystemContextX64->Rflags &= ~TF_BIT; // clearing the TF bit. -} - - - -/** ‘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 - **/ -VOID -EFIAPI -ContinueAtAddress ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - if (PacketData[1] != '\0') { - SystemContext.SystemContextX64->Rip = AsciiStrHexToUintn(&PacketData[1]); - } -} - - -/** ‘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 - **/ -VOID -EFIAPI -SingleStep ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - if (PacketData[1] != '\0') { - SystemContext.SystemContextX64->Rip = AsciiStrHexToUintn (&PacketData[1]); - } - - AddSingleStep (SystemContext); -} - - -/** - Returns breakpoint data address from DR0-DR3 based on the input breakpoint - number - - @param SystemContext Register content at time of the exception - @param BreakpointNumber Breakpoint number - - @retval Address Data address from DR0-DR3 based on the - breakpoint number. - -**/ -UINTN -GetBreakpointDataAddress ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN BreakpointNumber - ) -{ - UINTN Address; - - if (BreakpointNumber == 1) { - Address = SystemContext.SystemContextIa32->Dr0; - } else if (BreakpointNumber == 2) { - Address = SystemContext.SystemContextIa32->Dr1; - } else if (BreakpointNumber == 3) { - Address = SystemContext.SystemContextIa32->Dr2; - } else if (BreakpointNumber == 4) { - Address = SystemContext.SystemContextIa32->Dr3; - } else { - Address = 0; - } - - return Address; -} - -/** - Returns currently detected breakpoint value based on the register - DR6 B0-B3 field. - If no breakpoint is detected then it returns 0. - - @param SystemContext Register content at time of the exception - - @retval {1-4} Currently detected breakpoint value - @retval 0 No breakpoint detected. - -**/ -UINTN -GetBreakpointDetected ( - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - IA32_DR6 Dr6; - UINTN BreakpointNumber; - - Dr6.UintN = SystemContext.SystemContextIa32->Dr6; - - if (Dr6.Bits.B0 == 1) { - BreakpointNumber = 1; - } else if (Dr6.Bits.B1 == 1) { - BreakpointNumber = 2; - } else if (Dr6.Bits.B2 == 1) { - BreakpointNumber = 3; - } else if (Dr6.Bits.B3 == 1) { - BreakpointNumber = 4; - } else { - BreakpointNumber = 0; //No breakpoint detected - } - - return BreakpointNumber; -} - -/** - Returns Breakpoint type (InstructionExecution, DataWrite, DataRead - or DataReadWrite) based on the Breakpoint number - - @param SystemContext Register content at time of the exception - @param BreakpointNumber Breakpoint number - - @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn - field. For unknown value, it returns NotSupported. - -**/ -BREAK_TYPE -GetBreakpointType ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN BreakpointNumber - ) -{ - IA32_DR7 Dr7; - BREAK_TYPE Type = NotSupported; //Default is NotSupported type - - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (BreakpointNumber == 1) { - Type = (BREAK_TYPE) Dr7.Bits.RW0; - } else if (BreakpointNumber == 2) { - Type = (BREAK_TYPE) Dr7.Bits.RW1; - } else if (BreakpointNumber == 3) { - Type = (BREAK_TYPE) Dr7.Bits.RW2; - } else if (BreakpointNumber == 4) { - Type = (BREAK_TYPE) Dr7.Bits.RW3; - } - - return Type; -} - - -/** - Parses Length and returns the length which DR7 LENn field accepts. - For example: If we receive 1-Byte length then we should return 0. - Zero gets written to DR7 LENn field. - - @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte) - - @retval Length Appropriate converted values which DR7 LENn field accepts. - -**/ -UINTN -ConvertLengthData ( - IN UINTN Length - ) -{ - if (Length == 1) { //1-Byte length - return 0; - } else if (Length == 2) { //2-Byte length - return 1; - } else if (Length == 4) { //4-Byte length - return 3; - } else { //Undefined or 8-byte length - return 2; - } -} - - -/** - Finds the next free debug register. If all the registers are occupied then - EFI_OUT_OF_RESOURCES is returned. - - @param SystemContext Register content at time of the exception - @param Register Register value (0 - 3 for the first free debug register) - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -FindNextFreeDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - OUT UINTN *Register - ) -{ - IA32_DR7 Dr7; - - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (Dr7.Bits.G0 == 0) { - *Register = 0; - } else if (Dr7.Bits.G1 == 0) { - *Register = 1; - } else if (Dr7.Bits.G2 == 0) { - *Register = 2; - } else if (Dr7.Bits.G3 == 0) { - *Register = 3; - } else { - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - - -/** - Enables the debug register. Writes Address value to appropriate DR0-3 register. - Sets LENn, Gn, RWn bits in DR7 register. - - @param SystemContext Register content at time of the exception - @param Register Register value (0 - 3) - @param Address Breakpoint address value - @param Type Breakpoint type (Instruction, Data write, - Data read or write etc.) - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -EnableDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN Register, - IN UINTN Address, - IN UINTN Length, - IN UINTN Type - ) -{ - IA32_DR7 Dr7; - - //Convert length data - Length = ConvertLengthData (Length); - - //For Instruction execution, length should be 0 - //(Ref. Intel reference manual 18.2.4) - if ((Type == 0) && (Length != 0)) { - return EFI_INVALID_PARAMETER; - } - - //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle - //software breakpoint. We should send empty packet in both these cases. - if ((Type == (BREAK_TYPE)DataRead) || - (Type == (BREAK_TYPE)SoftwareBreakpoint)) { - return EFI_UNSUPPORTED; - } - - //Read DR7 so appropriate Gn, RWn and LENn bits can be modified. - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (Register == 0) { - SystemContext.SystemContextIa32->Dr0 = Address; - Dr7.Bits.G0 = 1; - Dr7.Bits.RW0 = Type; - Dr7.Bits.LEN0 = Length; - } else if (Register == 1) { - SystemContext.SystemContextIa32->Dr1 = Address; - Dr7.Bits.G1 = 1; - Dr7.Bits.RW1 = Type; - Dr7.Bits.LEN1 = Length; - } else if (Register == 2) { - SystemContext.SystemContextIa32->Dr2 = Address; - Dr7.Bits.G2 = 1; - Dr7.Bits.RW2 = Type; - Dr7.Bits.LEN2 = Length; - } else if (Register == 3) { - SystemContext.SystemContextIa32->Dr3 = Address; - Dr7.Bits.G3 = 1; - Dr7.Bits.RW3 = Type; - Dr7.Bits.LEN3 = Length; - } else { - return EFI_INVALID_PARAMETER; - } - - //Update Dr7 with appropriate Gn, RWn and LENn bits - SystemContext.SystemContextIa32->Dr7 = Dr7.UintN; - - return EFI_SUCCESS; -} - - -/** - Returns register number 0 - 3 for the maching debug register. - This function compares incoming Address, Type, Length and - if there is a match then it returns the appropriate register number. - In case of mismatch, function returns EFI_NOT_FOUND message. - - @param SystemContext Register content at time of the exception - @param Address Breakpoint address value - @param Length Breakpoint length value - @param Type Breakpoint type (Instruction, Data write, Data read - or write etc.) - @param Register Register value to be returned - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -FindMatchingDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN Address, - IN UINTN Length, - IN UINTN Type, - OUT UINTN *Register - ) -{ - IA32_DR7 Dr7; - - //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle - //software breakpoint. We should send empty packet in both these cases. - if ((Type == (BREAK_TYPE)DataRead) || - (Type == (BREAK_TYPE)SoftwareBreakpoint)) { - return EFI_UNSUPPORTED; - } - - //Convert length data - Length = ConvertLengthData(Length); - - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if ((Dr7.Bits.G0 == 1) && - (Dr7.Bits.LEN0 == Length) && - (Dr7.Bits.RW0 == Type) && - (Address == SystemContext.SystemContextIa32->Dr0)) { - *Register = 0; - } else if ((Dr7.Bits.G1 == 1) && - (Dr7.Bits.LEN1 == Length) && - (Dr7.Bits.RW1 == Type) && - (Address == SystemContext.SystemContextIa32->Dr1)) { - *Register = 1; - } else if ((Dr7.Bits.G2 == 1) && - (Dr7.Bits.LEN2 == Length) && - (Dr7.Bits.RW2 == Type) && - (Address == SystemContext.SystemContextIa32->Dr2)) { - *Register = 2; - } else if ((Dr7.Bits.G3 == 1) && - (Dr7.Bits.LEN3 == Length) && - (Dr7.Bits.RW3 == Type) && - (Address == SystemContext.SystemContextIa32->Dr3)) { - *Register = 3; - } else { - Print ((CHAR16 *)L"No match found..\n"); - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - - -/** - Disables the particular debug register. - - @param SystemContext Register content at time of the exception - @param Register Register to be disabled - - @retval EFI_STATUS Appropriate status value. - -**/ -EFI_STATUS -DisableDebugRegister ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN UINTN Register - ) -{ - IA32_DR7 Dr7; - UINTN Address = 0; - - //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off. - Dr7.UintN = SystemContext.SystemContextIa32->Dr7; - - if (Register == 0) { - SystemContext.SystemContextIa32->Dr0 = Address; - Dr7.Bits.G0 = 0; - Dr7.Bits.RW0 = 0; - Dr7.Bits.LEN0 = 0; - } else if (Register == 1) { - SystemContext.SystemContextIa32->Dr1 = Address; - Dr7.Bits.G1 = 0; - Dr7.Bits.RW1 = 0; - Dr7.Bits.LEN1 = 0; - } else if (Register == 2) { - SystemContext.SystemContextIa32->Dr2 = Address; - Dr7.Bits.G2 = 0; - Dr7.Bits.RW2 = 0; - Dr7.Bits.LEN2 = 0; - } else if (Register == 3) { - SystemContext.SystemContextIa32->Dr3 = Address; - Dr7.Bits.G3 = 0; - Dr7.Bits.RW3 = 0; - Dr7.Bits.LEN3 = 0; - } else { - return EFI_INVALID_PARAMETER; - } - - //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off. - SystemContext.SystemContextIa32->Dr7 = Dr7.UintN; - - return EFI_SUCCESS; -} - -/** - ‘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 - ) -{ - UINTN Type; - UINTN Address; - UINTN Length; - UINTN Register; - EFI_STATUS Status; - BREAK_TYPE BreakType = NotSupported; - UINTN ErrorCode; - - ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length); - if (ErrorCode > 0) { - SendError ((UINT8)ErrorCode); - return; - } - - switch (Type) { - - case 0: //Software breakpoint - BreakType = SoftwareBreakpoint; - break; - - case 1: //Hardware breakpoint - BreakType = InstructionExecution; - break; - - case 2: //Write watchpoint - BreakType = DataWrite; - break; - - case 3: //Read watchpoint - BreakType = DataRead; - break; - - case 4: //Access watchpoint - BreakType = DataReadWrite; - break; - - default : - Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type); - SendError (GDB_EINVALIDBRKPOINTTYPE); - return; - } - - // Find next free debug register - Status = FindNextFreeDebugRegister (SystemContext, &Register); - if (EFI_ERROR(Status)) { - Print ((CHAR16 *)L"No space left on device\n"); - SendError (GDB_ENOSPACE); - return; - } - - // Write Address, length data at particular DR register - Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType); - if (EFI_ERROR(Status)) { - - if (Status == EFI_UNSUPPORTED) { - Print ((CHAR16 *)L"Not supported\n"); - SendNotSupported(); - return; - } - - Print ((CHAR16 *)L"Invalid argument\n"); - SendError (GDB_EINVALIDARG); - return; - } - - SendSuccess (); -} - - -/** - ‘z1, [addr], [length]’ - ‘z2, [addr], [length]’ - ‘z3, [addr], [length]’ - ‘z4, [addr], [length]’ - - Remove hardware breakpoint/watchpoint at address addr of size length - - @param *PacketData Pointer to the Payload data for the packet - -**/ -VOID -EFIAPI -RemoveBreakPoint ( - IN EFI_SYSTEM_CONTEXT SystemContext, - IN CHAR8 *PacketData - ) -{ - UINTN Type; - UINTN Address; - UINTN Length; - UINTN Register; - BREAK_TYPE BreakType = NotSupported; - EFI_STATUS Status; - UINTN ErrorCode; - - //Parse breakpoint packet data - ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length); - if (ErrorCode > 0) { - SendError ((UINT8)ErrorCode); - return; - } - - switch (Type) { - - case 0: //Software breakpoint - BreakType = SoftwareBreakpoint; - break; - - case 1: //Hardware breakpoint - BreakType = InstructionExecution; - break; - - case 2: //Write watchpoint - BreakType = DataWrite; - break; - - case 3: //Read watchpoint - BreakType = DataRead; - break; - - case 4: //Access watchpoint - BreakType = DataReadWrite; - break; - - default : - SendError (GDB_EINVALIDBRKPOINTTYPE); - return; - } - - //Find matching debug register - Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register); - if (EFI_ERROR(Status)) { - - if (Status == EFI_UNSUPPORTED) { - Print ((CHAR16 *)L"Not supported.\n"); - SendNotSupported(); - return; - } - - Print ((CHAR16 *)L"No matching register found.\n"); - SendError (GDB_ENOSPACE); - return; - } - - //Remove breakpoint - Status = DisableDebugRegister(SystemContext, Register); - if (EFI_ERROR(Status)) { - Print ((CHAR16 *)L"Invalid argument.\n"); - SendError (GDB_EINVALIDARG); - return; - } - - SendSuccess (); -} - - -VOID -InitializeProcessor ( - VOID - ) -{ -} - -BOOLEAN -ValidateAddress ( - IN VOID *Address - ) -{ - return TRUE; -} - -BOOLEAN -ValidateException ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN OUT EFI_SYSTEM_CONTEXT SystemContext - ) -{ - return TRUE; -} - diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S b/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S deleted file mode 100644 index df1543a6d242..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S +++ /dev/null @@ -1,258 +0,0 @@ -#------------------------------------------------------------------------------ -# -# Use ARMv6 instruction to operate on a single stack -# -# Copyright (c) 2008 - 2010, 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. -# -#------------------------------------------------------------------------------ - -/* - -This is the stack constructed by the exception handler (low address to high address) - # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM - Reg Offset - === ====== - R0 0x00 # stmfd SP!,{R0-R12} - R1 0x04 - R2 0x08 - R3 0x0c - R4 0x10 - R5 0x14 - R6 0x18 - R7 0x1c - R8 0x20 - R9 0x24 - R10 0x28 - R11 0x2c - R12 0x30 - SP 0x34 # reserved via adding 0x20 (32) to the SP - LR 0x38 - PC 0x3c - CPSR 0x40 - DFSR 0x44 - DFAR 0x48 - IFSR 0x4c - IFAR 0x50 - - LR 0x54 # SVC Link register (we need to restore it) - - LR 0x58 # pushed by srsfd - CPSR 0x5c - - */ - - -GCC_ASM_EXPORT(ExceptionHandlersStart) -GCC_ASM_EXPORT(ExceptionHandlersEnd) -GCC_ASM_EXPORT(CommonExceptionEntry) -GCC_ASM_EXPORT(AsmCommonExceptionEntry) -GCC_ASM_EXPORT(GdbExceptionHandler) - -.text -.align 3 - - -// -// This code gets copied to the ARM vector table -// ExceptionHandlersStart - ExceptionHandlersEnd gets copied -// -ASM_PFX(ExceptionHandlersStart): - -ASM_PFX(Reset): - b ASM_PFX(Reset) - -ASM_PFX(UndefinedInstruction): - b ASM_PFX(UndefinedInstructionEntry) - -ASM_PFX(SoftwareInterrupt): - b ASM_PFX(SoftwareInterruptEntry) - -ASM_PFX(PrefetchAbort): - b ASM_PFX(PrefetchAbortEntry) - -ASM_PFX(DataAbort): - b ASM_PFX(DataAbortEntry) - -ASM_PFX(ReservedException): - b ASM_PFX(ReservedExceptionEntry) - -ASM_PFX(Irq): - b ASM_PFX(Irq) - -ASM_PFX(Fiq): - b ASM_PFX(FiqEntry) - - -ASM_PFX(UndefinedInstructionEntry): - sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry - srsdb #0x13! @ Store return state on SVC stack - cpsid f,#0x13 @ Switch to SVC for common stack - stmfd SP!,{LR} @ Store the link register for the current mode - sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} @ Store the register state - - mov R0,#1 @ ExceptionType - ldr R1,ASM_PFX(CommonExceptionEntry) - bx R1 - -ASM_PFX(SoftwareInterruptEntry): - sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry - srsdb #0x13! @ Store return state on SVC stack - cpsid f @ We are already in SVC mode - stmfd SP!,{LR} @ Store the link register for the current mode - sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} @ Store the register state - - mov R0,#2 @ ExceptionType - ldr R1,ASM_PFX(CommonExceptionEntry) - bx R1 - -ASM_PFX(PrefetchAbortEntry): - sub LR,LR,#4 - srsdb #0x13! @ Store return state on SVC stack - cpsid f,#0x13 @ Switch to SVC for common stack - stmfd SP!,{LR} @ Store the link register for the current mode - sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} @ Store the register state - - mov R0,#3 @ ExceptionType - ldr R1,ASM_PFX(CommonExceptionEntry) - bx R1 - -ASM_PFX(DataAbortEntry): - sub LR,LR,#8 - srsdb #0x13! @ Store return state on SVC stack - cpsid f,#0x13 @ Switch to SVC for common stack - stmfd SP!,{LR} @ Store the link register for the current mode - sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} @ Store the register state - - mov R0,#4 - ldr R1,ASM_PFX(CommonExceptionEntry) - bx R1 - -ASM_PFX(ReservedExceptionEntry): - srsdb #0x13! @ Store return state on SVC stack - cpsid f,#0x13 @ Switch to SVC for common stack - stmfd SP!,{LR} @ Store the link register for the current mode - sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} @ Store the register state - - mov R0,#5 - ldr R1,ASM_PFX(CommonExceptionEntry) - bx R1 - -ASM_PFX(FiqEntry): - sub LR,LR,#4 - srsdb #0x13! @ Store return state on SVC stack - cps #0x13 @ Switch to SVC for common stack - stmfd SP!,{LR} @ Store the link register for the current mode - sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} @ Store the register state - @ Since we have already switch to SVC R8_fiq - R12_fiq - @ never get used or saved - mov R0,#7 @ ExceptionType - ldr R1,ASM_PFX(CommonExceptionEntry) - bx R1 - -// -// This gets patched by the C code that patches in the vector table -// -ASM_PFX(CommonExceptionEntry): - .byte 0x12 - .byte 0x34 - .byte 0x56 - .byte 0x78 - -ASM_PFX(ExceptionHandlersEnd): - -// -// This code runs from CpuDxe driver loaded address. It is patched into -// CommonExceptionEntry. -// -ASM_PFX(AsmCommonExceptionEntry): - mrc p15, 0, R1, c6, c0, 2 @ Read IFAR - str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR - - mrc p15, 0, R1, c5, c0, 1 @ Read IFSR - str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR - - mrc p15, 0, R1, c6, c0, 0 @ Read DFAR - str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR - - mrc p15, 0, R1, c5, c0, 0 @ Read DFSR - str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR - - ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack - str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR - - add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR - and R3, R1, #0x1f @ Check CPSR to see if User or System Mode - cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df)) - cmpne R3, #0x10 @ - stmeqed R2, {lr}^ @ save unbanked lr - @ else - stmneed R2, {lr} @ save SVC lr - - - ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd - @ Check to see if we have to adjust for Thumb entry - sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) { - cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb - bhi NoAdjustNeeded - - tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry - addne R5, R5, #2 @ PC += 2@ - str R5,[SP,#0x58] @ Update LR value pused by srsfd - -NoAdjustNeeded: - - str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC - - sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack - str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP - - @ R0 is ExceptionType - mov R1,SP @ R1 is SystemContext - -/* -VOID -EFIAPI -GdbExceptionHandler ( - IN EFI_EXCEPTION_TYPE ExceptionType, R0 - IN OUT EFI_SYSTEM_CONTEXT SystemContext R1 - ) - -*/ - blx ASM_PFX(GdbExceptionHandler) @ Call exception handler - - ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC - str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored - - ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR - str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored - - add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry - add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR - and R1, R1, #0x1f @ Check to see if User or System Mode - cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f)) - cmpne R1, #0x10 @ - ldmeqed R2, {lr}^ @ restore unbanked lr - @ else - ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR} - - ldmfd SP!,{R0-R12} @ Restore general purpose registers - @ Exception handler can not change SP - - add SP,SP,#0x20 @ Clear out the remaining stack space - ldmfd SP!,{LR} @ restore the link register for this context - rfefd SP! @ return from exception via srsfd stack slot - diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm b/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm deleted file mode 100644 index 611e83d7dae4..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm +++ /dev/null @@ -1,259 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Use ARMv6 instruction to operate on a single stack -// -// Copyright (c) 2008 - 2010, 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. -// -//------------------------------------------------------------------------------ - - - -/* - -This is the stack constructed by the exception handler (low address to high address) - # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM - Reg Offset - === ====== - R0 0x00 # stmfd SP!,{R0-R12} - R1 0x04 - R2 0x08 - R3 0x0c - R4 0x10 - R5 0x14 - R6 0x18 - R7 0x1c - R8 0x20 - R9 0x24 - R10 0x28 - R11 0x2c - R12 0x30 - SP 0x34 # reserved via adding 0x20 (32) to the SP - LR 0x38 - PC 0x3c - CPSR 0x40 - DFSR 0x44 - DFAR 0x48 - IFSR 0x4c - IFAR 0x50 - - LR 0x54 # SVC Link register (we need to restore it) - - LR 0x58 # pushed by srsfd - CPSR 0x5c - - */ - - - EXPORT ExceptionHandlersStart - EXPORT ExceptionHandlersEnd - EXPORT CommonExceptionEntry - EXPORT AsmCommonExceptionEntry - IMPORT GdbExceptionHandler - - PRESERVE8 - AREA DxeExceptionHandlers, CODE, READONLY - -// -// This code gets copied to the ARM vector table -// ExceptionHandlersStart - ExceptionHandlersEnd gets copied -// -ExceptionHandlersStart - -Reset - b Reset - -UndefinedInstruction - b UndefinedInstructionEntry - -SoftwareInterrupt - b SoftwareInterruptEntry - -PrefetchAbort - b PrefetchAbortEntry - -DataAbort - b DataAbortEntry - -ReservedException - b ReservedExceptionEntry - -Irq - b Irq - -Fiq - b FiqEntry - - -UndefinedInstructionEntry - sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry - srsfd #0x13! ; Store return state on SVC stack - cpsid f, #0x13 ; Switch to SVC for common stack - stmfd SP!,{LR} ; Store the link register for the current mode - sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} ; Store the register state - - mov R0,#1 ; ExceptionType - ldr R1,CommonExceptionEntry; - bx R1 - -SoftwareInterruptEntry - sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry - srsfd #0x13! ; Store return state on SVC stack - cpsid f ; We are already in SVC mode - stmfd SP!,{LR} ; Store the link register for the current mode - sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} ; Store the register state - - mov R0,#2 ; ExceptionType - ldr R1,CommonExceptionEntry - bx R1 - -PrefetchAbortEntry - sub LR,LR,#4 - srsfd #0x13! ; Store return state on SVC stack - cpsid f, #0x13 ; Switch to SVC for common stack - stmfd SP!,{LR} ; Store the link register for the current mode - sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} ; Store the register state - - mov R0,#3 ; ExceptionType - ldr R1,CommonExceptionEntry - bx R1 - -DataAbortEntry - sub LR,LR,#8 - srsfd #0x13! ; Store return state on SVC stack - cpsid f, #0x13 ; Switch to SVC for common stack - stmfd SP!,{LR} ; Store the link register for the current mode - sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} ; Store the register state - - mov R0,#4 ; ExceptionType - ldr R1,CommonExceptionEntry - bx R1 - -ReservedExceptionEntry - srsfd #0x13! ; Store return state on SVC stack - cpsid f, #0x13 ; Switch to SVC for common stack - stmfd SP!,{LR} ; Store the link register for the current mode - sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} ; Store the register state - - mov R0,#5 ; ExceptionType - ldr R1,CommonExceptionEntry - bx R1 - -FiqEntry - sub LR,LR,#4 - srsfd #0x13! ; Store return state on SVC stack - cps #0x13 ; Switch to SVC for common stack - stmfd SP!,{LR} ; Store the link register for the current mode - sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR - stmfd SP!,{R0-R12} ; Store the register state - ; Since we have already switch to SVC R8_fiq - R12_fiq - ; never get used or saved - mov R0,#7 ; ExceptionType - ldr R1,CommonExceptionEntry - bx R1 - -// -// This gets patched by the C code that patches in the vector table -// -CommonExceptionEntry - dcd 0x12345678 - -ExceptionHandlersEnd - -// -// This code runs from CpuDxe driver loaded address. It is patched into -// CommonExceptionEntry. -// -AsmCommonExceptionEntry - mrc p15, 0, R1, c6, c0, 2 ; Read IFAR - str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR - - mrc p15, 0, R1, c5, c0, 1 ; Read IFSR - str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR - - mrc p15, 0, R1, c6, c0, 0 ; Read DFAR - str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR - - mrc p15, 0, R1, c5, c0, 0 ; Read DFSR - str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR - - ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack - str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR - - add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR - and R3, R1, #0x1f ; Check CPSR to see if User or System Mode - cmp R3, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1df)) - cmpne R3, #0x10 ; - stmeqed R2, {lr}^ ; save unbanked lr - ; else - stmneed R2, {lr} ; save SVC lr - - - ldr R5, [SP, #0x58] ; PC is the LR pushed by srsfd - ; Check to see if we have to adjust for Thumb entry - sub r4, r0, #1 ; if (ExceptionType == 1 || ExceptionType ==2)) { - cmp r4, #1 ; // UND & SVC have differnt LR adjust for Thumb - bhi NoAdjustNeeded - - tst r1, #0x20 ; if ((CPSR & T)) == T) { // Thumb Mode on entry - addne R5, R5, #2 ; PC += 2; - str R5,[SP,#0x58] ; Update LR value pused by srsfd - -NoAdjustNeeded - - str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC - - sub R1, SP, #0x60 ; We pused 0x60 bytes on the stack - str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP - - ; R0 is ExceptionType - mov R1,SP ; R1 is SystemContext - -/* -VOID -EFIAPI -GdbExceptionHandler ( - IN EFI_EXCEPTION_TYPE ExceptionType, R0 - IN OUT EFI_SYSTEM_CONTEXT SystemContext R1 - ) - -*/ - blx GdbExceptionHandler ; Call exception handler - - ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC - str R1,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored - - ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR - str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored - - add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry - add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR - and R1, R1, #0x1f ; Check to see if User or System Mode - cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f)) - cmpne R1, #0x10 ; - ldmeqed R2, {lr}^ ; restore unbanked lr - ; else - ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR} - - ldmfd SP!,{R0-R12} ; Restore general purpose registers - ; Exception handler can not change SP - - add SP,SP,#0x20 ; Clear out the remaining stack space - ldmfd SP!,{LR} ; restore the link register for this context - rfefd SP! ; return from exception via srsfd stack slot - - END - - diff --git a/EmbeddedPkg/Library/GdbDebugAgent/gdbnotes.txt b/EmbeddedPkg/Library/GdbDebugAgent/gdbnotes.txt deleted file mode 100644 index 287b09e6a8a7..000000000000 --- a/EmbeddedPkg/Library/GdbDebugAgent/gdbnotes.txt +++ /dev/null @@ -1,15 +0,0 @@ -arm-none-eabi-gcc -march=armv7-a -mthumb t.c -Wl,-nostdlib --emit-relocs - -target remote com7 -set debug remote 1 -set remotetimeout 30 -set remotelogfile log.txt -add-symbol-file c:/work/edk2/Build/BeagleBoard/DEBUG_GCC48/ARM/BeagleBoardPkg/Sec/Sec/DEBUG/BeagleBoardSec.dll 0x80008360 - - -qSupported -Hg0 - -Hc-1 -qC -qAttached \ No newline at end of file -- 2.19.2