summaryrefslogtreecommitdiff
path: root/EmbeddedPkg/Ebl/EfiDevice.c
diff options
context:
space:
mode:
Diffstat (limited to 'EmbeddedPkg/Ebl/EfiDevice.c')
-rw-r--r--EmbeddedPkg/Ebl/EfiDevice.c1050
1 files changed, 0 insertions, 1050 deletions
diff --git a/EmbeddedPkg/Ebl/EfiDevice.c b/EmbeddedPkg/Ebl/EfiDevice.c
deleted file mode 100644
index 7d2060936d..0000000000
--- a/EmbeddedPkg/Ebl/EfiDevice.c
+++ /dev/null
@@ -1,1050 +0,0 @@
-/** @file
- EBL commands for EFI and PI Devices
-
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "Ebl.h"
-
-
-EFI_DXE_SERVICES *gDS = NULL;
-
-
-/**
- Print information about the File System device.
-
- @param File Open File for the device
-
-**/
-VOID
-EblPrintFsInfo (
- IN EFI_OPEN_FILE *File
- )
-{
- CHAR16 *Str;
-
- if (File == NULL) {
- return;
- }
-
- AsciiPrint (" %a: ", File->DeviceName);
- if (File->FsInfo != NULL) {
- for (Str = File->FsInfo->VolumeLabel; *Str != '\0'; Str++) {
- if (*Str == ' ') {
- // UI makes you enter _ for space, so make the printout match that
- *Str = '_';
- }
- AsciiPrint ("%c", *Str);
- }
- AsciiPrint (":");
- if (File->FsInfo->ReadOnly) {
- AsciiPrint ("ReadOnly");
- }
- }
-
- AsciiPrint ("\n");
- EfiClose (File);
-}
-
-
-/**
- Print information about the FV devices.
-
- @param File Open File for the device
-
-**/
-VOID
-EblPrintFvbInfo (
- IN EFI_OPEN_FILE *File
- )
-{
- if (File == NULL) {
- return;
- }
-
- AsciiPrint (" %a: 0x%08lx - 0x%08lx : 0x%08x\n", File->DeviceName, File->FvStart, File->FvStart + File->FvSize - 1, File->FvSize);
- EfiClose (File);
-}
-
-
-/**
- Print information about the Blk IO devices.
- If the device supports PXE dump out extra information
-
- @param File Open File for the device
-
-**/
-VOID
-EblPrintBlkIoInfo (
- IN EFI_OPEN_FILE *File
- )
-{
- UINT64 DeviceSize;
- UINTN Index;
- UINTN Max;
- EFI_OPEN_FILE *FsFile;
-
- if (File == NULL) {
- return;
- }
-
- AsciiPrint (" %a: ", File->DeviceName);
-
- // print out name of file system, if any, on this block device
- Max = EfiGetDeviceCounts (EfiOpenFileSystem);
- if (Max != 0) {
- for (Index = 0; Index < Max; Index++) {
- FsFile = EfiDeviceOpenByType (EfiOpenFileSystem, Index);
- if (FsFile != NULL) {
- if (FsFile->EfiHandle == File->EfiHandle) {
- AsciiPrint ("fs%d: ", Index);
- EfiClose (FsFile);
- break;
- }
- EfiClose (FsFile);
- }
- }
- }
-
- // Print out useful Block IO media properties
- if (File->FsBlockIoMedia->RemovableMedia) {
- AsciiPrint ("Removable ");
- }
- if (!File->FsBlockIoMedia->MediaPresent) {
- AsciiPrint ("No Media\n");
- } else {
- if (File->FsBlockIoMedia->LogicalPartition) {
- AsciiPrint ("Partition ");
- }
- DeviceSize = MultU64x32 (File->FsBlockIoMedia->LastBlock + 1, File->FsBlockIoMedia->BlockSize);
- AsciiPrint ("Size = 0x%lX\n", DeviceSize);
- }
- EfiClose (File);
-}
-
- /**
- Print information about the Load File devices.
- If the device supports PXE dump out extra information
-
- @param File Open File for the device
-
-**/
-VOID
-EblPrintLoadFileInfo (
- IN EFI_OPEN_FILE *File
- )
-{
- EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
- MAC_ADDR_DEVICE_PATH *MacAddr;
- UINTN HwAddressSize;
- UINTN Index;
-
- if (File == NULL) {
- return;
- }
-
- AsciiPrint (" %a: %a ", File->DeviceName, EblLoadFileBootTypeString (File->EfiHandle));
-
- if (File->DevicePath != NULL) {
- // Try to print out the MAC address
- 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);
- }
- }
- }
- }
-
- AsciiPrint ("\n");
- EfiClose (File);
- return;
-}
-
-
-
-/**
- Dump information about devices in the system.
-
- fv: PI Firmware Volume
- fs: EFI Simple File System
- blk: EFI Block IO
- LoadFile: EFI Load File Protocol (commonly PXE network boot)
-
- 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 command name
-
- @return EFI_SUCCESS
-
-**/
-EFI_STATUS
-EblDeviceCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- UINTN Index;
- UINTN CurrentRow;
- UINTN Max;
-
- CurrentRow = 0;
-
- // Need to call here to make sure Device Counts are valid
- EblUpdateDeviceLists ();
-
- // Now we can print out the info...
- Max = EfiGetDeviceCounts (EfiOpenFirmwareVolume);
- if (Max != 0) {
- AsciiPrint ("Firmware Volume Devices:\n");
- for (Index = 0; Index < Max; Index++) {
- EblPrintFvbInfo (EfiDeviceOpenByType (EfiOpenFirmwareVolume, Index));
- if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
- break;
- }
- }
- }
-
- Max = EfiGetDeviceCounts (EfiOpenFileSystem);
- if (Max != 0) {
- AsciiPrint ("File System Devices:\n");
- for (Index = 0; Index < Max; Index++) {
- EblPrintFsInfo (EfiDeviceOpenByType (EfiOpenFileSystem, Index));
- if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
- break;
- }
- }
- }
-
- Max = EfiGetDeviceCounts (EfiOpenBlockIo);
- if (Max != 0) {
- AsciiPrint ("Block IO Devices:\n");
- for (Index = 0; Index < Max; Index++) {
- EblPrintBlkIoInfo (EfiDeviceOpenByType (EfiOpenBlockIo, Index));
- if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
- break;
- }
- }
- }
-
- Max = EfiGetDeviceCounts (EfiOpenLoadFile);
- if (Max != 0) {
- AsciiPrint ("LoadFile Devices: (usually network)\n");
- for (Index = 0; Index < Max; Index++) {
- EblPrintLoadFileInfo (EfiDeviceOpenByType (EfiOpenLoadFile, Index));
- if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
- break;
- }
- }
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Start an EFI image (PE32+ with EFI defined entry point).
-
- Argv[0] - "start"
- Argv[1] - device name and path
- Argv[2] - "" string to pass into image being started
-
- start fs1:\Temp\Fv.Fv "arg to pass" ; load an FV from the disk and pass the
- ; ascii string arg to pass to the image
- start fv0:\FV ; load an FV from an FV (not common)
- 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 command name
-
- @return EFI_SUCCESS
-
-**/
-EFI_STATUS
-EblStartCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- EFI_STATUS Status;
- EFI_OPEN_FILE *File;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_HANDLE ImageHandle;
- UINTN ExitDataSize;
- CHAR16 *ExitData;
- VOID *Buffer;
- UINTN BufferSize;
- EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
-
- ImageHandle = NULL;
-
- if (Argc < 2) {
- return EFI_INVALID_PARAMETER;
- }
-
- File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
- if (File == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- DevicePath = File->DevicePath;
- if (DevicePath != NULL) {
- // check for device path form: blk, fv, fs, and loadfile
- Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);
- } else {
- // Check for buffer form: A0x12345678:0x1234 syntax.
- // Means load using buffer starting at 0x12345678 of size 0x1234.
-
- Status = EfiReadAllocatePool (File, &Buffer, &BufferSize);
- if (EFI_ERROR (Status)) {
- EfiClose (File);
- return Status;
- }
- Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, Buffer, BufferSize, &ImageHandle);
-
- FreePool (Buffer);
- }
-
- EfiClose (File);
-
- if (!EFI_ERROR (Status)) {
- if (Argc >= 3) {
- // Argv[2] is a "" string that we pass directly to the EFI application without the ""
- // 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]);
- }
-
- // Transfer control to the EFI image we loaded with LoadImage()
- Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
- }
-
- return Status;
-}
-
-
-/**
- Load a Firmware Volume (FV) into memory from a device. This causes drivers in
- the FV to be dispatched if the dependencies of the drivers are met.
-
- Argv[0] - "loadfv"
- Argv[1] - device name and path
-
- loadfv fs1:\Temp\Fv.Fv ; load an FV from the disk
- loadfv fv0:\FV ; load an FV from an FV (not common)
- 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 command name
-
- @return EFI_SUCCESS
-
-**/
-EFI_STATUS
-EblLoadFvCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- EFI_STATUS Status;
- EFI_OPEN_FILE *File;
- VOID *FvStart;
- UINTN FvSize;
- EFI_HANDLE FvHandle;
-
-
- if (Argc < 2) {
- return EFI_INVALID_PARAMETER;
- }
-
- File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
- if (File == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (File->Type == EfiOpenMemoryBuffer) {
- // If it is a address just use it.
- Status = gDS->ProcessFirmwareVolume (File->Buffer, File->Size, &FvHandle);
- } else {
- // If it is a file read it into memory and use it
- Status = EfiReadAllocatePool (File, &FvStart, &FvSize);
- EfiClose (File);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = gDS->ProcessFirmwareVolume (FvStart, FvSize, &FvHandle);
- if (EFI_ERROR (Status)) {
- FreePool (FvStart);
- }
- }
- return Status;
-}
-
-
-/**
- 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
- 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 command name
-
- @return EFI_SUCCESS
-
-**/
-EFI_STATUS
-EblConnectCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- EFI_STATUS Status;
- UINTN HandleCount;
- EFI_HANDLE *HandleBuffer;
- UINTN Index;
- BOOLEAN Dispatch;
- EFI_OPEN_FILE *File;
-
-
- if (Argc > 1) {
- if ((*Argv[1] == 'd') || (*Argv[1] == 'D')) {
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- 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
- //
- } else {
- File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
- if (File != NULL) {
- AsciiPrint ("Connecting %a\n", Argv[1]);
- gBS->ConnectController (File->EfiHandle, NULL, NULL, TRUE);
- EfiClose (File);
- return EFI_SUCCESS;
- }
- }
- }
-
- Dispatch = FALSE;
- do {
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
- }
-
- FreePool (HandleBuffer);
-
- //
- // Check to see if it's possible to dispatch an more DXE drivers.
- // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
- // If anything is Dispatched Status == EFI_SUCCESS and we will try
- // the connect again.
- //
- if (gDS == NULL) {
- Status = EFI_NOT_FOUND;
- } else {
- Status = gDS->Dispatch ();
- if (!EFI_ERROR (Status)) {
- Dispatch = TRUE;
- }
- }
-
- } while (!EFI_ERROR (Status));
-
- if (Dispatch) {
- AsciiPrint ("Connected and dispatched\n");
- } else {
- AsciiPrint ("Connect\n");
- }
-
- return EFI_SUCCESS;
-}
-
-
-
-CHAR8 *gMemMapType[] = {
- "reserved ",
- "LoaderCode",
- "LoaderData",
- "BS_code ",
- "BS_data ",
- "RT_code ",
- "RT_data ",
- "available ",
- "Unusable ",
- "ACPI_recl ",
- "ACPI_NVS ",
- "MemMapIO ",
- "MemPortIO ",
- "PAL_code "
-};
-
-
-/**
- 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 command name
-
- @return EFI_SUCCESS
-
-**/
-EFI_STATUS
-EblMemMapCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- EFI_STATUS Status;
- EFI_MEMORY_DESCRIPTOR *MemMap;
- EFI_MEMORY_DESCRIPTOR *OrigMemMap;
- UINTN MemMapSize;
- UINTN MapKey;
- UINTN DescriptorSize;
- UINT32 DescriptorVersion;
- UINT64 PageCount[EfiMaxMemoryType];
- UINTN Index;
- UINT64 EntrySize;
- UINTN CurrentRow;
- UINT64 TotalMemory;
-
- 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;
- Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- // In case the AllocatPool changes the memory map we added in some extra descriptors
- MemMapSize += (DescriptorSize * 0x100);
- OrigMemMap = MemMap = AllocatePool (MemMapSize);
- if (OrigMemMap != NULL) {
- // 2nd time we get the data
- Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);
- if (!EFI_ERROR (Status)) {
- for (Index = 0, CurrentRow = 0; Index < MemMapSize/DescriptorSize; Index++) {
- EntrySize = LShiftU64 (MemMap->NumberOfPages, 12);
- AsciiPrint ("\n%a %016lx - %016lx: # %08lx %016lx", gMemMapType[MemMap->Type % EfiMaxMemoryType], MemMap->PhysicalStart, MemMap->PhysicalStart + EntrySize -1, MemMap->NumberOfPages, MemMap->Attribute);
- if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
- break;
- }
-
- PageCount[MemMap->Type % EfiMaxMemoryType] += MemMap->NumberOfPages;
- 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));
- if (Index == EfiLoaderCode ||
- Index == EfiLoaderData ||
- Index == EfiBootServicesCode ||
- Index == EfiBootServicesData ||
- Index == EfiRuntimeServicesCode ||
- Index == EfiRuntimeServicesData ||
- Index == EfiConventionalMemory ||
- Index == EfiACPIReclaimMemory ||
- Index == EfiACPIMemoryNVS ||
- Index == EfiPalCode
- ) {
- // Count total memory
- TotalMemory += PageCount[Index];
- }
- }
- }
-
- AsciiPrint ("\nTotal Memory: %,ld MB (%,ld bytes)\n", RShiftU64 (TotalMemory, 8), LShiftU64 (TotalMemory, 12));
-
- FreePool (OrigMemMap);
-
- }
- }
-
- return EFI_SUCCESS;
-}
-
-
-
-
-/**
- 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.
-
- 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
- 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
- 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 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 command name
-
- @return EFI_SUCCESS
-
-**/
-EFI_STATUS
-EblGoCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- EFI_STATUS Status;
- EFI_OPEN_FILE *File;
- VOID *Address;
- UINTN Size;
- EBL_COMMMAND EntryPoint;
- UINTN EntryPointArgc;
- CHAR8 *EntryPointArgv[MAX_ARGS];
-
-
- if (Argc <= 2) {
- // device name and laod address are required
- return EFI_SUCCESS;
- }
-
- File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
- if (File == NULL) {
- AsciiPrint (" %a is not a valid path\n", Argv[1]);
- return EFI_SUCCESS;
- }
-
- EntryPoint = (EBL_COMMMAND)((Argc > 3) ? (UINTN)AsciiStrHexToUintn (Argv[3]) : (UINTN)NULL);
- if (Argv[2][0] == '*') {
- // * Means allocate the buffer
- Status = EfiReadAllocatePool (File, &Address, &Size);
-
- // EntryPoint is relative to the start of the image
- EntryPoint = (EBL_COMMMAND)((UINTN)EntryPoint + (UINTN)Address);
-
- } else {
- Address = (VOID *)AsciiStrHexToUintn (Argv[2]);
- Size = File->Size;
-
- // File->Size for LoadFile is lazy so we need to use the tell to figure it out
- EfiTell (File, NULL);
- Status = EfiRead (File, Address, &Size);
- }
-
- if (!EFI_ERROR (Status)) {
- AsciiPrint ("Loaded %,d bytes to 0x%08x\n", Size, Address);
-
- if (Argc > 3) {
- if (Argc > 4) {
- ParseArguments (Argv[4], &EntryPointArgc, EntryPointArgv);
- } else {
- EntryPointArgc = 1;
- EntryPointArgv[0] = File->FileName;
- }
-
- Status = EntryPoint (EntryPointArgc, EntryPointArgv);
- }
- }
-
- EfiClose (File);
- return Status;
-}
-
-#define FILE_COPY_CHUNK 0x20000
-
-EFI_STATUS
-EblFileCopyCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- EFI_OPEN_FILE *Source = NULL;
- EFI_OPEN_FILE *Destination = NULL;
- EFI_STATUS Status = EFI_SUCCESS;
- VOID *Buffer = NULL;
- UINTN Size;
- UINTN Offset;
- 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(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;
- }
-
- Buffer = AllocatePool(FILE_COPY_CHUNK);
- 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);
- goto Exit;
- }
-
- Status = EfiWrite(Destination, Buffer, &Chunk);
- 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);
- goto Exit;
- }
-
- Status = EfiWrite(Destination, Buffer, &Chunk);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Write file error %r\n", Status);
- goto Exit;
- }
- }
-
-
-Exit:
- if (Source != NULL) {
- Status = EfiClose(Source);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Source close error %r\n", Status);
- }
- }
- if (Destination != NULL) {
- Status = EfiClose(Destination);
- 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
-EblFileDiffCmd (
- IN UINTN Argc,
- IN CHAR8 **Argv
- )
-{
- EFI_OPEN_FILE *File1 = NULL;
- EFI_OPEN_FILE *File2 = NULL;
- EFI_STATUS Status = EFI_SUCCESS;
- VOID *Buffer1 = NULL;
- VOID *Buffer2 = NULL;
- UINTN Size1;
- 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");
- return EFI_NOT_FOUND;
- }
-
- Size1 = EfiTell(File1, NULL);
- Size2 = EfiTell(File2, NULL);
-
- if (Size1 != Size2) {
- AsciiPrint("Files differ.\n");
- goto Exit;
- }
-
- Buffer1 = AllocatePool(FILE_COPY_CHUNK);
- 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");
- goto Exit;
- }
-
- Status = EfiRead(File2, Buffer2, &Chunk);
- if (EFI_ERROR(Status)) {
- 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");
- goto Exit;
- }
-
- Status = EfiRead(File2, Buffer2, &Chunk);
- if (EFI_ERROR(Status)) {
- AsciiPrint("File 2 read error\n");
- goto Exit;
- }
- }
-
- if (CompareMem(Buffer1, Buffer2, Chunk) != 0) {
- AsciiPrint("Files differ.\n");
- } else {
- AsciiPrint("Files are identical.\n");
- }
-
-Exit:
- if (File1 != NULL) {
- Status = EfiClose(File1);
- if (EFI_ERROR(Status)) {
- 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;
-}
-
-GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDeviceTemplate[] =
-{
- {
- "connect",
- "[d]; Connect all EFI devices. d means disconnect",
- NULL,
- EblConnectCmd
- },
- {
- "device",
- "; Show information about boot devices",
- NULL,
- EblDeviceCmd
- },
- {
- "go",
- " dev:path loadaddress entrypoint args; load to given address and jump in",
- NULL,
- EblGoCmd
- },
- {
- "loadfv",
- " devname; Load PI FV from device",
- NULL,
- EblLoadFvCmd
- },
- {
- "start",
- " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI",
- NULL,
- EblStartCmd
- },
- {
- "memmap",
- "; dump EFI memory map",
- NULL,
- EblMemMapCmd
- },
- {
- "cp",
- " file1 file2; copy file only.",
- NULL,
- EblFileCopyCmd
- },
- {
- "diff",
- " file1 file2; compare files",
- NULL,
- EblFileDiffCmd
- }
-};
-
-
-/**
- Initialize the commands in this in this file
-**/
-
-VOID
-EblInitializeDeviceCmd (
- VOID
- )
-{
- EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
- EblAddCommands (mCmdDeviceTemplate, sizeof (mCmdDeviceTemplate)/sizeof (EBL_COMMAND_TABLE));
-}
-