2 Main file for LoadPciRom shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UefiShellDebug1CommandsLib.h"
11 #include <IndustryStandard/Pci22.h>
12 #include <IndustryStandard/Pci23.h>
13 #include <IndustryStandard/PeImage.h>
14 #include <Protocol/Decompress.h>
17 Connects all available drives and controllers.
19 @retval EFI_SUCCESS The operation was successful.
20 @retval EFI_ABORTED The abort mechanism was received.
23 LoadPciRomConnectAllDriversToAllControllers (
30 @param[in] RomBar The Rom Base address.
31 @param[in] RomSize The Rom size.
32 @param[in] FileName The file name.
34 @retval EFI_SUCCESS The command completed successfully.
35 @retval EFI_INVALID_PARAMETER Command usage error.
36 @retval EFI_UNSUPPORTED Protocols unsupported.
37 @retval EFI_OUT_OF_RESOURCES Out of memory.
38 @retval Other value Unknown error.
41 LoadEfiDriversFromRomImage (
44 CONST CHAR16
*FileName
47 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
53 Function for 'loadpcirom' command.
55 @param[in] ImageHandle Handle to the Image (NULL if Internal).
56 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
60 ShellCommandRunLoadPciRom (
61 IN EFI_HANDLE ImageHandle
,
62 IN EFI_SYSTEM_TABLE
*SystemTable
65 EFI_SHELL_FILE_INFO
*FileList
;
71 SHELL_STATUS ShellStatus
;
75 EFI_SHELL_FILE_INFO
*Node
;
78 // Local variable initializations
81 ShellStatus
= SHELL_SUCCESS
;
85 // verify number of arguments
87 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
88 if (EFI_ERROR (Status
)) {
89 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
90 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"loadpcirom", ProblemParam
);
91 FreePool (ProblemParam
);
92 ShellStatus
= SHELL_INVALID_PARAMETER
;
97 if (ShellCommandLineGetCount (Package
) < 2) {
98 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"loadpcirom");
99 ShellStatus
= SHELL_INVALID_PARAMETER
;
101 if (ShellCommandLineGetFlag (Package
, L
"-nc")) {
108 // get a list with each file specified by parameters
109 // if parameter is a directory then add all the files below it to the list
111 for ( ParamCount
= 1, Param
= ShellCommandLineGetRawValue (Package
, ParamCount
)
113 ; ParamCount
++, Param
= ShellCommandLineGetRawValue (Package
, ParamCount
)
116 Status
= ShellOpenFileMetaArg ((CHAR16
*)Param
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
, &FileList
);
117 if (EFI_ERROR (Status
)) {
118 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Param
);
119 ShellStatus
= SHELL_ACCESS_DENIED
;
124 if ((ShellStatus
== SHELL_SUCCESS
) && (FileList
!= NULL
)) {
126 // loop through the list and make sure we are not aborting...
128 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&FileList
->Link
)
129 ; !IsNull (&FileList
->Link
, &Node
->Link
) && !ShellGetExecutionBreakFlag ()
130 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode (&FileList
->Link
, &Node
->Link
)
133 if (EFI_ERROR (Node
->Status
)) {
134 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
135 ShellStatus
= SHELL_INVALID_PARAMETER
;
139 if (FileHandleIsDirectory (Node
->Handle
) == EFI_SUCCESS
) {
140 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_DIR
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
141 ShellStatus
= SHELL_INVALID_PARAMETER
;
145 SourceSize
= (UINTN
)Node
->Info
->FileSize
;
146 File1Buffer
= AllocateZeroPool (SourceSize
);
147 if (File1Buffer
== NULL
) {
148 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellDebug1HiiHandle
, L
"loadpcirom");
149 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
153 Status
= gEfiShellProtocol
->ReadFile (Node
->Handle
, &SourceSize
, File1Buffer
);
154 if (EFI_ERROR (Status
)) {
155 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_FILE_READ_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
156 ShellStatus
= SHELL_INVALID_PARAMETER
;
158 Status
= LoadEfiDriversFromRomImage (
164 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOAD_PCI_ROM_RES
), gShellDebug1HiiHandle
, Node
->FullName
, Status
);
167 FreePool (File1Buffer
);
169 } else if (ShellStatus
== SHELL_SUCCESS
) {
170 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_SPEC
), gShellDebug1HiiHandle
, "loadpcirom");
171 ShellStatus
= SHELL_NOT_FOUND
;
174 if ((FileList
!= NULL
) && !IsListEmpty (&FileList
->Link
)) {
175 Status
= ShellCloseFileMetaArg (&FileList
);
181 Status
= LoadPciRomConnectAllDriversToAllControllers ();
186 return (ShellStatus
);
192 @param[in] RomBar The Rom Base address.
193 @param[in] RomSize The Rom size.
194 @param[in] FileName The file name.
196 @retval EFI_SUCCESS The command completed successfully.
197 @retval EFI_INVALID_PARAMETER Command usage error.
198 @retval EFI_UNSUPPORTED Protocols unsupported.
199 @retval EFI_OUT_OF_RESOURCES Out of memory.
200 @retval Other value Unknown error.
203 LoadEfiDriversFromRomImage (
206 CONST CHAR16
*FileName
210 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
211 PCI_DATA_STRUCTURE
*Pcir
;
216 EFI_HANDLE ImageHandle
;
218 EFI_STATUS ReturnStatus
;
219 CHAR16 RomFileName
[280];
220 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
222 UINT32 DestinationSize
;
226 VOID
*DecompressedImageBuffer
;
228 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
229 UINT32 InitializationSize
;
232 ReturnStatus
= EFI_NOT_FOUND
;
233 RomBarOffset
= (UINTN
)RomBar
;
236 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*)(UINTN
)RomBarOffset
;
238 if (EfiRomHeader
->Signature
!= PCI_EXPANSION_ROM_HEADER_SIGNATURE
) {
239 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_CORRUPT
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
240 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);
245 // If the pointer to the PCI Data Structure is invalid, no further images can be located.
246 // The PCI Data Structure must be DWORD aligned.
248 if ((EfiRomHeader
->PcirOffset
== 0) ||
249 ((EfiRomHeader
->PcirOffset
& 3) != 0) ||
250 (RomBarOffset
- (UINTN
)RomBar
+ EfiRomHeader
->PcirOffset
+ sizeof (PCI_DATA_STRUCTURE
) > RomSize
))
255 Pcir
= (PCI_DATA_STRUCTURE
*)(UINTN
)(RomBarOffset
+ EfiRomHeader
->PcirOffset
);
257 // If a valid signature is not present in the PCI Data Structure, no further images can be located.
259 if (Pcir
->Signature
!= PCI_DATA_STRUCTURE_SIGNATURE
) {
263 ImageSize
= Pcir
->ImageLength
* 512;
264 if (RomBarOffset
- (UINTN
)RomBar
+ ImageSize
> RomSize
) {
268 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
269 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) &&
270 ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
271 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
)))
273 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
274 InitializationSize
= EfiRomHeader
->InitializationSize
* 512;
276 if ((InitializationSize
<= ImageSize
) && (ImageOffset
< InitializationSize
)) {
277 ImageBuffer
= (VOID
*)(UINTN
)(RomBarOffset
+ ImageOffset
);
278 ImageLength
= InitializationSize
- ImageOffset
;
279 DecompressedImageBuffer
= NULL
;
282 // decompress here if needed
285 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
289 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
290 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**)&Decompress
);
291 ASSERT_EFI_ERROR (Status
);
292 if (EFI_ERROR (Status
)) {
296 Status
= Decompress
->GetInfo (
303 if (!EFI_ERROR (Status
)) {
304 DecompressedImageBuffer
= AllocateZeroPool (DestinationSize
);
305 if (ImageBuffer
!= NULL
) {
306 Scratch
= AllocateZeroPool (ScratchSize
);
307 if (Scratch
!= NULL
) {
308 Status
= Decompress
->Decompress (
312 DecompressedImageBuffer
,
317 if (!EFI_ERROR (Status
)) {
318 ImageBuffer
= DecompressedImageBuffer
;
319 ImageLength
= DestinationSize
;
332 // load image and start image
334 UnicodeSPrint (RomFileName
, sizeof (RomFileName
), L
"%s[%d]", FileName
, ImageIndex
);
335 FilePath
= FileDevicePath (NULL
, RomFileName
);
337 Status
= gBS
->LoadImage (
345 if (EFI_ERROR (Status
)) {
347 // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
348 // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
349 // If the caller doesn't have the option to defer the execution of an image, we should
350 // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
352 if (Status
== EFI_SECURITY_VIOLATION
) {
353 gBS
->UnloadImage (ImageHandle
);
356 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
357 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);
359 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
360 if (EFI_ERROR (Status
)) {
361 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_START_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
362 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);
364 ReturnStatus
= Status
;
369 if (DecompressedImageBuffer
!= NULL
) {
370 FreePool (DecompressedImageBuffer
);
375 RomBarOffset
= RomBarOffset
+ ImageSize
;
377 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomBarOffset
- (UINTN
)RomBar
) < RomSize
));
383 Connects all available drives and controllers.
385 @retval EFI_SUCCESS The operation was successful.
386 @retval EFI_ABORTED The abort mechanism was received.
389 LoadPciRomConnectAllDriversToAllControllers (
395 EFI_HANDLE
*HandleBuffer
;
398 Status
= gBS
->LocateHandleBuffer (
405 if (EFI_ERROR (Status
)) {
409 for (Index
= 0; Index
< HandleCount
; Index
++) {
410 if (ShellGetExecutionBreakFlag ()) {
411 Status
= EFI_ABORTED
;
415 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
418 if (HandleBuffer
!= NULL
) {
419 FreePool (HandleBuffer
);