]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Pei/Image/Image.c
Use PeiPiLib's PeiPiLibBuildPiFvInfoPpi interface instead of installing EFI_PEI_FIRM...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Image / Image.c
CommitLineData
192f6d4c 1/*++\r
2\r
3Copyright (c) 2006 - 2007, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 Image.c\r
15\r
16Abstract:\r
17\r
18 Pei Core Load Image Support\r
19\r
20--*/\r
21\r
192f6d4c 22#include <PeiMain.h>\r
23\r
b0d803fe 24/*++\r
25\r
26Routine Description:\r
27\r
28 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
192f6d4c 29\r
b0d803fe 30Arguments:\r
31\r
32 FileHandle - The handle to the PE/COFF file\r
33 FileOffset - The offset, in bytes, into the file to read\r
34 ReadSize - The number of bytes to read from the file starting at FileOffset\r
35 Buffer - A pointer to the buffer to read the data into.\r
36\r
37Returns:\r
38\r
39 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
40\r
41--*/ \r
192f6d4c 42\r
43EFI_STATUS\r
b0d803fe 44PeiLoadImageLoadImage (\r
45 IN EFI_PEI_SERVICES **PeiServices,\r
46 IN EFI_PEI_FILE_HANDLE FileHandle,\r
47 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
48 OUT UINT64 *ImageSizeArg, OPTIONAL\r
49 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
50 OUT UINT32 *AuthenticationState\r
192f6d4c 51 )\r
52/*++\r
53\r
54Routine Description:\r
55\r
56 Routine for loading file image.\r
57\r
58Arguments:\r
59\r
b0d803fe 60 PeiServices - The PEI core services table.\r
61 FileHandle - Pointer to the FFS file header of the image.\r
62 ImageAddressArg - Pointer to PE/TE image.\r
63 ImageSizeArg - Size of PE/TE image.\r
64 EntryPoint - Pointer to entry point of specified image file for output.\r
65 AuthenticationState - Pointer to attestation authentication state of image.\r
66\r
67Returns:\r
68\r
69 Status - EFI_SUCCESS - Image is successfully loaded.\r
70 EFI_NOT_FOUND - Fail to locate necessary PPI\r
71 Others - Fail to load file.\r
72\r
73--*/\r
74;\r
75\r
76EFI_STATUS\r
77EFIAPI\r
78PeiLoadImageLoadImageWrapper (\r
79 IN CONST EFI_PEI_LOAD_FILE_PPI *This,\r
80 IN EFI_PEI_FILE_HANDLE FileHandle,\r
81 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
82 OUT UINT64 *ImageSizeArg, OPTIONAL\r
83 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
84 OUT UINT32 *AuthenticationState\r
85 )\r
86/*++\r
87\r
88Routine Description:\r
89\r
90 The wrapper function of PeiLoadImageLoadImage().\r
91\r
92Arguments:\r
93\r
94 This - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
95 PeiServices - The PEI core services table.\r
96 FileHandle - Pointer to the FFS file header of the image.\r
97 ImageAddressArg - Pointer to PE/TE image.\r
98 ImageSizeArg - Size of PE/TE image.\r
99 EntryPoint - Pointer to entry point of specified image file for output.\r
100 AuthenticationState - Pointer to attestation authentication state of image.\r
101\r
102Returns:\r
103\r
104 EFI_STATUS.\r
105 \r
106--*/ \r
107;\r
108\r
109STATIC EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {\r
110 PeiLoadImageLoadImageWrapper\r
111};\r
112\r
113\r
114STATIC EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {\r
115 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
116 &gEfiPeiLoadFilePpiGuid,\r
117 &mPeiLoadImagePpi\r
118};\r
119\r
120EFI_STATUS\r
121EFIAPI\r
122PeiImageRead (\r
123 IN VOID *FileHandle,\r
124 IN UINTN FileOffset,\r
125 IN OUT UINTN *ReadSize,\r
126 OUT VOID *Buffer\r
127 )\r
128/*++\r
129\r
130Routine Description:\r
131\r
132 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
133\r
134Arguments:\r
135\r
136 FileHandle - The handle to the PE/COFF file\r
137 FileOffset - The offset, in bytes, into the file to read\r
138 ReadSize - The number of bytes to read from the file starting at FileOffset\r
139 Buffer - A pointer to the buffer to read the data into.\r
140\r
141Returns:\r
142\r
143 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
144\r
145--*/\r
146{\r
147 CHAR8 *Destination8;\r
148 CHAR8 *Source8;\r
149 UINTN Length;\r
150\r
151 Destination8 = Buffer;\r
152 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
153 Length = *ReadSize;\r
154 while (Length--) {\r
155 *(Destination8++) = *(Source8++);\r
156 }\r
157\r
158 return EFI_SUCCESS;\r
159}\r
160\r
161EFI_STATUS\r
162GetImageReadFunction (\r
163 IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
164 )\r
165/*++\r
166\r
167Routine Description:\r
168\r
169 Support routine to return the Image Read\r
170\r
171Arguments:\r
172\r
173 PeiServices - PEI Services Table\r
174\r
175 ImageContext - The context of the image being loaded\r
176\r
177Returns:\r
178\r
179 EFI_SUCCESS - If Image function location is found\r
180\r
181--*/\r
182{\r
183 VOID* MemoryBuffer;\r
184\r
185 MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);\r
186 ASSERT (MemoryBuffer != NULL);\r
187\r
188 CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400);\r
189\r
190 ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;\r
191\r
192 return EFI_SUCCESS;\r
193}\r
194\r
195STATIC\r
196EFI_STATUS\r
197LoadAndRelocatePeCoffImage (\r
198 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader,\r
199 IN VOID *Pe32Data,\r
200 OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
201 OUT UINT64 *ImageSize,\r
202 OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
203 )\r
204/*++\r
205\r
206Routine Description:\r
207\r
208 Loads and relocates a PE/COFF image into memory.\r
209\r
210Arguments:\r
211\r
212 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol\r
213\r
214 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated\r
215\r
216 ImageAddress - The base address of the relocated PE/COFF image\r
217\r
218 ImageSize - The size of the relocated PE/COFF image\r
219\r
220 EntryPoint - The entry point of the relocated PE/COFF image\r
221\r
222Returns:\r
223\r
224 EFI_SUCCESS - The file was loaded and relocated\r
225\r
226 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file\r
227\r
228--*/\r
229{\r
230 EFI_STATUS Status;\r
231 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
232\r
233 ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
234\r
235 ZeroMem (&ImageContext, sizeof (ImageContext));\r
236 ImageContext.Handle = Pe32Data;\r
237 Status = GetImageReadFunction (&ImageContext);\r
238\r
239 ASSERT_EFI_ERROR (Status);\r
240\r
241 Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext);\r
242 if (EFI_ERROR (Status)) {\r
243 return Status;\r
244 }\r
245 //\r
246 // Allocate Memory for the image\r
247 //\r
248 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\r
249 ASSERT (ImageContext.ImageAddress != 0);\r
250\r
251 //\r
252 // Load the image to our new buffer\r
253 //\r
254 Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext);\r
255 if (EFI_ERROR (Status)) {\r
256 return Status;\r
257 }\r
258 //\r
259 // Relocate the image in our new buffer\r
260 //\r
261 Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext);\r
262 if (EFI_ERROR (Status)) {\r
263 return Status;\r
264 }\r
265\r
266 //\r
267 // Flush the instruction cache so the image data is written before we execute it\r
268 //\r
269 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
270\r
271 *ImageAddress = ImageContext.ImageAddress;\r
272 *ImageSize = ImageContext.ImageSize;\r
273 *EntryPoint = ImageContext.EntryPoint;\r
274\r
275 return EFI_SUCCESS;\r
276}\r
277\r
278EFI_STATUS\r
279PeiLoadImageLoadImage (\r
280 IN EFI_PEI_SERVICES **PeiServices,\r
281 IN EFI_PEI_FILE_HANDLE FileHandle,\r
282 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
283 OUT UINT64 *ImageSizeArg, OPTIONAL\r
284 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
285 OUT UINT32 *AuthenticationState\r
286 )\r
287/*++\r
288\r
289Routine Description:\r
290\r
291 Routine for loading file image.\r
292\r
293Arguments:\r
294\r
295 PeiServices - The PEI core services table.\r
296 FileHandle - Pointer to the FFS file header of the image.\r
297 ImageAddressArg - Pointer to PE/TE image.\r
298 ImageSizeArg - Size of PE/TE image.\r
299 EntryPoint - Pointer to entry point of specified image file for output.\r
300 AuthenticationState - Pointer to attestation authentication state of image.\r
192f6d4c 301\r
302Returns:\r
303\r
304 Status - EFI_SUCCESS - Image is successfully loaded.\r
305 EFI_NOT_FOUND - Fail to locate necessary PPI\r
306 Others - Fail to load file.\r
307\r
308--*/\r
309{\r
310 EFI_STATUS Status;\r
311 VOID *Pe32Data;\r
192f6d4c 312 EFI_PHYSICAL_ADDRESS ImageAddress;\r
313 UINT64 ImageSize;\r
314 EFI_PHYSICAL_ADDRESS ImageEntryPoint;\r
315 EFI_TE_IMAGE_HEADER *TEImageHeader;\r
316 UINT16 Machine;\r
b0d803fe 317 PEI_CORE_INSTANCE *Private;\r
318 VOID *EntryPointArg;\r
192f6d4c 319\r
b0d803fe 320 *EntryPoint = 0;\r
192f6d4c 321 TEImageHeader = NULL;\r
b0d803fe 322 ImageSize = 0;\r
323 *AuthenticationState = 0;\r
192f6d4c 324\r
325 //\r
b0d803fe 326 // Try to find a TE section.\r
192f6d4c 327 //\r
328 Status = PeiServicesFfsFindSectionData (\r
b0d803fe 329 EFI_SECTION_TE,\r
330 FileHandle,\r
192f6d4c 331 &Pe32Data\r
332 );\r
b0d803fe 333 if (!EFI_ERROR (Status)) {\r
334 TEImageHeader = (EFI_TE_IMAGE_HEADER *)Pe32Data;\r
335 }\r
192f6d4c 336 //\r
337 // If we didn't find a PE32 section, try to find a TE section.\r
338 //\r
339 if (EFI_ERROR (Status)) {\r
340 Status = PeiServicesFfsFindSectionData (\r
b0d803fe 341 EFI_SECTION_PE32,\r
342 FileHandle,\r
343 &Pe32Data\r
192f6d4c 344 );\r
b0d803fe 345 if (EFI_ERROR (Status)) {\r
192f6d4c 346 //\r
b0d803fe 347 // PEI core only carry the loader function fro TE and PE32 executables\r
348 // If this two section does not exist, just return.\r
192f6d4c 349 //\r
b0d803fe 350 return Status;\r
351 }\r
352 }\r
353 \r
354 Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
192f6d4c 355\r
b0d803fe 356 if (Private->PeiMemoryInstalled && \r
357 (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
358 {\r
359 //\r
360 // If memory is installed, perform the shadow operations\r
361 //\r
362 Status = LoadAndRelocatePeCoffImage (\r
363 Private->PeCoffLoader,\r
364 Pe32Data,\r
365 &ImageAddress,\r
366 &ImageSize,\r
367 &ImageEntryPoint\r
368 );\r
192f6d4c 369\r
370 if (EFI_ERROR (Status)) {\r
371 return EFI_NOT_FOUND;\r
372 }\r
373\r
374 //\r
375 // Got the entry point from ImageEntryPoint and ImageStartAddress\r
376 //\r
377 Pe32Data = (VOID *) ((UINTN) ImageAddress);\r
b0d803fe 378 *EntryPoint = ImageEntryPoint;\r
379 }\r
380 } else {\r
381 if (TEImageHeader != NULL) {\r
192f6d4c 382 //\r
383 // Retrieve the entry point from the TE image header\r
384 //\r
385 ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;\r
b0d803fe 386 ImageSize = 0;\r
387 *EntryPoint = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
192f6d4c 388 TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);\r
b0d803fe 389 } else {\r
390 //\r
391 // Retrieve the entry point from the PE/COFF image header\r
392 //\r
393 ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;\r
394 ImageSize = 0;\r
395 Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointArg);\r
396 *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) EntryPointArg;\r
397 if (EFI_ERROR (Status)) {\r
398 return EFI_NOT_FOUND;\r
399 }\r
192f6d4c 400 }\r
401 }\r
402\r
403 if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
404 TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress;\r
405 Machine = TEImageHeader->Machine;\r
406 } else {\r
407 Machine = PeCoffLoaderGetMachineType (Pe32Data);\r
408 } \r
409 \r
410 if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {\r
411 return EFI_UNSUPPORTED; \r
412 }\r
413\r
b0d803fe 414 if (ImageAddressArg != NULL) {\r
415 *ImageAddressArg = ImageAddress;\r
416 }\r
417\r
418 if (ImageSizeArg != NULL) {\r
419 *ImageSizeArg = ImageSize;\r
420 }\r
421 \r
192f6d4c 422 //\r
423 // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
424 //\r
425 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));\r
426 DEBUG_CODE_BEGIN ();\r
427 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
428 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
429 UINTN DirCount;\r
430 UINTN Index;\r
431 UINTN Index1;\r
432 BOOLEAN FileNameFound;\r
433 CHAR8 *AsciiString;\r
434 CHAR8 AsciiBuffer[512];\r
435 VOID *CodeViewEntryPointer;\r
436 INTN TEImageAdjust;\r
437 EFI_IMAGE_DOS_HEADER *DosHeader;\r
438 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
439 UINT32 NumberOfRvaAndSizes;\r
440\r
441 Hdr.Pe32 = NULL;\r
442 if (TEImageHeader == NULL) {\r
443 DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
444 if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
445 //\r
446 // DOS image header is present, so read the PE header after the DOS image header\r
447 //\r
448 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHeader->e_lfanew) & 0x0ffff));\r
449 } else {\r
450 //\r
451 // DOS image header is not present, so PE header is at the image base\r
452 //\r
453 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
454 }\r
455 }\r
456\r
457 //\r
458 // Find the codeview info in the image and display the file name\r
459 // being loaded.\r
460 //\r
461 // Per the PE/COFF spec, you can't assume that a given data directory\r
462 // is present in the image. You have to check the NumberOfRvaAndSizes in\r
463 // the optional header to verify a desired directory entry is there.\r
464 //\r
465 DebugEntry = NULL;\r
466 DirectoryEntry = NULL;\r
467 NumberOfRvaAndSizes = 0;\r
468 TEImageAdjust = 0;\r
469 \r
470 if (TEImageHeader == NULL) {\r
471 if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
472 // \r
473 // Use PE32 offset get Debug Directory Entry\r
474 //\r
475 NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
476 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
477 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
478 } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
479 // \r
480 // Use PE32+ offset get Debug Directory Entry\r
481 //\r
482 NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
483 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
484 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
485 }\r
486\r
487 if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
488 DirectoryEntry = NULL;\r
489 DebugEntry = NULL;\r
490 }\r
491 } else {\r
492 if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
493 DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
494 TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;\r
495 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +\r
496 TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
497 TEImageAdjust);\r
498 }\r
499 }\r
500\r
501 if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
502 for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {\r
503 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
504 if (DebugEntry->SizeOfData > 0) {\r
505 CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);\r
506 switch (* (UINT32 *) CodeViewEntryPointer) {\r
507 case CODEVIEW_SIGNATURE_NB10:\r
508 AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
509 break;\r
510\r
511 case CODEVIEW_SIGNATURE_RSDS:\r
512 AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
513 break;\r
514\r
515 default:\r
516 AsciiString = NULL;\r
517 break;\r
518 }\r
519 if (AsciiString != NULL) {\r
520 FileNameFound = FALSE;\r
521 for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) {\r
522 if (AsciiString[Index] == '\\') {\r
523 Index1 = Index;\r
524 FileNameFound = TRUE;\r
525 }\r
526 }\r
527\r
528 if (FileNameFound) {\r
529 for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {\r
530 AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];\r
531 }\r
532 AsciiBuffer[Index - (Index1 + 1)] = 0;\r
533 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
534 break;\r
535 }\r
536 }\r
537 }\r
538 }\r
539 }\r
540 }\r
541 DEBUG_CODE_END ();\r
542\r
543 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
544\r
545 return EFI_SUCCESS;\r
b0d803fe 546\r
547}\r
548\r
549\r
550EFI_STATUS\r
551EFIAPI\r
552PeiLoadImageLoadImageWrapper (\r
553 IN CONST EFI_PEI_LOAD_FILE_PPI *This,\r
554 IN EFI_PEI_FILE_HANDLE FileHandle,\r
555 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
556 OUT UINT64 *ImageSizeArg, OPTIONAL\r
557 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
558 OUT UINT32 *AuthenticationState\r
559 )\r
560/*++\r
561\r
562Routine Description:\r
563\r
564 The wrapper function of PeiLoadImageLoadImage().\r
565\r
566Arguments:\r
567\r
568 This - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
569 PeiServices - The PEI core services table.\r
570 FileHandle - Pointer to the FFS file header of the image.\r
571 ImageAddressArg - Pointer to PE/TE image.\r
572 ImageSizeArg - Size of PE/TE image.\r
573 EntryPoint - Pointer to entry point of specified image file for output.\r
574 AuthenticationState - Pointer to attestation authentication state of image.\r
575\r
576Returns:\r
577\r
578 EFI_STATUS.\r
579 \r
580--*/ \r
581{\r
582 return PeiLoadImageLoadImage (\r
583 GetPeiServicesTablePointer (),\r
584 FileHandle,\r
585 ImageAddressArg,\r
586 ImageSizeArg,\r
587 EntryPoint,\r
588 AuthenticationState\r
589 );\r
192f6d4c 590}\r
b0d803fe 591\r
592EFI_STATUS\r
593PeiLoadImage (\r
594 IN EFI_PEI_SERVICES **PeiServices,\r
595 IN EFI_PEI_FILE_HANDLE FileHandle,\r
596 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
597 OUT UINT32 *AuthenticationState\r
598 )\r
599/*++\r
600\r
601Routine Description:\r
602\r
603 Routine for load image file.\r
604\r
605Arguments:\r
606\r
607 PeiServices - The PEI core services table.\r
608 FileHandle - Pointer to the FFS file header of the image.\r
609 EntryPoint - Pointer to entry point of specified image file for output.\r
610 AuthenticationState - Pointer to attestation authentication state of image.\r
611\r
612Returns:\r
613\r
614 Status - EFI_SUCCESS - Image is successfully loaded.\r
615 EFI_NOT_FOUND - Fail to locate necessary PPI\r
616 Others - Fail to load file.\r
617 \r
618--*/ \r
619{\r
620 EFI_STATUS PpiStatus;\r
621 EFI_STATUS Status;\r
622 UINTN Index;\r
623 EFI_PEI_LOAD_FILE_PPI *LoadFile;\r
624 EFI_PHYSICAL_ADDRESS ImageAddress;\r
625 UINT64 ImageSize;\r
626\r
627 //\r
628 // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.\r
629 // one at a time, until one reports EFI_SUCCESS.\r
630 //\r
631 Index = 0;\r
632 do {\r
633 PpiStatus = PeiServicesLocatePpi (\r
634 &gEfiPeiLoadFilePpiGuid,\r
635 Index,\r
636 NULL,\r
637 (VOID **)&LoadFile\r
638 );\r
639 if (!EFI_ERROR (PpiStatus)) {\r
640 Status = LoadFile->LoadFile (\r
641 LoadFile, \r
642 FileHandle, \r
643 &ImageAddress, \r
644 &ImageSize,\r
645 EntryPoint,\r
646 AuthenticationState\r
647 );\r
648 if (!EFI_ERROR (Status)) {\r
649 return Status;\r
650 }\r
651 }\r
652 Index++;\r
653 } while (!EFI_ERROR (PpiStatus));\r
654\r
655 //\r
656 // If no instances reports EFI_SUCCESS, then build-in support for\r
657 // the PE32+/TE XIP image format is used.\r
658 //\r
659 Status = PeiLoadImageLoadImage (\r
660 PeiServices, \r
661 FileHandle, \r
662 NULL, \r
663 NULL, \r
664 EntryPoint, \r
665 AuthenticationState\r
666 );\r
667 return Status;\r
668}\r
669\r
670\r
671VOID\r
672InitializeImageServices (\r
673 IN PEI_CORE_INSTANCE *PrivateData,\r
674 IN PEI_CORE_INSTANCE *OldCoreData\r
675 )\r
676/*++\r
677\r
678Routine Description:\r
679\r
680 Regitser PeCoffLoader to PeiCore PrivateData. And install\r
681 Pei Load File PPI.\r
682\r
683Arguments:\r
684\r
685 PrivateData - Pointer to PEI_CORE_INSTANCE.\r
686 OldCoreData - Pointer to PEI_CORE_INSTANCE.\r
687\r
688Returns:\r
689\r
690 NONE.\r
691 \r
692--*/ \r
693{\r
694 //\r
695 // Always update PeCoffLoader pointer as PEI core itself may get \r
696 // shadowed into memory\r
697 //\r
698 PrivateData->PeCoffLoader = GetPeCoffLoaderProtocol ();\r
699 \r
700 if (OldCoreData == NULL) {\r
701 //\r
702 // The first time we are XIP (running from FLASH). We need to remember the\r
703 // FLASH address so we can reinstall the memory version that runs faster\r
704 //\r
705 PrivateData->XipLoadFile = &gPpiLoadFilePpiList;\r
706 PeiServicesInstallPpi (PrivateData->XipLoadFile);\r
707 } else {\r
708 //\r
709 // 2nd time we are running from memory so replace the XIP version with the \r
710 // new memory version. \r
711 //\r
712 PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList); \r
713 }\r
714}\r
715\r
716\r
717\r