summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c')
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c846
1 files changed, 423 insertions, 423 deletions
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c
index 852d6dcf80..25d1da2a73 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c
@@ -1,423 +1,423 @@
-/** @file
- Main file for LoadPciRom shell Debug1 function.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellDebug1CommandsLib.h"
-#include <IndustryStandard/Pci22.h>
-#include <IndustryStandard/Pci23.h>
-#include <IndustryStandard/PeImage.h>
-#include <Protocol/Decompress.h>
-
-/**
- Connects all available drives and controllers.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The abort mechanism was received.
-**/
-EFI_STATUS
-LoadPciRomConnectAllDriversToAllControllers (
- VOID
- );
-
-/**
- Command entry point.
-
- @param[in] RomBar The Rom Base address.
- @param[in] RomSize The Rom size.
- @param[in] FileName The file name.
-
- @retval EFI_SUCCESS The command completed successfully.
- @retval EFI_INVALID_PARAMETER Command usage error.
- @retval EFI_UNSUPPORTED Protocols unsupported.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval Other value Unknown error.
-**/
-EFI_STATUS
-LoadEfiDriversFromRomImage (
- VOID *RomBar,
- UINTN RomSize,
- CONST CHAR16 *FileName
- );
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-nc", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'loadpcirom' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunLoadPciRom (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_SHELL_FILE_INFO *FileList;
- UINTN SourceSize;
- UINT8 *File1Buffer;
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- BOOLEAN Connect;
- CONST CHAR16 *Param;
- UINTN ParamCount;
- EFI_SHELL_FILE_INFO *Node;
-
- //
- // Local variable initializations
- //
- File1Buffer = NULL;
- ShellStatus = SHELL_SUCCESS;
- FileList = NULL;
-
- //
- // verify number of arguments
- //
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"loadpcirom", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- if (ShellCommandLineGetCount (Package) < 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"loadpcirom");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- if (ShellCommandLineGetFlag (Package, L"-nc")) {
- Connect = FALSE;
- } else {
- Connect = TRUE;
- }
-
- //
- // get a list with each file specified by parameters
- // if parameter is a directory then add all the files below it to the list
- //
- for ( ParamCount = 1, Param = ShellCommandLineGetRawValue (Package, ParamCount)
- ; Param != NULL
- ; ParamCount++, Param = ShellCommandLineGetRawValue (Package, ParamCount)
- )
- {
- Status = ShellOpenFileMetaArg ((CHAR16 *)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Param);
- ShellStatus = SHELL_ACCESS_DENIED;
- break;
- }
- }
-
- if ((ShellStatus == SHELL_SUCCESS) && (FileList != NULL)) {
- //
- // loop through the list and make sure we are not aborting...
- //
- for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
- ; !IsNull (&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag ()
- ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
- )
- {
- if (EFI_ERROR (Node->Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- continue;
- }
-
- if (FileHandleIsDirectory (Node->Handle) == EFI_SUCCESS) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- continue;
- }
-
- SourceSize = (UINTN)Node->Info->FileSize;
- File1Buffer = AllocateZeroPool (SourceSize);
- if (File1Buffer == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"loadpcirom");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- continue;
- }
-
- Status = gEfiShellProtocol->ReadFile (Node->Handle, &SourceSize, File1Buffer);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_READ_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = LoadEfiDriversFromRomImage (
- File1Buffer,
- SourceSize,
- Node->FullName
- );
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_PCI_ROM_RES), gShellDebug1HiiHandle, Node->FullName, Status);
- }
-
- FreePool (File1Buffer);
- }
- } else if (ShellStatus == SHELL_SUCCESS) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_SPEC), gShellDebug1HiiHandle, "loadpcirom");
- ShellStatus = SHELL_NOT_FOUND;
- }
-
- if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {
- Status = ShellCloseFileMetaArg (&FileList);
- }
-
- FileList = NULL;
-
- if (Connect) {
- Status = LoadPciRomConnectAllDriversToAllControllers ();
- }
- }
- }
-
- return (ShellStatus);
-}
-
-/**
- Command entry point.
-
- @param[in] RomBar The Rom Base address.
- @param[in] RomSize The Rom size.
- @param[in] FileName The file name.
-
- @retval EFI_SUCCESS The command completed successfully.
- @retval EFI_INVALID_PARAMETER Command usage error.
- @retval EFI_UNSUPPORTED Protocols unsupported.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval Other value Unknown error.
-**/
-EFI_STATUS
-LoadEfiDriversFromRomImage (
- VOID *RomBar,
- UINTN RomSize,
- CONST CHAR16 *FileName
- )
-
-{
- EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;
- PCI_DATA_STRUCTURE *Pcir;
- UINTN ImageIndex;
- UINTN RomBarOffset;
- UINT32 ImageSize;
- UINT16 ImageOffset;
- EFI_HANDLE ImageHandle;
- EFI_STATUS Status;
- EFI_STATUS ReturnStatus;
- CHAR16 RomFileName[280];
- EFI_DEVICE_PATH_PROTOCOL *FilePath;
- BOOLEAN SkipImage;
- UINT32 DestinationSize;
- UINT32 ScratchSize;
- UINT8 *Scratch;
- VOID *ImageBuffer;
- VOID *DecompressedImageBuffer;
- UINT32 ImageLength;
- EFI_DECOMPRESS_PROTOCOL *Decompress;
- UINT32 InitializationSize;
-
- ImageIndex = 0;
- ReturnStatus = EFI_NOT_FOUND;
- RomBarOffset = (UINTN)RomBar;
-
- do {
- EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *)(UINTN)RomBarOffset;
-
- if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_CORRUPT), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex);
- // PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);
- return ReturnStatus;
- }
-
- //
- // If the pointer to the PCI Data Structure is invalid, no further images can be located.
- // The PCI Data Structure must be DWORD aligned.
- //
- if ((EfiRomHeader->PcirOffset == 0) ||
- ((EfiRomHeader->PcirOffset & 3) != 0) ||
- (RomBarOffset - (UINTN)RomBar + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize))
- {
- break;
- }
-
- Pcir = (PCI_DATA_STRUCTURE *)(UINTN)(RomBarOffset + EfiRomHeader->PcirOffset);
- //
- // If a valid signature is not present in the PCI Data Structure, no further images can be located.
- //
- if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
- break;
- }
-
- ImageSize = Pcir->ImageLength * 512;
- if (RomBarOffset - (UINTN)RomBar + ImageSize > RomSize) {
- break;
- }
-
- if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
- (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&
- ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
- (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)))
- {
- ImageOffset = EfiRomHeader->EfiImageHeaderOffset;
- InitializationSize = EfiRomHeader->InitializationSize * 512;
-
- if ((InitializationSize <= ImageSize) && (ImageOffset < InitializationSize)) {
- ImageBuffer = (VOID *)(UINTN)(RomBarOffset + ImageOffset);
- ImageLength = InitializationSize - ImageOffset;
- DecompressedImageBuffer = NULL;
-
- //
- // decompress here if needed
- //
- SkipImage = FALSE;
- if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
- SkipImage = TRUE;
- }
-
- if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
- Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **)&Decompress);
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- SkipImage = TRUE;
- } else {
- SkipImage = TRUE;
- Status = Decompress->GetInfo (
- Decompress,
- ImageBuffer,
- ImageLength,
- &DestinationSize,
- &ScratchSize
- );
- if (!EFI_ERROR (Status)) {
- DecompressedImageBuffer = AllocateZeroPool (DestinationSize);
- if (ImageBuffer != NULL) {
- Scratch = AllocateZeroPool (ScratchSize);
- if (Scratch != NULL) {
- Status = Decompress->Decompress (
- Decompress,
- ImageBuffer,
- ImageLength,
- DecompressedImageBuffer,
- DestinationSize,
- Scratch,
- ScratchSize
- );
- if (!EFI_ERROR (Status)) {
- ImageBuffer = DecompressedImageBuffer;
- ImageLength = DestinationSize;
- SkipImage = FALSE;
- }
-
- FreePool (Scratch);
- }
- }
- }
- }
- }
-
- if (!SkipImage) {
- //
- // load image and start image
- //
- UnicodeSPrint (RomFileName, sizeof (RomFileName), L"%s[%d]", FileName, ImageIndex);
- FilePath = FileDevicePath (NULL, RomFileName);
-
- Status = gBS->LoadImage (
- TRUE,
- gImageHandle,
- FilePath,
- ImageBuffer,
- ImageLength,
- &ImageHandle
- );
- if (EFI_ERROR (Status)) {
- //
- // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
- // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
- // If the caller doesn't have the option to defer the execution of an image, we should
- // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
- //
- if (Status == EFI_SECURITY_VIOLATION) {
- gBS->UnloadImage (ImageHandle);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex);
- // PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);
- } else {
- Status = gBS->StartImage (ImageHandle, NULL, NULL);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_START_FAIL), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex);
- // PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);
- } else {
- ReturnStatus = Status;
- }
- }
- }
-
- if (DecompressedImageBuffer != NULL) {
- FreePool (DecompressedImageBuffer);
- }
- }
- }
-
- RomBarOffset = RomBarOffset + ImageSize;
- ImageIndex++;
- } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN)RomBar) < RomSize));
-
- return ReturnStatus;
-}
-
-/**
- Connects all available drives and controllers.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The abort mechanism was received.
-**/
-EFI_STATUS
-LoadPciRomConnectAllDriversToAllControllers (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN HandleCount;
- EFI_HANDLE *HandleBuffer;
- UINTN Index;
-
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- if (ShellGetExecutionBreakFlag ()) {
- Status = EFI_ABORTED;
- break;
- }
-
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
-
- return Status;
-}
+/** @file
+ Main file for LoadPciRom shell Debug1 function.
+
+ (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+ Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiShellDebug1CommandsLib.h"
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/Pci23.h>
+#include <IndustryStandard/PeImage.h>
+#include <Protocol/Decompress.h>
+
+/**
+ Connects all available drives and controllers.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_ABORTED The abort mechanism was received.
+**/
+EFI_STATUS
+LoadPciRomConnectAllDriversToAllControllers (
+ VOID
+ );
+
+/**
+ Command entry point.
+
+ @param[in] RomBar The Rom Base address.
+ @param[in] RomSize The Rom size.
+ @param[in] FileName The file name.
+
+ @retval EFI_SUCCESS The command completed successfully.
+ @retval EFI_INVALID_PARAMETER Command usage error.
+ @retval EFI_UNSUPPORTED Protocols unsupported.
+ @retval EFI_OUT_OF_RESOURCES Out of memory.
+ @retval Other value Unknown error.
+**/
+EFI_STATUS
+LoadEfiDriversFromRomImage (
+ VOID *RomBar,
+ UINTN RomSize,
+ CONST CHAR16 *FileName
+ );
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ { L"-nc", TypeFlag },
+ { NULL, TypeMax }
+};
+
+/**
+ Function for 'loadpcirom' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+**/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunLoadPciRom (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_SHELL_FILE_INFO *FileList;
+ UINTN SourceSize;
+ UINT8 *File1Buffer;
+ EFI_STATUS Status;
+ LIST_ENTRY *Package;
+ CHAR16 *ProblemParam;
+ SHELL_STATUS ShellStatus;
+ BOOLEAN Connect;
+ CONST CHAR16 *Param;
+ UINTN ParamCount;
+ EFI_SHELL_FILE_INFO *Node;
+
+ //
+ // Local variable initializations
+ //
+ File1Buffer = NULL;
+ ShellStatus = SHELL_SUCCESS;
+ FileList = NULL;
+
+ //
+ // verify number of arguments
+ //
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ if (EFI_ERROR (Status)) {
+ if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"loadpcirom", ProblemParam);
+ FreePool (ProblemParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ASSERT (FALSE);
+ }
+ } else {
+ if (ShellCommandLineGetCount (Package) < 2) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"loadpcirom");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ if (ShellCommandLineGetFlag (Package, L"-nc")) {
+ Connect = FALSE;
+ } else {
+ Connect = TRUE;
+ }
+
+ //
+ // get a list with each file specified by parameters
+ // if parameter is a directory then add all the files below it to the list
+ //
+ for ( ParamCount = 1, Param = ShellCommandLineGetRawValue (Package, ParamCount)
+ ; Param != NULL
+ ; ParamCount++, Param = ShellCommandLineGetRawValue (Package, ParamCount)
+ )
+ {
+ Status = ShellOpenFileMetaArg ((CHAR16 *)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Param);
+ ShellStatus = SHELL_ACCESS_DENIED;
+ break;
+ }
+ }
+
+ if ((ShellStatus == SHELL_SUCCESS) && (FileList != NULL)) {
+ //
+ // loop through the list and make sure we are not aborting...
+ //
+ for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
+ ; !IsNull (&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag ()
+ ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
+ )
+ {
+ if (EFI_ERROR (Node->Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ continue;
+ }
+
+ if (FileHandleIsDirectory (Node->Handle) == EFI_SUCCESS) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ continue;
+ }
+
+ SourceSize = (UINTN)Node->Info->FileSize;
+ File1Buffer = AllocateZeroPool (SourceSize);
+ if (File1Buffer == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"loadpcirom");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ continue;
+ }
+
+ Status = gEfiShellProtocol->ReadFile (Node->Handle, &SourceSize, File1Buffer);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_READ_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = LoadEfiDriversFromRomImage (
+ File1Buffer,
+ SourceSize,
+ Node->FullName
+ );
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_PCI_ROM_RES), gShellDebug1HiiHandle, Node->FullName, Status);
+ }
+
+ FreePool (File1Buffer);
+ }
+ } else if (ShellStatus == SHELL_SUCCESS) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_SPEC), gShellDebug1HiiHandle, "loadpcirom");
+ ShellStatus = SHELL_NOT_FOUND;
+ }
+
+ if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {
+ Status = ShellCloseFileMetaArg (&FileList);
+ }
+
+ FileList = NULL;
+
+ if (Connect) {
+ Status = LoadPciRomConnectAllDriversToAllControllers ();
+ }
+ }
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Command entry point.
+
+ @param[in] RomBar The Rom Base address.
+ @param[in] RomSize The Rom size.
+ @param[in] FileName The file name.
+
+ @retval EFI_SUCCESS The command completed successfully.
+ @retval EFI_INVALID_PARAMETER Command usage error.
+ @retval EFI_UNSUPPORTED Protocols unsupported.
+ @retval EFI_OUT_OF_RESOURCES Out of memory.
+ @retval Other value Unknown error.
+**/
+EFI_STATUS
+LoadEfiDriversFromRomImage (
+ VOID *RomBar,
+ UINTN RomSize,
+ CONST CHAR16 *FileName
+ )
+
+{
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;
+ PCI_DATA_STRUCTURE *Pcir;
+ UINTN ImageIndex;
+ UINTN RomBarOffset;
+ UINT32 ImageSize;
+ UINT16 ImageOffset;
+ EFI_HANDLE ImageHandle;
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ CHAR16 RomFileName[280];
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ BOOLEAN SkipImage;
+ UINT32 DestinationSize;
+ UINT32 ScratchSize;
+ UINT8 *Scratch;
+ VOID *ImageBuffer;
+ VOID *DecompressedImageBuffer;
+ UINT32 ImageLength;
+ EFI_DECOMPRESS_PROTOCOL *Decompress;
+ UINT32 InitializationSize;
+
+ ImageIndex = 0;
+ ReturnStatus = EFI_NOT_FOUND;
+ RomBarOffset = (UINTN)RomBar;
+
+ do {
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *)(UINTN)RomBarOffset;
+
+ if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_CORRUPT), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex);
+ // PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);
+ return ReturnStatus;
+ }
+
+ //
+ // If the pointer to the PCI Data Structure is invalid, no further images can be located.
+ // The PCI Data Structure must be DWORD aligned.
+ //
+ if ((EfiRomHeader->PcirOffset == 0) ||
+ ((EfiRomHeader->PcirOffset & 3) != 0) ||
+ (RomBarOffset - (UINTN)RomBar + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize))
+ {
+ break;
+ }
+
+ Pcir = (PCI_DATA_STRUCTURE *)(UINTN)(RomBarOffset + EfiRomHeader->PcirOffset);
+ //
+ // If a valid signature is not present in the PCI Data Structure, no further images can be located.
+ //
+ if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+ break;
+ }
+
+ ImageSize = Pcir->ImageLength * 512;
+ if (RomBarOffset - (UINTN)RomBar + ImageSize > RomSize) {
+ break;
+ }
+
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&
+ ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)))
+ {
+ ImageOffset = EfiRomHeader->EfiImageHeaderOffset;
+ InitializationSize = EfiRomHeader->InitializationSize * 512;
+
+ if ((InitializationSize <= ImageSize) && (ImageOffset < InitializationSize)) {
+ ImageBuffer = (VOID *)(UINTN)(RomBarOffset + ImageOffset);
+ ImageLength = InitializationSize - ImageOffset;
+ DecompressedImageBuffer = NULL;
+
+ //
+ // decompress here if needed
+ //
+ SkipImage = FALSE;
+ if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+ SkipImage = TRUE;
+ }
+
+ if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **)&Decompress);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ SkipImage = TRUE;
+ } else {
+ SkipImage = TRUE;
+ Status = Decompress->GetInfo (
+ Decompress,
+ ImageBuffer,
+ ImageLength,
+ &DestinationSize,
+ &ScratchSize
+ );
+ if (!EFI_ERROR (Status)) {
+ DecompressedImageBuffer = AllocateZeroPool (DestinationSize);
+ if (ImageBuffer != NULL) {
+ Scratch = AllocateZeroPool (ScratchSize);
+ if (Scratch != NULL) {
+ Status = Decompress->Decompress (
+ Decompress,
+ ImageBuffer,
+ ImageLength,
+ DecompressedImageBuffer,
+ DestinationSize,
+ Scratch,
+ ScratchSize
+ );
+ if (!EFI_ERROR (Status)) {
+ ImageBuffer = DecompressedImageBuffer;
+ ImageLength = DestinationSize;
+ SkipImage = FALSE;
+ }
+
+ FreePool (Scratch);
+ }
+ }
+ }
+ }
+ }
+
+ if (!SkipImage) {
+ //
+ // load image and start image
+ //
+ UnicodeSPrint (RomFileName, sizeof (RomFileName), L"%s[%d]", FileName, ImageIndex);
+ FilePath = FileDevicePath (NULL, RomFileName);
+
+ Status = gBS->LoadImage (
+ TRUE,
+ gImageHandle,
+ FilePath,
+ ImageBuffer,
+ ImageLength,
+ &ImageHandle
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
+ // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
+ // If the caller doesn't have the option to defer the execution of an image, we should
+ // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
+ //
+ if (Status == EFI_SECURITY_VIOLATION) {
+ gBS->UnloadImage (ImageHandle);
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex);
+ // PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);
+ } else {
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_START_FAIL), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex);
+ // PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);
+ } else {
+ ReturnStatus = Status;
+ }
+ }
+ }
+
+ if (DecompressedImageBuffer != NULL) {
+ FreePool (DecompressedImageBuffer);
+ }
+ }
+ }
+
+ RomBarOffset = RomBarOffset + ImageSize;
+ ImageIndex++;
+ } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN)RomBar) < RomSize));
+
+ return ReturnStatus;
+}
+
+/**
+ Connects all available drives and controllers.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_ABORTED The abort mechanism was received.
+**/
+EFI_STATUS
+LoadPciRomConnectAllDriversToAllControllers (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+
+ Status = gBS->LocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ if (ShellGetExecutionBreakFlag ()) {
+ Status = EFI_ABORTED;
+ break;
+ }
+
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ return Status;
+}