mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 07:34:13 +00:00 
			
		
		
		
	OvmfPkg/PlatformInitLib: Add PlatformAddHobCB
Add PlatformAddHobCB() callback function for use with PlatformScanE820(). It adds HOBs for high memory and reservations (low memory is handled elsewhere because there are some special cases to consider). This replaces calls to PlatformScanOrAdd64BitE820Ram() with AddHighHobs = TRUE. Write any actions done (adding HOBs, skip unknown types) to the firmware log with INFO loglevel. Also remove PlatformScanOrAdd64BitE820Ram() which is not used any more. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
		
							parent
							
								
									124b765051
								
							
						
					
					
						commit
						328076cfdf
					
				@ -112,143 +112,6 @@ PlatformQemuUc32BaseInitialization (
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Iterate over the RAM entries in QEMU's fw_cfg E820 RAM map that start outside
 | 
			
		||||
  of the 32-bit address range.
 | 
			
		||||
 | 
			
		||||
  Find the highest exclusive >=4GB RAM address, or produce memory resource
 | 
			
		||||
  descriptor HOBs for RAM entries that start at or above 4GB.
 | 
			
		||||
 | 
			
		||||
  @param[out] MaxAddress  If MaxAddress is NULL, then PlatformScanOrAdd64BitE820Ram()
 | 
			
		||||
                          produces memory resource descriptor HOBs for RAM
 | 
			
		||||
                          entries that start at or above 4GB.
 | 
			
		||||
 | 
			
		||||
                          Otherwise, MaxAddress holds the highest exclusive
 | 
			
		||||
                          >=4GB RAM address on output. If QEMU's fw_cfg E820
 | 
			
		||||
                          RAM map contains no RAM entry that starts outside of
 | 
			
		||||
                          the 32-bit address range, then MaxAddress is exactly
 | 
			
		||||
                          4GB on output.
 | 
			
		||||
 | 
			
		||||
  @retval EFI_SUCCESS         The fw_cfg E820 RAM map was found and processed.
 | 
			
		||||
 | 
			
		||||
  @retval EFI_PROTOCOL_ERROR  The RAM map was found, but its size wasn't a
 | 
			
		||||
                              whole multiple of sizeof(EFI_E820_ENTRY64). No
 | 
			
		||||
                              RAM entry was processed.
 | 
			
		||||
 | 
			
		||||
  @return                     Error codes from QemuFwCfgFindFile(). No RAM
 | 
			
		||||
                              entry was processed.
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
EFI_STATUS
 | 
			
		||||
PlatformScanOrAdd64BitE820Ram (
 | 
			
		||||
  IN BOOLEAN  AddHighHob,
 | 
			
		||||
  OUT UINT64  *LowMemory OPTIONAL,
 | 
			
		||||
  OUT UINT64  *MaxAddress OPTIONAL
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  EFI_STATUS            Status;
 | 
			
		||||
  FIRMWARE_CONFIG_ITEM  FwCfgItem;
 | 
			
		||||
  UINTN                 FwCfgSize;
 | 
			
		||||
  EFI_E820_ENTRY64      E820Entry;
 | 
			
		||||
  UINTN                 Processed;
 | 
			
		||||
 | 
			
		||||
  Status = QemuFwCfgFindFile ("etc/e820", &FwCfgItem, &FwCfgSize);
 | 
			
		||||
  if (EFI_ERROR (Status)) {
 | 
			
		||||
    return Status;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (FwCfgSize % sizeof E820Entry != 0) {
 | 
			
		||||
    return EFI_PROTOCOL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (LowMemory != NULL) {
 | 
			
		||||
    *LowMemory = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (MaxAddress != NULL) {
 | 
			
		||||
    *MaxAddress = BASE_4GB;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QemuFwCfgSelectItem (FwCfgItem);
 | 
			
		||||
  for (Processed = 0; Processed < FwCfgSize; Processed += sizeof E820Entry) {
 | 
			
		||||
    QemuFwCfgReadBytes (sizeof E820Entry, &E820Entry);
 | 
			
		||||
    DEBUG ((
 | 
			
		||||
      DEBUG_VERBOSE,
 | 
			
		||||
      "%a: Base=0x%Lx Length=0x%Lx Type=%u\n",
 | 
			
		||||
      __FUNCTION__,
 | 
			
		||||
      E820Entry.BaseAddr,
 | 
			
		||||
      E820Entry.Length,
 | 
			
		||||
      E820Entry.Type
 | 
			
		||||
      ));
 | 
			
		||||
    if (E820Entry.Type == EfiAcpiAddressRangeMemory) {
 | 
			
		||||
      if (AddHighHob && (E820Entry.BaseAddr >= BASE_4GB)) {
 | 
			
		||||
        UINT64  Base;
 | 
			
		||||
        UINT64  End;
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // Round up the start address, and round down the end address.
 | 
			
		||||
        //
 | 
			
		||||
        Base = ALIGN_VALUE (E820Entry.BaseAddr, (UINT64)EFI_PAGE_SIZE);
 | 
			
		||||
        End  = (E820Entry.BaseAddr + E820Entry.Length) &
 | 
			
		||||
               ~(UINT64)EFI_PAGE_MASK;
 | 
			
		||||
        if (Base < End) {
 | 
			
		||||
          PlatformAddMemoryRangeHob (Base, End);
 | 
			
		||||
          DEBUG ((
 | 
			
		||||
            DEBUG_VERBOSE,
 | 
			
		||||
            "%a: PlatformAddMemoryRangeHob [0x%Lx, 0x%Lx)\n",
 | 
			
		||||
            __FUNCTION__,
 | 
			
		||||
            Base,
 | 
			
		||||
            End
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (MaxAddress || LowMemory) {
 | 
			
		||||
        UINT64  Candidate;
 | 
			
		||||
 | 
			
		||||
        Candidate = E820Entry.BaseAddr + E820Entry.Length;
 | 
			
		||||
        if (MaxAddress && (Candidate > *MaxAddress)) {
 | 
			
		||||
          *MaxAddress = Candidate;
 | 
			
		||||
          DEBUG ((
 | 
			
		||||
            DEBUG_VERBOSE,
 | 
			
		||||
            "%a: MaxAddress=0x%Lx\n",
 | 
			
		||||
            __FUNCTION__,
 | 
			
		||||
            *MaxAddress
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (LowMemory && (Candidate > *LowMemory) && (Candidate < BASE_4GB)) {
 | 
			
		||||
          *LowMemory = Candidate;
 | 
			
		||||
          DEBUG ((
 | 
			
		||||
            DEBUG_VERBOSE,
 | 
			
		||||
            "%a: LowMemory=0x%Lx\n",
 | 
			
		||||
            __FUNCTION__,
 | 
			
		||||
            *LowMemory
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else if (E820Entry.Type == EfiAcpiAddressRangeReserved) {
 | 
			
		||||
      if (AddHighHob) {
 | 
			
		||||
        DEBUG ((
 | 
			
		||||
          DEBUG_INFO,
 | 
			
		||||
          "%a: Reserved: Base=0x%Lx Length=0x%Lx\n",
 | 
			
		||||
          __FUNCTION__,
 | 
			
		||||
          E820Entry.BaseAddr,
 | 
			
		||||
          E820Entry.Length
 | 
			
		||||
          ));
 | 
			
		||||
        BuildResourceDescriptorHob (
 | 
			
		||||
          EFI_RESOURCE_MEMORY_RESERVED,
 | 
			
		||||
          0,
 | 
			
		||||
          E820Entry.BaseAddr,
 | 
			
		||||
          E820Entry.Length
 | 
			
		||||
          );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef VOID (*E820_SCAN_CALLBACK) (
 | 
			
		||||
  EFI_E820_ENTRY64       *E820Entry,
 | 
			
		||||
  EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
 | 
			
		||||
@ -306,6 +169,53 @@ PlatformGetLowMemoryCB (
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Create HOBs for reservations and RAM (except low memory).
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
VOID
 | 
			
		||||
PlatformAddHobCB (
 | 
			
		||||
  IN     EFI_E820_ENTRY64       *E820Entry,
 | 
			
		||||
  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINT64  Base, End;
 | 
			
		||||
 | 
			
		||||
  Base = E820Entry->BaseAddr;
 | 
			
		||||
  End  = E820Entry->BaseAddr + E820Entry->Length;
 | 
			
		||||
 | 
			
		||||
  switch (E820Entry->Type) {
 | 
			
		||||
    case EfiAcpiAddressRangeMemory:
 | 
			
		||||
      if (Base >= BASE_4GB) {
 | 
			
		||||
        //
 | 
			
		||||
        // Round up the start address, and round down the end address.
 | 
			
		||||
        //
 | 
			
		||||
        Base = ALIGN_VALUE (Base, (UINT64)EFI_PAGE_SIZE);
 | 
			
		||||
        End  = End & ~(UINT64)EFI_PAGE_MASK;
 | 
			
		||||
        if (Base < End) {
 | 
			
		||||
          DEBUG ((DEBUG_INFO, "%a: HighMemory [0x%Lx, 0x%Lx)\n", __FUNCTION__, Base, End));
 | 
			
		||||
          PlatformAddMemoryRangeHob (Base, End);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      break;
 | 
			
		||||
    case EfiAcpiAddressRangeReserved:
 | 
			
		||||
      BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_RESERVED, 0, Base, End);
 | 
			
		||||
      DEBUG ((DEBUG_INFO, "%a: Reserved [0x%Lx, 0x%Lx)\n", __FUNCTION__, Base, End));
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      DEBUG ((
 | 
			
		||||
        DEBUG_WARN,
 | 
			
		||||
        "%a: Type %u [0x%Lx, 0x%Lx) (NOT HANDLED)\n",
 | 
			
		||||
        __FUNCTION__,
 | 
			
		||||
        E820Entry->Type,
 | 
			
		||||
        Base,
 | 
			
		||||
        End
 | 
			
		||||
        ));
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Iterate over the entries in QEMU's fw_cfg E820 RAM map, call the
 | 
			
		||||
  passed callback for each entry.
 | 
			
		||||
@ -1051,7 +961,7 @@ PlatformQemuInitializeRam (
 | 
			
		||||
    // entries. Otherwise, create a single memory HOB with the flat >=4GB
 | 
			
		||||
    // memory size read from the CMOS.
 | 
			
		||||
    //
 | 
			
		||||
    Status = PlatformScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
 | 
			
		||||
    Status = PlatformScanE820 (PlatformAddHobCB, PlatformInfoHob);
 | 
			
		||||
    if (EFI_ERROR (Status)) {
 | 
			
		||||
      UpperMemorySize = PlatformGetSystemMemorySizeAbove4gb ();
 | 
			
		||||
      if (UpperMemorySize != 0) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user