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
))
85 BuildMemoryAllocationHob (Base
, Size
, EfiUnusableMemory
);
86 } else if (MemoryMapEntry
->Type
== E820_PMEM
) {
87 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
))
129 // Skip resources above 4GiB
131 if ((MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
) > 0x100000000ULL
) {
135 if ((MemoryMapEntry
->Type
== E820_RAM
) || (MemoryMapEntry
->Type
== E820_ACPI
) ||
136 (MemoryMapEntry
->Type
== E820_NVS
))
139 // It's usable DRAM. Update TOLUD.
141 if (mTopOfLowerUsableDram
< (MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
)) {
142 mTopOfLowerUsableDram
= (UINT32
)(MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
);
146 // It might be 'reserved DRAM' or 'MMIO'.
148 // If it touches usable DRAM at Base assume it's DRAM as well,
149 // as it could be bootloader installed tables, TSEG, GTT, ...
151 if (mTopOfLowerUsableDram
== MemoryMapEntry
->Base
) {
152 mTopOfLowerUsableDram
= (UINT32
)(MemoryMapEntry
->Base
+ MemoryMapEntry
->Size
);
160 Callback function to build resource descriptor HOB
162 This function build a HOB based on the memory map entry info.
163 Only add EFI_RESOURCE_SYSTEM_MEMORY.
165 @param MemoryMapEntry Memory map entry info got from bootloader.
166 @param Params Not used for now.
168 @retval RETURN_SUCCESS Successfully build a HOB.
172 IN MEMORY_MAP_ENTRY
*MemoryMapEntry
,
176 EFI_PHYSICAL_ADDRESS Base
;
177 EFI_RESOURCE_TYPE Type
;
179 EFI_RESOURCE_ATTRIBUTE_TYPE Attribue
;
182 // Skip everything not known to be usable DRAM.
183 // It will be added later.
185 if ((MemoryMapEntry
->Type
!= E820_RAM
) && (MemoryMapEntry
->Type
!= E820_ACPI
) &&
186 (MemoryMapEntry
->Type
!= E820_NVS
))
188 return RETURN_SUCCESS
;
191 Type
= EFI_RESOURCE_SYSTEM_MEMORY
;
192 Base
= MemoryMapEntry
->Base
;
193 Size
= MemoryMapEntry
->Size
;
195 Attribue
= EFI_RESOURCE_ATTRIBUTE_PRESENT
|
196 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
197 EFI_RESOURCE_ATTRIBUTE_TESTED
|
198 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
199 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
200 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
201 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
;
203 BuildResourceDescriptorHob (Type
, Attribue
, (EFI_PHYSICAL_ADDRESS
)Base
, Size
);
204 DEBUG ((DEBUG_INFO
, "buildhob: base = 0x%lx, size = 0x%lx, type = 0x%x\n", Base
, Size
, Type
));
206 if (MemoryMapEntry
->Type
== E820_ACPI
) {
207 BuildMemoryAllocationHob (Base
, Size
, EfiACPIReclaimMemory
);
208 } else if (MemoryMapEntry
->Type
== E820_NVS
) {
209 BuildMemoryAllocationHob (Base
, Size
, EfiACPIMemoryNVS
);
212 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
)) {
244 DEBUG ((DEBUG_INFO
, "Assuming TOLUD = 0x%x\n", mTopOfLowerUsableDram
));
247 // Parse memory info and build memory HOBs for Usable RAM
249 DEBUG ((DEBUG_INFO
, "Building ResourceDescriptorHobs for usable memory:\n"));
250 Status
= ParseMemoryInfo (MemInfoCallback
, NULL
);
251 if (EFI_ERROR (Status
)) {
256 // Create guid hob for frame buffer information
258 Status
= ParseGfxInfo (&GfxInfo
);
259 if (!EFI_ERROR (Status
)) {
260 NewGfxInfo
= BuildGuidHob (&gEfiGraphicsInfoHobGuid
, sizeof (GfxInfo
));
261 ASSERT (NewGfxInfo
!= NULL
);
262 CopyMem (NewGfxInfo
, &GfxInfo
, sizeof (GfxInfo
));
263 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"));
275 // Creat SmBios table Hob
277 SmBiosTableHob
= BuildGuidHob (&gUniversalPayloadSmbiosTableGuid
, sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE
));
278 ASSERT (SmBiosTableHob
!= NULL
);
279 SmBiosTableHob
->Header
.Revision
= UNIVERSAL_PAYLOAD_SMBIOS_TABLE_REVISION
;
280 SmBiosTableHob
->Header
.Length
= sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE
);
281 DEBUG ((DEBUG_INFO
, "Create smbios table gUniversalPayloadSmbiosTableGuid guid hob\n"));
282 Status
= ParseSmbiosTable (SmBiosTableHob
);
283 if (!EFI_ERROR (Status
)) {
284 DEBUG ((DEBUG_INFO
, "Detected Smbios Table at 0x%lx\n", SmBiosTableHob
->SmBiosEntryPoint
));
288 // Creat ACPI table Hob
290 AcpiTableHob
= BuildGuidHob (&gUniversalPayloadAcpiTableGuid
, sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE
));
291 ASSERT (AcpiTableHob
!= NULL
);
292 AcpiTableHob
->Header
.Revision
= UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION
;
293 AcpiTableHob
->Header
.Length
= sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE
);
294 DEBUG ((DEBUG_INFO
, "Create ACPI table gUniversalPayloadAcpiTableGuid guid hob\n"));
295 Status
= ParseAcpiTableInfo (AcpiTableHob
);
296 if (!EFI_ERROR (Status
)) {
297 DEBUG ((DEBUG_INFO
, "Detected ACPI Table at 0x%lx\n", AcpiTableHob
->Rsdp
));
301 // Create guid hob for acpi board information
303 AcpiBoardInfo
= BuildHobFromAcpi (AcpiTableHob
->Rsdp
);
304 ASSERT (AcpiBoardInfo
!= NULL
);
307 // Parse memory info and build memory HOBs for reserved DRAM and MMIO
309 DEBUG ((DEBUG_INFO
, "Building ResourceDescriptorHobs for reserved memory:\n"));
310 Status
= ParseMemoryInfo (MemInfoCallbackMmio
, AcpiBoardInfo
);
311 if (EFI_ERROR (Status
)) {
316 // Parse the misc info provided by bootloader
318 Status
= ParseMiscInfo ();
319 if (EFI_ERROR (Status
)) {
320 DEBUG ((DEBUG_WARN
, "Error when parsing misc info, Status = %r\n", Status
));
324 // Parse platform specific information.
326 Status
= ParsePlatformInfo ();
327 if (EFI_ERROR (Status
)) {
328 DEBUG ((DEBUG_ERROR
, "Error when parsing platform info, Status = %r\n", Status
));
336 This function will build some generic HOBs that doesn't depend on information from bootloaders.
345 UINT8 PhysicalAddressBits
;
346 EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute
;
348 // The UEFI payload FV
349 BuildMemoryAllocationHob (PcdGet32 (PcdPayloadFdMemBase
), PcdGet32 (PcdPayloadFdMemSize
), EfiBootServicesData
);
352 // Build CPU memory space and IO space hob
354 AsmCpuid (0x80000000, &RegEax
, NULL
, NULL
, NULL
);
355 if (RegEax
>= 0x80000008) {
356 AsmCpuid (0x80000008, &RegEax
, NULL
, NULL
, NULL
);
357 PhysicalAddressBits
= (UINT8
)RegEax
;
359 PhysicalAddressBits
= 36;
362 BuildCpuHob (PhysicalAddressBits
, 16);
365 // Report Local APIC range, cause sbl HOB to be NULL, comment now
367 ResourceAttribute
= (
368 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
369 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
370 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
371 EFI_RESOURCE_ATTRIBUTE_TESTED
373 BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_MAPPED_IO
, ResourceAttribute
, 0xFEC80000, SIZE_512KB
);
374 BuildMemoryAllocationHob (0xFEC80000, SIZE_512KB
, EfiMemoryMappedIO
);
378 Entry point to the C language phase of UEFI payload.
380 @param[in] BootloaderParameter The starting address of bootloader parameter block.
382 @retval It will not return if SUCCESS, and return error when passing bootloader parameter.
387 IN UINTN BootloaderParameter
391 PHYSICAL_ADDRESS DxeCoreEntryPoint
;
395 EFI_PEI_HOB_POINTERS Hob
;
396 SERIAL_PORT_INFO SerialPortInfo
;
397 UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO
*UniversalSerialPort
;
399 Status
= PcdSet64S (PcdBootloaderParameter
, BootloaderParameter
);
400 ASSERT_EFI_ERROR (Status
);
402 // Initialize floating point operating environment to be compliant with UEFI spec.
403 InitializeFloatingPointUnits ();
405 // HOB region is used for HOB and memory allocation for this module
406 MemBase
= PcdGet32 (PcdPayloadFdMemBase
);
407 HobMemBase
= ALIGN_VALUE (MemBase
+ PcdGet32 (PcdPayloadFdMemSize
), SIZE_1MB
);
408 HobMemTop
= HobMemBase
+ FixedPcdGet32 (PcdSystemMemoryUefiRegionSize
);
410 HobConstructor ((VOID
*)MemBase
, (VOID
*)HobMemTop
, (VOID
*)HobMemBase
, (VOID
*)HobMemTop
);
413 // Build serial port info
415 Status
= ParseSerialInfo (&SerialPortInfo
);
416 if (!EFI_ERROR (Status
)) {
417 UniversalSerialPort
= BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid
, sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO
));
418 ASSERT (UniversalSerialPort
!= NULL
);
419 UniversalSerialPort
->Header
.Revision
= UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION
;
420 UniversalSerialPort
->Header
.Length
= sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO
);
421 UniversalSerialPort
->UseMmio
= (SerialPortInfo
.Type
== 1) ? FALSE
: TRUE
;
422 UniversalSerialPort
->RegisterBase
= SerialPortInfo
.BaseAddr
;
423 UniversalSerialPort
->BaudRate
= SerialPortInfo
.Baud
;
424 UniversalSerialPort
->RegisterStride
= (UINT8
)SerialPortInfo
.RegWidth
;
427 // The library constructors might depend on serial port, so call it after serial port hob
428 ProcessLibraryConstructorList ();
429 DEBUG ((DEBUG_INFO
, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN
)));
431 // Build HOB based on information from Bootloader
432 Status
= BuildHobFromBl ();
433 if (EFI_ERROR (Status
)) {
434 DEBUG ((DEBUG_ERROR
, "BuildHobFromBl Status = %r\n", Status
));
438 // Build other HOBs required by DXE
442 Status
= LoadDxeCore (&DxeCoreEntryPoint
);
443 ASSERT_EFI_ERROR (Status
);
445 DEBUG ((DEBUG_INFO
, "DxeCoreEntryPoint = 0x%lx\n", DxeCoreEntryPoint
));
448 // Mask off all legacy 8259 interrupt sources
450 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER
, 0xFF);
451 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE
, 0xFF);
453 Hob
.HandoffInformationTable
= (EFI_HOB_HANDOFF_INFO_TABLE
*)GetFirstHob (EFI_HOB_TYPE_HANDOFF
);
454 HandOffToDxeCore (DxeCoreEntryPoint
, Hob
);
456 // Should not get here