diff options
-rw-r--r-- | UefiPayloadPkg/Library/CbParseLib/CbParseLib.c | 9 | ||||
-rw-r--r-- | UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c | 119 |
2 files changed, 117 insertions, 11 deletions
diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c index 9e14953..03b6431 100644 --- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -400,15 +400,6 @@ ParseMemoryInfo ( MemoryMap.Size = cb_unpack64 (Range->size);
MemoryMap.Type = (UINT8)Range->type;
MemoryMap.Flag = 0;
- DEBUG ((
- DEBUG_INFO,
- "%d. %016lx - %016lx [%02x]\n",
- Index,
- MemoryMap.Base,
- MemoryMap.Base + MemoryMap.Size - 1,
- MemoryMap.Type
- ));
-
MemInfoCallback (&MemoryMap, Params);
}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c index 939873d..2ecea0c 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c @@ -168,6 +168,108 @@ FindToludCallback ( }
/**
+ Callback function to find free and usable DRAM for HOB
+ The memory region returned will have at least PcdSystemMemoryUefiRegionSize bytes
+ and will be aligned to 1 MiB.
+
+ The caller must initialize HobMemBase to zero.
+
+ @param MemoryMapEntry Memory map entry info got from bootloader.
+ @param Params Pointer to HobMemBase
+
+ @retval EFI_SUCCESS Continue walking the memory map
+ @retval EFI_ALREADY_STARTED HobMemBase is not zero
+
+**/
+EFI_STATUS
+FindFreeMemForHobCallback (
+ IN MEMORY_MAP_ENTRY *MemoryMapEntry,
+ IN VOID *Params
+ )
+{
+ EFI_STATUS Status;
+ MEMORY_MAP_ENTRY MemoryMapEntrySplit;
+ UINTN *HobMemBase = (UINTN *)Params;
+
+ //
+ // Found new base, nothing to do
+ //
+ if (*HobMemBase != 0) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Skip memory types not RAM
+ //
+ if (MemoryMapEntry->Type != E820_RAM) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Align on 1 MiB
+ //
+ if (ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) > MemoryMapEntry->Base) {
+ //
+ // Skip too small
+ //
+ if (ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) >= (MemoryMapEntry->Base + MemoryMapEntry->Size)) {
+ return EFI_SUCCESS;
+ }
+
+ MemoryMapEntry->Size -= ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) - MemoryMapEntry->Base;
+ MemoryMapEntry->Base = ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB);
+ }
+
+ //
+ // Skip resources above 4GiB on x86_32
+ //
+ if ((sizeof (UINTN) == 4) && (MemoryMapEntry->Base >= 0x100000000ULL)) {
+ return EFI_SUCCESS;
+ }
+
+ if ((sizeof (UINTN) == 4) && ((MemoryMapEntry->Base + MemoryMapEntry->Size) > 0x100000000ULL)) {
+ MemoryMapEntry->Size = 0x100000000ULL - MemoryMapEntry->Base;
+ }
+
+ //
+ // Skip too small
+ //
+ if (MemoryMapEntry->Size < FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Overlaps UefiPayload, split into smaller chunks
+ //
+ if ((MemoryMapEntry->Base <= PcdGet32 (PcdPayloadFdMemBase)) &&
+ ((MemoryMapEntry->Base + MemoryMapEntry->Size) >= PcdGet32 (PcdPayloadFdMemBase)))
+ {
+ MemoryMapEntrySplit.Type = E820_RAM;
+ MemoryMapEntrySplit.Base = MemoryMapEntry->Base;
+ MemoryMapEntrySplit.Size = PcdGet32 (PcdPayloadFdMemBase) - MemoryMapEntrySplit.Base;
+ Status = FindFreeMemForHobCallback (&MemoryMapEntrySplit, Params);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((MemoryMapEntry->Base + MemoryMapEntry->Size) > (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize))) {
+ MemoryMapEntrySplit.Base = PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize);
+ MemoryMapEntrySplit.Size = (MemoryMapEntry->Base + MemoryMapEntry->Size) - MemoryMapEntrySplit.Base;
+ Status = FindFreeMemForHobCallback (&MemoryMapEntrySplit, Params);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ *HobMemBase = MemoryMapEntry->Base;
+
+ return EFI_ALREADY_STARTED;
+}
+
+/**
Callback function to build resource descriptor HOB
This function build a HOB based on the memory map entry info.
@@ -404,8 +506,19 @@ _ModuleEntryPoint ( // HOB region is used for HOB and memory allocation for this module
MemBase = PcdGet32 (PcdPayloadFdMemBase);
- HobMemBase = ALIGN_VALUE (MemBase + PcdGet32 (PcdPayloadFdMemSize), SIZE_1MB);
- HobMemTop = HobMemBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+ HobMemBase = 0;
+
+ //
+ // Find a good place for HOB and memory allocation
+ //
+ ParseMemoryInfo (FindFreeMemForHobCallback, &HobMemBase);
+
+ ASSERT (HobMemBase != 0);
+ if (HobMemBase == 0) {
+ HobMemBase = ALIGN_VALUE (MemBase + PcdGet32 (PcdPayloadFdMemSize), SIZE_1MB);
+ }
+
+ HobMemTop = HobMemBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
HobConstructor ((VOID *)MemBase, (VOID *)HobMemTop, (VOID *)HobMemBase, (VOID *)HobMemTop);
@@ -435,6 +548,8 @@ _ModuleEntryPoint ( // The library constructors might depend on serial port, so call it after serial port hob
ProcessLibraryConstructorList ();
DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN)));
+ DEBUG ((DEBUG_INFO, "MemBase = 0x%llx\n", (UINT64)MemBase));
+ DEBUG ((DEBUG_INFO, "HobMemBase = 0x%llx\n", (UINT64)HobMemBase));
// Build HOB based on information from Bootloader
Status = BuildHobFromBl ();
|