2 Main file for LoadPciRom shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 2012, 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 ASSERT(File1Buffer
!= NULL
);
151 Status
= gEfiShellProtocol
->ReadFile(Node
->Handle
, &SourceSize
, File1Buffer
);
152 if (EFI_ERROR(Status
)) {
153 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_READ_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
154 ShellStatus
= SHELL_INVALID_PARAMETER
;
156 Status
= LoadEfiDriversFromRomImage (
162 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOAD_PCI_ROM_RES
), gShellDebug1HiiHandle
, Node
->FullName
, Status
);
164 FreePool(File1Buffer
);
166 } else if (ShellStatus
== SHELL_SUCCESS
) {
167 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_SPEC
), gShellDebug1HiiHandle
, "loadpcirom");
168 ShellStatus
= SHELL_NOT_FOUND
;
170 if (FileList
!= NULL
&& !IsListEmpty(&FileList
->Link
)) {
171 Status
= ShellCloseFileMetaArg(&FileList
);
176 Status
= LoadPciRomConnectAllDriversToAllControllers ();
181 return (ShellStatus
);
187 @param[in] RomBar The Rom Base address.
188 @param[in] RomSize The Rom size.
189 @param[in] FileName The file name.
191 @retval EFI_SUCCESS The command completed successfully.
192 @retval EFI_INVALID_PARAMETER Command usage error.
193 @retval EFI_UNSUPPORTED Protocols unsupported.
194 @retval EFI_OUT_OF_RESOURCES Out of memory.
195 @retval Other value Unknown error.
199 LoadEfiDriversFromRomImage (
202 CONST CHAR16
*FileName
206 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
207 PCI_DATA_STRUCTURE
*Pcir
;
212 EFI_HANDLE ImageHandle
;
214 EFI_STATUS ReturnStatus
;
215 CHAR16 RomFileName
[280];
216 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
218 UINT32 DestinationSize
;
222 VOID
*DecompressedImageBuffer
;
224 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
225 UINT32 InitializationSize
;
228 ReturnStatus
= EFI_NOT_FOUND
;
229 RomBarOffset
= (UINTN
) RomBar
;
233 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomBarOffset
;
235 if (EfiRomHeader
->Signature
!= PCI_EXPANSION_ROM_HEADER_SIGNATURE
) {
236 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_CORRUPT
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
237 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);
242 // If the pointer to the PCI Data Structure is invalid, no further images can be located.
243 // The PCI Data Structure must be DWORD aligned.
245 if (EfiRomHeader
->PcirOffset
== 0 ||
246 (EfiRomHeader
->PcirOffset
& 3) != 0 ||
247 RomBarOffset
- (UINTN
)RomBar
+ EfiRomHeader
->PcirOffset
+ sizeof (PCI_DATA_STRUCTURE
) > RomSize
) {
251 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomBarOffset
+ EfiRomHeader
->PcirOffset
);
253 // If a valid signature is not present in the PCI Data Structure, no further images can be located.
255 if (Pcir
->Signature
!= PCI_DATA_STRUCTURE_SIGNATURE
) {
258 ImageSize
= Pcir
->ImageLength
* 512;
259 if (RomBarOffset
- (UINTN
)RomBar
+ ImageSize
> RomSize
) {
263 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
264 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) &&
265 ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
266 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
))) {
268 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
269 InitializationSize
= EfiRomHeader
->InitializationSize
* 512;
271 if (InitializationSize
<= ImageSize
&& ImageOffset
< InitializationSize
) {
273 ImageBuffer
= (VOID
*) (UINTN
) (RomBarOffset
+ ImageOffset
);
274 ImageLength
= InitializationSize
- ImageOffset
;
275 DecompressedImageBuffer
= NULL
;
278 // decompress here if needed
281 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
285 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
286 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**)&Decompress
);
287 ASSERT_EFI_ERROR(Status
);
288 if (EFI_ERROR (Status
)) {
292 Status
= Decompress
->GetInfo (
299 if (!EFI_ERROR (Status
)) {
300 DecompressedImageBuffer
= AllocateZeroPool (DestinationSize
);
301 if (ImageBuffer
!= NULL
) {
302 Scratch
= AllocateZeroPool (ScratchSize
);
303 if (Scratch
!= NULL
) {
304 Status
= Decompress
->Decompress (
308 DecompressedImageBuffer
,
313 if (!EFI_ERROR (Status
)) {
314 ImageBuffer
= DecompressedImageBuffer
;
315 ImageLength
= DestinationSize
;
328 // load image and start image
330 UnicodeSPrint (RomFileName
, sizeof (RomFileName
), L
"%s[%d]", FileName
, ImageIndex
);
331 FilePath
= FileDevicePath (NULL
, RomFileName
);
333 Status
= gBS
->LoadImage (
341 if (EFI_ERROR (Status
)) {
342 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
343 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);
345 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
346 if (EFI_ERROR (Status
)) {
347 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_START_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
348 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);
350 ReturnStatus
= Status
;
355 if (DecompressedImageBuffer
!= NULL
) {
356 FreePool (DecompressedImageBuffer
);
362 RomBarOffset
= RomBarOffset
+ ImageSize
;
364 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomBarOffset
- (UINTN
) RomBar
) < RomSize
));
370 Connects all available drives and controllers.
372 @retval EFI_SUCCESS The operation was successful.
373 @retval EFI_ABORTED The abort mechanism was received.
377 LoadPciRomConnectAllDriversToAllControllers (
383 UINTN AllHandleCount
;
384 EFI_HANDLE
*AllHandleBuffer
;
387 EFI_HANDLE
*HandleBuffer
;
393 Status
= gBS
->LocateHandleBuffer(
400 if (EFI_ERROR (Status
)) {
404 for (Index
= 0; Index
< AllHandleCount
; Index
++) {
405 if (ShellGetExecutionBreakFlag ()) {
406 Status
= EFI_ABORTED
;
410 // Scan the handle database
412 Status
= ParseHandleDatabaseByRelationshipWithType(
414 AllHandleBuffer
[Index
],
420 Status = LibScanHandleDatabase (
423 AllHandleBuffer[Index],
430 if (EFI_ERROR (Status
)) {
435 if ((HandleType
[Index
] & HR_DRIVER_BINDING_HANDLE
) != 0) {
439 if ((HandleType
[Index
] & HR_IMAGE_HANDLE
) != 0) {
445 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
446 if ((HandleType
[HandleIndex
] & HR_PARENT_HANDLE
) != 0) {
452 if ((HandleType
[Index
] & HR_DEVICE_HANDLE
) != 0) {
453 Status
= gBS
->ConnectController (
454 AllHandleBuffer
[Index
],
463 FreePool (HandleBuffer
);
464 FreePool (HandleType
);
468 FreePool (AllHandleBuffer
);