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
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
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
}\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
},\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
IN UINTN Width,
IN UINTN Offset
);
+
+UINTN
+WidthFromCommandName (
+ IN CHAR8 *Argv,
+ IN UINTN Default
+ );
+
extern UINTN gScreenColumns;
extern UINTN gScreenRows;
/**\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
{\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
/**\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
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
{\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
/**\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
}\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
/**\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
\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
{\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
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
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 {
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;
}
}
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;
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;