Update EBL to have an optional width specifier on commands. So hexdump.4 means use a width of 4 bytes.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9974 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
andrewfish 2010-02-10 23:48:46 +00:00
parent f1569a9323
commit a6d7123ebc
5 changed files with 166 additions and 80 deletions

View File

@ -186,8 +186,16 @@ EblGetCommand (
UINTN BestMatchCount; UINTN BestMatchCount;
UINTN Length; UINTN Length;
EBL_COMMAND_TABLE *Match; EBL_COMMAND_TABLE *Match;
CHAR8 *Str;
Length = AsciiStrLen (CommandName); 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++) { for (Index = 0, BestMatchCount = 0, Match = NULL; Index < mCmdTableNextFreeIndex; Index++) {
if (AsciiStriCmp (mCmdTable[Index]->Name, CommandName) == 0) { if (AsciiStriCmp (mCmdTable[Index]->Name, CommandName) == 0) {
// match a command exactly // match a command exactly
@ -650,8 +658,60 @@ OutputData (
return EFI_SUCCESS; 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 #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 EFI_STATUS
EblHexdumpCmd ( EblHexdumpCmd (
IN UINTN Argc, IN UINTN Argc,
@ -661,19 +721,16 @@ EblHexdumpCmd (
EFI_OPEN_FILE *File; EFI_OPEN_FILE *File;
VOID *Location; VOID *Location;
UINTN Size; UINTN Size;
UINTN Width = 1; UINTN Width;
UINTN Offset = 0; UINTN Offset = 0;
EFI_STATUS Status; EFI_STATUS Status;
UINTN Chunk = HEXDUMP_CHUNK; UINTN Chunk = HEXDUMP_CHUNK;
if ((Argc < 2) || (Argc > 3)) { if ((Argc < 2) || (Argc > 4)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (Argc == 3) { Width = WidthFromCommandName (Argv[0], 1);
Width = AsciiStrDecimalToUintn(Argv[2]);
}
if ((Width != 1) && (Width != 2) && (Width != 4)) { if ((Width != 1) && (Width != 2) && (Width != 4)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@ -684,14 +741,26 @@ EblHexdumpCmd (
} }
Location = AllocatePool (Chunk); Location = AllocatePool (Chunk);
Size = EfiTell(File, NULL); Size = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : EfiTell (File, NULL);
for (Offset = 0; Offset + HEXDUMP_CHUNK <= Size; Offset += Chunk) { 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; Chunk = HEXDUMP_CHUNK;
Status = EfiRead (File, Location, &Chunk); Status = EfiRead (File, Location, &Chunk);
if (EFI_ERROR(Status)) if (EFI_ERROR(Status)) {
{
AsciiPrint ("Error reading file content\n"); AsciiPrint ("Error reading file content\n");
goto Exit; goto Exit;
} }
@ -778,7 +847,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdTemplate[] =
}, },
{ {
"hexdump", "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, NULL,
EblHexdumpCmd EblHexdumpCmd
} }

View File

@ -184,6 +184,13 @@ OutputData (
IN UINTN Width, IN UINTN Width,
IN UINTN Offset IN UINTN Offset
); );
UINTN
WidthFromCommandName (
IN CHAR8 *Argv,
IN UINTN Default
);
extern UINTN gScreenColumns; extern UINTN gScreenColumns;
extern UINTN gScreenRows; extern UINTN gScreenRows;

View File

@ -24,14 +24,13 @@
/** /**
Dump memory 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[1] - Hex Address to dump
Argv[2] - Number of hex bytes to dump (0x20 is default) 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.4 0x123445678 50 ; Dump 0x50 4 byte quantities starting at 0x123445678
md 0x123445678 40 ; Dump 0x40 1 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 0x123445678 ; Dump 0x20 1 byte quantities starting at 0x123445678
@param Argc Number of command arguments in Argv @param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line. @param Argv Array of strings that represent the parsed command line.
@ -48,21 +47,20 @@ EblMdCmd (
{ {
STATIC UINT8 *Address = NULL; STATIC UINT8 *Address = NULL;
STATIC UINTN Length = 0x20; STATIC UINTN Length = 0x20;
STATIC UINTN Width = 1; STATIC UINTN Width;
switch (Argc) Width = WidthFromCommandName (Argv[0], 1);
{
case 4: switch (Argc) {
Width = AsciiStrHexToUintn(Argv[3]);
case 3: case 3:
Length = AsciiStrHexToUintn(Argv[2]); Length = AsciiStrHexToUintn(Argv[2]);
case 2: case 2:
Address = (UINT8 *)AsciiStrHexToUintn(Argv[1]); Address = (UINT8 *)AsciiStrHexToUintn (Argv[1]);
default: default:
break; break;
} }
OutputData(Address, Length, Width, (UINTN)Address); OutputData (Address, Length, Width, (UINTN)Address);
Address += Length; Address += Length;
@ -73,14 +71,13 @@ EblMdCmd (
/** /**
Fill Memory with data 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[1] - Hex Address to fill
Argv[2] - Data to write (0x00 is default) Argv[2] - Data to write (0x00 is default)
Argv[3] - Number of units to dump. 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.1 0x123445678 aa 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.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 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 mf 0x123445678 ; Start at 0x123445678 and write 00 (4 byte) to the next 1 byte
@ -107,10 +104,11 @@ EblMfillCmd (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
Width = WidthFromCommandName (Argv[0], 4);
Address = AsciiStrHexToUintn (Argv[1]); Address = AsciiStrHexToUintn (Argv[1]);
Data = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 0; Data = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 0;
Width = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 4; Length = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;
Length = (Argc > 4) ? AsciiStrHexToUintn (Argv[4]) : 1;
for (EndAddress = Address + (Length * Width); Address < EndAddress; Address += Width) { for (EndAddress = Address + (Length * Width); Address < EndAddress; Address += Width) {
if (Width == 4) { if (Width == 4) {
@ -310,13 +308,13 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwDebugTemplate[] =
{ {
{ {
"md", "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, NULL,
EblMdCmd EblMdCmd
}, },
{ {
"mfill", "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, NULL,
EblMfillCmd EblMfillCmd
}, },

View File

@ -24,12 +24,11 @@
/** /**
Read from IO space 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[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.4 0x3f8 ;Do a 32-bit IO Read from 0x3f8
ior 0x3f8 1 ;Do a 8-bit IO Read from 0x3f8 ior 0x3f8 ;Do a 8-bit IO Read from 0x3f8
@param Argc Number of command arguments in Argv @param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line. @param Argv Array of strings that represent the parsed command line.
@ -53,7 +52,7 @@ EblIoReadCmd (
} }
Port = AsciiStrHexToUintn (Argv[1]); Port = AsciiStrHexToUintn (Argv[1]);
Width = (Argc > 2) ? AsciiStrHexToUintn (Argv[2]) : 1; Width = WidthFromCommandName (Argv[0], 1);
if (Width == 1) { if (Width == 1) {
Data = IoRead8 (Port); Data = IoRead8 (Port);
@ -74,13 +73,12 @@ EblIoReadCmd (
/** /**
Write to IO space 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[1] - Hex IO address
Argv[2] - Hex data to write 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.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 iow 0x3f8 af ;Do an 8-bit IO write of af to 0x3f8
@param Argc Number of command arguments in Argv @param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line. @param Argv Array of strings that represent the parsed command line.
@ -105,7 +103,7 @@ EblIoWriteCmd (
Port = AsciiStrHexToUintn (Argv[1]); Port = AsciiStrHexToUintn (Argv[1]);
Data = AsciiStrHexToUintn (Argv[2]); Data = AsciiStrHexToUintn (Argv[2]);
Width = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1; Width = WidthFromCommandName (Argv[0], 1);
if (Width == 1) { if (Width == 1) {
IoWrite8 (Port, (UINT8)Data); IoWrite8 (Port, (UINT8)Data);
@ -124,13 +122,13 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwIoDebugTemplate[] =
{ {
{ {
"ioread", "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, NULL,
EblIoReadCmd EblIoReadCmd
}, },
{ {
"iowrite", "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, NULL,
EblIoWriteCmd EblIoWriteCmd
} }

View File

@ -57,6 +57,7 @@
CHAR8 *gCwd = NULL; 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_HEADER 0x4B4D4641
#define EFI_OPEN_FILE_GUARD_FOOTER 0x444D5A56 #define EFI_OPEN_FILE_GUARD_FOOTER 0x444D5A56
@ -525,10 +526,27 @@ EblFvFileDevicePath (
return Status; 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); DevicePath = DevicePathFromHandle (File->EfiHandle);
if (*FileName == '\0') { if (*FileName == '\0') {
File->DevicePath = DuplicateDevicePath (DevicePath); File->DevicePath = DuplicateDevicePath (DevicePath);
File->Size = File->FvSize;
File->MaxPosition = File->Size;
} else { } else {
Key = 0; Key = 0;
do { do {
@ -579,21 +597,7 @@ EblFvFileDevicePath (
File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode); 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... // FVB not required if FV was soft loaded...
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1164,8 +1168,11 @@ EfiSeek (
} }
if (File->Type == EfiOpenLoadFile || File->Type == EfiOpenFirmwareVolume) { if (File->Type == EfiOpenLoadFile || File->Type == EfiOpenFirmwareVolume) {
// LoadFile and FV do not support Seek if (!CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
return EFI_UNSUPPORTED; // LoadFile and FV do not support Seek
// You can seek on a raw FV device
return EFI_UNSUPPORTED;
}
} }
CurrentPosition = File->CurrentPosition; CurrentPosition = File->CurrentPosition;
@ -1304,26 +1311,33 @@ EfiRead (
break; break;
case EfiOpenFirmwareVolume: case EfiOpenFirmwareVolume:
if (File->FvSectionType == EFI_SECTION_ALL) { if (CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
Status = File->Fv->ReadFile ( // This is the entire FV device, so treat like a memory buffer
File->Fv, CopyMem (Buffer, (VOID *)(UINTN)(File->FvStart + File->CurrentPosition), *BufferSize);
&File->FvNameGuid, File->CurrentPosition += *BufferSize;
&Buffer, Status = EFI_SUCCESS;
BufferSize,
&File->FvType,
&File->FvAttributes,
&AuthenticationStatus
);
} else { } else {
Status = File->Fv->ReadSection ( if (File->FvSectionType == EFI_SECTION_ALL) {
File->Fv, Status = File->Fv->ReadFile (
&File->FvNameGuid, File->Fv,
File->FvSectionType, &File->FvNameGuid,
0, &Buffer,
&Buffer, BufferSize,
BufferSize, &File->FvType,
&AuthenticationStatus &File->FvAttributes,
); &AuthenticationStatus
);
} else {
Status = File->Fv->ReadSection (
File->Fv,
&File->FvNameGuid,
File->FvSectionType,
0,
&Buffer,
BufferSize,
&AuthenticationStatus
);
}
} }
break; break;