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.
29 LoadPciRomConnectAllDriversToAllControllers (
36 @param[in] RomBar The Rom Base address.
37 @param[in] RomSize The Rom size.
38 @param[in] FileName The file name.
40 @retval EFI_SUCCESS The command completed successfully.
41 @retval EFI_INVALID_PARAMETER Command usage error.
42 @retval EFI_UNSUPPORTED Protocols unsupported.
43 @retval EFI_OUT_OF_RESOURCES Out of memory.
44 @retval Other value Unknown error.
48 LoadEfiDriversFromRomImage (
51 CONST CHAR16
*FileName
54 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
60 Function for 'loadpcirom' command.
62 @param[in] ImageHandle Handle to the Image (NULL if Internal).
63 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
67 ShellCommandRunLoadPciRom (
68 IN EFI_HANDLE ImageHandle
,
69 IN EFI_SYSTEM_TABLE
*SystemTable
72 EFI_SHELL_FILE_INFO
*FileList
;
78 SHELL_STATUS ShellStatus
;
82 EFI_SHELL_FILE_INFO
*Node
;
84 // Local variable initializations
87 ShellStatus
= SHELL_SUCCESS
;
92 // verify number of arguments
94 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
95 if (EFI_ERROR(Status
)) {
96 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
97 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"loadpcirom", ProblemParam
);
98 FreePool(ProblemParam
);
99 ShellStatus
= SHELL_INVALID_PARAMETER
;
104 if (ShellCommandLineGetCount(Package
) < 2) {
105 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"loadpcirom");
106 ShellStatus
= SHELL_INVALID_PARAMETER
;
108 if (ShellCommandLineGetFlag(Package
, L
"-nc")) {
115 // get a list with each file specified by parameters
116 // if parameter is a directory then add all the files below it to the list
118 for ( ParamCount
= 1, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
120 ; ParamCount
++, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
122 Status
= ShellOpenFileMetaArg((CHAR16
*)Param
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
, &FileList
);
123 if (EFI_ERROR(Status
)) {
124 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Param
);
125 ShellStatus
= SHELL_ACCESS_DENIED
;
129 if (ShellStatus
== SHELL_SUCCESS
&& FileList
!= NULL
) {
131 // loop through the list and make sure we are not aborting...
133 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
134 ; !IsNull(&FileList
->Link
, &Node
->Link
) && !ShellGetExecutionBreakFlag()
135 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
137 if (EFI_ERROR(Node
->Status
)){
138 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
139 ShellStatus
= SHELL_INVALID_PARAMETER
;
142 if (FileHandleIsDirectory(Node
->Handle
) == EFI_SUCCESS
) {
143 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_DIR
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
144 ShellStatus
= SHELL_INVALID_PARAMETER
;
147 SourceSize
= (UINTN
) Node
->Info
->FileSize
;
148 File1Buffer
= AllocateZeroPool (SourceSize
);
149 if (File1Buffer
== NULL
) {
150 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellDebug1HiiHandle
, L
"loadpcirom");
151 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
154 Status
= gEfiShellProtocol
->ReadFile(Node
->Handle
, &SourceSize
, File1Buffer
);
155 if (EFI_ERROR(Status
)) {
156 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_READ_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
157 ShellStatus
= SHELL_INVALID_PARAMETER
;
159 Status
= LoadEfiDriversFromRomImage (
165 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
;
173 if (FileList
!= NULL
&& !IsListEmpty(&FileList
->Link
)) {
174 Status
= ShellCloseFileMetaArg(&FileList
);
179 Status
= LoadPciRomConnectAllDriversToAllControllers ();
184 return (ShellStatus
);
190 @param[in] RomBar The Rom Base address.
191 @param[in] RomSize The Rom size.
192 @param[in] FileName The file name.
194 @retval EFI_SUCCESS The command completed successfully.
195 @retval EFI_INVALID_PARAMETER Command usage error.
196 @retval EFI_UNSUPPORTED Protocols unsupported.
197 @retval EFI_OUT_OF_RESOURCES Out of memory.
198 @retval Other value Unknown error.
202 LoadEfiDriversFromRomImage (
205 CONST CHAR16
*FileName
209 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
210 PCI_DATA_STRUCTURE
*Pcir
;
215 EFI_HANDLE ImageHandle
;
217 EFI_STATUS ReturnStatus
;
218 CHAR16 RomFileName
[280];
219 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
221 UINT32 DestinationSize
;
225 VOID
*DecompressedImageBuffer
;
227 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
228 UINT32 InitializationSize
;
231 ReturnStatus
= EFI_NOT_FOUND
;
232 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
) {
254 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomBarOffset
+ EfiRomHeader
->PcirOffset
);
256 // If a valid signature is not present in the PCI Data Structure, no further images can be located.
258 if (Pcir
->Signature
!= PCI_DATA_STRUCTURE_SIGNATURE
) {
261 ImageSize
= Pcir
->ImageLength
* 512;
262 if (RomBarOffset
- (UINTN
)RomBar
+ ImageSize
> RomSize
) {
266 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
267 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) &&
268 ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
269 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
))) {
271 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
272 InitializationSize
= EfiRomHeader
->InitializationSize
* 512;
274 if (InitializationSize
<= ImageSize
&& ImageOffset
< InitializationSize
) {
276 ImageBuffer
= (VOID
*) (UINTN
) (RomBarOffset
+ ImageOffset
);
277 ImageLength
= InitializationSize
- ImageOffset
;
278 DecompressedImageBuffer
= NULL
;
281 // decompress here if needed
284 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
288 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
289 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**)&Decompress
);
290 ASSERT_EFI_ERROR(Status
);
291 if (EFI_ERROR (Status
)) {
295 Status
= Decompress
->GetInfo (
302 if (!EFI_ERROR (Status
)) {
303 DecompressedImageBuffer
= AllocateZeroPool (DestinationSize
);
304 if (ImageBuffer
!= NULL
) {
305 Scratch
= AllocateZeroPool (ScratchSize
);
306 if (Scratch
!= NULL
) {
307 Status
= Decompress
->Decompress (
311 DecompressedImageBuffer
,
316 if (!EFI_ERROR (Status
)) {
317 ImageBuffer
= DecompressedImageBuffer
;
318 ImageLength
= DestinationSize
;
331 // load image and start image
333 UnicodeSPrint (RomFileName
, sizeof (RomFileName
), L
"%s[%d]", FileName
, ImageIndex
);
334 FilePath
= FileDevicePath (NULL
, RomFileName
);
336 Status
= gBS
->LoadImage (
344 if (EFI_ERROR (Status
)) {
345 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
346 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);
348 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
349 if (EFI_ERROR (Status
)) {
350 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_START_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
351 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);
353 ReturnStatus
= Status
;
358 if (DecompressedImageBuffer
!= NULL
) {
359 FreePool (DecompressedImageBuffer
);
365 RomBarOffset
= RomBarOffset
+ ImageSize
;
367 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomBarOffset
- (UINTN
) RomBar
) < RomSize
));
373 Connects all available drives and controllers.
375 @retval EFI_SUCCESS The operation was successful.
376 @retval EFI_ABORTED The abort mechanism was received.
379 LoadPciRomConnectAllDriversToAllControllers (
385 EFI_HANDLE
*HandleBuffer
;
388 Status
= gBS
->LocateHandleBuffer (
395 if (EFI_ERROR (Status
)) {
399 for (Index
= 0; Index
< HandleCount
; Index
++) {
400 if (ShellGetExecutionBreakFlag ()) {
401 Status
= EFI_ABORTED
;
404 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
407 if (HandleBuffer
!= NULL
) {
408 FreePool (HandleBuffer
);