]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Ebl/Command.c
ARM Packages: Removed trailing spaces
[mirror_edk2.git] / EmbeddedPkg / Ebl / Command.c
index 7899a0f442c53816a956bb408b58d7e41a9fb7bb..7c00bcae85748505b4d02fe8fed0a40858cf2088 100644 (file)
@@ -1,10 +1,10 @@
 /** @file\r
   Basic commands and command processing infrastructure for EBL\r
 \r
-  Copyright (c) 2007, Intel Corporation<BR>\r
-  Portions copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
+  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
 \r
-  All rights reserved. This program and the accompanying materials\r
+  This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
   http://opensource.org/licenses/bsd-license.php\r
@@ -32,7 +32,7 @@ EBL_COMMAND_TABLE *mCmdTable[EBL_MAX_COMMAND_COUNT];
 \r
   @param  chr   one Ascii character\r
 \r
-  @return The uppercase value of Ascii character \r
+  @return The uppercase value of Ascii character\r
 \r
 **/\r
 STATIC\r
@@ -46,7 +46,7 @@ AsciiToUpper (
 \r
 \r
 /**\r
-  Case insensitve comparison of two Null-terminated Unicode strings with maximum\r
+  Case insensitive comparison of two Null-terminated Unicode strings with maximum\r
   lengths, and returns the difference between the first mismatched Unicode\r
   characters.\r
   This function compares the Null-terminated Unicode string FirstString to the\r
@@ -55,11 +55,11 @@ AsciiToUpper (
   FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
   value returned is the first mismatched Unicode character in SecondString\r
   subtracted from the first mismatched Unicode character in FirstString.\r
-  \r
-  @param  FirstString   Pointer to a Null-terminated ASCII string.  \r
+\r
+  @param  FirstString   Pointer to a Null-terminated ASCII string.\r
   @param  SecondString  Pointer to a Null-terminated ASCII string.\r
   @param  Length        Max length to compare.\r
-  \r
+\r
   @retval 0   FirstString is identical to SecondString using case insensitive\r
               comparisons.\r
   @retval !=0 FirstString is not identical to SecondString using case\r
@@ -85,18 +85,18 @@ AsciiStrniCmp (
     SecondString++;\r
     Length--;\r
   }\r
-  \r
+\r
   return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);\r
 }\r
 \r
 \r
 \r
 /**\r
-  Add a command to the mCmdTable. If there is no free space in the command \r
-  table ASSERT. The mCmdTable is maintained in alphabetical order and the \r
-  new entry is inserted into its sorted possition.\r
+  Add a command to the mCmdTable. If there is no free space in the command\r
+  table ASSERT. The mCmdTable is maintained in alphabetical order and the\r
+  new entry is inserted into its sorted position.\r
 \r
-  @param  Entry   Commnad Entry to add to the CmdTable\r
+  @param  Entry   Command Entry to add to the CmdTable\r
 \r
 **/\r
 VOID\r
@@ -124,7 +124,7 @@ EblAddCommand (
       if (AsciiStriCmp (mCmdTable[Count - 1]->Name, Entry->Name) <= 0) {\r
         break;\r
       }\r
-      \r
+\r
       mCmdTable[Count] = mCmdTable[Count - 1];\r
     }\r
     mCmdTable[Count] = (EBL_COMMAND_TABLE *)Entry;\r
@@ -135,11 +135,11 @@ EblAddCommand (
 \r
 \r
 /**\r
-  Add an set of commands to the command table. Most commonly used on static \r
+  Add an set of commands to the command table. Most commonly used on static\r
   array of commands.\r
 \r
   @param  EntryArray   Pointer to array of command entries\r
-  @param  ArrayCount   Number of commnad entries to add\r
+  @param  ArrayCount   Number of command entries to add\r
 \r
 **/\r
 VOID\r
@@ -167,9 +167,9 @@ EBL_ADD_COMMAND_PROTOCOL gEblAddCommand = {
 \r
 \r
 /**\r
-  Return the best matching command for the passed in command name. The match \r
-  does not have to be exact, it just needs to be unqiue. This enables commands\r
-  to be shortend to the smallest set of starting characters that is unique.\r
+  Return the best matching command for the passed in command name. The match\r
+  does not have to be exact, it just needs to be unique. This enables commands\r
+  to be shortened to the smallest set of starting characters that is unique.\r
 \r
   @param  CommandName   Name of command to search for\r
 \r
@@ -186,8 +186,16 @@ EblGetCommand (
   UINTN               BestMatchCount;\r
   UINTN               Length;\r
   EBL_COMMAND_TABLE   *Match;\r
+  CHAR8               *Str;\r
 \r
   Length = AsciiStrLen (CommandName);\r
+  Str = AsciiStrStr (CommandName, ".");\r
+  if (Str != NULL) {\r
+    // If the command includes a trailing . command extension skip it for the match.\r
+    // Example: hexdump.4\r
+    Length = (UINTN)(Str - CommandName);\r
+  }\r
+\r
   for (Index = 0, BestMatchCount = 0, Match = NULL; Index < mCmdTableNextFreeIndex; Index++) {\r
     if (AsciiStriCmp (mCmdTable[Index]->Name,  CommandName) == 0) {\r
       // match a command exactly\r
@@ -212,17 +220,37 @@ EblGetCommand (
 }\r
 \r
 \r
+UINTN\r
+CountNewLines (\r
+  IN CHAR8  *Str\r
+  )\r
+{\r
+  UINTN Count;\r
+\r
+  if (Str == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  for (Count = 0; *Str != '\0'; Str++) {\r
+    if (Str[Count] == '\n') {\r
+      Count++;\r
+    }\r
+  }\r
+\r
+  return Count;\r
+}\r
+\r
 \r
 /**\r
-  List out help information on all the commands or print extended information \r
+  List out help information on all the commands or print extended information\r
   about a specific passed in command.\r
 \r
   Argv[0] - "help"\r
   Argv[1] - Command to display help about\r
 \r
   @param  Argc   Number of command arguments in Argv\r
-  @param  Argv   Array of strings that represent the parsed command line. \r
-                 Argv[0] is the comamnd name\r
+  @param  Argv   Array of strings that represent the parsed command line.\r
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -235,23 +263,31 @@ EblHelpCmd (
 {\r
   UINTN   Index;\r
   CHAR8   *Ptr;\r
-  UINTN   CurrentRow;\r
+  UINTN   CurrentRow = 0;\r
 \r
   if (Argc == 1) {\r
     // Print all the commands\r
     AsciiPrint ("Embedded Boot Loader (EBL) commands (help command for more info):\n");\r
+    CurrentRow++;\r
     for (Index = 0; Index < mCmdTableNextFreeIndex; Index++) {\r
       EblSetTextColor (EFI_YELLOW);\r
       AsciiPrint (" %a", mCmdTable[Index]->Name);\r
       EblSetTextColor (0);\r
       AsciiPrint ("%a\n", mCmdTable[Index]->HelpSummary);\r
+      // Handle multi line help summaries\r
+      CurrentRow += CountNewLines (mCmdTable[Index]->HelpSummary);\r
+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
+        break;\r
+      }\r
     }\r
   } else if (Argv[1] != NULL) {\r
-    // Print specific help \r
+    // Print specific help\r
     for (Index = 0, CurrentRow = 0; Index < mCmdTableNextFreeIndex; Index++) {\r
       if (AsciiStriCmp (Argv[1], mCmdTable[Index]->Name) == 0) {\r
         Ptr = (mCmdTable[Index]->Help == NULL) ? mCmdTable[Index]->HelpSummary : mCmdTable[Index]->Help;\r
         AsciiPrint ("%a%a\n", Argv[1], Ptr);\r
+        // Handle multi line help summaries\r
+        CurrentRow += CountNewLines (Ptr);\r
         if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
           break;\r
         }\r
@@ -264,14 +300,14 @@ EblHelpCmd (
 \r
 \r
 /**\r
-  Exit the EBL. If the commnad processor sees EFI_ABORTED return status it will\r
+  Exit the EBL. If the command processor sees EFI_ABORTED return status it will\r
   exit the EBL.\r
 \r
   Argv[0] - "exit"\r
 \r
   @param  Argc   Number of command arguments in Argv\r
-  @param  Argv   Array of strings that represent the parsed command line. \r
-                 Argv[0] is the comamnd name\r
+  @param  Argv   Array of strings that represent the parsed command line.\r
+                 Argv[0] is the command name\r
 \r
   @return EFI_ABORTED\r
 \r
@@ -282,66 +318,66 @@ EblExitCmd (
   IN CHAR8  **Argv\r
   )\r
 {\r
-  EFI_STATUS              Status;
-  UINTN                   MemoryMapSize;
-  EFI_MEMORY_DESCRIPTOR   *MemoryMap;
-  UINTN                   MapKey;
-  UINTN                   DescriptorSize;
-  UINTN                   DescriptorVersion;
-  UINTN                   Pages;
-\r
-  if (Argc > 1) { \r
+  EFI_STATUS              Status;\r
+  UINTN                   MemoryMapSize;\r
+  EFI_MEMORY_DESCRIPTOR   *MemoryMap;\r
+  UINTN                   MapKey;\r
+  UINTN                   DescriptorSize;\r
+  UINT32                  DescriptorVersion;\r
+  UINTN                   Pages;\r
+\r
+  if (Argc > 1) {\r
     if (AsciiStriCmp (Argv[1], "efi") != 0) {\r
       return EFI_ABORTED;\r
     }\r
   } else if (Argc == 1) {\r
     return EFI_ABORTED;\r
   }\r
-  \r
-  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));
+\r
+  MemoryMap = NULL;\r
+  MemoryMapSize = 0;\r
+  do {\r
+    Status = gBS->GetMemoryMap (\r
+                    &MemoryMapSize,\r
+                    MemoryMap,\r
+                    &MapKey,\r
+                    &DescriptorSize,\r
+                    &DescriptorVersion\r
+                    );\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+      Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;\r
+      MemoryMap = AllocatePages (Pages);\r
+\r
+      //\r
+      // Get System MemoryMap\r
+      //\r
+      Status = gBS->GetMemoryMap (\r
+                      &MemoryMapSize,\r
+                      MemoryMap,\r
+                      &MapKey,\r
+                      &DescriptorSize,\r
+                      &DescriptorVersion\r
+                      );\r
+      // Don't do anything between the GetMemoryMap() and ExitBootServices()\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = gBS->ExitBootServices (gImageHandle, MapKey);\r
+        if (EFI_ERROR (Status)) {\r
+          FreePages (MemoryMap, Pages);\r
+          MemoryMap = NULL;\r
+          MemoryMapSize = 0;\r
+        }\r
+      }\r
+    }\r
+  } while (EFI_ERROR (Status));\r
 \r
   //\r
   // At this point it is very dangerous to do things EFI as most of EFI is now gone.\r
   // This command is useful if you are working with a debugger as it will shutdown\r
   // DMA and other things that could break a soft resets.\r
-  //  \r
+  //\r
   CpuDeadLoop ();\r
-  \r
+\r
   // Should never get here, but makes the compiler happy\r
   return EFI_ABORTED;\r
 }\r
@@ -349,10 +385,10 @@ EblExitCmd (
 \r
 /**\r
   Update the screen by decrementing the timeout value.\r
-  This AsciiPrint has to match the AsciiPrint in \r
-  EblPauseCmd. \r
+  This AsciiPrint has to match the AsciiPrint in\r
+  EblPauseCmd.\r
 \r
-  @param  ElaspedTime   Current timout value remaining\r
+  @param  ElaspedTime   Current timeout value remaining\r
 \r
 **/\r
 VOID\r
@@ -374,11 +410,11 @@ EblPauseCallback (
   Argv[1] - timeout value is decimal seconds\r
 \r
   @param  Argc   Number of command arguments in Argv\r
-  @param  Argv   Array of strings that represent the parsed command line. \r
-                 Argv[0] is the comamnd name\r
+  @param  Argv   Array of strings that represent the parsed command line.\r
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS  Timeout expired with no input\r
-  @return EFI_TIMEOUT  Stop procesing other commands on the same command line\r
+  @return EFI_TIMEOUT  Stop processing other commands on the same command line\r
 \r
 **/\r
 EFI_STATUS\r
@@ -397,8 +433,8 @@ EblPauseCmd (
   Status = EblGetCharKey (&Key, Delay, EblPauseCallback);\r
   AsciiPrint ("\n");\r
 \r
-  // If we timeout then the pause succeded thus return success\r
-  // If we get a key return timout to stop other commnad on this cmd line\r
+  // If we timeout then the pause succeeded thus return success\r
+  // If we get a key return timeout to stop other command on this cmd line\r
   return (Status == EFI_SUCCESS) ? EFI_TIMEOUT : EFI_SUCCESS;;\r
 }\r
 \r
@@ -409,8 +445,8 @@ EblPauseCmd (
   Argv[0] - "break"\r
 \r
   @param  Argc   Number of command arguments in Argv\r
-  @param  Argv   Array of strings that represent the parsed command line. \r
-                 Argv[0] is the comamnd name\r
+  @param  Argv   Array of strings that represent the parsed command line.\r
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -435,8 +471,8 @@ EblBreakPointCmd (
   Argv[1] - warm or shutdown reset type\r
 \r
   @param  Argc   Number of command arguments in Argv\r
-  @param  Argv   Array of strings that represent the parsed command line. \r
-                 Argv[0] is the comamnd name\r
+  @param  Argv   Array of strings that represent the parsed command line.\r
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -460,7 +496,7 @@ EblResetCmd (
     case 's':\r
       ResetType = EfiResetShutdown;\r
     }\r
-  } \r
+  }\r
 \r
   gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);\r
   return EFI_SUCCESS;\r
@@ -475,8 +511,8 @@ EblResetCmd (
   Argv[1] - on or off\r
 \r
   @param  Argc   Number of command arguments in Argv\r
-  @param  Argv   Array of strings that represent the parsed command line. \r
-                 Argv[0] is the comamnd name\r
+  @param  Argv   Array of strings that represent the parsed command line.\r
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -488,7 +524,7 @@ EblPageCmd (
   )\r
 {\r
   if (Argc <= 1) {\r
-    // toggle setting   \r
+    // toggle setting\r
     gPageBreak = (gPageBreak) ? FALSE : TRUE;\r
   } else {\r
     // use argv to set the value\r
@@ -525,12 +561,9 @@ ConvertToTextLine (
   IN CHAR8  Character\r
   )\r
 {\r
-  if (Character < ' ' || Character > '~')\r
-  {\r
+  if (Character < ' ' || Character > '~') {\r
     return '.';\r
-  }\r
-  else\r
-  {\r
+  } else {\r
     return Character;\r
   }\r
 }\r
@@ -543,15 +576,15 @@ GetBytes (
 {\r
   UINTN Result = 0;\r
 \r
-  if (Bytes >= 1)\r
+  if (Bytes >= 1) {\r
     Result = *Address++;\r
-    \r
-  if (Bytes >= 2)\r
+  }\r
+  if (Bytes >= 2) {\r
     Result = (Result << 8) + *Address++;\r
-    \r
-  if (Bytes >= 3)\r
+  }\r
+  if (Bytes >= 3) {\r
     Result = (Result << 8) + *Address++;\r
-\r
+  }\r
   return Result;\r
 }\r
 \r
@@ -574,26 +607,20 @@ OutputData (
   CHAR8 Blanks[80];\r
 \r
   AsciiStrCpy (Blanks, mBlanks);\r
-  for (EndAddress = Address + Length; Address < EndAddress; Offset += Line)\r
-  {\r
+  for (EndAddress = Address + Length; Address < EndAddress; Offset += Line) {\r
     AsciiPrint ("%08x: ", Offset);\r
-    for (Line = 0; (Line < 0x10) && (Address < EndAddress);)\r
-    {\r
+    for (Line = 0; (Line < 0x10) && (Address < EndAddress);) {\r
       Bytes = EndAddress - Address;\r
-            \r
-      switch (Width)\r
-      {\r
+\r
+      switch (Width) {\r
         case 4:\r
-          if (Bytes >= 4)\r
-          {\r
+          if (Bytes >= 4) {\r
             AsciiPrint ("%08x ", *((UINT32 *)Address));\r
             TextLine[Line++] = ConvertToTextLine(*Address++);\r
             TextLine[Line++] = ConvertToTextLine(*Address++);\r
             TextLine[Line++] = ConvertToTextLine(*Address++);\r
             TextLine[Line++] = ConvertToTextLine(*Address++);\r
-          }\r
-          else\r
-          {\r
+          } else {\r
             AsciiPrint ("%08x ", GetBytes(Address, Bytes));\r
             Address += Bytes;\r
             Line    += Bytes;\r
@@ -601,14 +628,11 @@ OutputData (
           break;\r
 \r
         case 2:\r
-          if (Bytes >= 2)\r
-          {\r
+          if (Bytes >= 2) {\r
             AsciiPrint ("%04x ", *((UINT16 *)Address));\r
             TextLine[Line++] = ConvertToTextLine(*Address++);\r
             TextLine[Line++] = ConvertToTextLine(*Address++);\r
-          }\r
-          else\r
-          {\r
+          } else {\r
             AsciiPrint ("%04x ", GetBytes(Address, Bytes));\r
             Address += Bytes;\r
             Line    += Bytes;\r
@@ -627,10 +651,8 @@ OutputData (
     }\r
 \r
     // Pad spaces\r
-    if (Line < 0x10)\r
-    {\r
-      switch (Width)\r
-      {\r
+    if (Line < 0x10) {\r
+      switch (Width) {\r
         case 4:\r
           Spaces = 9 * ((0x10 - Line)/4);\r
           break;\r
@@ -645,29 +667,79 @@ OutputData (
       Blanks[Spaces] = '\0';\r
 \r
       AsciiPrint(Blanks);\r
-      \r
+\r
       Blanks[Spaces] = ' ';\r
     }\r
 \r
     TextLine[Line] = 0;\r
     AsciiPrint ("|%a|\n", TextLine);\r
 \r
-    if (EblAnyKeyToContinueQtoQuit(&CurrentRow, FALSE))\r
-    {\r
+    if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
       return EFI_END_OF_FILE;\r
     }\r
   }\r
 \r
-  if (Length % Width != 0)\r
-  {\r
+  if (Length % Width != 0) {\r
     AsciiPrint ("%08x\n", Offset);\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
+/**\r
+  See if command contains .# where # is a number. Return # as the Width\r
+  or 1 as the default Width for commands.\r
+\r
+  Example hexdump.4 returns a width of 4.\r
+\r
+  @param  Argv   Argv[0] is the command name\r
+\r
+  @return Width of command\r
+\r
+**/\r
+UINTN\r
+WidthFromCommandName (\r
+  IN CHAR8  *Argv,\r
+  IN UINTN  Default\r
+  )\r
+{\r
+  CHAR8         *Str;\r
+  UINTN         Width;\r
+\r
+  //Hexdump.2 HexDump.4 mean use a different width\r
+  Str = AsciiStrStr (Argv, ".");\r
+  if (Str != NULL) {\r
+    Width = AsciiStrDecimalToUintn (Str + 1);\r
+    if (Width == 0) {\r
+      Width = Default;\r
+    }\r
+  } else {\r
+    // Default answer\r
+    return Default;\r
+  }\r
+\r
+  return Width;\r
+}\r
+\r
 #define HEXDUMP_CHUNK 1024\r
 \r
+/**\r
+  Toggle page break global. This turns on and off prompting to Quit or hit any\r
+  key to continue when a command is about to scroll the screen with its output\r
+\r
+  Argv[0] - "hexdump"[.#]  # is optional 1,2, or 4 for width\r
+  Argv[1] - Device or File to dump.\r
+  Argv[2] - Optional offset to start dumping\r
+  Argv[3] - Optional number of bytes to dump\r
+\r
+  @param  Argc   Number of command arguments in Argv\r
+  @param  Argv   Array of strings that represent the parsed command line.\r
+                 Argv[0] is the command name\r
+\r
+  @return EFI_SUCCESS\r
+\r
+**/\r
 EFI_STATUS\r
 EblHexdumpCmd (\r
   IN UINTN  Argc,\r
@@ -677,70 +749,70 @@ EblHexdumpCmd (
   EFI_OPEN_FILE *File;\r
   VOID          *Location;\r
   UINTN         Size;\r
-  UINTN         Width = 1;\r
+  UINTN         Width;\r
   UINTN         Offset = 0;\r
   EFI_STATUS    Status;\r
   UINTN         Chunk = HEXDUMP_CHUNK;\r
 \r
-  if ((Argc < 2) || (Argc > 3))\r
-  {\r
+  if ((Argc < 2) || (Argc > 4)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
-  if (Argc == 3)\r
-  {\r
-      Width = AsciiStrDecimalToUintn(Argv[2]);\r
-  }\r
-  \r
-  if ((Width != 1) && (Width != 2) && (Width != 4))\r
-  {\r
+\r
+  Width = WidthFromCommandName (Argv[0], 1);\r
+  if ((Width != 1) && (Width != 2) && (Width != 4)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  File = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);\r
-  if (File == NULL)\r
-  {\r
+  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);\r
+  if (File == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  Location = AllocatePool(Chunk);\r
-  Size     = EfiTell(File, NULL);\r
+  Location = AllocatePool (Chunk);\r
+  Size     = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : EfiTell (File, NULL);\r
 \r
-  for (Offset = 0; Offset + HEXDUMP_CHUNK <= Size; Offset += Chunk)\r
-  {\r
+  Offset = 0;\r
+  if (Argc > 2) {\r
+    Offset = AsciiStrHexToUintn (Argv[2]);\r
+    if (Offset > 0) {\r
+      // Make sure size includes the part of the file we have skipped\r
+      Size += Offset;\r
+    }\r
+  }\r
+\r
+  Status = EfiSeek (File, Offset, EfiSeekStart);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  for (; Offset + HEXDUMP_CHUNK <= Size; Offset += Chunk) {\r
     Chunk = HEXDUMP_CHUNK;\r
-    \r
-    Status = EfiRead(File, Location, &Chunk);\r
-    if (EFI_ERROR(Status))\r
-    {\r
+    Status = EfiRead (File, Location, &Chunk);\r
+    if (EFI_ERROR(Status)) {\r
       AsciiPrint ("Error reading file content\n");\r
       goto Exit;\r
     }\r
 \r
-    Status = OutputData(Location, Chunk, Width, File->BaseOffset + Offset);\r
-    if (EFI_ERROR(Status))\r
-    {\r
+    Status = OutputData (Location, Chunk, Width, File->BaseOffset + Offset);\r
+    if (EFI_ERROR(Status)) {\r
       if (Status == EFI_END_OF_FILE) {\r
         Status = EFI_SUCCESS;\r
       }\r
       goto Exit;\r
     }\r
   }\r
-  \r
+\r
   // Any left over?\r
-  if (Offset < Size)\r
-  {\r
+  if (Offset < Size) {\r
     Chunk = Size - Offset;\r
-    Status = EfiRead(File, Location, &Chunk);\r
-    if (EFI_ERROR(Status))\r
-    {\r
+    Status = EfiRead (File, Location, &Chunk);\r
+    if (EFI_ERROR(Status)) {\r
       AsciiPrint ("Error reading file content\n");\r
       goto Exit;\r
     }\r
 \r
-    Status = OutputData(Location, Chunk, Width, File->BaseOffset + Offset);\r
-    if (EFI_ERROR(Status))\r
-    {\r
+    Status = OutputData (Location, Chunk, Width, File->BaseOffset + Offset);\r
+    if (EFI_ERROR(Status)) {\r
       if (Status == EFI_END_OF_FILE) {\r
         Status = EFI_SUCCESS;\r
       }\r
@@ -749,141 +821,13 @@ EblHexdumpCmd (
   }\r
 \r
 Exit:\r
-  EfiClose(File);\r
+  EfiClose (File);\r
 \r
-  FreePool(Location);\r
+  FreePool (Location);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-#define USE_DISKIO 1\r
-\r
-EFI_STATUS\r
-EblDiskIoCmd (\r
-  IN UINTN Argc,\r
-  IN CHAR8 **Argv\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-  UINTN Offset;\r
-  UINT8 *EndOffset;\r
-  UINTN Length;\r
-  UINTN Line;\r
-  UINT8 *Buffer;\r
-  UINT8 *BufferOffset;\r
-  CHAR8 TextLine[0x11];\r
-#if USE_DISKIO\r
-  EFI_DISK_IO_PROTOCOL  *DiskIo;\r
-#else\r
-  EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
-  UINTN                 Lba;\r
-#endif  \r
-\r
-  if (AsciiStrCmp(Argv[1], "r") == 0)\r
-  {  \r
-    Offset = AsciiStrHexToUintn(Argv[2]);\r
-    Length = AsciiStrHexToUintn(Argv[3]);\r
-\r
-#if USE_DISKIO\r
-    Status = gBS->LocateProtocol(&gEfiDiskIoProtocolGuid, NULL, (VOID **)&DiskIo);\r
-    if (EFI_ERROR(Status))\r
-    {\r
-      AsciiPrint("Did not locate DiskIO\n");\r
-      return Status;\r
-    }\r
-\r
-    Buffer = AllocatePool(Length);\r
-    BufferOffset = Buffer;\r
-    \r
-    Status = DiskIo->ReadDisk(DiskIo, SIGNATURE_32('f','l','s','h'), Offset, Length, Buffer);\r
-    if (EFI_ERROR(Status))\r
-    {\r
-      AsciiPrint("DiskIO read failed\n");\r
-      gBS->FreePool(Buffer);\r
-      return Status;\r
-    }    \r
-#else\r
-    Status = gBS->LocateProtocol(&gEfiBlockIoProtocolGuid, NULL, (VOID **)&BlockIo);\r
-    if (EFI_ERROR(Status))\r
-    {\r
-      AsciiPrint("Did not locate BlockIo\n");\r
-      return Status;\r
-    }\r
-    \r
-    Length = BlockIo->Media->BlockSize;\r
-    Buffer = AllocatePool(Length);\r
-    BufferOffset = Buffer;\r
-    Lba = Offset/BlockIo->Media->BlockSize;\r
-    \r
-    Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, Lba, Length, Buffer);\r
-    if (EFI_ERROR(Status))\r
-    {\r
-      AsciiPrint("BlockIo read failed\n");\r
-      gBS->FreePool(Buffer);\r
-      return Status;\r
-    }\r
-    \r
-    // Whack offset to what we actually read from\r
-    Offset = Lba * BlockIo->Media->BlockSize;\r
-    \r
-    Length = 0x100;\r
-#endif\r
-\r
-    for (EndOffset = BufferOffset + Length; BufferOffset < EndOffset; Offset += 0x10)\r
-    {\r
-      AsciiPrint ("%08x: ", Offset);\r
-      \r
-      for (Line = 0; Line < 0x10; Line++)\r
-      {\r
-        AsciiPrint ("%02x ", *BufferOffset);\r
-\r
-        if (*BufferOffset < ' ' || *BufferOffset > '~')\r
-          TextLine[Line] = '.';\r
-        else\r
-          TextLine[Line] = *BufferOffset;\r
-          \r
-        BufferOffset++;\r
-      }\r
-\r
-      TextLine[Line] = '\0';\r
-      AsciiPrint ("|%a|\n", TextLine);\r
-    }\r
-    \r
-    gBS->FreePool(Buffer);\r
-\r
-    return EFI_SUCCESS;\r
-  }\r
-  else if (AsciiStrCmp(Argv[1], "w") == 0)\r
-  {\r
-    Offset = AsciiStrHexToUintn(Argv[2]);\r
-    Length = AsciiStrHexToUintn(Argv[3]);\r
-    Buffer = (UINT8 *)AsciiStrHexToUintn(Argv[4]);\r
-    \r
-#if USE_DISKIO\r
-    Status = gBS->LocateProtocol(&gEfiDiskIoProtocolGuid, NULL, (VOID **)&DiskIo);\r
-    if (EFI_ERROR(Status))\r
-    {\r
-      AsciiPrint("Did not locate DiskIO\n");\r
-      return Status;\r
-    }\r
-\r
-    Status = DiskIo->WriteDisk(DiskIo, SIGNATURE_32('f','l','s','h'), Offset, Length, Buffer);\r
-    if (EFI_ERROR(Status))\r
-    {\r
-      AsciiPrint("DiskIO write failed\n");\r
-      return Status;\r
-    }\r
-\r
-#else\r
-#endif\r
-\r
-    return EFI_SUCCESS;\r
-  }\r
-  else\r
-  {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-}\r
 \r
 GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdTemplate[] =\r
 {\r
@@ -931,16 +875,10 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdTemplate[] =
   },\r
   {\r
     "hexdump",\r
-    " filename ; dump a file as hex bytes",\r
+    "[.{1|2|4}] filename [Offset] [Size]; dump a file as hex .width",\r
     NULL,\r
     EblHexdumpCmd\r
-  },\r
-  {\r
-    "diskio",\r
-    " [r|w] offset [length [dataptr]]; do a DiskIO read or write ",\r
-    NULL,\r
-    EblDiskIoCmd\r
-  }  \r
+  }\r
 };\r
 \r
 \r
@@ -956,7 +894,7 @@ EblInitializeCmdTable (
 {\r
 \r
   EblAddCommands (mCmdTemplate, sizeof (mCmdTemplate)/sizeof (EBL_COMMAND_TABLE));\r
-  \r
+\r
   gBS->InstallProtocolInterface (\r
         &gExternalCmdHandle,\r
         &gEfiEblAddCommandProtocolGuid,\r