/** @file

Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "Edb.h"

CHAR16  *mBranchTypeStr[] = {
  L"(CALL)",
  L"(CALLEX)",
  L"(RET)",
  L"(JMP)",
  L"(JMP8)",
};

/**

  Comvert Branch Type to string.

  @param Type        Branch Type

  @retval String     string of Branch Type.

**/
CHAR16 *
EdbBranchTypeToStr (
  IN EFI_DEBUGGER_BRANCH_TYPE  Type
  )
{
  if ((Type < 0) || (Type >= EfiDebuggerBranchTypeEbcMax)) {
    return L"(Unknown Type)";
  }

  return mBranchTypeStr[Type];
}

/**

  DebuggerCommand - CallStack.

  @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
DebuggerCallStack (
  IN     CHAR16                     *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE         ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT         SystemContext
  )
{
  INTN                            Index;
  UINTN                           SubIndex;
  CHAR8                           *FuncName;
  EFI_DEBUGGER_CALLSTACK_CONTEXT  *CallStackEntry;
  BOOLEAN                         ShowParameter;
  UINTN                           ParameterNumber;

  ShowParameter   = FALSE;
  ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER;

  //
  // Check argument
  //
  if (CommandArg != NULL) {
    if (StriCmp (CommandArg, L"c") == 0) {
      //
      // Clear Call-Stack
      //
      DebuggerPrivate->CallStackEntryCount = 0;
      ZeroMem (DebuggerPrivate->CallStackEntry, sizeof (DebuggerPrivate->CallStackEntry));
      EDBPrint (L"Call-Stack is cleared\n");
      return EFI_DEBUG_CONTINUE;
    } else if (StriCmp (CommandArg, L"p") == 0) {
      //
      // Print Call-Stack with parameter
      //
      ShowParameter = TRUE;
      CommandArg    = StrGetNextTokenLine (L" ");
      if (CommandArg != NULL) {
        //
        // Try to get the parameter number
        //
        ParameterNumber = Atoi (CommandArg);
        if (ParameterNumber > 16) {
          EDBPrint (L"Call-Stack argument Invalid\n");
          return EFI_DEBUG_CONTINUE;
        }
      }
    } else {
      EDBPrint (L"Call-Stack argument Invalid\n");
      return EFI_DEBUG_CONTINUE;
    }
  }

  //
  // Check CallStack Entry Count
  //
  if (DebuggerPrivate->CallStackEntryCount == 0) {
    EDBPrint (L"No Call-Stack\n");
    return EFI_DEBUG_CONTINUE;
  } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
    EDBPrint (L"Call-Stack Crash, re-initialize!\n");
    DebuggerPrivate->CallStackEntryCount = 0;
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Go through each CallStack entry and print
  //
  EDBPrint (L"Call-Stack (TOP):\n");
  EDBPrint (L"         Caller             Callee        Name\n");
  EDBPrint (L"  ================== ================== ========\n");
  // EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n");
  for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) {
    //
    // Get CallStack and print
    //
    CallStackEntry = &DebuggerPrivate->CallStackEntry[Index];
    EDBPrint (
      L"  0x%016lx 0x%016lx",
      CallStackEntry->SourceAddress,
      CallStackEntry->DestAddress
      );
    FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress);
    if (FuncName != NULL) {
      EDBPrint (L" %a()", FuncName);
    }

    EDBPrint (L"\n");

    if (ShowParameter) {
      //
      // Print parameter
      //
      if (sizeof (UINTN) == sizeof (UINT64)) {
        EDBPrint (
          L"    Parameter Address (0x%016lx) (\n",
          CallStackEntry->ParameterAddr
          );
        if (ParameterNumber == 0) {
          EDBPrint (L"        )\n");
          continue;
        }

        //
        // Print each parameter
        //
        for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
          if (SubIndex % 2 == 0) {
            EDBPrint (L"        ");
          }

          EDBPrint (
            L"0x%016lx, ",
            CallStackEntry->Parameter[SubIndex]
            );
          if (SubIndex % 2 == 1) {
            EDBPrint (L"\n");
          }
        }

        if (SubIndex % 2 == 0) {
          EDBPrint (L"        ");
        }

        EDBPrint (
          L"0x%016lx\n",
          CallStackEntry->Parameter[SubIndex]
          );
        EDBPrint (L"        )\n");
        //
        // break only for parameter
        //
        if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) &&
            (Index != 0))
        {
          if (SetPageBreak ()) {
            break;
          }
        }
      } else {
        EDBPrint (
          L"    Parameter Address (0x%08x) (\n",
          CallStackEntry->ParameterAddr
          );
        if (ParameterNumber == 0) {
          EDBPrint (L"        )\n");
          continue;
        }

        //
        // Print each parameter
        //
        for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
          if (SubIndex % 4 == 0) {
            EDBPrint (L"        ");
          }

          EDBPrint (
            L"0x%08x, ",
            CallStackEntry->Parameter[SubIndex]
            );
          if (SubIndex % 4 == 3) {
            EDBPrint (L"\n");
          }
        }

        if (SubIndex % 4 == 0) {
          EDBPrint (L"        ");
        }

        EDBPrint (
          L"0x%08x\n",
          CallStackEntry->Parameter[SubIndex]
          );
        EDBPrint (L"        )\n");
        //
        // break only for parameter
        //
        if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) &&
            (Index != 0))
        {
          if (SetPageBreak ()) {
            break;
          }
        }
      }
    }
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - InstructionBranch.

  @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
DebuggerInstructionBranch (
  IN     CHAR16                     *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE         ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT         SystemContext
  )
{
  UINTN  Index;

  //
  // Check argument
  //
  if (CommandArg != NULL) {
    if (StriCmp (CommandArg, L"c") == 0) {
      //
      // Clear Trace
      //
      DebuggerPrivate->TraceEntryCount = 0;
      ZeroMem (DebuggerPrivate->TraceEntry, sizeof (DebuggerPrivate->TraceEntry));
      EDBPrint (L"Instruction Trace is cleared\n");
    } else {
      EDBPrint (L"Trace argument Invalid\n");
    }

    return EFI_DEBUG_CONTINUE;
  }

  //
  // Check Trace Entry Count
  //
  if (DebuggerPrivate->TraceEntryCount == 0) {
    EDBPrint (L"No Instruction Trace\n");
    return EFI_DEBUG_CONTINUE;
  } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) {
    EDBPrint (L"Instruction Trace Crash, re-initialize!\n");
    DebuggerPrivate->TraceEntryCount = 0;
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Go through each Trace entry and print
  //
  EDBPrint (L"Instruction Trace (->Latest):\n");
  EDBPrint (L"    Source Addr        Destination Addr   Type\n");
  EDBPrint (L"  ================== ================== ========\n");
  // EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000  (CALLEX)\n");
  for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) {
    EDBPrint (
      L"  0x%016lx 0x%016lx  %s\n",
      DebuggerPrivate->TraceEntry[Index].SourceAddress,
      DebuggerPrivate->TraceEntry[Index].DestAddress,
      EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type)
      );
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}
