12ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** @file 22ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Processor specific parts of the GDB stub 32ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 460274ccab831d7874129a6b6c271969418296960hhtian Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 53402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 660274ccab831d7874129a6b6c271969418296960hhtian This program and the accompanying materials 72ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH are licensed and made available under the terms and conditions of the BSD License 82ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH which accompanies this distribution. The full text of the license may be found at 92ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH http://opensource.org/licenses/bsd-license.php 102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH#include <GdbStubInternal.h> 172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH// 192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH// Array of exception types that need to be hooked by the debugger 202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH// 212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = { 223402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { EXCEPT_X64_DIVIDE_ERROR, GDB_SIGFPE }, 232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_DEBUG, GDB_SIGTRAP }, 242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_NMI, GDB_SIGEMT }, 252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_BREAKPOINT, GDB_SIGTRAP }, 262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_OVERFLOW, GDB_SIGSEGV }, 272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_BOUND, GDB_SIGSEGV }, 282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_INVALID_OPCODE, GDB_SIGILL }, 292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_DOUBLE_FAULT, GDB_SIGEMT }, 302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_STACK_FAULT, GDB_SIGSEGV }, 312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_GP_FAULT, GDB_SIGSEGV }, 322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_PAGE_FAULT, GDB_SIGSEGV }, 332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_FP_ERROR, GDB_SIGEMT }, 342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_ALIGNMENT_CHECK, GDB_SIGEMT }, 352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH { EXCEPT_X64_MACHINE_CHECK, GDB_SIGEMT } 362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH}; 372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH// The offsets of registers SystemContextX64. 403402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron// The fields in the array are in the gdb ordering. 412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH// HAVE TO DOUBLE-CHECK THE ORDER of the 24 regs 422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH// 432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHUINTN gRegisterOffsets[] = { 442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rax), 452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rcx), 462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rdx), 472ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rbx), 482ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rsp), 492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rbp), 502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rsi), 512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rdi), 522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rip), 532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Rflags), 542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Cs), 552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Ss), 562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Ds), 572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Es), 582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Fs), 592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, Gs), 602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R8), 612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R9), 622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R10), 632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R11), 642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R12), 652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R13), 662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R14), 672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OFFSET_OF(EFI_SYSTEM_CONTEXT_X64, R15) 682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH}; 692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Return the number of entries in the gExceptionType[] 733402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @retval UINTN, the number of entries in the gExceptionType[] array. 752ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHUINTN 772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHMaxEfiException ( 782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH VOID 792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 802ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY); 822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 832ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 852ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Return the number of entries in the gRegisters[] 873402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 883402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @retval UINTN, the number of entries (registers) in the gRegisters[] array. 892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 902ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHUINTN 912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHMaxRegisterCount ( 922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH VOID 932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 952ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return sizeof (gRegisterOffsets)/sizeof (UINTN); 962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 983402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 1003402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Check to see if the ISA is supported. 1012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ISA = Instruction Set Architecture 1022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval TRUE if Isa is supported 1042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 1052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHBOOLEAN 1062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHCheckIsa ( 1072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa 1082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 1092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 1102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return (BOOLEAN)(Isa == IsaX64); 1112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 1122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 1152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering 1162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH It is, by default, set to find the register pointer of the X64 member 1173402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param SystemContext Register content at time of the exception 1182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param RegNumber The register to which we want to find a pointer 1192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval the pointer to the RegNumber-th pointer 1202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 1212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHUINTN * 1222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHFindPointerToRegister( 1232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 1243402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron IN UINTN RegNumber 1252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 1262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 1272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINT8 *TempPtr; 1282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH TempPtr = ((UINT8 *)SystemContext.SystemContextX64) + gRegisterOffsets[RegNumber]; 1292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return (UINTN *)TempPtr; 1302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 1312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 1342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr 1352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 1362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param RegNumber the number of the register that we want to read 1372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on. 1382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval the pointer to the next character of the output buffer that is available to be written on. 1392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 1402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHCHAR8 * 1412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHBasicReadRegister ( 1422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 1432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN RegNumber, 1442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *OutBufPtr 1452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 1462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 1472ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN RegSize; 1483402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH RegSize = 0; 1502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH while (RegSize < 64) { 1512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)]; 1522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)]; 1532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH RegSize = RegSize + 8; 1542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 1552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return OutBufPtr; 1562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 1572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1593402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron/** ‘p n’ 1603402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Reads the n-th register's value into an output buffer and sends it as a packet 1612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 1622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param InBuffer Pointer to the input buffer received from gdb server 1632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 1642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 1652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHReadNthRegister ( 1662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 1672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *InBuffer 1682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 1692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 1702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN RegNumber; 1712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 OutBuffer[17]; // 1 reg=16 hex chars, and the end '\0' (escape seq) 1722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 *OutBufPtr; // pointer to the output buffer 1733402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1742ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH RegNumber = AsciiStrHexToUintn (&InBuffer[1]); 1753402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) { 1773402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron SendError (GDB_EINVALIDREGNUM); 1782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 1792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 1803402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OutBufPtr = OutBuffer; 1822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr); 1833402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *OutBufPtr = '\0'; // the end of the buffer 1852ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendPacket (OutBuffer); 1862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 1872ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1882ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1893402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron/** ‘g’ 1903402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Reads the general registers into an output buffer and sends it as a packet 1912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 1922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 1932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 1942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 1952ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFIAPI 1963402aac7d985bf8a9f9d3c639f3fe93609380513Ronald CronReadGeneralRegisters ( 1972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext 1982ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 1992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 2002ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN i; 2012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 OutBuffer[385]; // 24 regs, 16 hex chars each, and the end '\0' (escape seq) 2022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 *OutBufPtr; // pointer to the output buffer 2033402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OutBufPtr = OutBuffer; 2053402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron for(i = 0 ; i < MaxRegisterCount() ; i++) { // there are only 24 registers to read 2062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr); 2072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 2083402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *OutBufPtr = '\0'; // the end of the buffer 2102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendPacket (OutBuffer); 2112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 2122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 2152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr 2162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 2182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param RegNumber the number of the register that we want to write 2192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on. 2202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval the pointer to the next character of the input buffer that can be used 2212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 2222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHCHAR8 * 2232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHBasicWriteRegister ( 2242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 2252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN RegNumber, 2262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *InBufPtr 2272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 2282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 2292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN RegSize; 2302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN TempValue; // the value transferred from a hex char 2312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINT64 NewValue; // the new value of the RegNumber-th Register 2323402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH NewValue = 0; 2342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH RegSize = 0; 2352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH while (RegSize < 64) { 2362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH TempValue = HexCharToInt(*InBufPtr++); 2373402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (TempValue < 0) { 2393402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron SendError (GDB_EBADMEMDATA); 2402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return NULL; 2412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 2423402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH NewValue += (TempValue << (RegSize+4)); 2442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH TempValue = HexCharToInt(*InBufPtr++); 2453402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (TempValue < 0) { 2473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron SendError (GDB_EBADMEMDATA); 2482ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return NULL; 2492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 2503402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2513402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron NewValue += (TempValue << RegSize); 2522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH RegSize = RegSize + 8; 2532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 2542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue; 2552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return InBufPtr; 2562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 2572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** ‘P n...=r...’ 2602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Writes the new value of n-th register received into the input buffer to the n-th register 2612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 2632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param InBuffer Ponter to the input buffer received from gdb server 2642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 2652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 2662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFIAPI 2672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHWriteNthRegister ( 2682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 2692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *InBuffer 2702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 2712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 2722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN RegNumber; 2732ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array 2742ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 *RegNumBufPtr; 2752ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 *InBufPtr; // pointer to the input buffer 2763402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH // find the register number to write 2782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH InBufPtr = &InBuffer[1]; 2792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH RegNumBufPtr = RegNumBuffer; 2802ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH while (*InBufPtr != '=') { 2812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *RegNumBufPtr++ = *InBufPtr++; 2823402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron } 2832ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *RegNumBufPtr = '\0'; 2843402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron RegNumber = AsciiStrHexToUintn (RegNumBuffer); 2852ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH // check if this is a valid Register Number 2872ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) { 28891c38d4e94c1461f5824b83d3722fe46626aa0d3Ronald Cron SendError (GDB_EINVALIDREGNUM); 2892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 2902ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 2912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH InBufPtr++; // skips the '=' character 2922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BasicWriteRegister (SystemContext, RegNumber, InBufPtr); 2932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendSuccess(); 2942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 2952ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 2972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** ‘G XX...’ 2982ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Writes the new values received into the input buffer to the general registers 2992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3002ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 3012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param InBuffer Pointer to the input buffer received from gdb server 3022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 3032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 3042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFIAPI 3052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHWriteGeneralRegisters ( 3062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 3072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *InBuffer 3082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 3092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 3102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN i; 3112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH CHAR8 *InBufPtr; /// pointer to the input buffer 3123402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3133402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron // check to see if the buffer is the right size which is 3143402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 385 3152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (AsciiStrLen(InBuffer) != 385) { // 24 regs, 16 hex chars each, and the end '\0' (escape seq) 3163402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron //Bad message. Message is not the right length 3173402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron SendError (GDB_EBADBUFSIZE); 3182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 3192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 3203402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH InBufPtr = &InBuffer[1]; 3223402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH // Read the new values for the registers from the input buffer to an array, NewValueArray. 3242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH // The values in the array are in the gdb ordering 3252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH for(i=0; i < MaxRegisterCount(); i++) { // there are only 16 registers to write 3262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr); 3272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 3283402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendSuccess(); 3302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 3312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3333402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron /** 3342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Insert Single Step in the SystemContext 3353402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 3372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 3382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 3392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHAddSingleStep ( 3402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext 3412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 3422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 3432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextX64->Rflags |= TF_BIT; //Setting the TF bit. 3442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 3452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3463402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3483402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron/** 3492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Remove Single Step in the SystemContext 3503402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 3522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 3532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 3542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHRemoveSingleStep ( 3552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext 3562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 3572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 3582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextX64->Rflags &= ~TF_BIT; // clearing the TF bit. 3592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 3602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3633402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron/** ‘c [addr ]’ 3643402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Continue. addr is Address to resume. If addr is omitted, resume at current 3652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Address. 3663402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3673402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param SystemContext Register content at time of the exception 3682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 3692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 3702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFIAPI 3712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHContinueAtAddress ( 3722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 3732ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *PacketData 3742ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 3752ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 3762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (PacketData[1] != '\0') { 3772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextX64->Rip = AsciiStrHexToUintn(&PacketData[1]); 3783402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron } 3792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 3802ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 3822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** ‘s [addr ]’ 3833402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Single step. addr is the Address at which to resume. If addr is omitted, resume 3842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH at same Address. 3853402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3863402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param SystemContext Register content at time of the exception 3872ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH **/ 3882ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 3892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFIAPI 3902ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHSingleStep ( 3912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 3922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *PacketData 3932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 3942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 3952ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (PacketData[1] != '\0') { 3962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextX64->Rip = AsciiStrHexToUintn (&PacketData[1]); 3972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 3983402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH AddSingleStep (SystemContext); 4002ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 4012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 4043402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Returns breakpoint data address from DR0-DR3 based on the input breakpoint 4052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH number 4062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 4082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param BreakpointNumber Breakpoint number 4092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4103402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @retval Address Data address from DR0-DR3 based on the 4112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH breakpoint number. 4122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 4142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHUINTN 4152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHGetBreakpointDataAddress ( 4162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 4172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN BreakpointNumber 4182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 4192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 4202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Address; 4212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (BreakpointNumber == 1) { 4232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Address = SystemContext.SystemContextIa32->Dr0; 4242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (BreakpointNumber == 2) { 4252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Address = SystemContext.SystemContextIa32->Dr1; 4262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (BreakpointNumber == 3) { 4272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Address = SystemContext.SystemContextIa32->Dr2; 4282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (BreakpointNumber == 4) { 4292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Address = SystemContext.SystemContextIa32->Dr3; 4302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else { 4312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Address = 0; 4322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 4332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return Address; 4352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 4362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 4383402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Returns currently detected breakpoint value based on the register 4392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH DR6 B0-B3 field. 4402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH If no breakpoint is detected then it returns 0. 4412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 4432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval {1-4} Currently detected breakpoint value 4452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval 0 No breakpoint detected. 4462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4472ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 4482ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHUINTN 4492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHGetBreakpointDetected ( 4502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext 4512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 4522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 4532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IA32_DR6 Dr6; 4542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN BreakpointNumber; 4552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr6.UintN = SystemContext.SystemContextIa32->Dr6; 4572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (Dr6.Bits.B0 == 1) { 4592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakpointNumber = 1; 4602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Dr6.Bits.B1 == 1) { 4612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakpointNumber = 2; 4622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Dr6.Bits.B2 == 1) { 4632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakpointNumber = 3; 4642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Dr6.Bits.B3 == 1) { 4652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakpointNumber = 4; 4662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else { 4672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakpointNumber = 0; //No breakpoint detected 4682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 4692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return BreakpointNumber; 4712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 4722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4732ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 4743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Returns Breakpoint type (InstructionExecution, DataWrite, DataRead 4752ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH or DataReadWrite) based on the Breakpoint number 4762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 4782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param BreakpointNumber Breakpoint number 4792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4803402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn 4812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH field. For unknown value, it returns NotSupported. 4822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4832ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 4842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHBREAK_TYPE 4852ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHGetBreakpointType ( 4862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 4872ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN BreakpointNumber 4882ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 4892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 4902ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IA32_DR7 Dr7; 4912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BREAK_TYPE Type = NotSupported; //Default is NotSupported type 4922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.UintN = SystemContext.SystemContextIa32->Dr7; 4942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 4952ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (BreakpointNumber == 1) { 4962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Type = (BREAK_TYPE) Dr7.Bits.RW0; 4972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (BreakpointNumber == 2) { 4982ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Type = (BREAK_TYPE) Dr7.Bits.RW1; 4992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (BreakpointNumber == 3) { 5002ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Type = (BREAK_TYPE) Dr7.Bits.RW2; 5012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (BreakpointNumber == 4) { 5022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Type = (BREAK_TYPE) Dr7.Bits.RW3; 5032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 5042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return Type; 5062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 5072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5093402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron/** 5102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Parses Length and returns the length which DR7 LENn field accepts. 5113402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron For example: If we receive 1-Byte length then we should return 0. 5122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Zero gets written to DR7 LENn field. 5132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte) 5152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval Length Appropriate converted values which DR7 LENn field accepts. 5172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 5192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHUINTN 5202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHConvertLengthData ( 5212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Length 5222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 5232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 5243402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron if (Length == 1) { //1-Byte length 5252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return 0; 5262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Length == 2) { //2-Byte length 5272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return 1; 5282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Length == 4) { //4-Byte length 5292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return 3; 5302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else { //Undefined or 8-byte length 5312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return 2; 5322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 5332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 5342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 5372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Finds the next free debug register. If all the registers are occupied then 5382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH EFI_OUT_OF_RESOURCES is returned. 5392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 5412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Register Register value (0 - 3 for the first free debug register) 5422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval EFI_STATUS Appropriate status value. 5442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 5462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFI_STATUS 5472ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHFindNextFreeDebugRegister ( 5482ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 5492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OUT UINTN *Register 5502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 5512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 5522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IA32_DR7 Dr7; 5532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.UintN = SystemContext.SystemContextIa32->Dr7; 5552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (Dr7.Bits.G0 == 0) { 5572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 0; 5582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Dr7.Bits.G1 == 0) { 5592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 1; 5602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Dr7.Bits.G2 == 0) { 5612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 2; 5622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Dr7.Bits.G3 == 0) { 5632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 3; 5642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else { 5652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_OUT_OF_RESOURCES; 5662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 5672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_SUCCESS; 5692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 5702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 5732ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Enables the debug register. Writes Address value to appropriate DR0-3 register. 5742ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Sets LENn, Gn, RWn bits in DR7 register. 5752ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 5772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Register Register value (0 - 3) 5782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Address Breakpoint address value 5793402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param Type Breakpoint type (Instruction, Data write, 5802ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Data read or write etc.) 5812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval EFI_STATUS Appropriate status value. 5832ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 5852ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFI_STATUS 5862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEnableDebugRegister ( 5872ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 5882ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Register, 5892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Address, 5902ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Length, 5912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Type 5922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 5932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 5942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IA32_DR7 Dr7; 5952ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Convert length data 5972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Length = ConvertLengthData (Length); 5982ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 5993402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron //For Instruction execution, length should be 0 6002ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //(Ref. Intel reference manual 18.2.4) 6012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if ((Type == 0) && (Length != 0)) { 6022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_INVALID_PARAMETER; 6032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 6042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle 6062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //software breakpoint. We should send empty packet in both these cases. 6073402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron if ((Type == (BREAK_TYPE)DataRead) || 6082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Type == (BREAK_TYPE)SoftwareBreakpoint)) { 6092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_UNSUPPORTED; 6102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 6112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Read DR7 so appropriate Gn, RWn and LENn bits can be modified. 6132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.UintN = SystemContext.SystemContextIa32->Dr7; 6142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (Register == 0) { 6162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr0 = Address; 6172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G0 = 1; 6182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW0 = Type; 6192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN0 = Length; 6202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Register == 1) { 6212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr1 = Address; 6222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G1 = 1; 6232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW1 = Type; 6242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN1 = Length; 6252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Register == 2) { 6262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr2 = Address; 6272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G2 = 1; 6282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW2 = Type; 6292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN2 = Length; 6302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Register == 3) { 6312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr3 = Address; 6322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G3 = 1; 6332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW3 = Type; 6342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN3 = Length; 6352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else { 6362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_INVALID_PARAMETER; 6372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 6382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Update Dr7 with appropriate Gn, RWn and LENn bits 6402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr7 = Dr7.UintN; 6412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_SUCCESS; 6432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 6442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6463402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron/** 6473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Returns register number 0 - 3 for the maching debug register. 6483402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron This function compares incoming Address, Type, Length and 6492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if there is a match then it returns the appropriate register number. 6502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH In case of mismatch, function returns EFI_NOT_FOUND message. 6512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 6533402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param Address Breakpoint address value 6542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Length Breakpoint length value 6552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Type Breakpoint type (Instruction, Data write, Data read 6562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH or write etc.) 6572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Register Register value to be returned 6582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval EFI_STATUS Appropriate status value. 6602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 6622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFI_STATUS 6632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHFindMatchingDebugRegister ( 6642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 6652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Address, 6662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Length, 6672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Type, 6682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH OUT UINTN *Register 6692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 6702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 6712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IA32_DR7 Dr7; 6722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6732ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle 6742ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //software breakpoint. We should send empty packet in both these cases. 6753402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron if ((Type == (BREAK_TYPE)DataRead) || 6762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Type == (BREAK_TYPE)SoftwareBreakpoint)) { 6772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_UNSUPPORTED; 6782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 6792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6802ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Convert length data 6812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Length = ConvertLengthData(Length); 6822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6832ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.UintN = SystemContext.SystemContextIa32->Dr7; 6842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 6853402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron if ((Dr7.Bits.G0 == 1) && 6862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Dr7.Bits.LEN0 == Length) && 6873402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron (Dr7.Bits.RW0 == Type) && 6882ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Address == SystemContext.SystemContextIa32->Dr0)) { 6892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 0; 6903402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron } else if ((Dr7.Bits.G1 == 1) && 6912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Dr7.Bits.LEN1 == Length) && 6923402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron (Dr7.Bits.RW1 == Type) && 6932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Address == SystemContext.SystemContextIa32->Dr1)) { 6942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 1; 6953402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron } else if ((Dr7.Bits.G2 == 1) && 6962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Dr7.Bits.LEN2 == Length) && 6973402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron (Dr7.Bits.RW2 == Type) && 6982ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Address == SystemContext.SystemContextIa32->Dr2)) { 6992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 2; 7003402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron } else if ((Dr7.Bits.G3 == 1) && 7012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Dr7.Bits.LEN3 == Length) && 7023402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron (Dr7.Bits.RW3 == Type) && 7032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH (Address == SystemContext.SystemContextIa32->Dr3)) { 7042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH *Register = 3; 7052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else { 7062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"No match found..\n"); 7072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_NOT_FOUND; 7082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 7092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_SUCCESS; 7112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 7122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 7152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Disables the particular debug register. 7162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 7182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param Register Register to be disabled 7192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @retval EFI_STATUS Appropriate status value. 7212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 7232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFI_STATUS 7242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHDisableDebugRegister ( 7252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 7262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN UINTN Register 7272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 7282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 7292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IA32_DR7 Dr7; 7302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Address = 0; 7312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off. 7332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.UintN = SystemContext.SystemContextIa32->Dr7; 7342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (Register == 0) { 7362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr0 = Address; 7372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G0 = 0; 7382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW0 = 0; 7392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN0 = 0; 7402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Register == 1) { 7412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr1 = Address; 7422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G1 = 0; 7432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW1 = 0; 7442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN1 = 0; 7452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Register == 2) { 7462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr2 = Address; 7472ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G2 = 0; 7482ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW2 = 0; 7492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN2 = 0; 7502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else if (Register == 3) { 7512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr3 = Address; 7522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.G3 = 0; 7532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.RW3 = 0; 7542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Dr7.Bits.LEN3 = 0; 7552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } else { 7562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_INVALID_PARAMETER; 7572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 7582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off. 7602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SystemContext.SystemContextIa32->Dr7 = Dr7.UintN; 7612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return EFI_SUCCESS; 7632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 7642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 7662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘Z1, [addr], [length]’ 7672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘Z2, [addr], [length]’ 7682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘Z3, [addr], [length]’ 7692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘Z4, [addr], [length]’ 7702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Insert hardware breakpoint/watchpoint at address addr of size length 7722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7732ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param SystemContext Register content at time of the exception 7742ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param *PacketData Pointer to the Payload data for the packet 7752ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 7772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 7782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFIAPI 7792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHInsertBreakPoint ( 7802ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 7812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *PacketData 7822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 7832ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 7842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Type; 7852ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Address; 7862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Length; 7872ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Register; 7882ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH EFI_STATUS Status; 7892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BREAK_TYPE BreakType = NotSupported; 7902ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN ErrorCode; 7912ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length); 7932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (ErrorCode > 0) { 7942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError ((UINT8)ErrorCode); 7952ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 7962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 7972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 7982ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH switch (Type) { 7992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8002ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 0: //Software breakpoint 8012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = SoftwareBreakpoint; 8022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 1: //Hardware breakpoint 8052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = InstructionExecution; 8062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 2: //Write watchpoint 8092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = DataWrite; 8102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 3: //Read watchpoint 8132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = DataRead; 8142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 4: //Access watchpoint 8172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = DataReadWrite; 8182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH default : 8212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type); 8222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError (GDB_EINVALIDBRKPOINTTYPE); 8232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 8242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 8252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH // Find next free debug register 8272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Status = FindNextFreeDebugRegister (SystemContext, &Register); 8282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (EFI_ERROR(Status)) { 8292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"No space left on device\n"); 8302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError (GDB_ENOSPACE); 8312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 8322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 8332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH // Write Address, length data at particular DR register 8352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType); 8362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (EFI_ERROR(Status)) { 8372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (Status == EFI_UNSUPPORTED) { 8392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"Not supported\n"); 8402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendNotSupported(); 8412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 8422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 8432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"Invalid argument\n"); 8452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError (GDB_EINVALIDARG); 8462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 8472ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 8482ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendSuccess (); 8502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 8512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH/** 8542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘z1, [addr], [length]’ 8552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘z2, [addr], [length]’ 8562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘z3, [addr], [length]’ 8572ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ‘z4, [addr], [length]’ 8582ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Remove hardware breakpoint/watchpoint at address addr of size length 8602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH @param *PacketData Pointer to the Payload data for the packet 8622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH**/ 8642ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 8652ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHEFIAPI 8662ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHRemoveBreakPoint ( 8672ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN EFI_SYSTEM_CONTEXT SystemContext, 8682ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN CHAR8 *PacketData 8692ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 8702ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 8712ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Type; 8722ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Address; 8732ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Length; 8742ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN Register; 8752ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BREAK_TYPE BreakType = NotSupported; 8762ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH EFI_STATUS Status; 8772ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH UINTN ErrorCode; 8782ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8792ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Parse breakpoint packet data 8802ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length); 8812ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (ErrorCode > 0) { 8822ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError ((UINT8)ErrorCode); 8832ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 8842ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 8852ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 8862ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH switch (Type) { 8873402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 8882ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 0: //Software breakpoint 8892ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = SoftwareBreakpoint; 8902ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8913402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 8922ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 1: //Hardware breakpoint 8932ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = InstructionExecution; 8942ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8953402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 8962ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 2: //Write watchpoint 8972ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = DataWrite; 8982ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 8992ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9002ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 3: //Read watchpoint 9012ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = DataRead; 9022ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 9032ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9042ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH case 4: //Access watchpoint 9052ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH BreakType = DataReadWrite; 9062ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH break; 9072ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9082ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH default : 9092ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError (GDB_EINVALIDBRKPOINTTYPE); 9102ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 9112ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 9122ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9132ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Find matching debug register 9142ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register); 9152ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (EFI_ERROR(Status)) { 9162ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9172ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (Status == EFI_UNSUPPORTED) { 9182ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"Not supported.\n"); 9192ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendNotSupported(); 9202ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 9212ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 9222ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9232ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"No matching register found.\n"); 9242ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError (GDB_ENOSPACE); 9252ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 9262ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 9272ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9282ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH //Remove breakpoint 9292ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Status = DisableDebugRegister(SystemContext, Register); 9302ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH if (EFI_ERROR(Status)) { 9312ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH Print ((CHAR16 *)L"Invalid argument.\n"); 9322ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendError (GDB_EINVALIDARG); 9332ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return; 9342ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH } 9352ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9362ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH SendSuccess (); 9372ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 9382ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9392ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9402ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHVOID 9412ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHInitializeProcessor ( 9422ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH VOID 9432ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 9442ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 9452ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 9462ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9472ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHBOOLEAN 9482ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHValidateAddress ( 9492ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH IN VOID *Address 9502ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 9512ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 9522ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return TRUE; 9532ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 9542ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 9552ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHBOOLEAN 9562ef2b01e07c02db339f34004445734a2dbdd80e1AJFISHValidateException ( 9573402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron IN EFI_EXCEPTION_TYPE ExceptionType, 9583402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron IN OUT EFI_SYSTEM_CONTEXT SystemContext 9592ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH ) 9602ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH{ 9612ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH return TRUE; 9622ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH} 9632ef2b01e07c02db339f34004445734a2dbdd80e1AJFISH 964