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