2 Main file for LoadPciRom shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 2018, 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.
47 LoadEfiDriversFromRomImage (
50 CONST CHAR16
*FileName
53 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
59 Function for 'loadpcirom' command.
61 @param[in] ImageHandle Handle to the Image (NULL if Internal).
62 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
66 ShellCommandRunLoadPciRom (
67 IN EFI_HANDLE ImageHandle
,
68 IN EFI_SYSTEM_TABLE
*SystemTable
71 EFI_SHELL_FILE_INFO
*FileList
;
77 SHELL_STATUS ShellStatus
;
81 EFI_SHELL_FILE_INFO
*Node
;
83 // Local variable initializations
86 ShellStatus
= SHELL_SUCCESS
;
91 // verify number of arguments
93 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
94 if (EFI_ERROR(Status
)) {
95 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
96 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"loadpcirom", ProblemParam
);
97 FreePool(ProblemParam
);
98 ShellStatus
= SHELL_INVALID_PARAMETER
;
103 if (ShellCommandLineGetCount(Package
) < 2) {
104 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"loadpcirom");
105 ShellStatus
= SHELL_INVALID_PARAMETER
;
107 if (ShellCommandLineGetFlag(Package
, L
"-nc")) {
114 // get a list with each file specified by parameters
115 // if parameter is a directory then add all the files below it to the list
117 for ( ParamCount
= 1, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
119 ; ParamCount
++, Param
= ShellCommandLineGetRawValue(Package
, ParamCount
)
121 Status
= ShellOpenFileMetaArg((CHAR16
*)Param
, EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
, &FileList
);
122 if (EFI_ERROR(Status
)) {
123 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Param
);
124 ShellStatus
= SHELL_ACCESS_DENIED
;
128 if (ShellStatus
== SHELL_SUCCESS
&& FileList
!= NULL
) {
130 // loop through the list and make sure we are not aborting...
132 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
133 ; !IsNull(&FileList
->Link
, &Node
->Link
) && !ShellGetExecutionBreakFlag()
134 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
136 if (EFI_ERROR(Node
->Status
)){
137 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
138 ShellStatus
= SHELL_INVALID_PARAMETER
;
141 if (FileHandleIsDirectory(Node
->Handle
) == EFI_SUCCESS
) {
142 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_DIR
), gShellDebug1HiiHandle
, L
"loadpcirom", Node
->FullName
);
143 ShellStatus
= SHELL_INVALID_PARAMETER
;
146 SourceSize
= (UINTN
) Node
->Info
->FileSize
;
147 File1Buffer
= AllocateZeroPool (SourceSize
);
148 if (File1Buffer
== NULL
) {
149 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellDebug1HiiHandle
, L
"loadpcirom");
150 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
);
166 FreePool(File1Buffer
);
168 } else if (ShellStatus
== SHELL_SUCCESS
) {
169 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_NOT_SPEC
), gShellDebug1HiiHandle
, "loadpcirom");
170 ShellStatus
= SHELL_NOT_FOUND
;
172 if (FileList
!= NULL
&& !IsListEmpty(&FileList
->Link
)) {
173 Status
= ShellCloseFileMetaArg(&FileList
);
178 Status
= LoadPciRomConnectAllDriversToAllControllers ();
183 return (ShellStatus
);
189 @param[in] RomBar The Rom Base address.
190 @param[in] RomSize The Rom size.
191 @param[in] FileName The file name.
193 @retval EFI_SUCCESS The command completed successfully.
194 @retval EFI_INVALID_PARAMETER Command usage error.
195 @retval EFI_UNSUPPORTED Protocols unsupported.
196 @retval EFI_OUT_OF_RESOURCES Out of memory.
197 @retval Other value Unknown error.
200 LoadEfiDriversFromRomImage (
203 CONST CHAR16
*FileName
207 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
208 PCI_DATA_STRUCTURE
*Pcir
;
213 EFI_HANDLE ImageHandle
;
215 EFI_STATUS ReturnStatus
;
216 CHAR16 RomFileName
[280];
217 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
219 UINT32 DestinationSize
;
223 VOID
*DecompressedImageBuffer
;
225 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
226 UINT32 InitializationSize
;
229 ReturnStatus
= EFI_NOT_FOUND
;
230 RomBarOffset
= (UINTN
) RomBar
;
234 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomBarOffset
;
236 if (EfiRomHeader
->Signature
!= PCI_EXPANSION_ROM_HEADER_SIGNATURE
) {
237 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_CORRUPT
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
238 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);
243 // If the pointer to the PCI Data Structure is invalid, no further images can be located.
244 // The PCI Data Structure must be DWORD aligned.
246 if (EfiRomHeader
->PcirOffset
== 0 ||
247 (EfiRomHeader
->PcirOffset
& 3) != 0 ||
248 RomBarOffset
- (UINTN
)RomBar
+ EfiRomHeader
->PcirOffset
+ sizeof (PCI_DATA_STRUCTURE
) > RomSize
) {
252 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomBarOffset
+ EfiRomHeader
->PcirOffset
);
254 // If a valid signature is not present in the PCI Data Structure, no further images can be located.
256 if (Pcir
->Signature
!= PCI_DATA_STRUCTURE_SIGNATURE
) {
259 ImageSize
= Pcir
->ImageLength
* 512;
260 if (RomBarOffset
- (UINTN
)RomBar
+ ImageSize
> RomSize
) {
264 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
265 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) &&
266 ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
267 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
))) {
269 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
270 InitializationSize
= EfiRomHeader
->InitializationSize
* 512;
272 if (InitializationSize
<= ImageSize
&& ImageOffset
< InitializationSize
) {
274 ImageBuffer
= (VOID
*) (UINTN
) (RomBarOffset
+ ImageOffset
);
275 ImageLength
= InitializationSize
- ImageOffset
;
276 DecompressedImageBuffer
= NULL
;
279 // decompress here if needed
282 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
286 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
287 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**)&Decompress
);
288 ASSERT_EFI_ERROR(Status
);
289 if (EFI_ERROR (Status
)) {
293 Status
= Decompress
->GetInfo (
300 if (!EFI_ERROR (Status
)) {
301 DecompressedImageBuffer
= AllocateZeroPool (DestinationSize
);
302 if (ImageBuffer
!= NULL
) {
303 Scratch
= AllocateZeroPool (ScratchSize
);
304 if (Scratch
!= NULL
) {
305 Status
= Decompress
->Decompress (
309 DecompressedImageBuffer
,
314 if (!EFI_ERROR (Status
)) {
315 ImageBuffer
= DecompressedImageBuffer
;
316 ImageLength
= DestinationSize
;
329 // load image and start image
331 UnicodeSPrint (RomFileName
, sizeof (RomFileName
), L
"%s[%d]", FileName
, ImageIndex
);
332 FilePath
= FileDevicePath (NULL
, RomFileName
);
334 Status
= gBS
->LoadImage (
342 if (EFI_ERROR (Status
)) {
343 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
344 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);
346 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
347 if (EFI_ERROR (Status
)) {
348 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_LOADPCIROM_START_FAIL
), gShellDebug1HiiHandle
, L
"loadpcirom", FileName
, ImageIndex
);
349 // PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);
351 ReturnStatus
= Status
;
356 if (DecompressedImageBuffer
!= NULL
) {
357 FreePool (DecompressedImageBuffer
);
363 RomBarOffset
= RomBarOffset
+ ImageSize
;
365 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomBarOffset
- (UINTN
) RomBar
) < RomSize
));
371 Connects all available drives and controllers.
373 @retval EFI_SUCCESS The operation was successful.
374 @retval EFI_ABORTED The abort mechanism was received.
377 LoadPciRomConnectAllDriversToAllControllers (
383 EFI_HANDLE
*HandleBuffer
;
386 Status
= gBS
->LocateHandleBuffer (
393 if (EFI_ERROR (Status
)) {
397 for (Index
= 0; Index
< HandleCount
; Index
++) {
398 if (ShellGetExecutionBreakFlag ()) {
399 Status
= EFI_ABORTED
;
402 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
405 if (HandleBuffer
!= NULL
) {
406 FreePool (HandleBuffer
);