/** @file

Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "Edb.h"

/**

  Check whether current IP is EBC BREAK3 instruction.

  @param  Address    EBC IP address.

  @retval TRUE       Current IP is EBC BREAK3 instruction
  @retval FALSE      Current IP is not EBC BREAK3 instruction

**/
BOOLEAN
IsEBCBREAK3 (
  IN UINTN  Address
  )
{
  if (GET_OPCODE (Address) != OPCODE_BREAK) {
    return FALSE;
  }

  if (GET_OPERANDS (Address) != 3) {
    return FALSE;
  } else {
    return TRUE;
  }
}

/**

  Check whether the Address is already set in breakpoint.

  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  Address           Breakpoint Address

  @retval TRUE              breakpoint is found
  @retval FALSE             breakpoint is not found

**/
BOOLEAN
DebuggerBreakpointIsDuplicated (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN UINTN                      Address
  )
{
  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;
}

/**

  Add this breakpoint.

  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  Address           Breakpoint Address

  @retval EFI_SUCCESS            breakpoint added successfully
  @retval EFI_ALREADY_STARTED    breakpoint is already added
  @retval EFI_OUT_OF_RESOURCES   all the breakpoint entries are used

**/
EFI_STATUS
DebuggerBreakpointAdd (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN UINTN                      Address
  )
{
  //
  // 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;
}

/**

  Delete this breakpoint.

  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  Index             Breakpoint Index

  @retval EFI_SUCCESS     breakpoint deleted successfully
  @retval EFI_NOT_FOUND   breakpoint not found

**/
EFI_STATUS
DebuggerBreakpointDel (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN UINTN                      Index
  )
{
  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++) {
    CopyMem (
      &DebuggerPrivate->DebuggerBreakpointContext[BpIndex],
      &DebuggerPrivate->DebuggerBreakpointContext[BpIndex + 1],
      sizeof (DebuggerPrivate->DebuggerBreakpointContext[BpIndex])
      );
  }

  ZeroMem (
    &DebuggerPrivate->DebuggerBreakpointContext[BpIndex],
    sizeof (DebuggerPrivate->DebuggerBreakpointContext[BpIndex])
    );

  DebuggerPrivate->DebuggerBreakpointCount--;

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**

  Disable this breakpoint.

  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  Index             Breakpoint Index

  @retval EFI_SUCCESS     breakpoint disabled successfully
  @retval EFI_NOT_FOUND   breakpoint not found

**/
EFI_STATUS
DebuggerBreakpointDis (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN UINTN                      Index
  )
{
  if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
      (Index >= DebuggerPrivate->DebuggerBreakpointCount))
  {
    return EFI_NOT_FOUND;
  }

  //
  // Disable this breakpoint
  //
  DebuggerPrivate->DebuggerBreakpointContext[Index].State = FALSE;

  return EFI_SUCCESS;
}

/**

  Enable this breakpoint.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  Index           - Breakpoint Index

  @retval EFI_SUCCESS   - breakpoint enabled successfully
  @retval EFI_NOT_FOUND - breakpoint not found

**/
EFI_STATUS
DebuggerBreakpointEn (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN UINTN                      Index
  )
{
  if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
      (Index >= DebuggerPrivate->DebuggerBreakpointCount))
  {
    return EFI_NOT_FOUND;
  }

  //
  // Enable this breakpoint
  //
  DebuggerPrivate->DebuggerBreakpointContext[Index].State = TRUE;

  return EFI_SUCCESS;
}

/**

  DebuggerCommand - BreakpointList.

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerBreakpointList (
  IN     CHAR16                     *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE         ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT         SystemContext
  )
{
  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;
}

/**

  DebuggerCommand - BreakpointSet.

  @param  CommandArg        The argument for this command
  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  ExceptionType     Exception type.
  @param  SystemContext     EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerBreakpointSet (
  IN     CHAR16                     *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE         ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT         SystemContext
  )
{
  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;
}

/**

  DebuggerCommand - BreakpointClear

  @param  CommandArg        The argument for this command
  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  ExceptionType     Exception type.
  @param  SystemContext     EBC system context.

  @retval EFI_DEBUG_CONTINUE   formal return value

**/
EFI_DEBUG_STATUS
DebuggerBreakpointClear (
  IN     CHAR16                     *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE         ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT         SystemContext
  )
{
  UINTN       Index;
  EFI_STATUS  Status;

  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 == (UINTN)-1) {
    EDBPrint (L"BreakpointClear Argument error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
      (Index >= DebuggerPrivate->DebuggerBreakpointCount))
  {
    EDBPrint (L"BreakpointClear error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Delete breakpoint
  //
  Status = DebuggerBreakpointDel (DebuggerPrivate, Index);
  if (EFI_ERROR (Status)) {
    EDBPrint (L"BreakpointClear error!\n");
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - BreakpointDisable

  @param  CommandArg        The argument for this command
  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  ExceptionType     Exception type.
  @param  SystemContext     EBC system context.

  @retval EFI_DEBUG_CONTINUE   formal return value

**/
EFI_DEBUG_STATUS
DebuggerBreakpointDisable (
  IN     CHAR16                     *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE         ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT         SystemContext
  )
{
  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);
  if (Index == (UINTN)-1) {
    EDBPrint (L"BreakpointDisable Argument error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Disable breakpoint
  //
  Status = DebuggerBreakpointDis (DebuggerPrivate, Index);
  if (EFI_ERROR (Status)) {
    EDBPrint (L"BreakpointDisable error!\n");
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**
  DebuggerCommand - BreakpointEnable.

  @param  CommandArg        The argument for this command
  @param  DebuggerPrivate   EBC Debugger private data structure
  @param  ExceptionType     Exception type.
  @param  SystemContext     EBC system context.

  @retval EFI_DEBUG_CONTINUE   formal return value

**/
EFI_DEBUG_STATUS
DebuggerBreakpointEnable (
  IN     CHAR16                     *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE         ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT         SystemContext
  )
{
  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);
  if (Index == (UINTN)-1) {
    EDBPrint (L"BreakpointEnable Argument error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Enable breakpoint
  //
  Status = DebuggerBreakpointEn (DebuggerPrivate, Index);
  if (EFI_ERROR (Status)) {
    EDBPrint (L"BreakpointEnable error!\n");
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}
