summaryrefslogtreecommitdiff
path: root/EmbeddedPkg/GdbStub/Arm/Processor.c
diff options
context:
space:
mode:
Diffstat (limited to 'EmbeddedPkg/GdbStub/Arm/Processor.c')
-rw-r--r--EmbeddedPkg/GdbStub/Arm/Processor.c703
1 files changed, 0 insertions, 703 deletions
diff --git a/EmbeddedPkg/GdbStub/Arm/Processor.c b/EmbeddedPkg/GdbStub/Arm/Processor.c
deleted file mode 100644
index 96b4f570c4..0000000000
--- a/EmbeddedPkg/GdbStub/Arm/Processor.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/** @file
- Processor specific parts of the GDB stub
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <GdbStubInternal.h>
-#include <Library/CacheMaintenanceLib.h>
-#include <Library/PrintLib.h>
-
-//
-// 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_SIGEMT },
-// { EXCEPT_ARM_RESERVED, GDB_SIGILL }
-};
-
-// 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);
-}
-
-
-/**
- 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
- )
-{
- 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 >= MaxRegisterCount ()) {
- 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;
- CHAR8 *OutBuffer;
- CHAR8 *OutBufPtr;
- UINTN RegisterCount = MaxRegisterCount ();
-
- // It is not safe to allocate pool here....
- OutBuffer = AllocatePool ((RegisterCount * 8) + 1); // 8 bytes per register in string format plus a null to terminate
- OutBufPtr = OutBuffer;
- for (Index = 0; Index < RegisterCount; Index++) {
- OutBufPtr = BasicReadRegister (SystemContext, Index, OutBufPtr);
- }
-
- *OutBufPtr = '\0';
- SendPacket (OutBuffer);
- FreePool (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 >= 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
- UINTN MinLength;
- UINTN RegisterCount = MaxRegisterCount ();
-
- 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 ();
-}
-
-// What about Thumb?
-// Use SWI 0xdbdbdb as the debug instruction
-#define GDB_ARM_BKPT 0xefdbdbdb
-
-BOOLEAN mSingleStepActive = FALSE;
-UINT32 mSingleStepPC;
-UINT32 mSingleStepData;
-UINTN mSingleStepDataSize;
-
-typedef struct {
- LIST_ENTRY Link;
- UINT64 Signature;
- UINT32 Address;
- UINT32 Instruction;
-} ARM_SOFTWARE_BREAKPOINT;
-
-#define ARM_SOFTWARE_BREAKPOINT_SIGNATURE SIGNATURE_64('A', 'R', 'M', 'B', 'R', 'K', 'P', 'T')
-#define ARM_SOFTWARE_BREAKPOINT_FROM_LINK(a) CR(a, ARM_SOFTWARE_BREAKPOINT, Link, ARM_SOFTWARE_BREAKPOINT_SIGNATURE)
-
-LIST_ENTRY BreakpointList;
-
-/**
- Insert Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-AddSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- if (mSingleStepActive) {
- // Currently don't support nesting
- return;
- }
- mSingleStepActive = TRUE;
-
- mSingleStepPC = SystemContext.SystemContextArm->PC;
-
- mSingleStepDataSize = sizeof (UINT32);
- mSingleStepData = (*(UINT32 *)mSingleStepPC);
- *(UINT32 *)mSingleStepPC = GDB_ARM_BKPT;
- if (*(UINT32 *)mSingleStepPC != GDB_ARM_BKPT) {
- // For some reason our breakpoint did not take
- mSingleStepActive = FALSE;
- }
-
- InvalidateInstructionCacheRange ((VOID *)mSingleStepPC, mSingleStepDataSize);
- //DEBUG((EFI_D_ERROR, "AddSingleStep at 0x%08x (was: 0x%08x is:0x%08x)\n", SystemContext.SystemContextArm->PC, mSingleStepData, *(UINT32 *)mSingleStepPC));
-}
-
-
-/**
- Remove Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-RemoveSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- if (!mSingleStepActive) {
- return;
- }
-
- if (mSingleStepDataSize == sizeof (UINT16)) {
- *(UINT16 *)mSingleStepPC = (UINT16)mSingleStepData;
- } else {
- //DEBUG((EFI_D_ERROR, "RemoveSingleStep at 0x%08x (was: 0x%08x is:0x%08x)\n", SystemContext.SystemContextArm->PC, *(UINT32 *)mSingleStepPC, mSingleStepData));
- *(UINT32 *)mSingleStepPC = mSingleStepData;
- }
- InvalidateInstructionCacheRange ((VOID *)mSingleStepPC, mSingleStepDataSize);
- mSingleStepActive = FALSE;
-}
-
-
-
-/**
- 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 ();
-}
-
-UINTN
-GetBreakpointDataAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- )
-{
- return 0;
-}
-
-UINTN
-GetBreakpointDetected (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- return 0;
-}
-
-BREAK_TYPE
-GetBreakpointType (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- )
-{
- return NotSupported;
-}
-
-ARM_SOFTWARE_BREAKPOINT *
-SearchBreakpointList (
- IN UINT32 Address
- )
-{
- LIST_ENTRY *Current;
- ARM_SOFTWARE_BREAKPOINT *Breakpoint;
-
- Current = GetFirstNode (&BreakpointList);
- while (!IsNull (&BreakpointList, Current)) {
- Breakpoint = ARM_SOFTWARE_BREAKPOINT_FROM_LINK(Current);
-
- if (Address == Breakpoint->Address) {
- return Breakpoint;
- }
-
- Current = GetNextNode (&BreakpointList, Current);
- }
-
- return NULL;
-}
-
-VOID
-SetBreakpoint (
- IN UINT32 Address
- )
-{
- ARM_SOFTWARE_BREAKPOINT *Breakpoint;
-
- Breakpoint = SearchBreakpointList (Address);
-
- if (Breakpoint != NULL) {
- return;
- }
-
- // create and fill breakpoint structure
- Breakpoint = AllocatePool (sizeof(ARM_SOFTWARE_BREAKPOINT));
-
- Breakpoint->Signature = ARM_SOFTWARE_BREAKPOINT_SIGNATURE;
- Breakpoint->Address = Address;
- Breakpoint->Instruction = *(UINT32 *)Address;
-
- // Add it to the list
- InsertTailList (&BreakpointList, &Breakpoint->Link);
-
- // Insert the software breakpoint
- *(UINT32 *)Address = GDB_ARM_BKPT;
- InvalidateInstructionCacheRange ((VOID *)Address, 4);
-
- //DEBUG((EFI_D_ERROR, "SetBreakpoint at 0x%08x (was: 0x%08x is:0x%08x)\n", Address, Breakpoint->Instruction, *(UINT32 *)Address));
-}
-
-VOID
-ClearBreakpoint (
- IN UINT32 Address
- )
-{
- ARM_SOFTWARE_BREAKPOINT *Breakpoint;
-
- Breakpoint = SearchBreakpointList (Address);
-
- if (Breakpoint == NULL) {
- return;
- }
-
- // Add it to the list
- RemoveEntryList (&Breakpoint->Link);
-
- // Restore the original instruction
- *(UINT32 *)Address = Breakpoint->Instruction;
- InvalidateInstructionCacheRange ((VOID *)Address, 4);
-
- //DEBUG((EFI_D_ERROR, "ClearBreakpoint at 0x%08x (was: 0x%08x is:0x%08x)\n", Address, GDB_ARM_BKPT, *(UINT32 *)Address));
-
- FreePool (Breakpoint);
-}
-
-VOID
-EFIAPI
-InsertBreakPoint (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- UINTN Type;
- UINTN Address;
- UINTN Length;
- UINTN ErrorCode;
-
- ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
- if (ErrorCode > 0) {
- SendError ((UINT8)ErrorCode);
- return;
- }
-
- switch (Type) {
- case 0: //Software breakpoint
- break;
-
- default :
- DEBUG((EFI_D_ERROR, "Insert breakpoint default: %x\n", Type));
- SendError (GDB_EINVALIDBRKPOINTTYPE);
- return;
- }
-
- SetBreakpoint (Address);
-
- SendSuccess ();
-}
-
-VOID
-EFIAPI
-RemoveBreakPoint (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- UINTN Type;
- UINTN Address;
- UINTN Length;
- 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
- break;
-
- default:
- SendError (GDB_EINVALIDBRKPOINTTYPE);
- return;
- }
-
- ClearBreakpoint (Address);
-
- SendSuccess ();
-}
-
-VOID
-InitializeProcessor (
- VOID
- )
-{
- // Initialize breakpoint list
- InitializeListHead (&BreakpointList);
-}
-
-BOOLEAN
-ValidateAddress (
- IN VOID *Address
- )
-{
- if ((UINT32)Address < 0x80000000) {
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-BOOLEAN
-ValidateException (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- UINT32 ExceptionAddress;
- UINT32 Instruction;
-
- // Is it a debugger SWI?
- ExceptionAddress = SystemContext.SystemContextArm->PC -= 4;
- Instruction = *(UINT32 *)ExceptionAddress;
- if (Instruction != GDB_ARM_BKPT) {
- return FALSE;
- }
-
- // Special for SWI-based exception handling. SWI sets up the context
- // to return to the instruction following the SWI instruction - NOT what we want
- // for a debugger!
- SystemContext.SystemContextArm->PC = ExceptionAddress;
-
- return TRUE;
-}
-