diff options
-rw-r--r-- | EmbeddedPkg/Ebl/Command.c | 93 | ||||
-rw-r--r-- | EmbeddedPkg/Ebl/Ebl.h | 7 | ||||
-rw-r--r-- | EmbeddedPkg/Ebl/HwDebug.c | 38 | ||||
-rw-r--r-- | EmbeddedPkg/Ebl/HwIoDebug.c | 22 | ||||
-rw-r--r-- | EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c | 86 |
5 files changed, 166 insertions, 80 deletions
diff --git a/EmbeddedPkg/Ebl/Command.c b/EmbeddedPkg/Ebl/Command.c index f0db375cef..3efe6ee671 100644 --- a/EmbeddedPkg/Ebl/Command.c +++ b/EmbeddedPkg/Ebl/Command.c @@ -186,8 +186,16 @@ EblGetCommand ( 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
@@ -650,8 +658,60 @@ OutputData ( 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 comamnd 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 comamnd name
+
+ @return EFI_SUCCESS
+
+**/
EFI_STATUS
EblHexdumpCmd (
IN UINTN Argc,
@@ -661,19 +721,16 @@ EblHexdumpCmd ( EFI_OPEN_FILE *File;
VOID *Location;
UINTN Size;
- UINTN Width = 1;
+ UINTN Width;
UINTN Offset = 0;
EFI_STATUS Status;
UINTN Chunk = HEXDUMP_CHUNK;
- if ((Argc < 2) || (Argc > 3)) {
+ if ((Argc < 2) || (Argc > 4)) {
return EFI_INVALID_PARAMETER;
}
- if (Argc == 3) {
- Width = AsciiStrDecimalToUintn(Argv[2]);
- }
-
+ Width = WidthFromCommandName (Argv[0], 1);
if ((Width != 1) && (Width != 2) && (Width != 4)) {
return EFI_INVALID_PARAMETER;
}
@@ -684,14 +741,26 @@ EblHexdumpCmd ( }
Location = AllocatePool (Chunk);
- Size = EfiTell(File, NULL);
+ 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;
+ }
+ }
- for (Offset = 0; Offset + HEXDUMP_CHUNK <= Size; Offset += Chunk) {
+ 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))
- {
+ if (EFI_ERROR(Status)) {
AsciiPrint ("Error reading file content\n");
goto Exit;
}
@@ -778,7 +847,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdTemplate[] = },
{
"hexdump",
- " filename ; dump a file as hex bytes",
+ "[.{1|2|4}] filename [Offset] [Size]; dump a file as hex bytes at a given width",
NULL,
EblHexdumpCmd
}
diff --git a/EmbeddedPkg/Ebl/Ebl.h b/EmbeddedPkg/Ebl/Ebl.h index 705511a0e4..48b69660fb 100644 --- a/EmbeddedPkg/Ebl/Ebl.h +++ b/EmbeddedPkg/Ebl/Ebl.h @@ -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; diff --git a/EmbeddedPkg/Ebl/HwDebug.c b/EmbeddedPkg/Ebl/HwDebug.c index 6ffbaf1170..b2ea9af64b 100644 --- a/EmbeddedPkg/Ebl/HwDebug.c +++ b/EmbeddedPkg/Ebl/HwDebug.c @@ -24,14 +24,13 @@ /**
Dump memory
- Argv[0] - "md"
+ Argv[0] - "md"[.#] # is optiona width 1, 2, 4, or 8. Default 1
Argv[1] - Hex Address to dump
Argv[2] - Number of hex bytes to dump (0x20 is default)
- Argv[3] - [1|2|4|8] byte width of the dump
- md 0x123445678 50 4 ; Dump 0x50 4 byte quantities starting at 0x123445678
- md 0x123445678 40 ; Dump 0x40 1 byte quantities starting at 0x123445678
- md 0x123445678 ; Dump 0x20 1 byte quantities starting at 0x123445678
+ md.4 0x123445678 50 ; Dump 0x50 4 byte quantities starting at 0x123445678
+ md 0x123445678 40 ; Dump 0x40 1 byte quantities starting at 0x123445678
+ md 0x123445678 ; Dump 0x20 1 byte quantities starting at 0x123445678
@param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line.
@@ -48,21 +47,20 @@ EblMdCmd ( {
STATIC UINT8 *Address = NULL;
STATIC UINTN Length = 0x20;
- STATIC UINTN Width = 1;
+ STATIC UINTN Width;
- switch (Argc)
- {
- case 4:
- Width = AsciiStrHexToUintn(Argv[3]);
+ Width = WidthFromCommandName (Argv[0], 1);
+
+ switch (Argc) {
case 3:
Length = AsciiStrHexToUintn(Argv[2]);
case 2:
- Address = (UINT8 *)AsciiStrHexToUintn(Argv[1]);
+ Address = (UINT8 *)AsciiStrHexToUintn (Argv[1]);
default:
break;
}
- OutputData(Address, Length, Width, (UINTN)Address);
+ OutputData (Address, Length, Width, (UINTN)Address);
Address += Length;
@@ -73,14 +71,13 @@ EblMdCmd ( /**
Fill Memory with data
- Argv[0] - "mfill"
+ Argv[0] - "mfill"[.#] # is optiona width 1, 2, 4, or 8. Default 4
Argv[1] - Hex Address to fill
Argv[2] - Data to write (0x00 is default)
Argv[3] - Number of units to dump.
- Argv[4] - [1|2|4|8] byte width of the dump
- mf 0x123445678 aa 1 100 ; Start at 0x123445678 and write aa (1 byte) to the next 100 bytes
- mf 0x123445678 aa 4 100 ; Start at 0x123445678 and write aa (4 byte) to the next 400 bytes
+ mf.1 0x123445678 aa 100 ; Start at 0x123445678 and write aa (1 byte) to the next 100 bytes
+ mf.4 0x123445678 aa 100 ; Start at 0x123445678 and write aa (4 byte) to the next 400 bytes
mf 0x123445678 aa ; Start at 0x123445678 and write aa (4 byte) to the next 1 byte
mf 0x123445678 ; Start at 0x123445678 and write 00 (4 byte) to the next 1 byte
@@ -107,10 +104,11 @@ EblMfillCmd ( return EFI_INVALID_PARAMETER;
}
+ Width = WidthFromCommandName (Argv[0], 4);
+
Address = AsciiStrHexToUintn (Argv[1]);
Data = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 0;
- Width = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 4;
- Length = (Argc > 4) ? AsciiStrHexToUintn (Argv[4]) : 1;
+ Length = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;
for (EndAddress = Address + (Length * Width); Address < EndAddress; Address += Width) {
if (Width == 4) {
@@ -310,13 +308,13 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwDebugTemplate[] = {
{
"md",
- " [Addr] [Len] [1|2|4]; Memory Dump from Addr Len bytes",
+ "[.{1|2|4}] [Addr] [Len] [1|2|4]; Memory Dump from Addr Len bytes",
NULL,
EblMdCmd
},
{
"mfill",
- " Addr Len [data] [1|2|4]; Memory Fill Addr Len*(1|2|4) bytes of data(0)",
+ "[.{1|2|4}] Addr Len [data] [1|2|4]; Memory Fill Addr Len*(1|2|4) bytes of data(0)",
NULL,
EblMfillCmd
},
diff --git a/EmbeddedPkg/Ebl/HwIoDebug.c b/EmbeddedPkg/Ebl/HwIoDebug.c index 2d23e7c936..d32aba6a2e 100644 --- a/EmbeddedPkg/Ebl/HwIoDebug.c +++ b/EmbeddedPkg/Ebl/HwIoDebug.c @@ -24,12 +24,11 @@ /**
Read from IO space
- Argv[0] - "ioread"
+ Argv[0] - "ioread"[.#] # is optiona width 1, 2, or 4. Default 1
Argv[1] - Hex IO address
- Argv[2] - IO Width [1|2|4] with a default of 1
- ior 0x3f8 4 ;Do a 32-bit IO Read from 0x3f8
- ior 0x3f8 1 ;Do a 8-bit IO Read from 0x3f8
+ ior.4 0x3f8 ;Do a 32-bit IO Read from 0x3f8
+ ior 0x3f8 ;Do a 8-bit IO Read from 0x3f8
@param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line.
@@ -53,7 +52,7 @@ EblIoReadCmd ( }
Port = AsciiStrHexToUintn (Argv[1]);
- Width = (Argc > 2) ? AsciiStrHexToUintn (Argv[2]) : 1;
+ Width = WidthFromCommandName (Argv[0], 1);
if (Width == 1) {
Data = IoRead8 (Port);
@@ -74,13 +73,12 @@ EblIoReadCmd ( /**
Write to IO space
- Argv[0] - "iowrite"
+ Argv[0] - "iowrite"[.#] # is optiona width 1, 2, or 4. Default 1
Argv[1] - Hex IO address
Argv[2] - Hex data to write
- Argv[3] - IO Width [1|2|4] with a default of 1
- iow 0x3f8 af 4 ;Do a 32-bit IO write of af to 0x3f8
- iow 0x3f8 af ;Do an 8-bit IO write of af to 0x3f8
+ iow.4 0x3f8 af ;Do a 32-bit IO write of af to 0x3f8
+ iow 0x3f8 af ;Do an 8-bit IO write of af to 0x3f8
@param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line.
@@ -105,7 +103,7 @@ EblIoWriteCmd ( Port = AsciiStrHexToUintn (Argv[1]);
Data = AsciiStrHexToUintn (Argv[2]);
- Width = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;
+ Width = WidthFromCommandName (Argv[0], 1);
if (Width == 1) {
IoWrite8 (Port, (UINT8)Data);
@@ -124,13 +122,13 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwIoDebugTemplate[] = {
{
"ioread",
- " Port [1|2|4]; IO read of width[1] byte(s) from Port",
+ "[.{1|2|4}] Port ; IO read of width byte(s) from Port",
NULL,
EblIoReadCmd
},
{
"iowrite",
- " Port Data [1|2|4]; IO write Data of width[1] byte(s) to Port",
+ "[.{1|2|4}] Port Data ; IO write Data of width byte(s) to Port",
NULL,
EblIoWriteCmd
}
diff --git a/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c b/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c index 861ca15165..2d53368c9f 100644 --- a/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c +++ b/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c @@ -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; |