2 Main file for LoadPciRom shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellDebug1CommandsLib.h"
17 #include <IndustryStandard/Pci22.h>
18 #include <IndustryStandard/Pci23.h>
19 #include <IndustryStandard/PeImage.h>
20 #include <Protocol/Decompress.h>
23 Connects all available drives and controllers.
25 @retval EFI_SUCCESS The operation was successful.
26 @retval EFI_ABORTED The abort mechanism was received.
30 LoadPciRomConnectAllDriversToAllControllers (
37 @param[in] RomBar The Rom Base address.
38 @param[in] RomSize The Rom size.
39 @param[in] FileName The file name.
41 @retval EFI_SUCCESS The command completed successfully.
42 @retval EFI_INVALID_PARAMETER Command usage error.
43 @retval EFI_UNSUPPORTED Protocols unsupported.
44 @retval EFI_OUT_OF_RESOURCES Out of memory.
45 @retval Other value Unknown error.
49 LoadEfiDriversFromRomImage (
52 CONST CHAR16
*FileName
55 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
61 Function for 'loadpcirom' command.
63 @param[in] ImageHandle Handle to the Image (NULL if Internal).
64 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
68 ShellCommandRunLoadPciRom (
69 IN EFI_HANDLE ImageHandle
,
70 IN EFI_SYSTEM_TABLE
*SystemTable
73 EFI_SHELL_FILE_INFO
*FileList
;
79 SHELL_STATUS ShellStatus
;
83 EFI_SHELL_FILE_INFO
*Node
;
85 // Local variable initializations
88 ShellStatus
= SHELL_SUCCESS
;
93 // verify number of arguments
95 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
96 if (EFI_ERROR(Status
)) {
97 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
98 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"loadpcirom", ProblemParam
);
99 FreePool(ProblemParam
);
100 ShellStatus
= SHELL_INVALID_PARAMETER
;
105 if (ShellCommandLineGetCount(Package
) < 2) {
106 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"loadpcirom");
107 ShellStatus
= SHELL_INVALID_PARAMETER
;
109 if (ShellCommandLineGetFlag(Package
, L
"-nc")) {
116 // get a list with each file specified by parameters
117 // if parameter is a directory then add all the files below it to the list
119 for ( ParamCount
= 1, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
121 ; ParamCount
++, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
123 Status
= ShellOpenFileMetaArg((CHAR16
*)Param
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
, &FileList
);
124 if (EFI_ERROR(Status
)) {
125 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Param
);
126 ShellStatus
= SHELL_ACCESS_DENIED
;
130 if (ShellStatus
== SHELL_SUCCESS
&& FileList
!= NULL
) {
132 // loop through the list and make sure we are not aborting...
134 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
135 ; !IsNull(&FileList
->Link
, &Node
->Link
) && !ShellGetExecutionBreakFlag()
136 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
138 if (EFI_ERROR(Node
->Status
)){
139 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
140 ShellStatus
= SHELL_INVALID_PARAMETER
;
143 if (FileHandleIsDirectory(Node
->Handle
) == EFI_SUCCESS
) {
144 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_DIR
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
145 ShellStatus
= SHELL_INVALID_PARAMETER
;
148 SourceSize
= (UINTN
) Node
->Info
->FileSize
;
149 File1Buffer
= AllocateZeroPool (SourceSize
);
150 if (File1Buffer
== NULL
) {
151 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellDebug1HiiHandle
, L
"loadpcirom");
152 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
155 Status
= gEfiShellProtocol
->ReadFile(Node
->Handle
, &SourceSize
, File1Buffer
);
156 if (EFI_ERROR(Status
)) {
157 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_READ_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
158 ShellStatus
= SHELL_INVALID_PARAMETER
;
160 Status
= LoadEfiDriversFromRomImage (
166 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOAD_PCI_ROM_RES
), gShellDebug1HiiHandle
, Node
->FullName
, Status
);
168 FreePool(File1Buffer
);
170 } else if (ShellStatus
== SHELL_SUCCESS
) {
171 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_SPEC
), gShellDebug1HiiHandle
, "loadpcirom");
172 ShellStatus
= SHELL_NOT_FOUND
;
174 if (FileList
!= NULL
&& !IsListEmpty(&FileList
->Link
)) {
175 Status
= ShellCloseFileMetaArg(&FileList
);
180 Status
= LoadPciRomConnectAllDriversToAllControllers ();
185 return (ShellStatus
);
191 @param[in] RomBar The Rom Base address.
192 @param[in] RomSize The Rom size.
193 @param[in] FileName The file name.
195 @retval EFI_SUCCESS The command completed successfully.
196 @retval EFI_INVALID_PARAMETER Command usage error.
197 @retval EFI_UNSUPPORTED Protocols unsupported.
198 @retval EFI_OUT_OF_RESOURCES Out of memory.
199 @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
;
237 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomBarOffset
;
239 if (EfiRomHeader
->Signature
!= PCI_EXPANSION_ROM_HEADER_SIGNATURE
) {
240 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_CORRUPT
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
241 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);
246 // If the pointer to the PCI Data Structure is invalid, no further images can be located.
247 // The PCI Data Structure must be DWORD aligned.
249 if (EfiRomHeader
->PcirOffset
== 0 ||
250 (EfiRomHeader
->PcirOffset
& 3) != 0 ||
251 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
) {
262 ImageSize
= Pcir
->ImageLength
* 512;
263 if (RomBarOffset
- (UINTN
)RomBar
+ ImageSize
> RomSize
) {
267 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
268 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) &&
269 ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
270 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
))) {
272 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
273 InitializationSize
= EfiRomHeader
->InitializationSize
* 512;
275 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
)) {
346 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
347 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);
349 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
350 if (EFI_ERROR (Status
)) {
351 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_START_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
352 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);
354 ReturnStatus
= Status
;
359 if (DecompressedImageBuffer
!= NULL
) {
360 FreePool (DecompressedImageBuffer
);
366 RomBarOffset
= RomBarOffset
+ ImageSize
;
368 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomBarOffset
- (UINTN
) RomBar
) < RomSize
));
374 Connects all available drives and controllers.
376 @retval EFI_SUCCESS The operation was successful.
377 @retval EFI_ABORTED The abort mechanism was received.
381 LoadPciRomConnectAllDriversToAllControllers (
387 UINTN AllHandleCount
;
388 EFI_HANDLE
*AllHandleBuffer
;
391 EFI_HANDLE
*HandleBuffer
;
397 Status
= gBS
->LocateHandleBuffer(
404 if (EFI_ERROR (Status
)) {
408 for (Index
= 0; Index
< AllHandleCount
; Index
++) {
409 if (ShellGetExecutionBreakFlag ()) {
410 Status
= EFI_ABORTED
;
414 // Scan the handle database
416 Status
= ParseHandleDatabaseByRelationshipWithType(
418 AllHandleBuffer
[Index
],
424 Status = LibScanHandleDatabase (
427 AllHandleBuffer[Index],
434 if (EFI_ERROR (Status
)) {
439 if ((HandleType
[Index
] & HR_DRIVER_BINDING_HANDLE
) != 0) {
443 if ((HandleType
[Index
] & HR_IMAGE_HANDLE
) != 0) {
449 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
450 if ((HandleType
[HandleIndex
] & HR_PARENT_HANDLE
) != 0) {
456 if ((HandleType
[Index
] & HR_DEVICE_HANDLE
) != 0) {
457 Status
= gBS
->ConnectController (
458 AllHandleBuffer
[Index
],
467 FreePool (HandleBuffer
);
468 FreePool (HandleType
);
472 FreePool (AllHandleBuffer
);