/*++ | |
Copyright (c) 2007, Intel Corporation | |
All rights reserved. This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
Module Name: | |
EdbCmdBreakpoint.c | |
Abstract: | |
--*/ | |
#include "Edb.h" | |
BOOLEAN | |
IsEBCBREAK3 ( | |
IN UINTN Address | |
) | |
/*++ | |
Routine Description: | |
Check whether current IP is EBC BREAK3 instruction | |
Arguments: | |
Address - EBC IP address. | |
Returns: | |
TRUE - Current IP is EBC BREAK3 instruction | |
FALSE - Current IP is not EBC BREAK3 instruction | |
--*/ | |
{ | |
if (GET_OPCODE(Address) != OPCODE_BREAK) { | |
return FALSE; | |
} | |
if (GET_OPERANDS (Address) != 3) { | |
return FALSE; | |
} else { | |
return TRUE; | |
} | |
} | |
BOOLEAN | |
DebuggerBreakpointIsDuplicated ( | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN UINTN Address | |
) | |
/*++ | |
Routine Description: | |
Check whether the Address is already set in breakpoint | |
Arguments: | |
DebuggerPrivate - EBC Debugger private data structure | |
Address - Breakpoint Address | |
Returns: | |
TRUE - breakpoint is found | |
FALSE - breakpoint is not found | |
--*/ | |
{ | |
UINTN Index; | |
// | |
// Go through each breakpoint context | |
// | |
for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { | |
if (DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress == Address) { | |
// | |
// Found it | |
// | |
return TRUE; | |
} | |
} | |
// | |
// Not found | |
// | |
return FALSE; | |
} | |
EFI_STATUS | |
DebuggerBreakpointAdd ( | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN UINTN Address | |
) | |
/*++ | |
Routine Description: | |
Add this breakpoint | |
Arguments: | |
DebuggerPrivate - EBC Debugger private data structure | |
Address - Breakpoint Address | |
Returns: | |
EFI_SUCCESS - breakpoint added successfully | |
EFI_ALREADY_STARTED - breakpoint is already added | |
EFI_OUT_OF_RESOURCES - all the breakpoint entries are used | |
--*/ | |
{ | |
// | |
// Check duplicated breakpoint | |
// | |
if (DebuggerBreakpointIsDuplicated (DebuggerPrivate, Address)) { | |
EDBPrint (L"Breakpoint duplicated!\n"); | |
return EFI_ALREADY_STARTED; | |
} | |
// | |
// Check whether the address is a breakpoint 3 instruction | |
// | |
if (IsEBCBREAK3 (Address)) { | |
EDBPrint (L"Breakpoint can not be set on BREAK 3 instruction!\n"); | |
return EFI_ALREADY_STARTED; | |
} | |
if (DebuggerPrivate->DebuggerBreakpointCount >= EFI_DEBUGGER_BREAKPOINT_MAX) { | |
EDBPrint (L"Breakpoint out of resource!\n"); | |
return EFI_OUT_OF_RESOURCES; | |
} | |
// | |
// Set the breakpoint | |
// | |
DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].BreakpointAddress = Address; | |
DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].State = TRUE; | |
DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction = 0; | |
CopyMem ( | |
&DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction, | |
(VOID *)Address, | |
sizeof(UINT16) | |
); | |
DebuggerPrivate->DebuggerBreakpointCount ++; | |
// | |
// Done | |
// | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
DebuggerBreakpointDel ( | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN UINTN Index | |
) | |
/*++ | |
Routine Description: | |
Delete this breakpoint | |
Arguments: | |
DebuggerPrivate - EBC Debugger private data structure | |
Index - Breakpoint Index | |
Returns: | |
EFI_SUCCESS - breakpoint deleted successfully | |
EFI_NOT_FOUND - breakpoint not found | |
--*/ | |
{ | |
UINTN BpIndex; | |
if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || | |
(Index >= DebuggerPrivate->DebuggerBreakpointCount)) { | |
return EFI_NOT_FOUND; | |
} | |
// | |
// Delete this breakpoint | |
// | |
for (BpIndex = Index; BpIndex < DebuggerPrivate->DebuggerBreakpointCount - 1; BpIndex++) { | |
DebuggerPrivate->DebuggerBreakpointContext[BpIndex] = DebuggerPrivate->DebuggerBreakpointContext[BpIndex + 1]; | |
} | |
ZeroMem ( | |
&DebuggerPrivate->DebuggerBreakpointContext[BpIndex], | |
sizeof(DebuggerPrivate->DebuggerBreakpointContext[BpIndex]) | |
); | |
DebuggerPrivate->DebuggerBreakpointCount --; | |
// | |
// Done | |
// | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
DebuggerBreakpointDis ( | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN UINTN Index | |
) | |
/*++ | |
Routine Description: | |
Disable this breakpoint | |
Arguments: | |
DebuggerPrivate - EBC Debugger private data structure | |
Index - Breakpoint Index | |
Returns: | |
EFI_SUCCESS - breakpoint disabled successfully | |
EFI_NOT_FOUND - breakpoint not found | |
--*/ | |
{ | |
if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || | |
(Index >= DebuggerPrivate->DebuggerBreakpointCount)) { | |
return EFI_NOT_FOUND; | |
} | |
// | |
// Disable this breakpoint | |
// | |
DebuggerPrivate->DebuggerBreakpointContext[Index].State = FALSE; | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
DebuggerBreakpointEn ( | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN UINTN Index | |
) | |
/*++ | |
Routine Description: | |
Enable this breakpoint | |
Arguments: | |
DebuggerPrivate - EBC Debugger private data structure | |
Index - Breakpoint Index | |
Returns: | |
EFI_SUCCESS - breakpoint enabled successfully | |
EFI_NOT_FOUND - breakpoint not found | |
--*/ | |
{ | |
if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || | |
(Index >= DebuggerPrivate->DebuggerBreakpointCount)) { | |
return EFI_NOT_FOUND; | |
} | |
// | |
// Enable this breakpoint | |
// | |
DebuggerPrivate->DebuggerBreakpointContext[Index].State = TRUE; | |
return EFI_SUCCESS; | |
} | |
EFI_DEBUG_STATUS | |
DebuggerBreakpointList ( | |
IN CHAR16 *CommandArg, | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN EFI_EXCEPTION_TYPE ExceptionType, | |
IN OUT EFI_SYSTEM_CONTEXT SystemContext | |
) | |
/*++ | |
Routine Description: | |
DebuggerCommand - BreakpointList | |
Arguments: | |
CommandArg - The argument for this command | |
DebuggerPrivate - EBC Debugger private data structure | |
InterruptType - Interrupt type. | |
SystemContext - EBC system context. | |
Returns: | |
EFI_DEBUG_CONTINUE - formal return value | |
--*/ | |
{ | |
UINTN Index; | |
// | |
// Check breakpoint cound | |
// | |
if (DebuggerPrivate->DebuggerBreakpointCount == 0) { | |
EDBPrint (L"No Breakpoint\n"); | |
return EFI_DEBUG_CONTINUE; | |
} else if (DebuggerPrivate->DebuggerBreakpointCount > EFI_DEBUGGER_BREAKPOINT_MAX) { | |
EDBPrint (L"Breakpoint too many!\n"); | |
DebuggerPrivate->DebuggerBreakpointCount = 0; | |
return EFI_DEBUG_CONTINUE; | |
} | |
// | |
// Go through each breakpoint | |
// | |
EDBPrint (L"Breakpoint :\n"); | |
EDBPrint (L" Index Address Status\n"); | |
EDBPrint (L"======= ================== ========\n"); | |
//EDBPrint (L" 1 0xFFFFFFFF00000000 *\n"); | |
//EDBPrint (L" 12 0x00000000FFFFFFFF\n"); | |
for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { | |
// | |
// Print the breakpoint | |
// | |
EDBPrint (L" %2d 0x%016lx", Index, DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress); | |
if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) { | |
EDBPrint (L" *\n"); | |
} else { | |
EDBPrint (L"\n"); | |
} | |
} | |
// | |
// Done | |
// | |
return EFI_DEBUG_CONTINUE; | |
} | |
EFI_DEBUG_STATUS | |
DebuggerBreakpointSet ( | |
IN CHAR16 *CommandArg, | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN EFI_EXCEPTION_TYPE ExceptionType, | |
IN OUT EFI_SYSTEM_CONTEXT SystemContext | |
) | |
/*++ | |
Routine Description: | |
DebuggerCommand - BreakpointSet | |
Arguments: | |
CommandArg - The argument for this command | |
DebuggerPrivate - EBC Debugger private data structure | |
InterruptType - Interrupt type. | |
SystemContext - EBC system context. | |
Returns: | |
EFI_DEBUG_CONTINUE - formal return value | |
--*/ | |
{ | |
UINTN Address; | |
EFI_STATUS Status; | |
if (CommandArg == NULL) { | |
EDBPrint (L"BreakpointSet Argument error!\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
// | |
// Get breakpoint address | |
// | |
Status = Symboltoi (CommandArg, &Address); | |
if (EFI_ERROR (Status)) { | |
if (Status == EFI_NOT_FOUND) { | |
Address = Xtoi(CommandArg); | |
} else { | |
// | |
// Something wrong, let Symboltoi print error info. | |
// | |
EDBPrint (L"Command Argument error!\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
} | |
// | |
// Add breakpoint | |
// | |
Status = DebuggerBreakpointAdd (DebuggerPrivate, Address); | |
if (EFI_ERROR(Status)) { | |
EDBPrint (L"BreakpointSet error!\n"); | |
} | |
// | |
// Done | |
// | |
return EFI_DEBUG_CONTINUE; | |
} | |
EFI_DEBUG_STATUS | |
DebuggerBreakpointClear ( | |
IN CHAR16 *CommandArg, | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN EFI_EXCEPTION_TYPE ExceptionType, | |
IN OUT EFI_SYSTEM_CONTEXT SystemContext | |
) | |
/*++ | |
Routine Description: | |
DebuggerCommand - BreakpointClear | |
Arguments: | |
CommandArg - The argument for this command | |
DebuggerPrivate - EBC Debugger private data structure | |
InterruptType - Interrupt type. | |
SystemContext - EBC system context. | |
Returns: | |
EFI_DEBUG_CONTINUE - formal return value | |
--*/ | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
UINTN Address; | |
UINT16 OldInstruction; | |
if (CommandArg == NULL) { | |
EDBPrint (L"BreakpointClear Argument error!\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
if (StriCmp (CommandArg, L"*") == 0) { | |
// | |
// delete all breakpoint | |
// | |
DebuggerPrivate->DebuggerBreakpointCount = 0; | |
ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof(DebuggerPrivate->DebuggerBreakpointContext)); | |
EDBPrint (L"All the Breakpoint is cleared\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
// | |
// Get breakpoint index | |
// | |
Index = Atoi(CommandArg); | |
if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) || | |
(Index >= DebuggerPrivate->DebuggerBreakpointCount)) { | |
EDBPrint (L"BreakpointClear error!\n"); | |
return EFI_DEBUG_CONTINUE; | |
} else { | |
Address = (UINTN)DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress; | |
OldInstruction = (UINT16)DebuggerPrivate->DebuggerBreakpointContext[Index].OldInstruction; | |
} | |
// | |
// Delete breakpoint | |
// | |
Status = DebuggerBreakpointDel (DebuggerPrivate, Index); | |
if (EFI_ERROR(Status)) { | |
EDBPrint (L"BreakpointClear error!\n"); | |
} | |
// | |
// Done | |
// | |
return EFI_DEBUG_CONTINUE; | |
} | |
EFI_DEBUG_STATUS | |
DebuggerBreakpointDisable ( | |
IN CHAR16 *CommandArg, | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN EFI_EXCEPTION_TYPE ExceptionType, | |
IN OUT EFI_SYSTEM_CONTEXT SystemContext | |
) | |
/*++ | |
Routine Description: | |
DebuggerCommand - BreakpointDisable | |
Arguments: | |
CommandArg - The argument for this command | |
DebuggerPrivate - EBC Debugger private data structure | |
InterruptType - Interrupt type. | |
SystemContext - EBC system context. | |
Returns: | |
EFI_DEBUG_CONTINUE - formal return value | |
--*/ | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
if (CommandArg == NULL) { | |
EDBPrint (L"BreakpointDisable Argument error!\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
if (StriCmp (CommandArg, L"*") == 0) { | |
// | |
// disable all breakpoint | |
// | |
for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { | |
Status = DebuggerBreakpointDis (DebuggerPrivate, Index); | |
} | |
EDBPrint (L"All the Breakpoint is disabled\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
// | |
// Get breakpoint index | |
// | |
Index = Atoi(CommandArg); | |
// | |
// Disable breakpoint | |
// | |
Status = DebuggerBreakpointDis (DebuggerPrivate, Index); | |
if (EFI_ERROR(Status)) { | |
EDBPrint (L"BreakpointDisable error!\n"); | |
} | |
// | |
// Done | |
// | |
return EFI_DEBUG_CONTINUE; | |
} | |
EFI_DEBUG_STATUS | |
DebuggerBreakpointEnable ( | |
IN CHAR16 *CommandArg, | |
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, | |
IN EFI_EXCEPTION_TYPE ExceptionType, | |
IN OUT EFI_SYSTEM_CONTEXT SystemContext | |
) | |
/*++ | |
Routine Description: | |
DebuggerCommand - BreakpointEnable | |
Arguments: | |
CommandArg - The argument for this command | |
DebuggerPrivate - EBC Debugger private data structure | |
InterruptType - Interrupt type. | |
SystemContext - EBC system context. | |
Returns: | |
EFI_DEBUG_CONTINUE - formal return value | |
--*/ | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
if (CommandArg == NULL) { | |
EDBPrint (L"BreakpointEnable Argument error!\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
if (StriCmp (CommandArg, L"*") == 0) { | |
// | |
// enable all breakpoint | |
// | |
for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) { | |
Status = DebuggerBreakpointEn (DebuggerPrivate, Index); | |
} | |
EDBPrint (L"All the Breakpoint is enabled\n"); | |
return EFI_DEBUG_CONTINUE; | |
} | |
// | |
// Get breakpoint index | |
// | |
Index = Atoi(CommandArg); | |
// | |
// Enable breakpoint | |
// | |
Status = DebuggerBreakpointEn (DebuggerPrivate, Index); | |
if (EFI_ERROR(Status)) { | |
EDBPrint (L"BreakpointEnable error!\n"); | |
} | |
// | |
// Done | |
// | |
return EFI_DEBUG_CONTINUE; | |
} |