/** @file
  Basic commands and command processing infrastructure for EBL

  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Ebl.h"
#include <Protocol/DiskIo.h>
#include <Protocol/BlockIo.h>

UINTN             mCmdTableMaxIndex = EBL_MAX_COMMAND_COUNT;
UINTN             mCmdTableNextFreeIndex = 0;
EBL_COMMAND_TABLE *mCmdTable[EBL_MAX_COMMAND_COUNT];

/**
  Converts a lowercase Ascii character to upper one

  If Chr is lowercase Ascii character, then converts it to upper one.

  If Value >= 0xA0, then ASSERT().
  If (Value & 0x0F) >= 0x0A, then ASSERT().

  @param  chr   one Ascii character

  @return The uppercase value of Ascii character

**/
STATIC
CHAR8
AsciiToUpper (
  IN      CHAR8                     Chr
  )
{
  return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);
}


/**
  Case insensitive comparison of two Null-terminated Unicode strings with maximum
  lengths, and returns the difference between the first mismatched Unicode
  characters.
  This function compares the Null-terminated Unicode string FirstString to the
  Null-terminated Unicode string SecondString. At most, Length Unicode
  characters will be compared. If Length is 0, then 0 is returned. If
  FirstString is identical to SecondString, then 0 is returned. Otherwise, the
  value returned is the first mismatched Unicode character in SecondString
  subtracted from the first mismatched Unicode character in FirstString.

  @param  FirstString   Pointer to a Null-terminated ASCII string.
  @param  SecondString  Pointer to a Null-terminated ASCII string.
  @param  Length        Max length to compare.

  @retval 0   FirstString is identical to SecondString using case insensitive
              comparisons.
  @retval !=0 FirstString is not identical to SecondString using case
              insensitive comparisons.

**/
INTN
EFIAPI
AsciiStrniCmp (
  IN      CONST CHAR8               *FirstString,
  IN      CONST CHAR8               *SecondString,
  IN      UINTN                     Length
  )
{
  if (Length == 0) {
    return 0;
  }

  while ((AsciiToUpper (*FirstString) != '\0') &&
         (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString)) &&
         (Length > 1)) {
    FirstString++;
    SecondString++;
    Length--;
  }

  return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);
}



/**
  Add a command to the mCmdTable. If there is no free space in the command
  table ASSERT. The mCmdTable is maintained in alphabetical order and the
  new entry is inserted into its sorted position.

  @param  Entry   Command Entry to add to the CmdTable

**/
VOID
EFIAPI
EblAddCommand (
  IN const EBL_COMMAND_TABLE   *Entry
  )
{
  UINTN               Count;

  if (mCmdTableNextFreeIndex == EBL_MAX_COMMAND_COUNT) {
    //
    // Ran out of space to store commands. Increase EBL_MAX_COMMAND_COUNT
    //
    ASSERT (FALSE);
    return;
  }

  //
  // Add command and Insertion sort array in the process
  //
  mCmdTable[mCmdTableNextFreeIndex] = (EBL_COMMAND_TABLE *)Entry;
  if (mCmdTableNextFreeIndex != 0) {
    for (Count = mCmdTableNextFreeIndex; Count > 0; Count--) {
      if (AsciiStriCmp (mCmdTable[Count - 1]->Name, Entry->Name) <= 0) {
        break;
      }

      mCmdTable[Count] = mCmdTable[Count - 1];
    }
    mCmdTable[Count] = (EBL_COMMAND_TABLE *)Entry;
  }

  mCmdTableNextFreeIndex++;
}


/**
  Add an set of commands to the command table. Most commonly used on static
  array of commands.

  @param  EntryArray   Pointer to array of command entries
  @param  ArrayCount   Number of command entries to add

**/
VOID
EFIAPI
EblAddCommands (
  IN const EBL_COMMAND_TABLE   *EntryArray,
  IN UINTN                     ArrayCount
  )
{
  UINTN   Index;

  for (Index = 0; Index < ArrayCount; Index++) {
    EblAddCommand (&EntryArray[Index]);
  }
}


EBL_ADD_COMMAND_PROTOCOL gEblAddCommand = {
  EblAddCommand,
  EblAddCommands,
  EblGetCharKey,
  EblAnyKeyToContinueQtoQuit
};



/**
  Return the best matching command for the passed in command name. The match
  does not have to be exact, it just needs to be unique. This enables commands
  to be shortened to the smallest set of starting characters that is unique.

  @param  CommandName   Name of command to search for

  @return NULL  CommandName did not match or was not unique
          Other Pointer to EBL_COMMAND_TABLE entry for CommandName

**/
EBL_COMMAND_TABLE *
EblGetCommand (
  IN CHAR8    *CommandName
  )
{
  UINTN               Index;
  UINTN               BestMatchCount;
  UINTN               Length;
  EBL_COMMAND_TABLE   *Match;
  CHAR8               *Str;

  Length = AsciiStrLen (CommandName);
  Str = AsciiStrStr (CommandName, ".");
  if (Str != NULL) {
    // If the command includes a trailing . command extension skip it for the match.
    // Example: hexdump.4
    Length = (UINTN)(Str - CommandName);
  }

  for (Index = 0, BestMatchCount = 0, Match = NULL; Index < mCmdTableNextFreeIndex; Index++) {
    if (AsciiStriCmp (mCmdTable[Index]->Name,  CommandName) == 0) {
      // match a command exactly
      return mCmdTable[Index];
    }

    if (AsciiStrniCmp (CommandName, mCmdTable[Index]->Name, Length) == 0)  {
      // partial match, so keep looking to make sure there is only one partial match
      BestMatchCount++;
      Match = mCmdTable[Index];
    }
  }

  if (BestMatchCount == 1) {
    return Match;
  }

  //
  // We had no matches or too many matches
  //
  return NULL;
}


UINTN
CountNewLines (
  IN CHAR8  *Str
  )
{
  UINTN Count;

  if (Str == NULL) {
    return 0;
  }

  for (Count = 0; *Str != '\0'; Str++) {
    if (Str[Count] == '\n') {
      Count++;
    }
  }

  return Count;
}


/**
  List out help information on all the commands or print extended information
  about a specific passed in command.

  Argv[0] - "help"
  Argv[1] - Command to display help about

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblHelpCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN   Index;
  CHAR8   *Ptr;
  UINTN   CurrentRow = 0;

  if (Argc == 1) {
    // Print all the commands
    AsciiPrint ("Embedded Boot Loader (EBL) commands (help command for more info):\n");
    CurrentRow++;
    for (Index = 0; Index < mCmdTableNextFreeIndex; Index++) {
      EblSetTextColor (EFI_YELLOW);
      AsciiPrint (" %a", mCmdTable[Index]->Name);
      EblSetTextColor (0);
      AsciiPrint ("%a\n", mCmdTable[Index]->HelpSummary);
      // Handle multi line help summaries
      CurrentRow += CountNewLines (mCmdTable[Index]->HelpSummary);
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
        break;
      }
    }
  } else if (Argv[1] != NULL) {
    // Print specific help
    for (Index = 0, CurrentRow = 0; Index < mCmdTableNextFreeIndex; Index++) {
      if (AsciiStriCmp (Argv[1], mCmdTable[Index]->Name) == 0) {
        Ptr = (mCmdTable[Index]->Help == NULL) ? mCmdTable[Index]->HelpSummary : mCmdTable[Index]->Help;
        AsciiPrint ("%a%a\n", Argv[1], Ptr);
        // Handle multi line help summaries
        CurrentRow += CountNewLines (Ptr);
        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
          break;
        }
      }
    }
  }

  return EFI_SUCCESS;
}


/**
  Exit the EBL. If the command processor sees EFI_ABORTED return status it will
  exit the EBL.

  Argv[0] - "exit"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_ABORTED

**/
EFI_STATUS
EFIAPI
EblExitCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS              Status;
  UINTN                   MemoryMapSize;
  EFI_MEMORY_DESCRIPTOR   *MemoryMap;
  UINTN                   MapKey;
  UINTN                   DescriptorSize;
  UINT32                  DescriptorVersion;
  UINTN                   Pages;

  if (Argc > 1) {
    if (AsciiStriCmp (Argv[1], "efi") != 0) {
      return EFI_ABORTED;
    }
  } else if (Argc == 1) {
    return EFI_ABORTED;
  }

  MemoryMap = NULL;
  MemoryMapSize = 0;
  do {
    Status = gBS->GetMemoryMap (
                    &MemoryMapSize,
                    MemoryMap,
                    &MapKey,
                    &DescriptorSize,
                    &DescriptorVersion
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {

      Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
      MemoryMap = AllocatePages (Pages);

      //
      // Get System MemoryMap
      //
      Status = gBS->GetMemoryMap (
                      &MemoryMapSize,
                      MemoryMap,
                      &MapKey,
                      &DescriptorSize,
                      &DescriptorVersion
                      );
      // Don't do anything between the GetMemoryMap() and ExitBootServices()
      if (!EFI_ERROR (Status)) {
        Status = gBS->ExitBootServices (gImageHandle, MapKey);
        if (EFI_ERROR (Status)) {
          FreePages (MemoryMap, Pages);
          MemoryMap = NULL;
          MemoryMapSize = 0;
        }
      }
    }
  } while (EFI_ERROR (Status));

  //
  // At this point it is very dangerous to do things EFI as most of EFI is now gone.
  // This command is useful if you are working with a debugger as it will shutdown
  // DMA and other things that could break a soft resets.
  //
  CpuDeadLoop ();

  // Should never get here, but makes the compiler happy
  return EFI_ABORTED;
}


/**
  Update the screen by decrementing the timeout value.
  This AsciiPrint has to match the AsciiPrint in
  EblPauseCmd.

  @param  ElaspedTime   Current timeout value remaining

**/
VOID
EFIAPI
EblPauseCallback (
  IN  UINTN   ElapsedTime
  )
{
  AsciiPrint ("\b\b\b\b\b\b\b\b\b\b\b\b   \b\b%3d seconds", ElapsedTime);
}

/**
  Pause until a key is pressed and abort the remaining commands on the command
  line. If no key is pressed continue processing the command line. This command
  allows the user to stop an operation from happening and return control to the
  command prompt.

  Argv[0] - "pause"
  Argv[1] - timeout value is decimal seconds

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS  Timeout expired with no input
  @return EFI_TIMEOUT  Stop processing other commands on the same command line

**/
EFI_STATUS
EFIAPI
EblPauseCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS      Status;
  UINTN           Delay;
  EFI_INPUT_KEY   Key;

  Delay = (Argc == 1)? 10 : AsciiStrDecimalToUintn (Argv[1]);

  AsciiPrint ("Hit any key to break. You have %3d seconds", Delay);
  Status = EblGetCharKey (&Key, Delay, EblPauseCallback);
  AsciiPrint ("\n");

  // If we timeout then the pause succeeded thus return success
  // If we get a key return timeout to stop other command on this cmd line
  return (Status == EFI_SUCCESS) ? EFI_TIMEOUT : EFI_SUCCESS;;
}


/**
  On a debug build issue a software breakpoint to enter the debugger

  Argv[0] - "break"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblBreakPointCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  CpuBreakpoint ();
  return EFI_SUCCESS;
}


/**
  Reset the system. If no Argument do a Cold reset. If argument use that reset type
  (W)arm = Warm Reset
  (S)hutdown = Shutdown Reset

  Argv[0] - "reset"
  Argv[1] - warm or shutdown reset type

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblResetCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_RESET_TYPE    ResetType;

  ResetType = EfiResetCold;
  if (Argc > 1) {
    switch (*Argv[1]) {
    case 'W':
    case 'w':
      ResetType = EfiResetWarm;
      break;
    case 'S':
    case 's':
      ResetType = EfiResetShutdown;
    }
  }

  gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
  return EFI_SUCCESS;
}


/**
  Toggle page break global. This turns on and off prompting to Quit or hit any
  key to continue when a command is about to scroll the screen with its output

  Argv[0] - "page"
  Argv[1] - on or off

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblPageCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  if (Argc <= 1) {
    // toggle setting
    gPageBreak = (gPageBreak) ? FALSE : TRUE;
  } else {
    // use argv to set the value
    if ((Argv[1][0] == 'o') || (Argv[1][0] == 'O')) {
      if ((Argv[1][1] == 'n') || (Argv[1][1] == 'N')) {
        gPageBreak = TRUE;
      } else if ((Argv[1][1] == 'f') || (Argv[1][1] == 'F')) {
        gPageBreak = FALSE;
      } else {
        return EFI_INVALID_PARAMETER;
      }
    }
  }
  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
EblSleepCmd (
  IN UINTN Argc,
  IN CHAR8 **Argv
  )
{
  UINTN Delay;

  Delay = (Argc == 1)? 10 : AsciiStrDecimalToUintn (Argv[1]);

  gBS->Stall (Delay * 1000000);

  return EFI_SUCCESS;
}

CHAR8
ConvertToTextLine (
  IN CHAR8  Character
  )
{
  if (Character < ' ' || Character > '~') {
    return '.';
  } else {
    return Character;
  }
}

UINTN
GetBytes (
  IN UINT8  *Address,
  IN UINTN  Bytes
  )
{
  UINTN Result = 0;

  if (Bytes >= 1) {
    Result = *Address++;
  }
  if (Bytes >= 2) {
    Result = (Result << 8) + *Address++;
  }
  if (Bytes >= 3) {
    Result = (Result << 8) + *Address++;
  }
  return Result;
}

CHAR8 mBlanks[] = "                                           ";

EFI_STATUS
OutputData (
  IN UINT8  *Address,
  IN UINTN  Length,
  IN UINTN  Width,
  IN UINTN  Offset
  )
{
  UINT8 *EndAddress;
  UINTN Line;
  CHAR8 TextLine[0x11];
  UINTN CurrentRow = 0;
  UINTN Bytes;
  UINTN Spaces   = 0;
  CHAR8 Blanks[80];

  AsciiStrCpyS (Blanks, sizeof Blanks, mBlanks);
  for (EndAddress = Address + Length; Address < EndAddress; Offset += Line) {
    AsciiPrint ("%08x: ", Offset);
    for (Line = 0; (Line < 0x10) && (Address < EndAddress);) {
      Bytes = EndAddress - Address;

      switch (Width) {
        case 4:
          if (Bytes >= 4) {
            AsciiPrint ("%08x ", *((UINT32 *)Address));
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
          } else {
            AsciiPrint ("%08x ", GetBytes(Address, Bytes));
            Address += Bytes;
            Line    += Bytes;
          }
          break;

        case 2:
          if (Bytes >= 2) {
            AsciiPrint ("%04x ", *((UINT16 *)Address));
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
          } else {
            AsciiPrint ("%04x ", GetBytes(Address, Bytes));
            Address += Bytes;
            Line    += Bytes;
          }
          break;

        case 1:
          AsciiPrint ("%02x ", *((UINT8 *)Address));
          TextLine[Line++] = ConvertToTextLine(*Address++);
          break;

        default:
          AsciiPrint ("Width must be 1, 2, or 4!\n");
          return EFI_INVALID_PARAMETER;
      }
    }

    // Pad spaces
    if (Line < 0x10) {
      switch (Width) {
        case 4:
          Spaces = 9 * ((0x10 - Line)/4);
          break;
        case 2:
          Spaces = 5 * ((0x10 - Line)/2);
          break;
        case 1:
          Spaces = 3 * (0x10 - Line);
          break;
      }

      Blanks[Spaces] = '\0';

      AsciiPrint(Blanks);

      Blanks[Spaces] = ' ';
    }

    TextLine[Line] = 0;
    AsciiPrint ("|%a|\n", TextLine);

    if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
      return EFI_END_OF_FILE;
    }
  }

  if (Length % Width != 0) {
    AsciiPrint ("%08x\n", Offset);
  }

  return EFI_SUCCESS;
}


/**
  See if command contains .# where # is a number. Return # as the Width
  or 1 as the default Width for commands.

  Example hexdump.4 returns a width of 4.

  @param  Argv   Argv[0] is the command name

  @return Width of command

**/
UINTN
WidthFromCommandName (
  IN CHAR8  *Argv,
  IN UINTN  Default
  )
{
  CHAR8         *Str;
  UINTN         Width;

  //Hexdump.2 HexDump.4 mean use a different width
  Str = AsciiStrStr (Argv, ".");
  if (Str != NULL) {
    Width = AsciiStrDecimalToUintn (Str + 1);
    if (Width == 0) {
      Width = Default;
    }
  } else {
    // Default answer
    return Default;
  }

  return Width;
}

#define HEXDUMP_CHUNK 1024

/**
  Toggle page break global. This turns on and off prompting to Quit or hit any
  key to continue when a command is about to scroll the screen with its output

  Argv[0] - "hexdump"[.#]  # is optional 1,2, or 4 for width
  Argv[1] - Device or File to dump.
  Argv[2] - Optional offset to start dumping
  Argv[3] - Optional number of bytes to dump

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblHexdumpCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_OPEN_FILE *File;
  VOID          *Location;
  UINTN         Size;
  UINTN         Width;
  UINTN         Offset = 0;
  EFI_STATUS    Status;
  UINTN         Chunk = HEXDUMP_CHUNK;

  if ((Argc < 2) || (Argc > 4)) {
    return EFI_INVALID_PARAMETER;
  }

  Width = WidthFromCommandName (Argv[0], 1);
  if ((Width != 1) && (Width != 2) && (Width != 4)) {
    return EFI_INVALID_PARAMETER;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    return EFI_NOT_FOUND;
  }

  Location = AllocatePool (Chunk);
  Size     = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : EfiTell (File, NULL);

  Offset = 0;
  if (Argc > 2) {
    Offset = AsciiStrHexToUintn (Argv[2]);
    if (Offset > 0) {
      // Make sure size includes the part of the file we have skipped
      Size += Offset;
    }
  }

  Status = EfiSeek (File, Offset, EfiSeekStart);
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  for (; Offset + HEXDUMP_CHUNK <= Size; Offset += Chunk) {
    Chunk = HEXDUMP_CHUNK;
    Status = EfiRead (File, Location, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint ("Error reading file content\n");
      goto Exit;
    }

    Status = OutputData (Location, Chunk, Width, File->BaseOffset + Offset);
    if (EFI_ERROR(Status)) {
      if (Status == EFI_END_OF_FILE) {
        Status = EFI_SUCCESS;
      }
      goto Exit;
    }
  }

  // Any left over?
  if (Offset < Size) {
    Chunk = Size - Offset;
    Status = EfiRead (File, Location, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint ("Error reading file content\n");
      goto Exit;
    }

    Status = OutputData (Location, Chunk, Width, File->BaseOffset + Offset);
    if (EFI_ERROR(Status)) {
      if (Status == EFI_END_OF_FILE) {
        Status = EFI_SUCCESS;
      }
      goto Exit;
    }
  }

Exit:
  EfiClose (File);

  FreePool (Location);

  return EFI_SUCCESS;
}


GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdTemplate[] =
{
  {
    "reset",
    " [type]; Reset system. type = [warm] [shutdown] default is cold reset",
    NULL,
    EblResetCmd
  },
  {
    "exit",
    "; Exit EBL",
    NULL,
    EblExitCmd
  },
  {
    "help",
    " [cmd]; Help on cmd or a list of all commands if cmd is ommited",
    NULL,
    EblHelpCmd
  },
  {
    "break",
    "; Generate debugging breakpoint",
    NULL,
    EblBreakPointCmd
  },
  {
    "page",
    " [on|off]]; toggle promting on command output larger than screen",
    NULL,
    EblPageCmd
  },
  {
    "pause",
    " [sec]; Pause for sec[10] seconds. ",
    NULL,
    EblPauseCmd
  },
  {
    "sleep",
    " [sec]; Sleep for sec[10] seconds. ",
    NULL,
    EblSleepCmd
  },
  {
    "hexdump",
    "[.{1|2|4}] filename [Offset] [Size]; dump a file as hex .width",
    NULL,
    EblHexdumpCmd
  }
};


EFI_HANDLE  gExternalCmdHandle = NULL;

/**
  Initialize the commands in this in this file
**/
VOID
EblInitializeCmdTable (
  VOID
  )
{

  EblAddCommands (mCmdTemplate, sizeof (mCmdTemplate)/sizeof (EBL_COMMAND_TABLE));

  gBS->InstallProtocolInterface (
        &gExternalCmdHandle,
        &gEfiEblAddCommandProtocolGuid,
        EFI_NATIVE_INTERFACE,
        &gEblAddCommand
        );

}


VOID
EblShutdownExternalCmdTable (
  VOID
  )
{
  gBS->UninstallProtocolInterface (gExternalCmdHandle, &gEfiEblAddCommandProtocolGuid,  &gEblAddCommand);
}


