]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c
add Edit and Hexedit shared features.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / LoadPciRom.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for LoadPciRom shell Debug1 function.\r
3\r
4 Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellDebug1CommandsLib.h"\r
16#include <IndustryStandard/Pci22.h>\r
17#include <IndustryStandard/Pci23.h>\r
18#include <IndustryStandard/PeImage.h>\r
19#include <Protocol/Decompress.h>\r
20\r
21EFI_STATUS\r
22EFIAPI\r
23LoadPciRomConnectAllDriversToAllControllers (\r
24 VOID\r
25 );\r
26\r
27EFI_STATUS\r
28EFIAPI\r
29InitializeLoadPciRom (\r
30 IN EFI_HANDLE ImageHandle,\r
31 IN EFI_SYSTEM_TABLE *SystemTable\r
32 );\r
33\r
34EFI_STATUS\r
35EFIAPI\r
36LoadEfiDriversFromRomImage (\r
37 VOID *RomBar,\r
38 UINTN RomSize,\r
39 CONST CHAR16 *FileName\r
40 );\r
41\r
42STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
43 {L"-nc", TypeFlag},\r
44 {NULL, TypeMax}\r
45 };\r
46\r
47SHELL_STATUS\r
48EFIAPI\r
49ShellCommandRunLoadPciRom (\r
50 IN EFI_HANDLE ImageHandle,\r
51 IN EFI_SYSTEM_TABLE *SystemTable\r
52 )\r
53{\r
54 EFI_SHELL_FILE_INFO *FileList;\r
55 UINTN SourceSize;\r
56 UINT8 *File1Buffer;\r
57 EFI_STATUS Status;\r
58 LIST_ENTRY *Package;\r
59 CHAR16 *ProblemParam;\r
60 SHELL_STATUS ShellStatus;\r
61 BOOLEAN Connect;\r
62 CONST CHAR16 *Param;\r
63 UINTN ParamCount;\r
64 EFI_SHELL_FILE_INFO *Node;\r
65 //\r
66 // Local variable initializations\r
67 //\r
68 File1Buffer = NULL;\r
69 ShellStatus = SHELL_SUCCESS;\r
70 FileList = NULL;\r
71\r
72\r
73 //\r
74 // verify number of arguments\r
75 //\r
76 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
77 if (EFI_ERROR(Status)) {\r
78 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
79 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
80 FreePool(ProblemParam);\r
81 ShellStatus = SHELL_INVALID_PARAMETER;\r
82 } else {\r
83 ASSERT(FALSE);\r
84 }\r
85 } else {\r
86 if (ShellCommandLineGetCount(Package) < 1) {\r
87 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
88 ShellStatus = SHELL_INVALID_PARAMETER;\r
89 } else {\r
90 if (!ShellCommandLineGetFlag(Package, L"-nc")) {\r
91 Connect = FALSE;\r
92 } else {\r
93 Connect = TRUE;\r
94 }\r
95\r
96 //\r
97 // get a list with each file specified by parameters\r
98 // if parameter is a directory then add all the files below it to the list\r
99 //\r
100 for ( ParamCount = 1, Param = ShellCommandLineGetRawValue(Package, ParamCount)\r
101 ; Param != NULL\r
102 ; ParamCount++, Param = ShellCommandLineGetRawValue(Package, ParamCount)\r
103 ){\r
104 Status = ShellOpenFileMetaArg((CHAR16*)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);\r
105 if (EFI_ERROR(Status)) {\r
106 ShellStatus = SHELL_ACCESS_DENIED;\r
107 break;\r
108 }\r
109 }\r
110 if (FileList == NULL || IsListEmpty(&FileList->Link)) {\r
111 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle);\r
112 } else if (ShellStatus == SHELL_SUCCESS) {\r
113\r
114\r
115 //\r
116 // loop through the list and make sure we are not aborting...\r
117 //\r
118 for ( Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link)\r
119 ; !IsNull(&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag()\r
120 ; Node = (EFI_SHELL_FILE_INFO*)GetNextNode(&FileList->Link, &Node->Link)\r
121 ){\r
122 if (EFI_ERROR(Node->Status)){\r
123 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_OPEN_FAIL), gShellDebug1HiiHandle, Node->FullName);\r
124 ShellStatus = SHELL_INVALID_PARAMETER;\r
125 continue;\r
126 }\r
127 if (FileHandleIsDirectory(Node->Handle) == EFI_SUCCESS) {\r
128 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, Node->FullName);\r
129 ShellStatus = SHELL_INVALID_PARAMETER;\r
130 continue;\r
131 }\r
132 SourceSize = (UINTN) Node->Info->FileSize;\r
133 File1Buffer = AllocatePool (SourceSize);\r
134 ASSERT(File1Buffer != NULL);\r
135 Status = gEfiShellProtocol->ReadFile(Node->Handle, &SourceSize, File1Buffer);\r
136 if (EFI_ERROR(Status)) {\r
137 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_READ_FAIL), gShellDebug1HiiHandle, Node->FullName);\r
138 ShellStatus = SHELL_INVALID_PARAMETER;\r
139 } else {\r
140 Status = LoadEfiDriversFromRomImage (\r
141 File1Buffer,\r
142 SourceSize,\r
143 Node->FullName\r
144 );\r
145\r
146 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_PCI_ROM_RES), gShellDebug1HiiHandle, Node->FullName, Status);\r
147 }\r
148 FreePool(File1Buffer);\r
149 }\r
150 }\r
151 if (FileList != NULL && !IsListEmpty(&FileList->Link)) {\r
152 Status = ShellCloseFileMetaArg(&FileList);\r
153 }\r
154 FileList = NULL;\r
155\r
156 if (Connect) {\r
157 Status = LoadPciRomConnectAllDriversToAllControllers ();\r
158 }\r
159 }\r
160 }\r
161\r
162 return (ShellStatus);\r
163}\r
164\r
165EFI_STATUS\r
166LoadEfiDriversFromRomImage (\r
167 VOID *RomBar,\r
168 UINTN RomSize,\r
169 CONST CHAR16 *FileName\r
170 )\r
171/*++\r
172\r
173Routine Description:\r
174 Command entry point.\r
175\r
176Arguments:\r
177\r
178 RomBar - Rom\r
179 RomSize - Rom size\r
180 FileName - The file name\r
181\r
182Returns:\r
183 EFI_SUCCESS - The command completed successfully\r
184 EFI_INVALID_PARAMETER - Command usage error\r
185 EFI_UNSUPPORTED - Protocols unsupported\r
186 EFI_OUT_OF_RESOURCES - Out of memory\r
187 Other value - Unknown error\r
188\r
189**/\r
190{\r
191 EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
192 PCI_DATA_STRUCTURE *Pcir;\r
193 UINTN ImageIndex;\r
194 UINTN RomBarOffset;\r
195 UINT32 ImageSize;\r
196 UINT16 ImageOffset;\r
197 EFI_HANDLE ImageHandle;\r
198 EFI_STATUS Status;\r
199 EFI_STATUS retStatus;\r
200 CHAR16 RomFileName[280];\r
201 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
202 BOOLEAN SkipImage;\r
203 UINT32 DestinationSize;\r
204 UINT32 ScratchSize;\r
205 UINT8 *Scratch;\r
206 VOID *ImageBuffer;\r
207 VOID *DecompressedImageBuffer;\r
208 UINT32 ImageLength;\r
209 EFI_DECOMPRESS_PROTOCOL *Decompress;\r
210\r
211 ImageIndex = 0;\r
212 retStatus = EFI_NOT_FOUND;\r
213 RomBarOffset = (UINTN) RomBar;\r
214\r
215 do {\r
216\r
217 EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;\r
218\r
219 if (EfiRomHeader->Signature != 0xaa55) {\r
220 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_CORRUPT), gShellDebug1HiiHandle, FileName, ImageIndex);\r
221// PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);\r
222 return retStatus;\r
223 }\r
224\r
225 Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);\r
226 ImageSize = Pcir->ImageLength * 512;\r
227\r
228 if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
229 (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)\r
230 ) {\r
231\r
232 if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
233 (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)\r
234 ) {\r
235 ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
236 ImageSize = EfiRomHeader->InitializationSize * 512;\r
237\r
238 ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset);\r
239 ImageLength = ImageSize - ImageOffset;\r
240 DecompressedImageBuffer = NULL;\r
241\r
242 //\r
243 // decompress here if needed\r
244 //\r
245 SkipImage = FALSE;\r
246 if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
247 SkipImage = TRUE;\r
248 }\r
249\r
250 if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
251 Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID**)&Decompress);\r
252 ASSERT_EFI_ERROR(Status);\r
253 if (EFI_ERROR (Status)) {\r
254 SkipImage = TRUE;\r
255 } else {\r
256 SkipImage = TRUE;\r
257 Status = Decompress->GetInfo (\r
258 Decompress,\r
259 ImageBuffer,\r
260 ImageLength,\r
261 &DestinationSize,\r
262 &ScratchSize\r
263 );\r
264 if (!EFI_ERROR (Status)) {\r
265 DecompressedImageBuffer = AllocatePool (DestinationSize);\r
266 if (ImageBuffer != NULL) {\r
267 Scratch = AllocatePool (ScratchSize);\r
268 if (Scratch != NULL) {\r
269 Status = Decompress->Decompress (\r
270 Decompress,\r
271 ImageBuffer,\r
272 ImageLength,\r
273 DecompressedImageBuffer,\r
274 DestinationSize,\r
275 Scratch,\r
276 ScratchSize\r
277 );\r
278 if (!EFI_ERROR (Status)) {\r
279 ImageBuffer = DecompressedImageBuffer;\r
280 ImageLength = DestinationSize;\r
281 SkipImage = FALSE;\r
282 }\r
283\r
284 FreePool (Scratch);\r
285 }\r
286 }\r
287 }\r
288 }\r
289 }\r
290\r
291 if (!SkipImage) {\r
292 //\r
293 // load image and start image\r
294 //\r
295 UnicodeSPrint (RomFileName, sizeof (RomFileName), L"%s[%d]", FileName, ImageIndex);\r
296 FilePath = FileDevicePath (NULL, RomFileName);\r
297\r
298 Status = gBS->LoadImage (\r
299 TRUE,\r
300 gImageHandle,\r
301 FilePath,\r
302 ImageBuffer,\r
303 ImageLength,\r
304 &ImageHandle\r
305 );\r
306 if (EFI_ERROR (Status)) {\r
307 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL), gShellDebug1HiiHandle, FileName, ImageIndex, Status);\r
308// PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status);\r
309 } else {\r
310 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
311 if (EFI_ERROR (Status)) {\r
312 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_START_FAIL), gShellDebug1HiiHandle, FileName, ImageIndex, Status);\r
313// PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status);\r
314 } else {\r
315 retStatus = Status;\r
316 }\r
317 }\r
318 }\r
319\r
320 if (DecompressedImageBuffer != NULL) {\r
321 FreePool (DecompressedImageBuffer);\r
322 }\r
323\r
324 }\r
325 }\r
326\r
327 RomBarOffset = RomBarOffset + ImageSize;\r
328 ImageIndex++;\r
329 } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));\r
330\r
331 return retStatus;\r
332}\r
333\r
334EFI_STATUS\r
335LoadPciRomConnectAllDriversToAllControllers (\r
336 VOID\r
337 )\r
338\r
339{\r
340 EFI_STATUS Status;\r
341 UINTN AllHandleCount;\r
342 EFI_HANDLE *AllHandleBuffer;\r
343 UINTN Index;\r
344 UINTN HandleCount;\r
345 EFI_HANDLE *HandleBuffer;\r
346 UINTN *HandleType;\r
347 UINTN HandleIndex;\r
348 BOOLEAN Parent;\r
349 BOOLEAN Device;\r
350\r
351 Status = gBS->LocateHandleBuffer(\r
352 AllHandles,\r
353 NULL,\r
354 NULL,\r
355 &AllHandleCount,\r
356 &AllHandleBuffer\r
357 );\r
358 if (EFI_ERROR (Status)) {\r
359 return Status;\r
360 }\r
361\r
362 for (Index = 0; Index < AllHandleCount; Index++) {\r
363 if (ShellGetExecutionBreakFlag ()) {\r
364 Status = EFI_ABORTED;\r
365 goto Done;\r
366 }\r
367 //\r
368 // Scan the handle database\r
369 //\r
370 Status = ParseHandleDatabaseByRelationshipWithType(\r
371 NULL,\r
372 AllHandleBuffer[Index],\r
373 &HandleCount,\r
374 &HandleBuffer,\r
375 &HandleType\r
376 );\r
377/*\r
378 Status = LibScanHandleDatabase (\r
379 NULL,\r
380 NULL,\r
381 AllHandleBuffer[Index],\r
382 NULL,\r
383 &HandleCount,\r
384 &HandleBuffer,\r
385 &HandleType\r
386 );\r
387*/\r
388 if (EFI_ERROR (Status)) {\r
389 goto Done;\r
390 }\r
391\r
392 Device = TRUE;\r
393 if ((HandleType[Index] & HR_DRIVER_BINDING_HANDLE) != 0) {\r
394 Device = FALSE;\r
395 }\r
396\r
397 if ((HandleType[Index] & HR_IMAGE_HANDLE) != 0) {\r
398 Device = FALSE;\r
399 }\r
400\r
401 if (Device) {\r
402 Parent = FALSE;\r
403 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
404 if ((HandleType[HandleIndex] & HR_PARENT_HANDLE) != 0) {\r
405 Parent = TRUE;\r
406 }\r
407 }\r
408\r
409 if (!Parent) {\r
410 if ((HandleType[Index] & HR_DEVICE_HANDLE) != 0) {\r
411 Status = gBS->ConnectController (\r
412 AllHandleBuffer[Index],\r
413 NULL,\r
414 NULL,\r
415 TRUE\r
416 );\r
417 }\r
418 }\r
419 }\r
420\r
421 FreePool (HandleBuffer);\r
422 FreePool (HandleType);\r
423 }\r
424\r
425Done:\r
426 FreePool (AllHandleBuffer);\r
427 return Status;\r
428}\r