/** @file Copyright (c) 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include #include /** 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; }