X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EmbeddedPkg%2FEbl%2FEfiDevice.c;h=ec9c331b70047bad00a60105eab2926eaf3a03ec;hp=2f9a6067267cc4e950000d17ac53bd1f2444f589;hb=50c6a4d2d4d7ede07143c0cde9505938e5d43a5b;hpb=884366cf56a53f3e54c19790e60c9eb788706e1c
diff --git a/EmbeddedPkg/Ebl/EfiDevice.c b/EmbeddedPkg/Ebl/EfiDevice.c
index 2f9a606726..ec9c331b70 100644
--- a/EmbeddedPkg/Ebl/EfiDevice.c
+++ b/EmbeddedPkg/Ebl/EfiDevice.c
@@ -3,6 +3,7 @@
Copyright (c) 2007, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -157,23 +158,23 @@ EblPrintLoadFileInfo (
if (File->DevicePath != NULL) {
// Try to print out the MAC address
- for (DevicePathNode = File->DevicePath;
- !IsDevicePathEnd (DevicePathNode);
+ for (DevicePathNode = File->DevicePath;
+ !IsDevicePathEnd (DevicePathNode);
DevicePathNode = NextDevicePathNode (DevicePathNode)) {
-
+
if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePathNode) == MSG_MAC_ADDR_DP)) {
MacAddr = (MAC_ADDR_DEVICE_PATH *)DevicePathNode;
-
+
HwAddressSize = sizeof (EFI_MAC_ADDRESS);
if (MacAddr->IfType == 0x01 || MacAddr->IfType == 0x00) {
HwAddressSize = 6;
}
-
+
AsciiPrint ("MAC ");
for (Index = 0; Index < HwAddressSize; Index++) {
AsciiPrint ("%02x", MacAddr->MacAddress.Addr[Index] & 0xff);
}
- }
+ }
}
}
@@ -185,7 +186,7 @@ EblPrintLoadFileInfo (
/**
- Dump information about devices in the system.
+ Dump information about devices in the system.
fv: PI Firmware Volume
fs: EFI Simple File System
@@ -195,13 +196,14 @@ EblPrintLoadFileInfo (
Argv[0] - "device"
@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
+ @param Argv Array of strings that represent the parsed command line.
+ Argv[0] is the command name
@return EFI_SUCCESS
**/
EFI_STATUS
+EFIAPI
EblDeviceCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -249,7 +251,7 @@ EblDeviceCmd (
}
}
}
-
+
Max = EfiGetDeviceCounts (EfiOpenLoadFile);
if (Max != 0) {
AsciiPrint ("LoadFile Devices: (usually network)\n");
@@ -266,7 +268,7 @@ EblDeviceCmd (
/**
- Start an EFI image (PE32+ with EFI defined entry point).
+ Start an EFI image (PE32+ with EFI defined entry point).
Argv[0] - "start"
Argv[1] - device name and path
@@ -278,13 +280,14 @@ EblDeviceCmd (
start LoadFile0: ; load an FV via a PXE boot
@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
+ @param Argv Array of strings that represent the parsed command line.
+ Argv[0] is the command name
@return EFI_SUCCESS
**/
EFI_STATUS
+EFIAPI
EblStartCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -308,7 +311,7 @@ EblStartCmd (
File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
if (File == NULL) {
- return EFI_INVALID_PARAMETER;
+ return EFI_INVALID_PARAMETER;
}
DevicePath = File->DevicePath;
@@ -328,7 +331,7 @@ EblStartCmd (
FreePool (Buffer);
}
-
+
EfiClose (File);
if (!EFI_ERROR (Status)) {
@@ -337,7 +340,7 @@ EblStartCmd (
// We don't pass Argv[0] to the EFI Application (it's name) just the args
Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo);
ASSERT_EFI_ERROR (Status);
-
+
ImageInfo->LoadOptionsSize = (UINT32)AsciiStrSize (Argv[2]);
ImageInfo->LoadOptions = AllocatePool (ImageInfo->LoadOptionsSize);
AsciiStrCpy (ImageInfo->LoadOptions, Argv[2]);
@@ -353,8 +356,8 @@ EblStartCmd (
/**
Load a Firmware Volume (FV) into memory from a device. This causes drivers in
- the FV to be dispatched if the dependancies of the drivers are met.
-
+ the FV to be dispatched if the dependencies of the drivers are met.
+
Argv[0] - "loadfv"
Argv[1] - device name and path
@@ -363,13 +366,14 @@ EblStartCmd (
loadfv LoadFile0: ; load an FV via a PXE boot
@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
+ @param Argv Array of strings that represent the parsed command line.
+ Argv[0] is the command name
@return EFI_SUCCESS
**/
EFI_STATUS
+EFIAPI
EblLoadFvCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -388,7 +392,7 @@ EblLoadFvCmd (
File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
if (File == NULL) {
- return EFI_INVALID_PARAMETER;
+ return EFI_INVALID_PARAMETER;
}
if (File->Type == EfiOpenMemoryBuffer) {
@@ -401,29 +405,32 @@ EblLoadFvCmd (
if (EFI_ERROR (Status)) {
return Status;
}
-
+
Status = gDS->ProcessFirmwareVolume (FvStart, FvSize, &FvHandle);
- FreePool (FvStart);
+ if (EFI_ERROR (Status)) {
+ FreePool (FvStart);
+ }
}
return Status;
}
/**
- Perform an EFI connect to connect devices that follow the EFI driver model.
+ Perform an EFI connect to connect devices that follow the EFI driver model.
If it is a PI system also call the dispatcher in case a new FV was made
- availible by one of the connect EFI drivers (this is not a common case).
-
+ available by one of the connect EFI drivers (this is not a common case).
+
Argv[0] - "connect"
@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
+ @param Argv Array of strings that represent the parsed command line.
+ Argv[0] is the command name
@return EFI_SUCCESS
**/
EFI_STATUS
+EFIAPI
EblConnectCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -449,11 +456,11 @@ EblConnectCmd (
if (EFI_ERROR (Status)) {
return Status;
}
-
+
for (Index = 0; Index < HandleCount; Index++) {
gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
}
-
+
//
// Given we disconnect our console we should go and do a connect now
//
@@ -535,17 +542,18 @@ CHAR8 *gMemMapType[] = {
/**
Dump out the EFI memory map
-
+
Argv[0] - "memmap"
@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
+ @param Argv Array of strings that represent the parsed command line.
+ Argv[0] is the command name
@return EFI_SUCCESS
**/
EFI_STATUS
+EFIAPI
EblMemMapCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -567,7 +575,7 @@ EblMemMapCmd (
ZeroMem (PageCount, sizeof (PageCount));
AsciiPrint ("EFI Memory Map\n");
-
+
// First call is to figure out how big the buffer needs to be
MemMapSize = 0;
MemMap = NULL;
@@ -591,7 +599,7 @@ EblMemMapCmd (
MemMap = NEXT_MEMORY_DESCRIPTOR (MemMap, DescriptorSize);
}
}
-
+
for (Index = 0, TotalMemory = 0; Index < EfiMaxMemoryType; Index++) {
if (PageCount[Index] != 0) {
AsciiPrint ("\n %a %,7ld Pages (%,14ld)", gMemMapType[Index], PageCount[Index], LShiftU64 (PageCount[Index], 12));
@@ -626,35 +634,36 @@ EblMemMapCmd (
/**
- Load a file into memory and optionally jump to it. A load addres can be
+ Load a file into memory and optionally jump to it. A load address can be
specified or automatically allocated. A quoted command line can optionally
- be passed into the image.
+ be passed into the image.
Argv[0] - "go"
Argv[1] - Device Name:path for the file to load
Argv[2] - Address to load to or '*' if the load address will be allocated
Argv[3] - Optional Entry point to the image. Image will be called if present
- Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs
+ Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs
to include the command name
- go fv1:\EblCmdX 0x10000 0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX
- from FV1 to location 0x10000 and call the entry point at 0x10010 passing
+ go fv1:\EblCmdX 0x10000 0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX
+ from FV1 to location 0x10000 and call the entry point at 0x10010 passing
in "EblCmdX Arg2 Arg3 Arg4" as the arguments.
- go fv0:\EblCmdX * 0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0
- to location allocated by this comamnd and call the entry point at offset 0x10
+ go fv0:\EblCmdX * 0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0
+ to location allocated by this command and call the entry point at offset 0x10
passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments.
go fv1:\EblCmdX 0x10000; Load EblCmdX to address 0x10000 and return
@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
+ @param Argv Array of strings that represent the parsed command line.
+ Argv[0] is the command name
@return EFI_SUCCESS
**/
EFI_STATUS
+EFIAPI
EblGoCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -667,7 +676,7 @@ EblGoCmd (
EBL_COMMMAND EntryPoint;
UINTN EntryPointArgc;
CHAR8 *EntryPointArgv[MAX_ARGS];
-
+
if (Argc <= 2) {
// device name and laod address are required
@@ -684,8 +693,8 @@ EblGoCmd (
if (Argv[2][0] == '*') {
// * Means allocate the buffer
Status = EfiReadAllocatePool (File, &Address, &Size);
-
- // EntryPoint is relatvie to the start of the image
+
+ // EntryPoint is relative to the start of the image
EntryPoint = (EBL_COMMMAND)((UINTN)EntryPoint + (UINTN)Address);
} else {
@@ -707,7 +716,7 @@ EblGoCmd (
EntryPointArgc = 1;
EntryPointArgv[0] = File->FileName;
}
-
+
Status = EntryPoint (EntryPointArgc, EntryPointArgv);
}
}
@@ -719,6 +728,7 @@ EblGoCmd (
#define FILE_COPY_CHUNK 0x20000
EFI_STATUS
+EFIAPI
EblFileCopyCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -730,19 +740,64 @@ EblFileCopyCmd (
VOID *Buffer = NULL;
UINTN Size;
UINTN Offset;
- UINTN Chunk = FILE_COPY_CHUNK;
+ UINTN Chunk = FILE_COPY_CHUNK;
+ UINTN FileNameLen;
+ CHAR8* DestFileName;
+ CHAR8* SrcFileName;
+ CHAR8* SrcPtr;
if (Argc < 3) {
return EFI_INVALID_PARAMETER;
}
-
+
+ DestFileName = Argv[2];
+ FileNameLen = AsciiStrLen (DestFileName);
+
+ // Check if the destination file name looks like a directory
+ if ((DestFileName[FileNameLen-1] == '\\') || (DestFileName[FileNameLen-1] == ':')) {
+ // Set the pointer after the source drive (eg: after fs1:)
+ SrcPtr = AsciiStrStr (Argv[1], ":");
+ if (SrcPtr == NULL) {
+ SrcPtr = Argv[1];
+ } else {
+ SrcPtr++;
+ if (*SrcPtr == '\\') {
+ SrcPtr++;
+ }
+ }
+
+ if (*SrcPtr == '\0') {
+ AsciiPrint("Source file incorrect.\n");
+ }
+
+ // Skip the Source Directories
+ while (1) {
+ SrcFileName = SrcPtr;
+ SrcPtr = AsciiStrStr (SrcPtr,"\\");
+ if (SrcPtr != NULL) {
+ SrcPtr++;
+ } else {
+ break;
+ }
+ }
+
+ if (*SrcFileName == '\0') {
+ AsciiPrint("Source file incorrect (Error 2).\n");
+ }
+
+ // Construct the destination filepath
+ DestFileName = (CHAR8*)AllocatePool (FileNameLen + AsciiStrLen (SrcFileName) + 1);
+ AsciiStrCpy (DestFileName, Argv[2]);
+ AsciiStrCat (DestFileName, SrcFileName);
+ }
+
Source = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);
if (Source == NULL) {
AsciiPrint("Source file open error.\n");
return EFI_NOT_FOUND;
}
-
- Destination = EfiOpen(Argv[2], EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
+
+ Destination = EfiOpen(DestFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
if (Destination == NULL) {
AsciiPrint("Destination file open error.\n");
return EFI_NOT_FOUND;
@@ -752,12 +807,12 @@ EblFileCopyCmd (
if (Buffer == NULL) {
goto Exit;
}
-
+
Size = EfiTell(Source, NULL);
for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) {
Chunk = FILE_COPY_CHUNK;
-
+
Status = EfiRead(Source, Buffer, &Chunk);
if (EFI_ERROR(Status)) {
AsciiPrint("Read file error %r\n", Status);
@@ -768,13 +823,13 @@ EblFileCopyCmd (
if (EFI_ERROR(Status)) {
AsciiPrint("Write file error %r\n", Status);
goto Exit;
- }
+ }
}
-
+
// Any left over?
if (Offset < Size) {
Chunk = Size - Offset;
-
+
Status = EfiRead(Source, Buffer, &Chunk);
if (EFI_ERROR(Status)) {
AsciiPrint("Read file error %r\n", Status);
@@ -785,7 +840,7 @@ EblFileCopyCmd (
if (EFI_ERROR(Status)) {
AsciiPrint("Write file error %r\n", Status);
goto Exit;
- }
+ }
}
@@ -801,16 +856,22 @@ Exit:
if (EFI_ERROR(Status)) {
AsciiPrint("Destination close error %r\n", Status);
}
+
+ // Case when we have concated the filename to the destination directory
+ if (DestFileName != Argv[2]) {
+ FreePool (DestFileName);
+ }
}
-
+
if (Buffer != NULL) {
FreePool(Buffer);
}
-
+
return Status;
}
EFI_STATUS
+EFIAPI
EblFileDiffCmd (
IN UINTN Argc,
IN CHAR8 **Argv
@@ -825,17 +886,17 @@ EblFileDiffCmd (
UINTN Size2;
UINTN Offset;
UINTN Chunk = FILE_COPY_CHUNK;
-
+
if (Argc != 3) {
return EFI_INVALID_PARAMETER;
}
-
+
File1 = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);
if (File1 == NULL) {
AsciiPrint("File 1 open error.\n");
return EFI_NOT_FOUND;
}
-
+
File2 = EfiOpen(Argv[2], EFI_FILE_MODE_READ, 0);
if (File2 == NULL) {
AsciiPrint("File 2 open error.\n");
@@ -854,15 +915,15 @@ EblFileDiffCmd (
if (Buffer1 == NULL) {
goto Exit;
}
-
+
Buffer2 = AllocatePool(FILE_COPY_CHUNK);
if (Buffer2 == NULL) {
goto Exit;
- }
+ }
for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size1; Offset += Chunk) {
Chunk = FILE_COPY_CHUNK;
-
+
Status = EfiRead(File1, Buffer1, &Chunk);
if (EFI_ERROR(Status)) {
AsciiPrint("File 1 read error\n");
@@ -874,17 +935,17 @@ EblFileDiffCmd (
AsciiPrint("File 2 read error\n");
goto Exit;
}
-
+
if (CompareMem(Buffer1, Buffer2, Chunk) != 0) {
AsciiPrint("Files differ.\n");
goto Exit;
};
}
-
+
// Any left over?
if (Offset < Size1) {
Chunk = Size1 - Offset;
-
+
Status = EfiRead(File1, Buffer1, &Chunk);
if (EFI_ERROR(Status)) {
AsciiPrint("File 1 read error\n");
@@ -895,9 +956,9 @@ EblFileDiffCmd (
if (EFI_ERROR(Status)) {
AsciiPrint("File 2 read error\n");
goto Exit;
- }
+ }
}
-
+
if (CompareMem(Buffer1, Buffer2, Chunk) != 0) {
AsciiPrint("Files differ.\n");
} else {
@@ -911,22 +972,22 @@ Exit:
AsciiPrint("File 1 close error %r\n", Status);
}
}
-
+
if (File2 != NULL) {
Status = EfiClose(File2);
if (EFI_ERROR(Status)) {
AsciiPrint("File 2 close error %r\n", Status);
}
}
-
+
if (Buffer1 != NULL) {
FreePool(Buffer1);
}
-
+
if (Buffer2 != NULL) {
FreePool(Buffer2);
}
-
+
return Status;
}
@@ -946,31 +1007,31 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDeviceTemplate[] =
},
{
"go",
- " dev:path loadaddress entrypoint args; load to given address and jump in",
+ " dev:path loadaddress entrypoint args; load to given address and jump in",
NULL,
EblGoCmd
},
{
"loadfv",
- " devname; Load PI FV from device",
+ " devname; Load PI FV from device",
NULL,
EblLoadFvCmd
},
{
"start",
- " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI",
+ " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI",
NULL,
EblStartCmd
},
{
"memmap",
- "; dump EFI memory map",
+ "; dump EFI memory map",
NULL,
EblMemMapCmd
},
{
"cp",
- " file1 file2; copy file",
+ " file1 file2; copy file only.",
NULL,
EblFileCopyCmd
},