TianoCore EDK2 master
Loading...
Searching...
No Matches
PayloadLoaderPeim.c
Go to the documentation of this file.
1
9#include <PiPei.h>
12
13#include <Ppi/LoadFile.h>
14
15#include <Library/DebugLib.h>
16#include <Library/HobLib.h>
21#include "ElfLib.h"
22
23CONST EFI_PEI_PPI_DESCRIPTOR gReadyToPayloadSignalPpi = {
24 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
25 &gUplReadyToPayloadPpiGuid,
26 NULL
27};
28
38EFIAPI
40 IN EFI_PEI_SERVICES **PeiServices,
41 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
42 IN VOID *Ppi
43 )
44{
45 EFI_STATUS Status;
46
47 //
48 // Ready to Payload phase signal
49 //
50 Status = PeiServicesInstallPpi (&gReadyToPayloadSignalPpi);
51
52 return Status;
53}
54
55EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiNotifyList[] = {
56 {
57 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
58 &gEfiEndOfPeiSignalPpiGuid,
60 }
61};
62
77EFIAPI
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 EFI_STATUS Status;
88 VOID *Elf;
90 UNIVERSAL_PAYLOAD_BASE *PayloadBase;
91 ELF_IMAGE_CONTEXT Context;
92 UINT32 Index;
93 UINT16 ExtraDataIndex;
94 CHAR8 *SectionName;
95 UINTN Offset;
96 UINTN Size;
97 UINT32 ExtraDataCount;
98 UINTN Instance;
99 UINTN Length;
100
101 //
102 // ELF is added to file as RAW section for EDKII bootloader.
103 // But RAW section might be added by build tool before the ELF RAW section when alignment is specified for ELF RAW section.
104 // Below loop skips the RAW section that doesn't contain valid ELF image.
105 //
106 Instance = 0;
107 do {
108 Status = PeiServicesFfsFindSectionData3 (EFI_SECTION_RAW, Instance++, FileHandle, &Elf, AuthenticationState);
109 if (EFI_ERROR (Status)) {
110 return Status;
111 }
112
113 ZeroMem (&Context, sizeof (Context));
114 Status = ParseElfImage (Elf, &Context);
115 } while (EFI_ERROR (Status));
116
117 Length = sizeof (UNIVERSAL_PAYLOAD_BASE);
118 PayloadBase = BuildGuidHob (
119 &gUniversalPayloadBaseGuid,
120 Length
121 );
122 PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)Context.FileBase;
123
124 DEBUG (
125 (
126 DEBUG_INFO,
127 "Payload File Size: 0x%08X, Mem Size: 0x%08x, Reload: %d\n",
128 Context.FileSize,
129 Context.ImageSize,
130 Context.ReloadRequired
131 )
132 );
133
134 //
135 // Get UNIVERSAL_PAYLOAD_INFO_HEADER and number of additional PLD sections.
136 //
137 ExtraDataCount = 0;
138 for (Index = 0; Index < Context.ShNum; Index++) {
139 Status = GetElfSectionName (&Context, Index, &SectionName);
140 if (EFI_ERROR (Status)) {
141 continue;
142 }
143
144 DEBUG ((DEBUG_INFO, "Payload Section[%d]: %a\n", Index, SectionName));
145 if (AsciiStrCmp (SectionName, UNIVERSAL_PAYLOAD_INFO_SEC_NAME) == 0) {
146 Status = GetElfSectionPos (&Context, Index, &Offset, &Size);
147 } else if (AsciiStrnCmp (SectionName, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH) == 0) {
148 Status = GetElfSectionPos (&Context, Index, &Offset, &Size);
149 if (!EFI_ERROR (Status)) {
150 ExtraDataCount++;
151 }
152 }
153 }
154
155 //
156 // Report the additional PLD sections through HOB.
157 //
158 Length = sizeof (UNIVERSAL_PAYLOAD_EXTRA_DATA) + ExtraDataCount * sizeof (UNIVERSAL_PAYLOAD_EXTRA_DATA_ENTRY);
159 ExtraData = BuildGuidHob (
160 &gUniversalPayloadExtraDataGuid,
161 Length
162 );
163 ExtraData->Count = ExtraDataCount;
164 ExtraData->Header.Revision = UNIVERSAL_PAYLOAD_EXTRA_DATA_REVISION;
165 ExtraData->Header.Length = (UINT16)Length;
166 if (ExtraDataCount != 0) {
167 for (ExtraDataIndex = 0, Index = 0; Index < Context.ShNum; Index++) {
168 Status = GetElfSectionName (&Context, Index, &SectionName);
169 if (EFI_ERROR (Status)) {
170 continue;
171 }
172
173 if (AsciiStrnCmp (SectionName, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH) == 0) {
174 Status = GetElfSectionPos (&Context, Index, &Offset, &Size);
175 if (!EFI_ERROR (Status)) {
176 ASSERT (ExtraDataIndex < ExtraDataCount);
178 ExtraData->Entry[ExtraDataIndex].Identifier,
179 sizeof (ExtraData->Entry[ExtraDataIndex].Identifier),
180 SectionName + UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH
181 );
182 ExtraData->Entry[ExtraDataIndex].Base = (UINTN)(Context.FileBase + Offset);
183 ExtraData->Entry[ExtraDataIndex].Size = Size;
184 ExtraDataIndex++;
185 }
186 }
187 }
188 }
189
190 if (Context.ReloadRequired || (Context.PreferredImageAddress != Context.FileBase)) {
192 } else {
193 Context.ImageAddress = Context.FileBase;
194 }
195
196 //
197 // Load ELF into the required base
198 //
199 Status = LoadElfImage (&Context);
200 if (!EFI_ERROR (Status)) {
201 *ImageAddressArg = (UINTN)Context.ImageAddress;
202 *EntryPoint = Context.EntryPoint;
203 *ImageSizeArg = Context.ImageSize;
204 }
205
206 DEBUG ((DEBUG_INFO, "LoadElfImage :%r, EntryPoint :%x\n", Status, (UINTN)Context.EntryPoint));
207
208 Status = PeiServicesNotifyPpi (&mEndOfPeiNotifyList[0]);
209 ASSERT_EFI_ERROR (Status);
210
211 return Status;
212}
213
214EFI_PEI_LOAD_FILE_PPI mPeiLoadFilePpi = {
216};
217
218EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
219 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
220 &gEfiPeiLoadFilePpiGuid,
221 &mPeiLoadFilePpi
222};
223
236EFIAPI
238 IN EFI_PEI_FILE_HANDLE FileHandle,
239 IN CONST EFI_PEI_SERVICES **PeiServices
240 )
241{
242 EFI_STATUS Status;
243
244 Status = PeiServicesInstallPpi (&gPpiLoadFilePpiList);
245
246 return Status;
247}
UINT64 UINTN
VOID *EFIAPI BuildGuidHob(IN CONST EFI_GUID *Guid, IN UINTN DataLength)
Definition: HobLib.c:336
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
Definition: String.c:872
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1797
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI LoadElfImage(IN ELF_IMAGE_CONTEXT *ElfCt)
Definition: ElfLib.c:351
EFI_STATUS EFIAPI GetElfSectionName(IN ELF_IMAGE_CONTEXT *ElfCt, IN UINT32 SectionIndex, OUT CHAR8 **SectionName)
Definition: ElfLib.c:392
EFI_STATUS EFIAPI GetElfSectionPos(IN ELF_IMAGE_CONTEXT *ElfCt, IN UINT32 Index, OUT UINTN *Offset, OUT UINTN *Size)
Definition: ElfLib.c:446
EFI_STATUS EFIAPI ParseElfImage(IN VOID *ImageBase, OUT ELF_IMAGE_CONTEXT *ElfCt)
Definition: ElfLib.c:229
EFI_STATUS EFIAPI PeiServicesNotifyPpi(IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS EFIAPI PeiLoadFileLoadPayload(IN CONST EFI_PEI_LOAD_FILE_PPI *This, IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, OUT UINT64 *ImageSizeArg OPTIONAL, OUT EFI_PHYSICAL_ADDRESS *EntryPoint, OUT UINT32 *AuthenticationState)
EFI_STATUS EFIAPI EndOfPeiPpiNotifyCallback(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi)
EFI_STATUS EFIAPI InitializePayloadLoaderPeim(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
EFI_STATUS EFIAPI PeiServicesFfsFindSectionData3(IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData, OUT UINT32 *AuthenticationStatus)
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID *EFIAPI AllocatePages(IN UINTN Pages)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
UINTN FileSize
The size including sections that don't require loading.
Definition: ElfLib.h:22
UINT8 * ImageAddress
The destination memory address set by caller.
Definition: ElfLib.h:25
UINTN EntryPoint
Return the actual entry point after LoadElfImage().
Definition: ElfLib.h:32
UINT8 * PreferredImageAddress
The preferred image to be loaded. No relocation is needed if loaded to this address.
Definition: ElfLib.h:23
UINTN ImageSize
The memory size for loading and execution.
Definition: ElfLib.h:26
UINT8 * FileBase
The source location in memory.
Definition: ElfLib.h:21
BOOLEAN ReloadRequired
The image needs a new memory location for running.
Definition: ElfLib.h:24