summaryrefslogtreecommitdiff
path: root/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c
diff options
context:
space:
mode:
Diffstat (limited to 'EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c')
-rwxr-xr-xEmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c675
1 files changed, 0 insertions, 675 deletions
diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c b/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c
deleted file mode 100755
index 61c6184fae..0000000000
--- 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.<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 <GdbDebugAgent.h>
-#include <Library/PrintLib.h>
-#include <Library/ArmLib.h>
-
-//
-// 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
- )
-{
- UINT32 VectorBase = PcdGet32 (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 Libary 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;
- UINT32 *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 = (UINT32 *)(UINTN)PcdGet32 (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 *)PcdGet32(PcdCpuVectorBaseAddress), Length);
-
- // setup a timer so gdb can break in via ctrl-c
- DebugAgentTimerIntialize ();
-
- if (IrqEnabled) {
- ArmEnableInterrupts ();
- }
-
- if (Function != NULL) {
- Function (Context);
- }
-
- return;
-}
-