audk/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c

169 lines
4.9 KiB
C

/** @file
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <Pi/PiHob.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PrintLib.h>
#include <Library/FdtLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
/**
Add a new HOB to the HOB List.
@param HobType Type of the new HOB.
@param HobLength Length of the new HOB to allocate.
@return NULL if there is no space to create a hob.
@return The address point to the new created hob.
**/
VOID *
EFIAPI
CreateHob (
IN UINT16 HobType,
IN UINT16 HobLength
);
/**
Add HOB into HOB list
@param[in] Hob The HOB to be added into the HOB list.
**/
VOID
AddNewHob (
IN EFI_PEI_HOB_POINTERS *Hob
);
/**
Check the HOB and decide if it is need inside Payload
Payload maintainer may make decision which HOB is need or needn't
Then add the check logic in the function.
@param[in] Hob The HOB to check
@retval TRUE If HOB is need inside Payload
@retval FALSE If HOB is needn't inside Payload
**/
BOOLEAN
EFIAPI
FitIsHobNeed (
EFI_PEI_HOB_POINTERS Hob
)
{
if (FixedPcdGetBool (PcdHandOffFdtEnable)) {
if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
return FALSE;
}
if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gUniversalPayloadDeviceTreeGuid)) {
return FALSE;
}
if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
return FALSE;
}
if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiReservedMemoryType) ||
(Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiBootServicesCode) ||
(Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiBootServicesData) ||
(Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiRuntimeServicesCode) ||
(Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiRuntimeServicesData) ||
(Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiACPIReclaimMemory) ||
(Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiACPIMemoryNVS))
{
return FALSE;
}
}
if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
return FALSE;
}
}
if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadSmbios3TableGuid)) {
return FALSE;
}
if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadSerialPortInfoGuid)) {
return FALSE;
}
if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadAcpiTableGuid)) {
return FALSE;
}
if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadPciRootBridgeInfoGuid)) {
return FALSE;
}
}
}
// Arrive here mean the HOB is need
return TRUE;
}
/**
It will Parse FDT -custom node based on information from bootloaders.
@param[in] FdtBase The starting memory address of FdtBase
@param[in] HobList The starting memory address of New Hob list.
**/
UINTN
EFIAPI
CustomFdtNodeParser (
IN VOID *FdtBase,
IN VOID *HobList
)
{
INT32 Node, CustomNode;
INT32 TempLen;
UINT64 *Data64;
UINTN CHobList;
CONST FDT_PROPERTY *PropertyPtr;
EFI_PEI_HOB_POINTERS Hob;
CHobList = (UINTN)HobList;
DEBUG ((DEBUG_INFO, "%a() #1 \n", __func__));
//
// Look for if exists hob list node
//
Node = FdtSubnodeOffsetNameLen (FdtBase, 0, "options", (INT32)AsciiStrLen ("options"));
if (Node > 0) {
DEBUG ((DEBUG_INFO, " Found options node (%08X)", Node));
CustomNode = FdtSubnodeOffsetNameLen (FdtBase, Node, "upl-custom", (INT32)AsciiStrLen ("upl-custom"));
if (CustomNode > 0) {
DEBUG ((DEBUG_INFO, " Found upl-custom node (%08X)", CustomNode));
PropertyPtr = FdtGetProperty (FdtBase, CustomNode, "hoblistptr", &TempLen);
Data64 = (UINT64 *)(PropertyPtr->Data);
CHobList = (UINTN)Fdt64ToCpu (ReadUnaligned64 (Data64));
DEBUG ((DEBUG_INFO, " Found hob list node (%08X)", CustomNode));
DEBUG ((DEBUG_INFO, " -pointer %016lX\n", CHobList));
}
}
Hob.Raw = (UINT8 *)CHobList;
//
// Since payload created new Hob, move all hobs except PHIT from boot loader hob list.
//
while (!END_OF_HOB_LIST (Hob)) {
if (FitIsHobNeed (Hob)) {
// Add this hob to payload HOB
AddNewHob (&Hob);
}
Hob.Raw = GET_NEXT_HOB (Hob);
}
return CHobList;
}