TianoCore EDK2 master
Loading...
Searching...
No Matches
UniversalPayloadEntry.c
Go to the documentation of this file.
1
8#include "UefiPayloadEntry.h"
9
10#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
11 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
12 EFI_RESOURCE_ATTRIBUTE_TESTED | \
13 EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \
14 EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \
15 EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \
16 EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \
17 EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \
18 EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \
19 EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | \
20 EFI_RESOURCE_ATTRIBUTE_PERSISTENT )
21
22#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
23 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
24 EFI_RESOURCE_ATTRIBUTE_TESTED )
25
26extern VOID *mHobList;
27
33VOID
35 IN CONST VOID *HobStart
36 );
37
52 )
53{
54 EFI_STATUS Status;
55 EFI_FFS_FILE_HEADER *FileHeader;
56 VOID *PcdRawData;
57 PEI_PCD_DATABASE *PeiDatabase;
58 PEI_PCD_DATABASE *UplDatabase;
59 EFI_HOB_GUID_TYPE *GuidHob;
60 DYNAMICEX_MAPPING *ExMapTable;
61 UINTN Index;
62
63 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
64 if (GuidHob == NULL) {
65 //
66 // No fix-up is needed.
67 //
68 return EFI_SUCCESS;
69 }
70
71 PeiDatabase = (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);
72 DEBUG ((DEBUG_INFO, "Find the Pei PCD data base, the total local token number is %d\n", PeiDatabase->LocalTokenCount));
73
74 Status = FvFindFileByTypeGuid (DxeFv, EFI_FV_FILETYPE_DRIVER, PcdGetPtr (PcdPcdDriverFile), &FileHeader);
75 ASSERT_EFI_ERROR (Status);
76 if (EFI_ERROR (Status)) {
77 return Status;
78 }
79
80 Status = FileFindSection (FileHeader, EFI_SECTION_RAW, &PcdRawData);
81 ASSERT_EFI_ERROR (Status);
82 if (EFI_ERROR (Status)) {
83 return Status;
84 }
85
86 UplDatabase = (PEI_PCD_DATABASE *)PcdRawData;
87 ExMapTable = (DYNAMICEX_MAPPING *)(UINTN)((UINTN)PcdRawData + UplDatabase->ExMapTableOffset);
88
89 for (Index = 0; Index < UplDatabase->ExTokenCount; Index++) {
90 ExMapTable[Index].TokenNumber += PeiDatabase->LocalTokenCount;
91 }
92
93 DEBUG ((DEBUG_INFO, "Fix up UPL PCD database successfully\n"));
94 return EFI_SUCCESS;
95}
96
102VOID
105 )
106{
108
109 if (Hob->Raw == NULL) {
110 return;
111 }
112
113 NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header->HobLength);
114 ASSERT (NewHob.Header != NULL);
115 if (NewHob.Header == NULL) {
116 return;
117 }
118
119 CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - sizeof (EFI_HOB_GENERIC_HEADER));
120}
121
133 IN VOID *HobList,
136 )
137{
139 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
140
141 for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
142 //
143 // Skip all HOBs except Resource Descriptor HOBs
144 //
145 if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
146 continue;
147 }
148
149 //
150 // Skip Resource Descriptor HOBs that do not describe tested system memory
151 //
152 ResourceHob = Hob.ResourceDescriptor;
153 if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
154 continue;
155 }
156
157 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
158 continue;
159 }
160
161 //
162 // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
163 //
164 if (Base < ResourceHob->PhysicalStart) {
165 continue;
166 }
167
168 if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
169 continue;
170 }
171
172 return ResourceHob;
173 }
174
175 return NULL;
176}
177
189 IN VOID *HobList,
190 IN UINTN MinimalNeededSize,
191 IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob
192 )
193{
195 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
196 EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob;
197
198 ReturnResourceHob = NULL;
199
200 for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
201 //
202 // Skip all HOBs except Resource Descriptor HOBs
203 //
204 if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
205 continue;
206 }
207
208 //
209 // Skip Resource Descriptor HOBs that do not describe tested system memory
210 //
211 ResourceHob = Hob.ResourceDescriptor;
212 if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
213 continue;
214 }
215
216 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
217 continue;
218 }
219
220 //
221 // Skip if the Resource Descriptor HOB equals to ExceptResourceHob
222 //
223 if (ResourceHob == ExceptResourceHob) {
224 continue;
225 }
226
227 //
228 // Skip Resource Descriptor HOBs that are beyond 4G
229 //
230 if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > BASE_4GB) {
231 continue;
232 }
233
234 //
235 // Skip Resource Descriptor HOBs that are too small
236 //
237 if (ResourceHob->ResourceLength < MinimalNeededSize) {
238 continue;
239 }
240
241 //
242 // Return the topest Resource Descriptor
243 //
244 if (ReturnResourceHob == NULL) {
245 ReturnResourceHob = ResourceHob;
246 } else {
247 if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) {
248 ReturnResourceHob = ResourceHob;
249 }
250 }
251 }
252
253 return ReturnResourceHob;
254}
255
267BOOLEAN
270 )
271{
272 if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
273 return FALSE;
274 }
275
276 if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
277 if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
278 return FALSE;
279 }
280 }
281
282 // Arrive here mean the HOB is need
283 return TRUE;
284}
285
297 IN UINTN BootloaderParameter,
299 )
300{
302 UINTN MinimalNeededSize;
303 EFI_PHYSICAL_ADDRESS FreeMemoryBottom;
304 EFI_PHYSICAL_ADDRESS FreeMemoryTop;
305 EFI_PHYSICAL_ADDRESS MemoryBottom;
306 EFI_PHYSICAL_ADDRESS MemoryTop;
307 EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob;
308 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
310 UINT8 *GuidHob;
313 ACPI_BOARD_INFO *AcpiBoardInfo;
315 UINT8 Idx;
316
317 Hob.Raw = (UINT8 *)BootloaderParameter;
318 MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
319
320 ASSERT (Hob.Raw != NULL);
321 ASSERT ((UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop == Hob.HandoffInformationTable->EfiFreeMemoryTop);
322 ASSERT ((UINTN)Hob.HandoffInformationTable->EfiMemoryTop == Hob.HandoffInformationTable->EfiMemoryTop);
323 ASSERT ((UINTN)Hob.HandoffInformationTable->EfiFreeMemoryBottom == Hob.HandoffInformationTable->EfiFreeMemoryBottom);
324 ASSERT ((UINTN)Hob.HandoffInformationTable->EfiMemoryBottom == Hob.HandoffInformationTable->EfiMemoryBottom);
325
326 //
327 // Try to find Resource Descriptor HOB that contains Hob range EfiMemoryBottom..EfiMemoryTop
328 //
329 PhitResourceHob = FindResourceDescriptorByRange (Hob.Raw, Hob.HandoffInformationTable->EfiMemoryBottom, Hob.HandoffInformationTable->EfiMemoryTop);
330 if (PhitResourceHob == NULL) {
331 //
332 // Boot loader's Phit Hob is not in an available Resource Descriptor, find another Resource Descriptor for new Phit Hob
333 //
334 ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, NULL);
335 if (ResourceHob == NULL) {
336 return EFI_NOT_FOUND;
337 }
338
339 MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize;
340 FreeMemoryBottom = MemoryBottom;
341 FreeMemoryTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength;
342 MemoryTop = FreeMemoryTop;
343 } else if (PhitResourceHob->PhysicalStart + PhitResourceHob->ResourceLength - Hob.HandoffInformationTable->EfiMemoryTop >= MinimalNeededSize) {
344 //
345 // New availiable Memory range in new hob is right above memory top in old hob.
346 //
347 MemoryBottom = Hob.HandoffInformationTable->EfiFreeMemoryTop;
348 FreeMemoryBottom = Hob.HandoffInformationTable->EfiMemoryTop;
349 FreeMemoryTop = FreeMemoryBottom + MinimalNeededSize;
350 MemoryTop = FreeMemoryTop;
351 } else if (Hob.HandoffInformationTable->EfiMemoryBottom - PhitResourceHob->PhysicalStart >= MinimalNeededSize) {
352 //
353 // New availiable Memory range in new hob is right below memory bottom in old hob.
354 //
355 MemoryBottom = Hob.HandoffInformationTable->EfiMemoryBottom - MinimalNeededSize;
356 FreeMemoryBottom = MemoryBottom;
357 FreeMemoryTop = Hob.HandoffInformationTable->EfiMemoryBottom;
358 MemoryTop = Hob.HandoffInformationTable->EfiMemoryTop;
359 } else {
360 //
361 // In the Resource Descriptor HOB contains boot loader Hob, there is no enough free memory size for payload hob
362 // Find another Resource Descriptor Hob
363 //
364 ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, PhitResourceHob);
365 if (ResourceHob == NULL) {
366 return EFI_NOT_FOUND;
367 }
368
369 MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize;
370 FreeMemoryBottom = MemoryBottom;
371 FreeMemoryTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength;
372 MemoryTop = FreeMemoryTop;
373 }
374
375 HobInfo = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMemoryTop);
376 HobInfo->BootMode = Hob.HandoffInformationTable->BootMode;
377 //
378 // From now on, mHobList will point to the new Hob range.
379 //
380
381 //
382 // Create an empty FvHob for the DXE FV that contains DXE core.
383 //
385 //
386 // Since payload created new Hob, move all hobs except PHIT from boot loader hob list.
387 //
388 while (!END_OF_HOB_LIST (Hob)) {
389 if (IsHobNeed (Hob)) {
390 // Add this hob to payload HOB
391 AddNewHob (&Hob);
392 }
393
394 Hob.Raw = GET_NEXT_HOB (Hob);
395 }
396
397 //
398 // Get DXE FV location
399 //
400 GuidHob = GetFirstGuidHob (&gUniversalPayloadExtraDataGuid);
401 ASSERT (GuidHob != NULL);
402 ExtraData = (UNIVERSAL_PAYLOAD_EXTRA_DATA *)GET_GUID_HOB_DATA (GuidHob);
403 DEBUG ((DEBUG_INFO, "Multiple Fv Count=%d\n", ExtraData->Count));
404 ASSERT (AsciiStrCmp (ExtraData->Entry[0].Identifier, "uefi_fv") == 0);
405
406 *DxeFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)ExtraData->Entry[0].Base;
407 ASSERT ((*DxeFv)->FvLength == ExtraData->Entry[0].Size);
408 //
409 // support multiple FVs provided by UPL
410 //
411 for (Idx = 1; Idx < ExtraData->Count; Idx++) {
412 BuildFvHob (ExtraData->Entry[Idx].Base, ExtraData->Entry[Idx].Size);
413 DEBUG ((
414 DEBUG_INFO,
415 "UPL Multiple fv[%d], Base=0x%x, size=0x%x\n",
416 Idx,
417 ExtraData->Entry[Idx].Base,
418 ExtraData->Entry[Idx].Size
419 ));
420 }
421
422 //
423 // Create guid hob for acpi board information
424 //
425 GuidHob = GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid);
426 if (GuidHob != NULL) {
427 AcpiTable = (UNIVERSAL_PAYLOAD_ACPI_TABLE *)GET_GUID_HOB_DATA (GuidHob);
429 if (GuidHob == NULL) {
430 AcpiBoardInfo = BuildHobFromAcpi ((UINT64)AcpiTable->Rsdp);
431 ASSERT (AcpiBoardInfo != NULL);
432 }
433 }
434
435 //
436 // Update DXE FV information to first fv hob in the hob list, which
437 // is the empty FvHob created before.
438 //
439 FvHob = GetFirstHob (EFI_HOB_TYPE_FV);
440 FvHob->BaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)*DxeFv;
441 FvHob->Length = (*DxeFv)->FvLength;
442 return EFI_SUCCESS;
443}
444
453EFIAPI
455 IN UINTN BootloaderParameter
456 )
457{
458 EFI_STATUS Status;
459 PHYSICAL_ADDRESS DxeCoreEntryPoint;
462
463 mHobList = (VOID *)BootloaderParameter;
464 DxeFv = NULL;
465 // Call constructor for all libraries
466 ProcessLibraryConstructorList ();
467
468 DEBUG ((DEBUG_INFO, "Entering Universal Payload...\n"));
469 DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN)));
470
471 DEBUG_CODE (
472 //
473 // Dump the Hobs from boot loader
474 //
475 PrintHob (mHobList);
476 );
477
478 // Initialize floating point operating environment to be compliant with UEFI spec.
480
481 // Build HOB based on information from Bootloader
482 Status = BuildHobs (BootloaderParameter, &DxeFv);
483 ASSERT_EFI_ERROR (Status);
484
485 FixUpPcdDatabase (DxeFv);
486 Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint);
487 ASSERT_EFI_ERROR (Status);
488
489 Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF);
490 HandOffToDxeCore (DxeCoreEntryPoint, Hob);
491
492 // Should not get here
493 CpuDeadLoop ();
494 return EFI_SUCCESS;
495}
UINT64 UINTN
EFI_GUID gUefiAcpiBoardInfoGuid
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID EFIAPI BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:404
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID HandOffToDxeCore(IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, IN EFI_PEI_HOB_POINTERS HobList)
Definition: DxeHandoff.c:26
ACPI_BOARD_INFO * BuildHobFromAcpi(IN UINT64 AcpiTableBase)
Definition: AcpiTable.c:139
EFI_STATUS UniversalLoadDxeCore(IN EFI_FIRMWARE_VOLUME_HEADER *DxeFv, OUT PHYSICAL_ADDRESS *DxeCoreEntryPoint)
Definition: LoadDxeCore.c:327
EFI_STATUS FileFindSection(IN EFI_FFS_FILE_HEADER *FileHeader, IN EFI_SECTION_TYPE SectionType, OUT VOID **SectionData)
Definition: LoadDxeCore.c:201
EFI_STATUS FvFindFileByTypeGuid(IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader, IN EFI_FV_FILETYPE FileType, IN EFI_GUID *Guid OPTIONAL, OUT EFI_FFS_FILE_HEADER **FileHeader)
Definition: LoadDxeCore.c:131
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#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
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
VOID * CreateHob(IN UINT16 HobType, IN UINT16 HobLenght)
Definition: Hob.c:101
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID PrintHob(IN CONST VOID *HobStart)
Definition: PrintHob.c:362
EFI_STATUS FixUpPcdDatabase(IN EFI_FIRMWARE_VOLUME_HEADER *DxeFv)
EFI_STATUS BuildHobs(IN UINTN BootloaderParameter, OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv)
VOID AddNewHob(IN EFI_PEI_HOB_POINTERS *Hob)
EFI_HOB_RESOURCE_DESCRIPTOR * FindResourceDescriptorByRange(IN VOID *HobList, IN EFI_PHYSICAL_ADDRESS Base, IN EFI_PHYSICAL_ADDRESS Top)
EFI_STATUS EFIAPI _ModuleEntryPoint(IN UINTN BootloaderParameter)
BOOLEAN IsHobNeed(EFI_PEI_HOB_POINTERS Hob)
EFI_HOB_RESOURCE_DESCRIPTOR * FindAnotherHighestBelow4GResourceDescriptor(IN VOID *HobList, IN UINTN MinimalNeededSize, IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob)
VOID EFIAPI InitializeFloatingPointUnits(VOID)
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:364
EFI_BOOT_MODE BootMode
Definition: PiHob.h:74
EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom
Definition: PiHob.h:92
EFI_PHYSICAL_ADDRESS EfiMemoryTop
Definition: PiHob.h:79
EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop
Definition: PiHob.h:88
EFI_PHYSICAL_ADDRESS EfiMemoryBottom
Definition: PiHob.h:83
EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader
Definition: PiHob.h:207
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:320
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute
Definition: PiHob.h:324