3 Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "UefiPayloadEntry.h"
10 STATIC UINT32 mTopOfLowerUsableDram
= 0;
13 Callback function to build resource descriptor HOB
15 This function build a HOB based on the memory map entry info.
16 It creates only EFI_RESOURCE_MEMORY_MAPPED_IO and EFI_RESOURCE_MEMORY_RESERVED
19 @param MemoryMapEntry Memory map entry info got from bootloader.
20 @param Params A pointer to ACPI_BOARD_INFO.
22 @retval EFI_SUCCESS Successfully build a HOB.
23 @retval EFI_INVALID_PARAMETER Invalid parameter provided.
27 IN MEMORY_MAP_ENTRY
*MemoryMapEntry
,
31 EFI_PHYSICAL_ADDRESS Base
;
32 EFI_RESOURCE_TYPE Type
;
34 EFI_RESOURCE_ATTRIBUTE_TYPE Attribue
;
35 ACPI_BOARD_INFO
*AcpiBoardInfo
;
37 AcpiBoardInfo
= (ACPI_BOARD_INFO
*)Params
;
38 if (AcpiBoardInfo
== NULL
) {
39 return EFI_INVALID_PARAMETER
;
43 // Skip types already handled in MemInfoCallback
45 if (MemoryMapEntry
->Type
== E820_RAM
|| MemoryMapEntry
->Type
== E820_ACPI
) {
49 if (MemoryMapEntry
->Base
== AcpiBoardInfo
->PcieBaseAddress
) {
51 // MMCONF is always MMIO
53 Type
= EFI_RESOURCE_MEMORY_MAPPED_IO
;
54 } else if (MemoryMapEntry
->Base
< mTopOfLowerUsableDram
) {
56 // It's in DRAM and thus must be reserved
58 Type
= EFI_RESOURCE_MEMORY_RESERVED
;
59 } else if ((MemoryMapEntry
->Base
< 0x100000000ULL
) && (MemoryMapEntry
->Base
>= mTopOfLowerUsableDram
)) {
61 // It's not in DRAM, must be MMIO
63 Type
= EFI_RESOURCE_MEMORY_MAPPED_IO
;
65 Type
= EFI_RESOURCE_MEMORY_RESERVED
;
68 Base
= MemoryMapEntry
->Base
;
69 Size
= MemoryMapEntry
->Size
;
71 Attribue
= EFI_RESOURCE_ATTRIBUTE_PRESENT
|
72 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
73 EFI_RESOURCE_ATTRIBUTE_TESTED
|
74 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
75 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
76 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
77 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
;
79 BuildResourceDescriptorHob (Type
, Attribue
, (EFI_PHYSICAL_ADDRESS
)Base
, Size
);
80 DEBUG ((DEBUG_INFO
, "buildhob: base = 0x%lx, size = 0x%lx, type = 0x%x\n", Base
, Size
, Type
));
82 if (MemoryMapEntry
->Type
== E820_UNUSABLE
||
83 MemoryMapEntry
->Type
== E820_DISABLED
) {
84 BuildMemoryAllocationHob (Base
, Size
, EfiUnusableMemory
);
85 } else if (MemoryMapEntry
->Type
== E820_PMEM
) {
86 BuildMemoryAllocationHob (Base
, Size
, EfiPersistentMemory
);
94 Callback function to find TOLUD (Top of Lower Usable DRAM)
96 Estimate where TOLUD (Top of Lower Usable DRAM) resides. The exact position
97 would require platform specific code.
99 @param MemoryMapEntry Memory map entry info got from bootloader.
100 @param Params Not used for now.
102 @retval EFI_SUCCESS Successfully updated mTopOfLowerUsableDram.
106 IN MEMORY_MAP_ENTRY
*MemoryMapEntry
,
111 // This code assumes that the memory map on this x86 machine below 4GiB is continous
112 // until TOLUD. In addition it assumes that the bootloader provided memory tables have
113 // no "holes" and thus the first memory range not covered by e820 marks the end of
114 // usable DRAM. In addition it's assumed that every reserved memory region touching
115 // usable RAM is also covering DRAM, everything else that is marked reserved thus must be
116 // MMIO not detectable by bootloader/OS
120 // Skip memory types not RAM or reserved
122 if ((MemoryMapEntry
->Type
== E820_UNUSABLE
) || (MemoryMapEntry
->Type
== E820_DISABLED
) ||
123 (MemoryMapEntry
->Type
== E820_PMEM
)) {
128 // Skip resources above 4GiB
130 if ((MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
) > 0x100000000ULL
) {
134 if ((MemoryMapEntry
->Type
== E820_RAM
) || (MemoryMapEntry
->Type
== E820_ACPI
) ||
135 (MemoryMapEntry
->Type
== E820_NVS
)) {
137 // It's usable DRAM. Update TOLUD.
139 if (mTopOfLowerUsableDram
< (MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
)) {
140 mTopOfLowerUsableDram
= (UINT32
)(MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
);
144 // It might be 'reserved DRAM' or 'MMIO'.
146 // If it touches usable DRAM at Base assume it's DRAM as well,
147 // as it could be bootloader installed tables, TSEG, GTT, ...
149 if (mTopOfLowerUsableDram
== MemoryMapEntry
->Base
) {
150 mTopOfLowerUsableDram
= (UINT32
)(MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
);
159 Callback function to build resource descriptor HOB
161 This function build a HOB based on the memory map entry info.
162 Only add EFI_RESOURCE_SYSTEM_MEMORY.
164 @param MemoryMapEntry Memory map entry info got from bootloader.
165 @param Params Not used for now.
167 @retval RETURN_SUCCESS Successfully build a HOB.
171 IN MEMORY_MAP_ENTRY
*MemoryMapEntry
,
175 EFI_PHYSICAL_ADDRESS Base
;
176 EFI_RESOURCE_TYPE Type
;
178 EFI_RESOURCE_ATTRIBUTE_TYPE Attribue
;
181 // Skip everything not known to be usable DRAM.
182 // It will be added later.
184 if ((MemoryMapEntry
->Type
!= E820_RAM
) && (MemoryMapEntry
->Type
!= E820_ACPI
) &&
185 (MemoryMapEntry
->Type
!= E820_NVS
)) {
186 return RETURN_SUCCESS
;
189 Type
= EFI_RESOURCE_SYSTEM_MEMORY
;
190 Base
= MemoryMapEntry
->Base
;
191 Size
= MemoryMapEntry
->Size
;
193 Attribue
= EFI_RESOURCE_ATTRIBUTE_PRESENT
|
194 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
195 EFI_RESOURCE_ATTRIBUTE_TESTED
|
196 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
197 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
198 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
199 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
;
201 BuildResourceDescriptorHob (Type
, Attribue
, (EFI_PHYSICAL_ADDRESS
)Base
, Size
);
202 DEBUG ((DEBUG_INFO
, "buildhob: base = 0x%lx, size = 0x%lx, type = 0x%x\n", Base
, Size
, Type
));
204 if (MemoryMapEntry
->Type
== E820_ACPI
) {
205 BuildMemoryAllocationHob (Base
, Size
, EfiACPIReclaimMemory
);
206 } else if (MemoryMapEntry
->Type
== E820_NVS
) {
207 BuildMemoryAllocationHob (Base
, Size
, EfiACPIMemoryNVS
);
210 return RETURN_SUCCESS
;
216 It will build HOBs based on information from bootloaders.
218 @retval EFI_SUCCESS If it completed successfully.
219 @retval Others If it failed to build required HOBs.
227 ACPI_BOARD_INFO
*AcpiBoardInfo
;
228 EFI_PEI_GRAPHICS_INFO_HOB GfxInfo
;
229 EFI_PEI_GRAPHICS_INFO_HOB
*NewGfxInfo
;
230 EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo
;
231 EFI_PEI_GRAPHICS_DEVICE_INFO_HOB
*NewGfxDeviceInfo
;
232 UNIVERSAL_PAYLOAD_SMBIOS_TABLE
*SmBiosTableHob
;
233 UNIVERSAL_PAYLOAD_ACPI_TABLE
*AcpiTableHob
;
238 DEBUG ((DEBUG_INFO
, "Guessing Top of Lower Usable DRAM:\n"));
239 Status
= ParseMemoryInfo (FindToludCallback
, NULL
);
240 if (EFI_ERROR(Status
)) {
243 DEBUG ((DEBUG_INFO
, "Assuming TOLUD = 0x%x\n", mTopOfLowerUsableDram
));
246 // Parse memory info and build memory HOBs for Usable RAM
248 DEBUG ((DEBUG_INFO
, "Building ResourceDescriptorHobs for usable memory:\n"));
249 Status
= ParseMemoryInfo (MemInfoCallback
, NULL
);
250 if (EFI_ERROR(Status
)) {
255 // Create guid hob for frame buffer information
257 Status
= ParseGfxInfo (&GfxInfo
);
258 if (!EFI_ERROR (Status
)) {
259 NewGfxInfo
= BuildGuidHob (&gEfiGraphicsInfoHobGuid
, sizeof (GfxInfo
));
260 ASSERT (NewGfxInfo
!= NULL
);
261 CopyMem (NewGfxInfo
, &GfxInfo
, sizeof (GfxInfo
));
262 DEBUG ((DEBUG_INFO
, "Created graphics info hob\n"));
266 Status
= ParseGfxDeviceInfo (&GfxDeviceInfo
);
267 if (!EFI_ERROR (Status
)) {
268 NewGfxDeviceInfo
= BuildGuidHob (&gEfiGraphicsDeviceInfoHobGuid
, sizeof (GfxDeviceInfo
));
269 ASSERT (NewGfxDeviceInfo
!= NULL
);
270 CopyMem (NewGfxDeviceInfo
, &GfxDeviceInfo
, sizeof (GfxDeviceInfo
));
271 DEBUG ((DEBUG_INFO
, "Created graphics device info hob\n"));
276 // Creat SmBios table Hob
278 SmBiosTableHob
= BuildGuidHob (&gUniversalPayloadSmbiosTableGuid
, sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE
));
279 ASSERT (SmBiosTableHob
!= NULL
);
280 SmBiosTableHob
->Header
.Revision
= UNIVERSAL_PAYLOAD_SMBIOS_TABLE_REVISION
;
281 SmBiosTableHob
->Header
.Length
= sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE
);
282 DEBUG ((DEBUG_INFO
, "Create smbios table gUniversalPayloadSmbiosTableGuid guid hob\n"));
283 Status
= ParseSmbiosTable(SmBiosTableHob
);
284 if (!EFI_ERROR (Status
)) {
285 DEBUG ((DEBUG_INFO
, "Detected Smbios Table at 0x%lx\n", SmBiosTableHob
->SmBiosEntryPoint
));
289 // Creat ACPI table Hob
291 AcpiTableHob
= BuildGuidHob (&gUniversalPayloadAcpiTableGuid
, sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE
));
292 ASSERT (AcpiTableHob
!= NULL
);
293 AcpiTableHob
->Header
.Revision
= UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION
;
294 AcpiTableHob
->Header
.Length
= sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE
);
295 DEBUG ((DEBUG_INFO
, "Create ACPI table gUniversalPayloadAcpiTableGuid guid hob\n"));
296 Status
= ParseAcpiTableInfo(AcpiTableHob
);
297 if (!EFI_ERROR (Status
)) {
298 DEBUG ((DEBUG_INFO
, "Detected ACPI Table at 0x%lx\n", AcpiTableHob
->Rsdp
));
302 // Create guid hob for acpi board information
304 AcpiBoardInfo
= BuildHobFromAcpi (AcpiTableHob
->Rsdp
);
305 ASSERT (AcpiBoardInfo
!= NULL
);
308 // Parse memory info and build memory HOBs for reserved DRAM and MMIO
310 DEBUG ((DEBUG_INFO
, "Building ResourceDescriptorHobs for reserved memory:\n"));
311 Status
= ParseMemoryInfo (MemInfoCallbackMmio
, AcpiBoardInfo
);
312 if (EFI_ERROR(Status
)) {
317 // Parse the misc info provided by bootloader
319 Status
= ParseMiscInfo ();
320 if (EFI_ERROR (Status
)) {
321 DEBUG ((DEBUG_WARN
, "Error when parsing misc info, Status = %r\n", Status
));
325 // Parse platform specific information.
327 Status
= ParsePlatformInfo ();
328 if (EFI_ERROR (Status
)) {
329 DEBUG ((DEBUG_ERROR
, "Error when parsing platform info, Status = %r\n", Status
));
338 This function will build some generic HOBs that doesn't depend on information from bootloaders.
347 UINT8 PhysicalAddressBits
;
348 EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute
;
350 // The UEFI payload FV
351 BuildMemoryAllocationHob (PcdGet32 (PcdPayloadFdMemBase
), PcdGet32 (PcdPayloadFdMemSize
), EfiBootServicesData
);
354 // Build CPU memory space and IO space hob
356 AsmCpuid (0x80000000, &RegEax
, NULL
, NULL
, NULL
);
357 if (RegEax
>= 0x80000008) {
358 AsmCpuid (0x80000008, &RegEax
, NULL
, NULL
, NULL
);
359 PhysicalAddressBits
= (UINT8
) RegEax
;
361 PhysicalAddressBits
= 36;
364 BuildCpuHob (PhysicalAddressBits
, 16);
367 // Report Local APIC range, cause sbl HOB to be NULL, comment now
369 ResourceAttribute
= (
370 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
371 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
372 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
373 EFI_RESOURCE_ATTRIBUTE_TESTED
375 BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_MAPPED_IO
, ResourceAttribute
, 0xFEC80000, SIZE_512KB
);
376 BuildMemoryAllocationHob ( 0xFEC80000, SIZE_512KB
, EfiMemoryMappedIO
);
382 Entry point to the C language phase of UEFI payload.
384 @param[in] BootloaderParameter The starting address of bootloader parameter block.
386 @retval It will not return if SUCCESS, and return error when passing bootloader parameter.
391 IN UINTN BootloaderParameter
395 PHYSICAL_ADDRESS DxeCoreEntryPoint
;
399 EFI_PEI_HOB_POINTERS Hob
;
400 SERIAL_PORT_INFO SerialPortInfo
;
401 UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO
*UniversalSerialPort
;
403 Status
= PcdSet64S (PcdBootloaderParameter
, BootloaderParameter
);
404 ASSERT_EFI_ERROR (Status
);
406 // Initialize floating point operating environment to be compliant with UEFI spec.
407 InitializeFloatingPointUnits ();
409 // HOB region is used for HOB and memory allocation for this module
410 MemBase
= PcdGet32 (PcdPayloadFdMemBase
);
411 HobMemBase
= ALIGN_VALUE (MemBase
+ PcdGet32 (PcdPayloadFdMemSize
), SIZE_1MB
);
412 HobMemTop
= HobMemBase
+ FixedPcdGet32 (PcdSystemMemoryUefiRegionSize
);
414 HobConstructor ((VOID
*)MemBase
, (VOID
*)HobMemTop
, (VOID
*)HobMemBase
, (VOID
*)HobMemTop
);
417 // Build serial port info
419 Status
= ParseSerialInfo (&SerialPortInfo
);
420 if (!EFI_ERROR (Status
)) {
421 UniversalSerialPort
= BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid
, sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO
));
422 ASSERT (UniversalSerialPort
!= NULL
);
423 UniversalSerialPort
->Header
.Revision
= UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION
;
424 UniversalSerialPort
->Header
.Length
= sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO
);
425 UniversalSerialPort
->UseMmio
= (SerialPortInfo
.Type
== 1)?FALSE
:TRUE
;
426 UniversalSerialPort
->RegisterBase
= SerialPortInfo
.BaseAddr
;
427 UniversalSerialPort
->BaudRate
= SerialPortInfo
.Baud
;
428 UniversalSerialPort
->RegisterStride
= (UINT8
)SerialPortInfo
.RegWidth
;
431 // The library constructors might depend on serial port, so call it after serial port hob
432 ProcessLibraryConstructorList ();
433 DEBUG ((DEBUG_INFO
, "sizeof(UINTN) = 0x%x\n", sizeof(UINTN
)));
435 // Build HOB based on information from Bootloader
436 Status
= BuildHobFromBl ();
437 if (EFI_ERROR (Status
)) {
438 DEBUG ((DEBUG_ERROR
, "BuildHobFromBl Status = %r\n", Status
));
442 // Build other HOBs required by DXE
446 Status
= LoadDxeCore (&DxeCoreEntryPoint
);
447 ASSERT_EFI_ERROR (Status
);
449 DEBUG ((DEBUG_INFO
, "DxeCoreEntryPoint = 0x%lx\n", DxeCoreEntryPoint
));
452 // Mask off all legacy 8259 interrupt sources
454 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER
, 0xFF);
455 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE
, 0xFF);
457 Hob
.HandoffInformationTable
= (EFI_HOB_HANDOFF_INFO_TABLE
*) GetFirstHob(EFI_HOB_TYPE_HANDOFF
);
458 HandOffToDxeCore (DxeCoreEntryPoint
, Hob
);
460 // Should not get here