Update EBL to have an optional width specifier on commands. So hexdump.4 means use...
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 10 Feb 2010 23:48:46 +0000 (23:48 +0000)
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 10 Feb 2010 23:48:46 +0000 (23:48 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk@9974 6f19259b-4bc3-4df7-8a09-765794883524

edk2/EmbeddedPkg/Ebl/Command.c
edk2/EmbeddedPkg/Ebl/Ebl.h
edk2/EmbeddedPkg/Ebl/HwDebug.c
edk2/EmbeddedPkg/Ebl/HwIoDebug.c
edk2/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c

index f0db375..3efe6ee 100644 (file)
@@ -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
@@ -650,8 +658,60 @@ OutputData (
   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 comamnd 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 comamnd name\r
+\r
+  @return EFI_SUCCESS\r
+\r
+**/\r
 EFI_STATUS\r
 EblHexdumpCmd (\r
   IN UINTN  Argc,\r
@@ -661,19 +721,16 @@ 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
+  if ((Argc < 2) || (Argc > 4)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r
-  if (Argc == 3) {\r
-      Width = AsciiStrDecimalToUintn(Argv[2]);\r
-  }\r
-  \r
+  Width = WidthFromCommandName (Argv[0], 1);\r
   if ((Width != 1) && (Width != 2) && (Width != 4)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -684,14 +741,26 @@ EblHexdumpCmd (
   }\r
 \r
   Location = AllocatePool (Chunk);\r
-  Size     = EfiTell(File, NULL);\r
+  Size     = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : EfiTell (File, NULL);\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
-  for (Offset = 0; Offset + HEXDUMP_CHUNK <= Size; Offset += Chunk) {\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
+    if (EFI_ERROR(Status)) {\r
       AsciiPrint ("Error reading file content\n");\r
       goto Exit;\r
     }\r
@@ -778,7 +847,7 @@ 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 bytes at a given width",\r
     NULL,\r
     EblHexdumpCmd\r
   }\r
index 705511a..48b6966 100644 (file)
@@ -184,6 +184,13 @@ OutputData (
   IN UINTN  Width,
   IN UINTN  Offset
   );
+  
+UINTN
+WidthFromCommandName (
+  IN CHAR8  *Argv,
+  IN UINTN  Default
+  );
+
 
 extern UINTN    gScreenColumns;
 extern UINTN    gScreenRows;
index 6ffbaf1..b2ea9af 100644 (file)
 /**\r
   Dump memory\r
 \r
-  Argv[0] - "md"\r
+  Argv[0] - "md"[.#] # is optiona width 1, 2, 4, or 8. Default 1\r
   Argv[1] - Hex Address to dump\r
   Argv[2] - Number of hex bytes to dump (0x20 is default)\r
-  Argv[3] - [1|2|4|8] byte width of the dump\r
 \r
-  md 0x123445678 50 4 ; Dump 0x50 4 byte quantities starting at 0x123445678\r
-  md 0x123445678 40   ; Dump 0x40 1 byte quantities starting at 0x123445678\r
-  md 0x123445678      ; Dump 0x20 1 byte quantities starting at 0x123445678\r
+  md.4 0x123445678 50 ; Dump 0x50 4 byte quantities starting at 0x123445678\r
+  md   0x123445678 40 ; Dump 0x40 1 byte quantities starting at 0x123445678\r
+  md   0x123445678    ; Dump 0x20 1 byte quantities starting at 0x123445678\r
 \r
   @param  Argc   Number of command arguments in Argv\r
   @param  Argv   Array of strings that represent the parsed command line. \r
@@ -48,21 +47,20 @@ EblMdCmd (
 {\r
   STATIC UINT8  *Address = NULL;\r
   STATIC UINTN  Length   = 0x20;\r
-  STATIC UINTN  Width    = 1;\r
+  STATIC UINTN  Width;\r
 \r
-  switch (Argc)\r
-  {\r
-    case 4:\r
-      Width = AsciiStrHexToUintn(Argv[3]);\r
+  Width = WidthFromCommandName (Argv[0], 1);\r
+\r
+  switch (Argc) {\r
     case 3:\r
       Length = AsciiStrHexToUintn(Argv[2]);\r
     case 2:\r
-      Address = (UINT8 *)AsciiStrHexToUintn(Argv[1]);\r
+      Address = (UINT8 *)AsciiStrHexToUintn (Argv[1]);\r
     default:\r
       break;\r
   }\r
 \r
-  OutputData(Address, Length, Width, (UINTN)Address);\r
+  OutputData (Address, Length, Width, (UINTN)Address);\r
 \r
   Address += Length;\r
   \r
@@ -73,14 +71,13 @@ EblMdCmd (
 /**\r
   Fill Memory with data\r
 \r
-  Argv[0] - "mfill"\r
+  Argv[0] - "mfill"[.#] # is optiona width 1, 2, 4, or 8. Default 4\r
   Argv[1] - Hex Address to fill\r
   Argv[2] - Data to write (0x00 is default)\r
   Argv[3] - Number of units to dump.\r
-  Argv[4] - [1|2|4|8] byte width of the dump\r
 \r
-  mf 0x123445678 aa 1 100 ; Start at 0x123445678 and write aa (1 byte) to the next 100 bytes\r
-  mf 0x123445678 aa 4 100 ; Start at 0x123445678 and write aa (4 byte) to the next 400 bytes\r
+  mf.1 0x123445678 aa 100 ; Start at 0x123445678 and write aa (1 byte) to the next 100 bytes\r
+  mf.4 0x123445678 aa 100 ; Start at 0x123445678 and write aa (4 byte) to the next 400 bytes\r
   mf 0x123445678 aa       ; Start at 0x123445678 and write aa (4 byte) to the next 1 byte\r
   mf 0x123445678          ; Start at 0x123445678 and write 00 (4 byte) to the next 1 byte\r
 \r
@@ -107,10 +104,11 @@ EblMfillCmd (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  Width = WidthFromCommandName (Argv[0], 4);\r
+\r
   Address = AsciiStrHexToUintn (Argv[1]);\r
   Data    = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 0;\r
-  Width   = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 4;\r
-  Length  = (Argc > 4) ? AsciiStrHexToUintn (Argv[4]) : 1;\r
+  Length  = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;\r
 \r
   for (EndAddress = Address + (Length * Width); Address < EndAddress; Address += Width) {\r
     if (Width == 4) {\r
@@ -310,13 +308,13 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwDebugTemplate[] =
 {\r
   {\r
     "md",\r
-    " [Addr] [Len] [1|2|4]; Memory Dump from Addr Len bytes",\r
+    "[.{1|2|4}] [Addr] [Len] [1|2|4]; Memory Dump from Addr Len bytes",\r
     NULL,\r
     EblMdCmd\r
   },\r
   {\r
     "mfill",\r
-    " Addr Len [data] [1|2|4]; Memory Fill Addr Len*(1|2|4) bytes of data(0)",\r
+    "[.{1|2|4}] Addr Len [data] [1|2|4]; Memory Fill Addr Len*(1|2|4) bytes of data(0)",\r
     NULL,\r
     EblMfillCmd\r
   },\r
index 2d23e7c..d32aba6 100644 (file)
 /**\r
   Read from IO space\r
 \r
-  Argv[0] - "ioread"\r
+  Argv[0] - "ioread"[.#] # is optiona width 1, 2, or 4. Default 1\r
   Argv[1] - Hex IO address\r
-  Argv[2] - IO Width [1|2|4] with a default of 1\r
 \r
-  ior 0x3f8 4  ;Do a 32-bit IO Read from 0x3f8\r
-  ior 0x3f8 1  ;Do a  8-bit IO Read from 0x3f8\r
+  ior.4 0x3f8  ;Do a 32-bit IO Read from 0x3f8\r
+  ior   0x3f8  ;Do a  8-bit IO Read from 0x3f8\r
 \r
   @param  Argc   Number of command arguments in Argv\r
   @param  Argv   Array of strings that represent the parsed command line. \r
@@ -53,7 +52,7 @@ EblIoReadCmd (
   }\r
 \r
   Port = AsciiStrHexToUintn (Argv[1]);\r
-  Width = (Argc > 2) ? AsciiStrHexToUintn (Argv[2]) : 1;\r
+  Width = WidthFromCommandName (Argv[0], 1);\r
 \r
   if (Width == 1) {\r
     Data = IoRead8 (Port);\r
@@ -74,13 +73,12 @@ EblIoReadCmd (
 /**\r
   Write to IO space\r
 \r
-  Argv[0] - "iowrite"\r
+  Argv[0] - "iowrite"[.#] # is optiona width 1, 2, or 4. Default 1\r
   Argv[1] - Hex IO address\r
   Argv[2] - Hex data to write\r
-  Argv[3] - IO Width [1|2|4] with a default of 1\r
 \r
-  iow 0x3f8 af 4  ;Do a 32-bit IO write of af to 0x3f8\r
-  iow 0x3f8 af    ;Do an 8-bit IO write of af to 0x3f8\r
+  iow.4 0x3f8 af  ;Do a 32-bit IO write of af to 0x3f8\r
+  iow   0x3f8 af  ;Do an 8-bit IO write of af to 0x3f8\r
 \r
   @param  Argc   Number of command arguments in Argv\r
   @param  Argv   Array of strings that represent the parsed command line. \r
@@ -105,7 +103,7 @@ EblIoWriteCmd (
 \r
   Port = AsciiStrHexToUintn (Argv[1]);\r
   Data = AsciiStrHexToUintn (Argv[2]);\r
-  Width = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;\r
+  Width = WidthFromCommandName (Argv[0], 1);\r
  \r
   if (Width == 1) {\r
     IoWrite8 (Port, (UINT8)Data);\r
@@ -124,13 +122,13 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwIoDebugTemplate[] =
 {\r
   {\r
     "ioread",\r
-    " Port [1|2|4]; IO read of width[1] byte(s) from Port",\r
+    "[.{1|2|4}] Port ; IO read of width byte(s) from Port",\r
     NULL,\r
     EblIoReadCmd\r
   },\r
   {\r
     "iowrite",\r
-    " Port Data [1|2|4]; IO write Data of width[1] byte(s) to Port",\r
+    "[.{1|2|4}] Port Data ; IO write Data of width byte(s) to Port",\r
     NULL,\r
     EblIoWriteCmd\r
   }\r
index 861ca15..2d53368 100644 (file)
@@ -57,6 +57,7 @@
 
 CHAR8 *gCwd = NULL;
 
+CONST EFI_GUID gZeroGuid  = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
 
 #define EFI_OPEN_FILE_GUARD_HEADER  0x4B4D4641
 #define EFI_OPEN_FILE_GUARD_FOOTER  0x444D5A56
@@ -525,10 +526,27 @@ EblFvFileDevicePath (
     return Status;
   }
 
+  // Get FVB Info about the handle
+  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
+  if (!EFI_ERROR (Status)) {
+    Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
+    if (!EFI_ERROR (Status)) {
+      for (Lba = 0, File->FvSize = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
+        Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
+        if (EFI_ERROR (Status)) {
+          break;
+        }
+      }
+    }
+  }
+
+
   DevicePath = DevicePathFromHandle (File->EfiHandle);
 
   if (*FileName == '\0') {
     File->DevicePath = DuplicateDevicePath (DevicePath);
+    File->Size = File->FvSize;
+    File->MaxPosition = File->Size;
   } else {
     Key = 0;
     do {
@@ -579,21 +597,7 @@ EblFvFileDevicePath (
     File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
   }
 
-  
-  // Get FVB Info about the handle
-  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
-  if (!EFI_ERROR (Status)) {
-    Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
-    if (!EFI_ERROR (Status)) {
-      for (Lba = 0, File->FvSize = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
-        Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
-        if (EFI_ERROR (Status)) {
-          break;
-        }
-      }
-    }
-  }
-  
+    
   // FVB not required if FV was soft loaded...
   return EFI_SUCCESS;
 }
@@ -1164,8 +1168,11 @@ EfiSeek (
   }
 
   if (File->Type == EfiOpenLoadFile || File->Type == EfiOpenFirmwareVolume) {
-    // LoadFile and FV do not support Seek
-    return EFI_UNSUPPORTED;
+    if (!CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
+      // LoadFile and FV do not support Seek
+      // You can seek on a raw FV device
+      return EFI_UNSUPPORTED;
+    }
   }
 
   CurrentPosition = File->CurrentPosition;
@@ -1304,26 +1311,33 @@ EfiRead (
     break;
   
   case EfiOpenFirmwareVolume:
-    if (File->FvSectionType == EFI_SECTION_ALL) {
-      Status = File->Fv->ReadFile (
-                            File->Fv,
-                            &File->FvNameGuid,
-                            &Buffer,
-                            BufferSize,
-                            &File->FvType,
-                            &File->FvAttributes,
-                            &AuthenticationStatus
-                            );
+    if (CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
+      // This is the entire FV device, so treat like a memory buffer 
+      CopyMem (Buffer, (VOID *)(UINTN)(File->FvStart + File->CurrentPosition), *BufferSize);
+      File->CurrentPosition += *BufferSize;
+      Status = EFI_SUCCESS;
     } else {
-      Status = File->Fv->ReadSection (
-                            File->Fv,
-                            &File->FvNameGuid,
-                            File->FvSectionType,
-                            0,
-                            &Buffer,
-                            BufferSize,
-                            &AuthenticationStatus
-                            );
+      if (File->FvSectionType == EFI_SECTION_ALL) {
+        Status = File->Fv->ReadFile (
+                              File->Fv,
+                              &File->FvNameGuid,
+                              &Buffer,
+                              BufferSize,
+                              &File->FvType,
+                              &File->FvAttributes,
+                              &AuthenticationStatus
+                              );
+      } else {
+        Status = File->Fv->ReadSection (
+                              File->Fv,
+                              &File->FvNameGuid,
+                              File->FvSectionType,
+                              0,
+                              &Buffer,
+                              BufferSize,
+                              &AuthenticationStatus
+                              );
+      }
     }
     break;