mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
UefiPayloadPkg: Add FDT Paser relative LIBs.
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4786 Add FDTParser and CustomFdtNodePaser to retrive all FDT node and create the relate hobs. Signed-off-by: Linus Liu <linus.liu@intel.com>
This commit is contained in:
parent
a297b81b62
commit
b0c6b049c4
65
UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf
Normal file
65
UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf
Normal file
@ -0,0 +1,65 @@
|
||||
## @file
|
||||
# Flat Device Tree Table Build Library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = BuildFdtLib
|
||||
FILE_GUID = 5DA69A29-C990-49EE-A4E6-BA5311A1ADAF
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = BuildFdtLib
|
||||
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
X86_BuildFdtLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
UefiPayloadPkg/UefiPayloadPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
PcdLib
|
||||
HobLib
|
||||
FdtLib
|
||||
|
||||
[Guids]
|
||||
gUniversalPayloadDeviceTreeGuid
|
||||
gEfiGraphicsInfoHobGuid
|
||||
gEfiGraphicsDeviceInfoHobGuid
|
||||
gUniversalPayloadAcpiTableGuid
|
||||
gUniversalPayloadSerialPortInfoGuid
|
||||
gEfiHobMemoryAllocModuleGuid
|
||||
gEfiHobMemoryAllocStackGuid
|
||||
gEfiHobMemoryAllocBspStoreGuid
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio
|
||||
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
|
||||
|
||||
[Ppis]
|
||||
gEdkiiPeiPciDevicePpiGuid ## CONSUMES
|
||||
|
||||
[BuildOptions]
|
||||
MSFT:*_*_*_CC_FLAGS = /wd4305
|
||||
GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
945
UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c
Normal file
945
UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c
Normal file
@ -0,0 +1,945 @@
|
||||
/** @file
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <IndustryStandard/Pci22.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/FdtLib.h>
|
||||
#include <Library/PciLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <UniversalPayload/UniversalPayload.h>
|
||||
#include <UniversalPayload/AcpiTable.h>
|
||||
#include <UniversalPayload/SerialPortInfo.h>
|
||||
#include <UniversalPayload/PciRootBridges.h>
|
||||
#include <Guid/GraphicsInfoHob.h>
|
||||
#include <Guid/UniversalPayloadSerialPortDeviceParentInfo.h>
|
||||
#include <Guid/UniversalPayloadBase.h>
|
||||
#include <Protocol/PciRootBridgeIo.h>
|
||||
#include <Ppi/PciDevice.h>
|
||||
|
||||
#define IGD_BUS_NUM 0x00
|
||||
#define IGD_DEV_NUM 0x02
|
||||
#define IGD_FUN_NUM 0x00
|
||||
|
||||
EDKII_PCI_DEVICE_PPI *mPciDevicePpi;
|
||||
BOOLEAN mResourceAssigned;
|
||||
|
||||
CHAR8 *mMemoryAllocType[] = {
|
||||
"Reserved",
|
||||
"LoaderCode",
|
||||
"LoaderData",
|
||||
"boot-code",
|
||||
"boot-data",
|
||||
"runtime-code",
|
||||
"runtime-data",
|
||||
"ConventionalMemory",
|
||||
"UnusableMemory",
|
||||
"acpi",
|
||||
"acpi-nvs",
|
||||
"mmio",
|
||||
"MemoryMappedIOPortSpace",
|
||||
"PalCode",
|
||||
"PersistentMemory",
|
||||
};
|
||||
|
||||
/**
|
||||
The wrapper function of PeiServicesLocatePpi() for gEdkiiPeiPciDevicePpiGuid
|
||||
and Save the PPI to mPciDevicePpi.
|
||||
@retval EFI_SUCCESS If it locate gEdkiiPeiPciDevicePpiGuid successfully.
|
||||
@retval EFI_NOT_FOUND If it can't find gEdkiiPeiPciDevicePpiGuid.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
LocatePciDevicePpi (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
|
||||
|
||||
mPciDevicePpi = NULL;
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEdkiiPeiPciDevicePpiGuid,
|
||||
0,
|
||||
&PpiDescriptor,
|
||||
(void **)&mPciDevicePpi
|
||||
);
|
||||
if (EFI_ERROR (Status) || (mPciDevicePpi == NULL)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT based on memory information from Hobs.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForMemory (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_HOB_POINTERS Hob;
|
||||
EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
|
||||
VOID *HobStart;
|
||||
VOID *Fdt;
|
||||
INT32 TempNode;
|
||||
CHAR8 TempStr[32];
|
||||
UINT64 RegTmp[2];
|
||||
|
||||
Fdt = FdtBase;
|
||||
|
||||
HobStart = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
|
||||
//
|
||||
// Scan resource descriptor hobs to set memory nodes
|
||||
//
|
||||
for (Hob.Raw = HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
|
||||
if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
|
||||
ResourceHob = Hob.ResourceDescriptor;
|
||||
// Memory
|
||||
if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
|
||||
// DEBUG ((DEBUG_ERROR, "Found hob for memory: base %016lX length %016lX\n", ResourceHob->PhysicalStart, ResourceHob->ResourceLength));
|
||||
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "memory@%lX", ResourceHob->PhysicalStart);
|
||||
TempNode = FdtAddSubnode (Fdt, 0, TempStr);
|
||||
ASSERT (TempNode > 0);
|
||||
|
||||
RegTmp[0] = CpuToFdt64 (ResourceHob->PhysicalStart);
|
||||
RegTmp[1] = CpuToFdt64 (ResourceHob->ResourceLength);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg", &RegTmp, sizeof (RegTmp));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "device_type", "memory", (UINT32)(AsciiStrLen ("memory")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT based on memory allocation information from Hobs.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForMemAlloc (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_HOB_POINTERS Hob;
|
||||
VOID *HobStart;
|
||||
VOID *Fdt;
|
||||
INT32 ParentNode;
|
||||
INT32 TempNode;
|
||||
CHAR8 TempStr[32];
|
||||
UINT64 RegTmp[2];
|
||||
UINT32 AllocMemType;
|
||||
EFI_GUID *AllocMemName;
|
||||
UINT8 IsStackHob;
|
||||
UINT8 IsBspStore;
|
||||
UINT32 Data32;
|
||||
|
||||
Fdt = FdtBase;
|
||||
|
||||
ParentNode = FdtAddSubnode (Fdt, 0, "reserved-memory");
|
||||
ASSERT (ParentNode > 0);
|
||||
|
||||
Data32 = CpuToFdt32 (2);
|
||||
Status = FdtSetProp (Fdt, ParentNode, "#address-cells", &Data32, sizeof (UINT32));
|
||||
Status = FdtSetProp (Fdt, ParentNode, "#size-cells", &Data32, sizeof (UINT32));
|
||||
|
||||
HobStart = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
|
||||
//
|
||||
// Scan memory allocation hobs to set memory type
|
||||
//
|
||||
for (Hob.Raw = HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
|
||||
if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
|
||||
AllocMemName = NULL;
|
||||
IsStackHob = 0;
|
||||
IsBspStore = 0;
|
||||
if (CompareGuid (&(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid)) {
|
||||
continue;
|
||||
} else if (IsZeroGuid (&(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name)) == FALSE) {
|
||||
AllocMemName = &(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name);
|
||||
|
||||
if (CompareGuid (AllocMemName, &gEfiHobMemoryAllocStackGuid)) {
|
||||
IsStackHob = 1;
|
||||
} else if (CompareGuid (AllocMemName, &gEfiHobMemoryAllocBspStoreGuid)) {
|
||||
IsBspStore = 1;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_ERROR,
|
||||
"Found hob for rsvd memory alloc: base %016lX length %016lX type %x\n",
|
||||
Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
|
||||
Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
|
||||
Hob.MemoryAllocation->AllocDescriptor.MemoryType
|
||||
));
|
||||
|
||||
AllocMemType = Hob.MemoryAllocation->AllocDescriptor.MemoryType;
|
||||
if (IsStackHob == 1) {
|
||||
Status = AsciiSPrint (
|
||||
TempStr,
|
||||
sizeof (TempStr),
|
||||
"%a@%lX",
|
||||
"stackhob",
|
||||
Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
|
||||
);
|
||||
} else if (IsBspStore == 1) {
|
||||
Status = AsciiSPrint (
|
||||
TempStr,
|
||||
sizeof (TempStr),
|
||||
"%a@%lX",
|
||||
"bspstore",
|
||||
Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
|
||||
);
|
||||
} else {
|
||||
Status = AsciiSPrint (
|
||||
TempStr,
|
||||
sizeof (TempStr),
|
||||
"%a@%lX",
|
||||
mMemoryAllocType[AllocMemType],
|
||||
Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
|
||||
);
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (mMemoryAllocType[AllocMemType], "ConventionalMemory") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (mMemoryAllocType[AllocMemType], "mmio") == 0) {
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "mmio@%lX", Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress);
|
||||
} else {
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "memory@%lX", Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress);
|
||||
}
|
||||
|
||||
TempNode = FdtAddSubnode (Fdt, ParentNode, TempStr);
|
||||
DEBUG ((DEBUG_INFO, "FdtAddSubnode %x", TempNode));
|
||||
if (TempNode < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RegTmp[0] = CpuToFdt64 (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress);
|
||||
RegTmp[1] = CpuToFdt64 (Hob.MemoryAllocation->AllocDescriptor.MemoryLength);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg", &RegTmp, sizeof (RegTmp));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (!(AsciiStrCmp (mMemoryAllocType[AllocMemType], "mmio") == 0)) {
|
||||
Status = FdtSetProp (Fdt, TempNode, "compatible", mMemoryAllocType[AllocMemType], (UINT32)(AsciiStrLen (mMemoryAllocType[AllocMemType])+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT based on serial information.
|
||||
@param[in] ISANode ISANode.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForSerial (
|
||||
IN INT32 ISANode,
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Fdt;
|
||||
INT32 TempNode;
|
||||
UINT64 RegisterBase;
|
||||
CHAR8 TempStr[32];
|
||||
UINT32 RegData[3];
|
||||
UINT32 Data32;
|
||||
UINT64 Data64;
|
||||
|
||||
Fdt = FdtBase;
|
||||
RegisterBase = 0;
|
||||
|
||||
//
|
||||
// Create SerialPortInfo FDT node.
|
||||
//
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "serial@%lX", (RegisterBase == 0) ? PcdGet64 (PcdSerialRegisterBase) : RegisterBase);
|
||||
TempNode = FdtAddSubnode (Fdt, ISANode, TempStr);
|
||||
ASSERT (TempNode > 0);
|
||||
|
||||
Data32 = CpuToFdt32 (PcdGet32 (PcdSerialBaudRate));
|
||||
Status = FdtSetProp (Fdt, TempNode, "current-speed", &Data32, sizeof (Data32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (PcdGetBool (PcdSerialUseMmio)) {
|
||||
Data32 = 0;
|
||||
RegData[0] = CpuToFdt32 (Data32);
|
||||
} else {
|
||||
Data32 = 1;
|
||||
RegData[0] = CpuToFdt32 (Data32);
|
||||
}
|
||||
|
||||
Data64 = (RegisterBase == 0) ? PcdGet64 (PcdSerialRegisterBase) : RegisterBase;
|
||||
Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
|
||||
RegData[1] = CpuToFdt32 (Data32);
|
||||
RegData[2] = CpuToFdt32 (8);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Data32 = CpuToFdt32 (1);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg-io-width", &Data32, sizeof (Data32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "compatible", "isa", (UINT32)(AsciiStrLen ("isa")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT based on serial information.
|
||||
|
||||
@param[in] ISANode ISANode.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForSerialLpss (
|
||||
IN INT32 ISANode,
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
EFI_STATUS Status;
|
||||
UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *SerialPortInfo;
|
||||
VOID *Fdt;
|
||||
INT32 TempNode;
|
||||
UINT32 Data32;
|
||||
UINT32 RegData[2];
|
||||
CHAR8 TempStr[32];
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
SerialPortInfo = NULL;
|
||||
Fdt = FdtBase;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "BuildFdtForSerialLpss start \n"));
|
||||
GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid);
|
||||
while (GuidHob != NULL) {
|
||||
SerialPortInfo = (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *)GET_GUID_HOB_DATA (GuidHob);
|
||||
|
||||
if (!SerialPortInfo->UseMmio) {
|
||||
GuidHob = GET_NEXT_HOB (GuidHob);
|
||||
GuidHob = GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob);
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "Create SerialPortInfo LPSS FDT node \n"));
|
||||
//
|
||||
// Create SerialPortInfo FDT node.
|
||||
//
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "serial@%lX", SerialPortInfo->RegisterBase);
|
||||
TempNode = FdtAddSubnode (Fdt, ISANode, TempStr);
|
||||
ASSERT (TempNode > 0);
|
||||
|
||||
Data32 = CpuToFdt32 (SerialPortInfo->BaudRate);
|
||||
Status = FdtSetProp (Fdt, TempNode, "current-speed", &Data32, sizeof (Data32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
RegData[0] = CpuToFdt32 ((UINT32)SerialPortInfo->RegisterBase);
|
||||
RegData[1] = CpuToFdt32 (0x80);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Data32 = CpuToFdt32 (4);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg-io-width", &Data32, sizeof (Data32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "compatible", "ns16550a", (UINT32)(AsciiStrLen ("ns16550a")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
GuidHob = GET_NEXT_HOB (GuidHob);
|
||||
GuidHob = GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT based on BuildFdtForPciRootBridge information.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForPciRootBridge (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Fdt;
|
||||
INT32 TempNode;
|
||||
INT32 GmaNode;
|
||||
INT32 eSPINode;
|
||||
CHAR8 TempStr[32];
|
||||
CHAR8 GmaStr[32];
|
||||
CHAR8 eSPIStr[32];
|
||||
UINT32 RegTmp[2];
|
||||
UINT32 RegData[21];
|
||||
UINT32 DMARegData[8];
|
||||
UINT32 Data32;
|
||||
UINT64 Data64;
|
||||
UINT8 BusNumber;
|
||||
UINT8 BusLimit;
|
||||
UINT8 BusBase;
|
||||
UINT8 DevBase;
|
||||
UINT8 FunBase;
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
|
||||
UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
|
||||
UINT8 Index;
|
||||
PCI_TYPE00 PciData;
|
||||
UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO *SerialParent;
|
||||
|
||||
Fdt = FdtBase;
|
||||
BusNumber = 0;
|
||||
BusLimit = 0;
|
||||
BusBase = 0x80;
|
||||
DevBase = 0x31;
|
||||
FunBase = 0;
|
||||
Status = EFI_SUCCESS;
|
||||
PciRootBridgeInfo = NULL;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "%a: #1 \n", __func__));
|
||||
//
|
||||
// Create BuildFdtForPciRootBridge FDT node.
|
||||
//
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid);
|
||||
if (GuidHob != NULL) {
|
||||
GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
|
||||
if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) <= GET_GUID_HOB_DATA_SIZE (GuidHob)) && (GenericHeader->Length <= GET_GUID_HOB_DATA_SIZE (GuidHob))) {
|
||||
if ((GenericHeader->Revision == UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) && (GenericHeader->Length >= sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) {
|
||||
DEBUG ((DEBUG_INFO, "%a: #2 \n", __func__));
|
||||
|
||||
//
|
||||
// UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION
|
||||
//
|
||||
PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortParentDeviceInfoGuid);
|
||||
if (GuidHob != NULL) {
|
||||
SerialParent = (UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO *)GET_GUID_HOB_DATA (GuidHob);
|
||||
BusBase = (SerialParent->ParentDevicePcieBaseAddress >> 20) & 0xFF;
|
||||
DevBase = (SerialParent->ParentDevicePcieBaseAddress >> 15) & 0x1F;
|
||||
FunBase = (SerialParent->ParentDevicePcieBaseAddress >> 12) & 0x07;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridgeInfo->Count %x\n", PciRootBridgeInfo->Count));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Segment %x, \n", PciRootBridgeInfo->RootBridge[0].Segment));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, \n", PciRootBridgeInfo->RootBridge[0].Bus.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, \n", PciRootBridgeInfo->RootBridge[0].Bus.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", PciRootBridgeInfo->RootBridge[0].Mem.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", PciRootBridgeInfo->RootBridge[0].Mem.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", PciRootBridgeInfo->RootBridge[0].MemAbove4G.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", PciRootBridgeInfo->RootBridge[0].MemAbove4G.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.Base %llx, \n", PciRootBridgeInfo->RootBridge[0].PMem.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.limit %llx, \n", PciRootBridgeInfo->RootBridge[0].PMem.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, \n", PciRootBridgeInfo->RootBridge[1].Bus.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, \n", PciRootBridgeInfo->RootBridge[1].Bus.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", PciRootBridgeInfo->RootBridge[1].Mem.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", PciRootBridgeInfo->RootBridge[1].Mem.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", PciRootBridgeInfo->RootBridge[1].MemAbove4G.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", PciRootBridgeInfo->RootBridge[1].MemAbove4G.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.Base %x, \n", PciRootBridgeInfo->RootBridge[1].PMem.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.limit %x, \n", PciRootBridgeInfo->RootBridge[1].PMem.Limit));
|
||||
|
||||
if (PciRootBridgeInfo != NULL) {
|
||||
for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) {
|
||||
UINTN PciExpressBaseAddress;
|
||||
|
||||
mResourceAssigned = PciRootBridgeInfo->ResourceAssigned;
|
||||
PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress) + (PCI_LIB_ADDRESS (PciRootBridgeInfo->RootBridge[Index].Bus.Base, 0, 0, 0));
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "pci-rb%d@%lX", Index, PciExpressBaseAddress);
|
||||
TempNode = FdtAddSubnode (Fdt, 0, TempStr);
|
||||
ASSERT (TempNode > 0);
|
||||
SetMem (RegData, sizeof (RegData), 0);
|
||||
|
||||
// non-reloc/non-prefetch/mmio, child-addr, parent-addr, length
|
||||
Data32 = (N_NON_RELOCATABLE + SS_32BIT_MEMORY_SPACE);
|
||||
RegData[0] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[0] %x, \n", Data32));
|
||||
|
||||
// child-addr
|
||||
RegData[1] = CpuToFdt32 (0);
|
||||
Data32 = (UINT32)PciRootBridgeInfo->RootBridge[Index].Mem.Base;
|
||||
RegData[2] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[2] %x, \n", Data32));
|
||||
|
||||
// parent-addr
|
||||
RegData[3] = CpuToFdt32 (0);
|
||||
RegData[4] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[4] %x, \n", Data32));
|
||||
|
||||
// size
|
||||
Data64 = (PciRootBridgeInfo->RootBridge[Index].Mem.Limit - PciRootBridgeInfo->RootBridge[Index].Mem.Base + 1);
|
||||
if (Data64 & 0xFFFFFFFF00000000) {
|
||||
Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 31);
|
||||
} else {
|
||||
Data32 = 0;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.size RegData[5] %x, \n", Data32));
|
||||
RegData[5] = CpuToFdt32 (Data32);
|
||||
Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.size RegData[6] %x, \n", Data32));
|
||||
|
||||
RegData[6] = CpuToFdt32 (Data32);
|
||||
|
||||
// non-reloc/non-prefetch/64 mmio, child-addr, parent-addr, length
|
||||
Data32 = (N_NON_RELOCATABLE + SS_64BIT_MEMORY_SPACE);
|
||||
RegData[7] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[7] %x, \n", Data32));
|
||||
|
||||
// child-addr
|
||||
Data64 = PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Base;
|
||||
Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32);
|
||||
|
||||
RegData[8] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[8] %x, \n", Data32));
|
||||
Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
|
||||
RegData[9] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[9] %x, \n", Data32));
|
||||
|
||||
// parent-addr
|
||||
RegData[10] = RegData[8];
|
||||
RegData[11] = RegData[9];
|
||||
|
||||
// size
|
||||
Data64 = (PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Limit - PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Base + 1);
|
||||
if (Data64 & 0xFFFFFFFF00000000) {
|
||||
Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32);
|
||||
} else {
|
||||
Data32 = 0;
|
||||
}
|
||||
|
||||
RegData[12] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.size RegData[12] %x, \n", Data32));
|
||||
|
||||
Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
|
||||
RegData[13] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.size RegData[13] %x, \n", Data32));
|
||||
|
||||
// non-reloc/32bit/io, child-addr, parent-addr, length
|
||||
Data32 = (N_NON_RELOCATABLE + SS_IO_SPACE);
|
||||
|
||||
RegData[14] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base RegData[14] %x, \n", Data32));
|
||||
|
||||
Data32 = (UINT32)PciRootBridgeInfo->RootBridge[Index].Io.Base;
|
||||
// child-addr
|
||||
RegData[15] = CpuToFdt32 (0);
|
||||
RegData[16] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base RegData[16] %x, \n", Data32));
|
||||
|
||||
// parent-addr
|
||||
RegData[17] = CpuToFdt32 (0);
|
||||
RegData[18] = CpuToFdt32 (Data32);
|
||||
// size
|
||||
Data64 = (PciRootBridgeInfo->RootBridge[Index].Io.Limit - PciRootBridgeInfo->RootBridge[Index].Io.Base + 1);
|
||||
if (Data64 & 0xFFFFFFFF00000000) {
|
||||
Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32);
|
||||
} else {
|
||||
Data32 = 0;
|
||||
}
|
||||
|
||||
RegData[19] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base size [19] %x, \n", Data32));
|
||||
|
||||
Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
|
||||
RegData[20] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base size [20] %x, \n", Data32));
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "ranges", &RegData, sizeof (RegData));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// non-reloc/non-prefetch/memory, child-addr, parent-addr, length
|
||||
// indicate rb1 does not support above 4GB DMA
|
||||
Data32 = (N_NON_RELOCATABLE + SS_32BIT_MEMORY_SPACE);
|
||||
|
||||
DMARegData[0] = CpuToFdt32 (Data32);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->DMA base RegData[0] %x, \n", Data32));
|
||||
|
||||
// child-addr
|
||||
DMARegData[2] = CpuToFdt32 (0);
|
||||
DMARegData[3] = CpuToFdt32 (0);
|
||||
// parent-addr
|
||||
DMARegData[4] = CpuToFdt32 (0);
|
||||
DMARegData[5] = CpuToFdt32 (0);
|
||||
// size
|
||||
DMARegData[6] = CpuToFdt32 (1);
|
||||
DMARegData[7] = CpuToFdt32 (0);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "dma-ranges", &DMARegData, sizeof (DMARegData));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Data32 = CpuToFdt32 (2);
|
||||
Status = FdtSetProp (Fdt, TempNode, "#size-cells", &Data32, sizeof (UINT32));
|
||||
|
||||
Data32 = CpuToFdt32 (3);
|
||||
Status = FdtSetProp (Fdt, TempNode, "#address-cells", &Data32, sizeof (UINT32));
|
||||
|
||||
BusNumber = PciRootBridgeInfo->RootBridge[Index].Bus.Base & 0xFF;
|
||||
RegTmp[0] = CpuToFdt32 (BusNumber);
|
||||
BusLimit = PciRootBridgeInfo->RootBridge[Index].Bus.Limit & 0xFF;
|
||||
RegTmp[1] = CpuToFdt32 (BusLimit);
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->BusNumber %x, \n", BusNumber));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->BusLimit %x, \n", BusLimit));
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "bus-range", &RegTmp, sizeof (RegTmp));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "compatible", "pci-rb", (UINT32)(AsciiStrLen ("pci-rb")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (Index == 0) {
|
||||
PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress) + (PCI_LIB_ADDRESS (IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0));
|
||||
Status = AsciiSPrint (GmaStr, sizeof (GmaStr), "gma@%lX", PciExpressBaseAddress);
|
||||
GmaNode = FdtAddSubnode (Fdt, TempNode, GmaStr);
|
||||
Status = LocatePciDevicePpi ();
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = mPciDevicePpi->PciIo.Pci.Read (
|
||||
&mPciDevicePpi->PciIo,
|
||||
(EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
|
||||
PCI_VENDOR_ID_OFFSET,
|
||||
sizeof (PciData.Hdr.VendorId),
|
||||
&(PciData.Hdr.VendorId)
|
||||
);
|
||||
|
||||
Status = mPciDevicePpi->PciIo.Pci.Read (
|
||||
&mPciDevicePpi->PciIo,
|
||||
(EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
|
||||
PCI_DEVICE_ID_OFFSET,
|
||||
sizeof (PciData.Hdr.DeviceId),
|
||||
&(PciData.Hdr.DeviceId)
|
||||
);
|
||||
|
||||
Status = mPciDevicePpi->PciIo.Pci.Read (
|
||||
&mPciDevicePpi->PciIo,
|
||||
(EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint8,
|
||||
PCI_REVISION_ID_OFFSET,
|
||||
sizeof (PciData.Hdr.RevisionID),
|
||||
&(PciData.Hdr.RevisionID)
|
||||
);
|
||||
|
||||
Status = mPciDevicePpi->PciIo.Pci.Read (
|
||||
&mPciDevicePpi->PciIo,
|
||||
(EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
|
||||
PCI_SVID_OFFSET,
|
||||
sizeof (PciData.Device.SubsystemVendorID),
|
||||
&(PciData.Device.SubsystemVendorID)
|
||||
);
|
||||
|
||||
Status = mPciDevicePpi->PciIo.Pci.Read (
|
||||
&mPciDevicePpi->PciIo,
|
||||
(EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
|
||||
PCI_SID_OFFSET,
|
||||
sizeof (PciData.Device.SubsystemID),
|
||||
&(PciData.Device.SubsystemID)
|
||||
);
|
||||
}
|
||||
|
||||
Data32 = CpuToFdt32 (PciData.Device.SubsystemID);
|
||||
Status = FdtSetProp (Fdt, GmaNode, "subsystem-id", &Data32, sizeof (UINT32));
|
||||
|
||||
Data32 = CpuToFdt32 (PciData.Device.SubsystemVendorID);
|
||||
Status = FdtSetProp (Fdt, GmaNode, "subsystem-vendor-id", &Data32, sizeof (UINT32));
|
||||
|
||||
Data32 = CpuToFdt32 (PciData.Hdr.RevisionID);
|
||||
Status = FdtSetProp (Fdt, GmaNode, "revision-id", &Data32, sizeof (UINT32));
|
||||
|
||||
Data32 = CpuToFdt32 (PciData.Hdr.DeviceId);
|
||||
Status = FdtSetProp (Fdt, GmaNode, "device-id", &Data32, sizeof (UINT32));
|
||||
|
||||
Data32 = CpuToFdt32 (PciData.Hdr.VendorId);
|
||||
Status = FdtSetProp (Fdt, GmaNode, "vendor-id", &Data32, sizeof (UINT32));
|
||||
}
|
||||
|
||||
if (SerialParent != NULL) {
|
||||
DEBUG ((DEBUG_INFO, "SerialParent->IsIsaCompatible :%x , SerialParent->ParentDevicePcieBaseAddress :%x\n", SerialParent->IsIsaCompatible, SerialParent->ParentDevicePcieBaseAddress));
|
||||
DEBUG ((DEBUG_INFO, "BusBase :%x , PciRootBridgeInfo->RootBridge[Index].Bus.Base :%x\n", BusBase, PciRootBridgeInfo->RootBridge[Index].Bus.Base));
|
||||
}
|
||||
|
||||
{
|
||||
if ((BusBase >= PciRootBridgeInfo->RootBridge[Index].Bus.Base) && (BusBase <= PciRootBridgeInfo->RootBridge[Index].Bus.Limit)) {
|
||||
eSPINode = TempNode;
|
||||
if (SerialParent != NULL) {
|
||||
if (SerialParent->IsIsaCompatible) {
|
||||
Status = AsciiSPrint (eSPIStr, sizeof (eSPIStr), "isa@%X,%X", DevBase, FunBase);
|
||||
eSPINode = FdtAddSubnode (Fdt, TempNode, eSPIStr);
|
||||
Status = FdtSetProp (Fdt, eSPINode, "compatible", "isa", (UINT32)(AsciiStrLen ("isa")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
Data32 = CpuToFdt32 (1);
|
||||
Status = FdtSetProp (Fdt, eSPINode, "#size-cells", &Data32, sizeof (UINT32));
|
||||
Data32 = CpuToFdt32 (2);
|
||||
Status = FdtSetProp (Fdt, eSPINode, "#address-cells", &Data32, sizeof (UINT32));
|
||||
Status = BuildFdtForSerial (eSPINode, FdtBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
} else {
|
||||
Status = BuildFdtForSerialLpss (eSPINode, FdtBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "%a: #3 \n", __func__));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT based on FrameBuffer.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForFrameBuffer (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Fdt;
|
||||
INT32 TempNode;
|
||||
UINT32 Data32;
|
||||
CHAR8 TempStr[32];
|
||||
UINT64 RegData[2];
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo;
|
||||
|
||||
Fdt = FdtBase;
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid);
|
||||
if (GuidHob != NULL) {
|
||||
GraphicsInfo = (EFI_PEI_GRAPHICS_INFO_HOB *)(GET_GUID_HOB_DATA (GuidHob));
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "framebuffer@%lX", GraphicsInfo->FrameBufferBase);
|
||||
TempNode = FdtAddSubnode (Fdt, 0, TempStr);
|
||||
ASSERT (TempNode > 0);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "display", "&gma", (UINT32)(AsciiStrLen ("&gma")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "format", "a8r8g8b8", (UINT32)(AsciiStrLen ("a8r8g8b8")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Data32 = CpuToFdt32 (GraphicsInfo->GraphicsMode.VerticalResolution);
|
||||
Status = FdtSetProp (Fdt, TempNode, "height", &Data32, sizeof (UINT32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Data32 = CpuToFdt32 (GraphicsInfo->GraphicsMode.HorizontalResolution);
|
||||
Status = FdtSetProp (Fdt, TempNode, "width", &Data32, sizeof (UINT32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
RegData[0] = CpuToFdt64 (GraphicsInfo->FrameBufferBase);
|
||||
RegData[1] = CpuToFdt64 (GraphicsInfo->FrameBufferSize);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "compatible", "simple-framebuffer", (UINT32)(AsciiStrLen ("simple-framebuffer")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
} else {
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "framebuffer@%lX", 0xB0000000);
|
||||
TempNode = FdtAddSubnode (Fdt, 0, TempStr);
|
||||
ASSERT (TempNode > 0);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "display", "&gma", (UINT32)(AsciiStrLen ("&gma")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "format", "a8r8g8b8", (UINT32)(AsciiStrLen ("a8r8g8b8")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Data32 = CpuToFdt32 (1024);
|
||||
Status = FdtSetProp (Fdt, TempNode, "height", &Data32, sizeof (UINT32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Data32 = CpuToFdt32 (1280);
|
||||
Status = FdtSetProp (Fdt, TempNode, "width", &Data32, sizeof (UINT32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
RegData[0] = CpuToFdt64 (0xB0000000);
|
||||
RegData[1] = CpuToFdt64 (0x500000);
|
||||
Status = FdtSetProp (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, TempNode, "compatible", "simple-framebuffer", (UINT32)(AsciiStrLen ("simple-framebuffer")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT for UPL required data.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForUplRequired (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Fdt;
|
||||
VOID *Fit;
|
||||
INT32 ParentNode;
|
||||
INT32 CustomNode;
|
||||
INT32 UPLParaNode;
|
||||
INT32 UPLImageNode;
|
||||
EFI_HOB_CPU *CpuHob;
|
||||
UINT64 Data64;
|
||||
UINT32 Data32;
|
||||
VOID *HobPtr;
|
||||
EFI_BOOT_MODE BootMode;
|
||||
CHAR8 TempStr[32];
|
||||
UINT8 *GuidHob;
|
||||
UNIVERSAL_PAYLOAD_BASE *PayloadBase;
|
||||
|
||||
Fdt = FdtBase;
|
||||
Fit = NULL;
|
||||
|
||||
//
|
||||
// Create Hob list FDT node.
|
||||
//
|
||||
ParentNode = FdtAddSubnode (Fdt, 0, "options");
|
||||
ASSERT (ParentNode > 0);
|
||||
|
||||
UPLParaNode = FdtAddSubnode (Fdt, ParentNode, "upl-params");
|
||||
ASSERT (UPLParaNode > 0);
|
||||
|
||||
//
|
||||
// Create CPU info FDT node
|
||||
//
|
||||
CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU);
|
||||
ASSERT (CpuHob != NULL);
|
||||
|
||||
if (mResourceAssigned) {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "pci-enum-done", NULL, 0);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
BootMode = GetBootModeHob ();
|
||||
|
||||
Data32 = CpuToFdt32 ((UINT32)CpuHob->SizeOfMemorySpace);
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "addr-width", &Data32, sizeof (Data32));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (BootMode == BOOT_WITH_FULL_CONFIGURATION) {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "normal", (UINT32)(AsciiStrLen ("normal")+1));
|
||||
} else if (BootMode == BOOT_WITH_MINIMAL_CONFIGURATION) {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "fast", (UINT32)(AsciiStrLen ("fast")+1));
|
||||
} else if (BootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS) {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "full", (UINT32)(AsciiStrLen ("full")+1));
|
||||
} else if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "default", (UINT32)(AsciiStrLen ("default")+1));
|
||||
} else if (BootMode == BOOT_ON_S4_RESUME) {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "s4", (UINT32)(AsciiStrLen ("s4")+1));
|
||||
} else if (BootMode == BOOT_ON_S3_RESUME) {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "s3", (UINT32)(AsciiStrLen ("s3")+1));
|
||||
} else {
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "boot-mode", "na", (UINT32)(AsciiStrLen ("na")+1));
|
||||
}
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FdtSetProp (Fdt, UPLParaNode, "compatible", "upl", (UINT32)(AsciiStrLen ("upl")+1));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gUniversalPayloadBaseGuid);
|
||||
if (GuidHob != NULL) {
|
||||
PayloadBase = (UNIVERSAL_PAYLOAD_BASE *)GET_GUID_HOB_DATA (GuidHob);
|
||||
Fit = (VOID *)(UINTN)PayloadBase->Entry;
|
||||
DEBUG ((DEBUG_INFO, "PayloadBase Entry = 0x%08x\n", PayloadBase->Entry));
|
||||
|
||||
Status = AsciiSPrint (TempStr, sizeof (TempStr), "upl-images@%lX", (UINTN)(Fit));
|
||||
UPLImageNode = FdtAddSubnode (Fdt, ParentNode, TempStr);
|
||||
|
||||
Data64 = CpuToFdt64 ((UINTN)Fit);
|
||||
Status = FdtSetProp (FdtBase, UPLImageNode, "addr", &Data64, sizeof (Data64));
|
||||
}
|
||||
|
||||
CustomNode = FdtAddSubnode (Fdt, ParentNode, "upl-custom");
|
||||
ASSERT (CustomNode > 0);
|
||||
|
||||
HobPtr = GetHobList ();
|
||||
Data64 = CpuToFdt64 ((UINT64)(EFI_PHYSICAL_ADDRESS)HobPtr);
|
||||
Status = FdtSetProp (Fdt, CustomNode, "hoblistptr", &Data64, sizeof (Data64));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
It will build FDT for UPL consumed.
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to build required FDT.
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildFdtForUPL (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Build FDT for memory related
|
||||
//
|
||||
Status = BuildFdtForMemory (FdtBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = BuildFdtForMemAlloc (FdtBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = BuildFdtForPciRootBridge (FdtBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = BuildFdtForFrameBuffer (FdtBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = BuildFdtForUplRequired (FdtBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
/** @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, &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 (*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;
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
## @file
|
||||
# Custom FDT Node Parse Library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = CustomFdtNodeParserLib
|
||||
FILE_GUID = 732B2B8F-65AD-4BF8-A98F-6E0D330F7A60
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = CustomFdtNodeParserLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
CustomFdtNodeParserLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
UefiPayloadPkg/UefiPayloadPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
FdtLib
|
||||
HobLib
|
||||
PcdLib
|
||||
|
||||
[Guids]
|
||||
gUniversalPayloadPciRootBridgeInfoGuid
|
||||
gUniversalPayloadSerialPortInfoGuid
|
||||
gUniversalPayloadDeviceTreeGuid
|
||||
gUniversalPayloadAcpiTableGuid
|
||||
gEfiHobMemoryAllocModuleGuid
|
||||
|
||||
[Pcd]
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
|
@ -0,0 +1,46 @@
|
||||
/** @file
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
#include <PiPei.h>
|
||||
#include <Pi/PiHob.h>
|
||||
|
||||
/**
|
||||
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
|
||||
FitIsHobNeed (
|
||||
EFI_PEI_HOB_POINTERS Hob
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
@retval HobList The base address of Hoblist.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
CustomFdtNodeParser (
|
||||
IN VOID *Fdt,
|
||||
IN VOID *HobList
|
||||
)
|
||||
{
|
||||
UINTN CHobList;
|
||||
|
||||
CHobList = 0;
|
||||
if (HobList != NULL) {
|
||||
CHobList = (UINTN)HobList;
|
||||
}
|
||||
|
||||
return CHobList;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
## @file
|
||||
# Custom FDT Node Parse Library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = CustomFdtNodeParserLibNull
|
||||
FILE_GUID = 386496E4-37DB-4531-BA0C-16D126E63C55
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = CustomFdtNodeParserLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
CustomFdtNodeParserNullLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
64
UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
Normal file
64
UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
Normal file
@ -0,0 +1,64 @@
|
||||
## @file
|
||||
# Coreboot Table Parse Library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = FdtParseLib
|
||||
FILE_GUID = 8956F72D-9626-4959-98B7-1BD4A3EA687E
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = FdtParseLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
FdtParserLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
UefiPayloadPkg/UefiPayloadPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
PcdLib
|
||||
HobLib
|
||||
FdtLib
|
||||
CustomFdtNodeParserLib
|
||||
|
||||
[Guids]
|
||||
gUniversalPayloadDeviceTreeGuid
|
||||
gEfiGraphicsInfoHobGuid
|
||||
gEfiGraphicsDeviceInfoHobGuid
|
||||
gUniversalPayloadAcpiTableGuid
|
||||
gUniversalPayloadSerialPortInfoGuid
|
||||
|
||||
[Pcd.IA32,Pcd.X64]
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemBase
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemLimit
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBBase
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBLimit
|
||||
gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace
|
||||
|
||||
|
||||
[BuildOptions]
|
||||
MSFT:*_*_*_CC_FLAGS = /wd4305
|
||||
GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
||||
GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
|
944
UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
Normal file
944
UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
Normal file
@ -0,0 +1,944 @@
|
||||
/** @file
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Guid/MemoryAllocationHob.h>
|
||||
#include <Guid/DebugPrintErrorLevel.h>
|
||||
#include <Guid/SerialPortInfoGuid.h>
|
||||
#include <Guid/MemoryMapInfoGuid.h>
|
||||
#include <Guid/AcpiBoardInfoGuid.h>
|
||||
#include <Guid/GraphicsInfoHob.h>
|
||||
#include <Guid/UniversalPayloadBase.h>
|
||||
#include <UniversalPayload/SmbiosTable.h>
|
||||
#include <UniversalPayload/AcpiTable.h>
|
||||
#include <UniversalPayload/UniversalPayload.h>
|
||||
#include <UniversalPayload/ExtraData.h>
|
||||
#include <UniversalPayload/SerialPortInfo.h>
|
||||
#include <UniversalPayload/DeviceTree.h>
|
||||
#include <UniversalPayload/PciRootBridges.h>
|
||||
#include <IndustryStandard/SmBios.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/FdtLib.h>
|
||||
#include <Protocol/PciHostBridgeResourceAllocation.h>
|
||||
#include <Protocol/PciIo.h>
|
||||
|
||||
typedef enum {
|
||||
ReservedMemory = 1,
|
||||
Memory,
|
||||
FrameBuffer,
|
||||
PciRootBridge,
|
||||
Options,
|
||||
DoNothing
|
||||
} FDT_NODE_TYPE;
|
||||
|
||||
#define MEMORY_ATTRIBUTE_DEFAULT (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
|
||||
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_TESTED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | \
|
||||
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | \
|
||||
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \
|
||||
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE )
|
||||
|
||||
#define ROOT_BRIDGE_SUPPORTS_DEFAULT (EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \
|
||||
EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | \
|
||||
EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 | \
|
||||
EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | \
|
||||
EFI_PCI_IO_ATTRIBUTE_VGA_IO | \
|
||||
EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \
|
||||
EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | \
|
||||
EFI_PCI_IO_ATTRIBUTE_ISA_IO | \
|
||||
EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO )
|
||||
|
||||
extern VOID *mHobList;
|
||||
UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *mPciRootBridgeInfo = NULL;
|
||||
INT32 mNode[0x500] = { 0 };
|
||||
UINT32 mNodeIndex = 0;
|
||||
|
||||
/**
|
||||
Build a Handoff Information Table HOB
|
||||
|
||||
This function initialize a HOB region from EfiMemoryBegin to
|
||||
EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
|
||||
be inside the HOB region.
|
||||
|
||||
@param[in] EfiMemoryBottom Total memory start address
|
||||
@param[in] EfiMemoryTop Total memory end address.
|
||||
@param[in] EfiFreeMemoryBottom Free memory start address
|
||||
@param[in] EfiFreeMemoryTop Free memory end address.
|
||||
|
||||
@return The pointer to the handoff HOB table.
|
||||
|
||||
**/
|
||||
EFI_HOB_HANDOFF_INFO_TABLE *
|
||||
EFIAPI
|
||||
HobConstructor (
|
||||
IN VOID *EfiMemoryBottom,
|
||||
IN VOID *EfiMemoryTop,
|
||||
IN VOID *EfiFreeMemoryBottom,
|
||||
IN VOID *EfiFreeMemoryTop
|
||||
);
|
||||
|
||||
/**
|
||||
It will record the memory node initialized.
|
||||
|
||||
@param[in] Node memory node is going to parsing..
|
||||
**/
|
||||
VOID
|
||||
RecordMemoryNode (
|
||||
INT32 Node
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_INFO, "\n RecordMemoryNode %x , mNodeIndex :%x \n", Node, mNodeIndex));
|
||||
mNode[mNodeIndex] = Node;
|
||||
mNodeIndex++;
|
||||
}
|
||||
|
||||
/**
|
||||
Check the memory node if initialized.
|
||||
|
||||
@param[in] Node memory node is going to parsing..
|
||||
|
||||
@return TRUE memory node was initialized. don't parse it again.
|
||||
@return FALSE memory node wasn't initialized , go to parse it.
|
||||
**/
|
||||
BOOLEAN
|
||||
CheckMemoryNodeIfInit (
|
||||
INT32 Node
|
||||
)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i < mNodeIndex; i++) {
|
||||
if (mNode[i] == Node) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
It will check device node from FDT.
|
||||
|
||||
@param[in] NodeString Device node name string.
|
||||
@param[in] Depth Check layer of Device node , only parse the 1st layer
|
||||
|
||||
@return FDT_NODE_TYPE what type of the device node.
|
||||
**/
|
||||
FDT_NODE_TYPE
|
||||
CheckNodeType (
|
||||
CHAR8 *NodeString,
|
||||
INT32 Depth
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_INFO, "\n CheckNodeType %a \n", NodeString));
|
||||
if (AsciiStrnCmp (NodeString, "reserved-memory", AsciiStrLen ("reserved-memory")) == 0 ) {
|
||||
return ReservedMemory;
|
||||
} else if (AsciiStrnCmp (NodeString, "memory@", AsciiStrLen ("memory@")) == 0 ) {
|
||||
return Memory;
|
||||
} else if (AsciiStrnCmp (NodeString, "framebuffer@", AsciiStrLen ("framebuffer@")) == 0) {
|
||||
return FrameBuffer;
|
||||
} else if (AsciiStrnCmp (NodeString, "pci-rb", AsciiStrLen ("pci-rb")) == 0 ) {
|
||||
return PciRootBridge;
|
||||
} else if (AsciiStrCmp (NodeString, "options") == 0) {
|
||||
return Options;
|
||||
} else {
|
||||
return DoNothing;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
It will ParseMemory node from FDT.
|
||||
|
||||
@param[in] Fdt Address of the Fdt data.
|
||||
@param[in] SubNode first node of the PCI root bridge node.
|
||||
**/
|
||||
VOID
|
||||
ParseMemory (
|
||||
IN VOID *Fdt,
|
||||
IN INT32 Node
|
||||
)
|
||||
{
|
||||
UINT32 Attribute;
|
||||
UINT8 ECCAttribute;
|
||||
UINT32 ECCData, ECCData2;
|
||||
INT32 Property;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
INT32 TempLen;
|
||||
CONST CHAR8 *TempStr;
|
||||
UINT64 *Data64;
|
||||
UINT32 *Data32;
|
||||
UINT64 StartAddress;
|
||||
UINT64 NumberOfBytes;
|
||||
|
||||
Attribute = MEMORY_ATTRIBUTE_DEFAULT;
|
||||
ECCAttribute = 0;
|
||||
ECCData = ECCData2 = 0;
|
||||
for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
|
||||
PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
|
||||
TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
|
||||
if (AsciiStrCmp (TempStr, "reg") == 0) {
|
||||
Data64 = (UINT64 *)(PropertyPtr->Data);
|
||||
StartAddress = Fdt64ToCpu (*Data64);
|
||||
NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
|
||||
} else if (AsciiStrCmp (TempStr, "ecc-detection-bits") == 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
ECCData = Fdt32ToCpu (*Data32);
|
||||
} else if (AsciiStrCmp (TempStr, "ecc-correction-bits") == 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
ECCData2 = Fdt32ToCpu (*Data32);
|
||||
}
|
||||
}
|
||||
|
||||
if (ECCData == ECCData2) {
|
||||
if (ECCData == 1) {
|
||||
ECCAttribute = EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC;
|
||||
} else if (ECCData == 2) {
|
||||
ECCAttribute = EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC;
|
||||
}
|
||||
}
|
||||
|
||||
if (ECCAttribute != 0) {
|
||||
Attribute |= ECCAttribute;
|
||||
}
|
||||
|
||||
BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attribute, StartAddress, NumberOfBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
It will ParseReservedMemory node from FDT.
|
||||
|
||||
@param[in] Fdt Address of the Fdt data.
|
||||
@param[in] SubNode first node of the PCI root bridge node.
|
||||
**/
|
||||
VOID
|
||||
ParseReservedMemory (
|
||||
IN VOID *Fdt,
|
||||
IN INT32 Node
|
||||
)
|
||||
{
|
||||
INT32 SubNode;
|
||||
INT32 TempLen;
|
||||
CONST CHAR8 *TempStr;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
UINT64 *Data64;
|
||||
UINT64 StartAddress;
|
||||
UINT64 NumberOfBytes;
|
||||
UNIVERSAL_PAYLOAD_ACPI_TABLE *PlatformAcpiTable;
|
||||
FDT_NODE_HEADER *NodePtr;
|
||||
|
||||
PlatformAcpiTable = NULL;
|
||||
|
||||
for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) {
|
||||
NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
|
||||
DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name));
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
TempStr = (CHAR8 *)(PropertyPtr->Data);
|
||||
if (TempLen > 0) {
|
||||
Data64 = (UINT64 *)(PropertyPtr->Data);
|
||||
StartAddress = Fdt64ToCpu (*Data64);
|
||||
NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
|
||||
DEBUG ((DEBUG_INFO, "\n Property %a", TempStr));
|
||||
DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress, NumberOfBytes));
|
||||
}
|
||||
|
||||
RecordMemoryNode (SubNode);
|
||||
|
||||
if (AsciiStrnCmp (NodePtr->Name, "mmio@", AsciiStrLen ("mmio@")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " MemoryMappedIO"));
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiMemoryMappedIO);
|
||||
} else {
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen);
|
||||
TempStr = (CHAR8 *)(PropertyPtr->Data);
|
||||
if (AsciiStrnCmp (TempStr, "boot-code", AsciiStrLen ("boot-code")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " boot-code"));
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesCode);
|
||||
} else if (AsciiStrnCmp (TempStr, "boot-data", AsciiStrLen ("boot-data")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " boot-data"));
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData);
|
||||
} else if (AsciiStrnCmp (TempStr, "runtime-code", AsciiStrLen ("runtime-code")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " runtime-code"));
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesCode);
|
||||
} else if (AsciiStrnCmp (TempStr, "runtime-data", AsciiStrLen ("runtime-data")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " runtime-data"));
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesData);
|
||||
} else if (AsciiStrnCmp (TempStr, "acpi", AsciiStrLen ("acpi")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " acpi, StartAddress:%x, NumberOfBytes:%x", StartAddress, NumberOfBytes));
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData);
|
||||
PlatformAcpiTable = BuildGuidHob (&gUniversalPayloadAcpiTableGuid, sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE));
|
||||
if (PlatformAcpiTable != NULL) {
|
||||
DEBUG ((DEBUG_INFO, " build gUniversalPayloadAcpiTableGuid , NumberOfBytes:%x", NumberOfBytes));
|
||||
PlatformAcpiTable->Rsdp = (EFI_PHYSICAL_ADDRESS)(UINTN)StartAddress;
|
||||
PlatformAcpiTable->Header.Revision = UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION;
|
||||
PlatformAcpiTable->Header.Length = sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE);
|
||||
}
|
||||
} else if (AsciiStrnCmp (TempStr, "acpi-nvs", AsciiStrLen ("acpi-nvs")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " acpi-nvs"));
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiACPIMemoryNVS);
|
||||
} else {
|
||||
BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiReservedMemoryType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
It will ParseFrameBuffer node from FDT.
|
||||
|
||||
@param[in] Fdt Address of the Fdt data.
|
||||
@param[in] SubNode first Sub node of the PCI root bridge node.
|
||||
|
||||
@return GmaStr Graphic device node name string.
|
||||
**/
|
||||
CHAR8 *
|
||||
ParseFrameBuffer (
|
||||
IN VOID *Fdt,
|
||||
IN INT32 Node
|
||||
)
|
||||
{
|
||||
INT32 Property;
|
||||
INT32 TempLen;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
CONST CHAR8 *TempStr;
|
||||
UINT32 *Data32;
|
||||
UINT64 FrameBufferBase;
|
||||
UINT32 FrameBufferSize;
|
||||
EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo;
|
||||
CHAR8 *GmaStr;
|
||||
|
||||
GmaStr = "Gma";
|
||||
//
|
||||
// Create GraphicInfo HOB.
|
||||
//
|
||||
GraphicsInfo = BuildGuidHob (&gEfiGraphicsInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_INFO_HOB));
|
||||
ASSERT (GraphicsInfo != NULL);
|
||||
if (GraphicsInfo == NULL) {
|
||||
return GmaStr;
|
||||
}
|
||||
|
||||
ZeroMem (GraphicsInfo, sizeof (EFI_PEI_GRAPHICS_INFO_HOB));
|
||||
|
||||
for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
|
||||
PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
|
||||
TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
|
||||
if (AsciiStrCmp (TempStr, "reg") == 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
FrameBufferBase = Fdt32ToCpu (*(Data32 + 0));
|
||||
FrameBufferSize = Fdt32ToCpu (*(Data32 + 1));
|
||||
GraphicsInfo->FrameBufferBase = FrameBufferBase;
|
||||
GraphicsInfo->FrameBufferSize = (UINT32)FrameBufferSize;
|
||||
} else if (AsciiStrCmp (TempStr, "width") == 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
GraphicsInfo->GraphicsMode.HorizontalResolution = Fdt32ToCpu (*Data32);
|
||||
} else if (AsciiStrCmp (TempStr, "height") == 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
GraphicsInfo->GraphicsMode.VerticalResolution = Fdt32ToCpu (*Data32);
|
||||
} else if (AsciiStrCmp (TempStr, "format") == 0) {
|
||||
TempStr = (CHAR8 *)(PropertyPtr->Data);
|
||||
if (AsciiStrCmp (TempStr, "a8r8g8b8") == 0) {
|
||||
GraphicsInfo->GraphicsMode.PixelFormat = PixelRedGreenBlueReserved8BitPerColor;
|
||||
} else if (AsciiStrCmp (TempStr, "a8b8g8r8") == 0) {
|
||||
GraphicsInfo->GraphicsMode.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
|
||||
} else {
|
||||
GraphicsInfo->GraphicsMode.PixelFormat = PixelFormatMax;
|
||||
}
|
||||
} else if (AsciiStrCmp (TempStr, "display") == 0) {
|
||||
GmaStr = (CHAR8 *)(PropertyPtr->Data);
|
||||
GmaStr++;
|
||||
DEBUG ((DEBUG_INFO, " display (%s)", GmaStr));
|
||||
}
|
||||
}
|
||||
|
||||
return GmaStr;
|
||||
}
|
||||
|
||||
/**
|
||||
It will ParseOptions node from FDT.
|
||||
|
||||
@param[in] Fdt Address of the Fdt data.
|
||||
@param[in] SubNode first Sub node of the PCI root bridge node.
|
||||
@param[out] PciEnumDone Init ParsePciRootBridge node for ParsePciRootBridge.
|
||||
@param[out] BootMode Init the system boot mode
|
||||
**/
|
||||
VOID
|
||||
ParseOptions (
|
||||
IN VOID *Fdt,
|
||||
IN INT32 Node,
|
||||
OUT UINT8 *PciEnumDone,
|
||||
OUT EFI_BOOT_MODE *BootMode
|
||||
)
|
||||
{
|
||||
INT32 SubNode;
|
||||
FDT_NODE_HEADER *NodePtr;
|
||||
UNIVERSAL_PAYLOAD_BASE *PayloadBase;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
CONST CHAR8 *TempStr;
|
||||
INT32 TempLen;
|
||||
UINT32 *Data32;
|
||||
UINT64 *Data64;
|
||||
UINT64 StartAddress;
|
||||
UINT8 SizeOfMemorySpace;
|
||||
|
||||
for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) {
|
||||
NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
|
||||
DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name));
|
||||
|
||||
if (AsciiStrnCmp (NodePtr->Name, "upl-images@", AsciiStrLen ("upl-images@")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " Found image@ node \n"));
|
||||
//
|
||||
// Build PayloadBase HOB .
|
||||
//
|
||||
PayloadBase = BuildGuidHob (&gUniversalPayloadBaseGuid, sizeof (UNIVERSAL_PAYLOAD_BASE));
|
||||
ASSERT (PayloadBase != NULL);
|
||||
if (PayloadBase == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
PayloadBase->Header.Revision = UNIVERSAL_PAYLOAD_BASE_REVISION;
|
||||
PayloadBase->Header.Length = sizeof (UNIVERSAL_PAYLOAD_BASE);
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "addr", &TempLen);
|
||||
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data64 = (UINT64 *)(PropertyPtr->Data);
|
||||
StartAddress = Fdt64ToCpu (*Data64);
|
||||
DEBUG ((DEBUG_INFO, "\n Property(00000000) entry"));
|
||||
DEBUG ((DEBUG_INFO, " %016lX\n", StartAddress));
|
||||
|
||||
PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)StartAddress;
|
||||
}
|
||||
}
|
||||
|
||||
if (AsciiStrnCmp (NodePtr->Name, "upl-params", AsciiStrLen ("upl-params")) == 0) {
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "addr-width", &TempLen);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
DEBUG ((DEBUG_INFO, "\n Property(00000000) address_width"));
|
||||
DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
|
||||
SizeOfMemorySpace = (UINT8)Fdt32ToCpu (*Data32);
|
||||
BuildCpuHob (SizeOfMemorySpace, PcdGet8 (SizeOfIoSpace));
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "pci-enum-done", &TempLen);
|
||||
if (TempLen > 0) {
|
||||
*PciEnumDone = 1;
|
||||
DEBUG ((DEBUG_INFO, " Found PciEnumDone (%08X)\n", *PciEnumDone));
|
||||
} else {
|
||||
*PciEnumDone = 0;
|
||||
DEBUG ((DEBUG_INFO, " Not Found PciEnumDone \n"));
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "boot-mode", &TempLen);
|
||||
if (TempLen > 0) {
|
||||
TempStr = (CHAR8 *)(PropertyPtr->Data);
|
||||
if (AsciiStrCmp (TempStr, "normal") == 0) {
|
||||
*BootMode = BOOT_WITH_FULL_CONFIGURATION;
|
||||
} else if (AsciiStrCmp (TempStr, "fast") == 0) {
|
||||
*BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
|
||||
} else if (AsciiStrCmp (TempStr, "full") == 0) {
|
||||
*BootMode = BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS;
|
||||
} else if (AsciiStrCmp (TempStr, "default") == 0) {
|
||||
*BootMode = BOOT_WITH_DEFAULT_SETTINGS;
|
||||
} else if (AsciiStrCmp (TempStr, "s4") == 0) {
|
||||
*BootMode = BOOT_ON_S4_RESUME;
|
||||
} else if (AsciiStrCmp (TempStr, "s3") == 0) {
|
||||
*BootMode = BOOT_ON_S3_RESUME;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
It will Parsegraphic node from FDT.
|
||||
|
||||
@param[in] Fdt Address of the Fdt data.
|
||||
@param[in] SubNode first Sub node of the PCI root bridge node.
|
||||
**/
|
||||
VOID
|
||||
ParsegraphicNode (
|
||||
IN VOID *Fdt,
|
||||
IN INT32 SubNode
|
||||
)
|
||||
{
|
||||
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *GraphicsDev;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
UINT16 GmaID;
|
||||
UINT32 *Data32;
|
||||
INT32 TempLen;
|
||||
|
||||
DEBUG ((DEBUG_INFO, " Found gma@ node \n"));
|
||||
GraphicsDev = NULL;
|
||||
//
|
||||
// Build Graphic info HOB .
|
||||
//
|
||||
GraphicsDev = BuildGuidHob (&gEfiGraphicsDeviceInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB));
|
||||
ASSERT (GraphicsDev != NULL);
|
||||
if (GraphicsDev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetMem (GraphicsDev, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB), 0xFF);
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "vendor-id", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
GmaID = (UINT16)Fdt32ToCpu (*Data32);
|
||||
DEBUG ((DEBUG_INFO, "\n vendor-id"));
|
||||
DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
|
||||
GraphicsDev->VendorId = GmaID;
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "device-id", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
GmaID = (UINT16)Fdt32ToCpu (*Data32);
|
||||
DEBUG ((DEBUG_INFO, "\n device-id"));
|
||||
DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
|
||||
GraphicsDev->DeviceId = GmaID;
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "revision-id", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
GmaID = (UINT16)Fdt32ToCpu (*Data32);
|
||||
DEBUG ((DEBUG_INFO, "\n revision-id"));
|
||||
DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
|
||||
GraphicsDev->RevisionId = (UINT8)GmaID;
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-vendor-id", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
GmaID = (UINT16)Fdt32ToCpu (*Data32);
|
||||
DEBUG ((DEBUG_INFO, "\n subsystem-vendor-id"));
|
||||
DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
|
||||
GraphicsDev->SubsystemVendorId = GmaID;
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-id", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
GmaID = (UINT16)Fdt32ToCpu (*Data32);
|
||||
DEBUG ((DEBUG_INFO, "\n subsystem-id"));
|
||||
DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
|
||||
GraphicsDev->SubsystemId = GmaID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
It will ParseSerialPort node from FDT.
|
||||
|
||||
@param[in] Fdt Address of the Fdt data.
|
||||
@param[in] SubNode first Sub node of the PCI root bridge node.
|
||||
**/
|
||||
VOID
|
||||
ParseSerialPort (
|
||||
IN VOID *Fdt,
|
||||
IN INT32 SubNode
|
||||
)
|
||||
{
|
||||
UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *Serial;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
INT32 TempLen;
|
||||
CONST CHAR8 *TempStr;
|
||||
UINT32 *Data32;
|
||||
UINT32 Attribute;
|
||||
|
||||
//
|
||||
// Create SerialPortInfo HOB.
|
||||
//
|
||||
Serial = BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid, sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO));
|
||||
ASSERT (Serial != NULL);
|
||||
if (Serial == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial->Header.Revision = UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION;
|
||||
Serial->Header.Length = sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO);
|
||||
Serial->RegisterStride = 1;
|
||||
Serial->UseMmio = 1;
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "current-speed", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
|
||||
Serial->BaudRate = Fdt32ToCpu (*Data32);
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen);
|
||||
TempStr = (CHAR8 *)(PropertyPtr->Data);
|
||||
if (AsciiStrnCmp (TempStr, "isa", AsciiStrLen ("isa")) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " find serial compatible isa \n"));
|
||||
Serial->UseMmio = 0;
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
Attribute = Fdt32ToCpu (*(Data32 + 0));
|
||||
Serial->RegisterBase = Fdt32ToCpu (*(Data32 + 1));
|
||||
Serial->UseMmio = Attribute == 1 ? FALSE : TRUE;
|
||||
DEBUG ((DEBUG_INFO, "\n in espi serial Property() %a", TempStr));
|
||||
DEBUG ((DEBUG_INFO, " StartAddress %016lX\n", Serial->RegisterBase));
|
||||
DEBUG ((DEBUG_INFO, " Attribute %016lX\n", Attribute));
|
||||
}
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, " NOT serial compatible isa \n"));
|
||||
PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
|
||||
ASSERT (TempLen > 0);
|
||||
if (TempLen > 0) {
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
Serial->RegisterBase = Fdt32ToCpu (*Data32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
It will ParsePciRootBridge node from FDT.
|
||||
|
||||
@param[in] Fdt Address of the Fdt data.
|
||||
@param[in] Node first node of the Fdt data.
|
||||
@param[in] PciEnumDone To use ParsePciRootBridge node.
|
||||
@param[in] RootBridgeCount Number of pci RootBridge.
|
||||
@param[in] GmaStr Graphic device node name string.
|
||||
@param[in] index Index of ParsePciRootBridge node.
|
||||
**/
|
||||
VOID
|
||||
ParsePciRootBridge (
|
||||
IN VOID *Fdt,
|
||||
IN INT32 Node,
|
||||
IN UINT8 PciEnumDone,
|
||||
IN UINT8 RootBridgeCount,
|
||||
IN CHAR8 *GmaStr,
|
||||
IN UINT8 *index
|
||||
)
|
||||
{
|
||||
INT32 SubNode;
|
||||
INT32 Property;
|
||||
INT32 SSubNode;
|
||||
FDT_NODE_HEADER *NodePtr;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
INT32 TempLen;
|
||||
UINT32 *Data32;
|
||||
UINT32 MemType;
|
||||
CONST CHAR8 *TempStr;
|
||||
UINT8 RbIndex;
|
||||
UINTN HobDataSize;
|
||||
UINT8 Base;
|
||||
|
||||
RbIndex = *index;
|
||||
HobDataSize = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + RootBridgeCount *sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE);
|
||||
//
|
||||
// Create PCI Root Bridge Info Hob.
|
||||
//
|
||||
if (mPciRootBridgeInfo == NULL) {
|
||||
mPciRootBridgeInfo = BuildGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid, HobDataSize);
|
||||
ASSERT (mPciRootBridgeInfo != NULL);
|
||||
if (mPciRootBridgeInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZeroMem (mPciRootBridgeInfo, HobDataSize);
|
||||
mPciRootBridgeInfo->Header.Length = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES);
|
||||
mPciRootBridgeInfo->Header.Revision = UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION;
|
||||
mPciRootBridgeInfo->Count = RootBridgeCount;
|
||||
mPciRootBridgeInfo->ResourceAssigned = (BOOLEAN)PciEnumDone;
|
||||
}
|
||||
|
||||
for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) {
|
||||
NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
|
||||
DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name));
|
||||
|
||||
if (AsciiStrnCmp (NodePtr->Name, GmaStr, AsciiStrLen (GmaStr)) == 0) {
|
||||
DEBUG ((DEBUG_INFO, " Found gma@ node \n"));
|
||||
ParsegraphicNode (Fdt, SubNode);
|
||||
}
|
||||
|
||||
if (AsciiStrnCmp (NodePtr->Name, "isa", AsciiStrLen ("isa")) == 0) {
|
||||
SSubNode = FdtFirstSubnode (Fdt, SubNode); // serial
|
||||
ParseSerialPort (Fdt, SSubNode);
|
||||
}
|
||||
|
||||
if (AsciiStrnCmp (NodePtr->Name, "serial@", AsciiStrLen ("serial@")) == 0) {
|
||||
ParseSerialPort (Fdt, SubNode);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, " RbIndex :%x \n", RbIndex));
|
||||
|
||||
for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
|
||||
PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
|
||||
TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
|
||||
|
||||
if (AsciiStrCmp (TempStr, "ranges") == 0) {
|
||||
DEBUG ((DEBUG_INFO, " Found ranges Property TempLen (%08X), limit %x\n", TempLen, TempLen/sizeof (UINT32)));
|
||||
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Supports = ROOT_BRIDGE_SUPPORTS_DEFAULT;
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Base = PcdGet64 (PcdPciReservedPMemAbove4GBBase);
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Limit = PcdGet64 (PcdPciReservedPMemAbove4GBLimit);
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Base = PcdGet32 (PcdPciReservedPMemBase);
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Limit = PcdGet32 (PcdPciReservedPMemLimit);
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].UID = RbIndex;
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].HID = EISA_PNP_ID (0x0A03);
|
||||
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
for (Base = 0; Base < TempLen/sizeof (UINT32); Base = Base + DWORDS_TO_NEXT_ADDR_TYPE) {
|
||||
DEBUG ((DEBUG_INFO, " Base :%x \n", Base));
|
||||
MemType = Fdt32ToCpu (*(Data32 + Base));
|
||||
if (((MemType) & (SS_64BIT_MEMORY_SPACE)) == SS_64BIT_MEMORY_SPACE) {
|
||||
DEBUG ((DEBUG_INFO, " To program 64 mm \n"));
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base = Fdt32ToCpu (*(Data32 + Base + 2)) + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 1)), 32);
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 5)), 32) + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
|
||||
} else if (((MemType) & (SS_32BIT_MEMORY_SPACE)) == SS_32BIT_MEMORY_SPACE) {
|
||||
DEBUG ((DEBUG_INFO, " To program 32 mem \n"));
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base = Fdt32ToCpu (*(Data32 + Base + 2));
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
|
||||
} else if (((MemType) & (SS_IO_SPACE)) == SS_IO_SPACE) {
|
||||
DEBUG ((DEBUG_INFO, " To program Io\n"));
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base = Fdt32ToCpu (*(Data32 + Base + 2));
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "RootBridgeCount %x, index :%x\n", RootBridgeCount, RbIndex));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit));
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Io.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Io.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit));
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (TempStr, "bus-range") == 0) {
|
||||
DEBUG ((DEBUG_INFO, " Found bus-range Property TempLen (%08X)\n", TempLen));
|
||||
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base = Fdt32ToCpu (*Data32) & 0xFF;
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit = Fdt32ToCpu (*(Data32 + 1)) & 0xFF;
|
||||
mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Translation = 0;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base, RbIndex));
|
||||
DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit, RbIndex));
|
||||
}
|
||||
}
|
||||
|
||||
if (RbIndex > 0) {
|
||||
RbIndex--;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "After updated RbIndex :%x \n", RbIndex));
|
||||
*index = RbIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
It will parse FDT based on DTB from bootloaders.
|
||||
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
|
||||
@return The address to the new hob list
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
ParseDtb (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
VOID *Fdt;
|
||||
INT32 Node;
|
||||
INT32 Property;
|
||||
INT32 Depth;
|
||||
FDT_NODE_HEADER *NodePtr;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
CONST CHAR8 *TempStr;
|
||||
INT32 TempLen;
|
||||
UINT64 *Data64;
|
||||
UINT64 StartAddress;
|
||||
UINT64 NumberOfBytes;
|
||||
UINTN MinimalNeededSize;
|
||||
EFI_PHYSICAL_ADDRESS FreeMemoryBottom;
|
||||
EFI_PHYSICAL_ADDRESS FreeMemoryTop;
|
||||
EFI_PHYSICAL_ADDRESS MemoryBottom;
|
||||
EFI_PHYSICAL_ADDRESS MemoryTop;
|
||||
BOOLEAN IsHobConstructed;
|
||||
UINTN NewHobList;
|
||||
UINT8 RootBridgeCount;
|
||||
UINT8 index;
|
||||
UINTN HobDataSize;
|
||||
UINT8 PciEnumDone;
|
||||
UINT8 NodeType;
|
||||
EFI_BOOT_MODE BootMode;
|
||||
CHAR8 *GmaStr;
|
||||
|
||||
Fdt = FdtBase;
|
||||
Depth = 0;
|
||||
MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
|
||||
IsHobConstructed = FALSE;
|
||||
NewHobList = 0;
|
||||
RootBridgeCount = 0;
|
||||
index = 0;
|
||||
HobDataSize = 0;
|
||||
PciEnumDone = 0;
|
||||
BootMode = 0;
|
||||
NodeType = 0;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "FDT = 0x%x %x\n", Fdt, Fdt32ToCpu (*((UINT32 *)Fdt))));
|
||||
DEBUG ((DEBUG_INFO, "Start parsing DTB data\n"));
|
||||
DEBUG ((DEBUG_INFO, "MinimalNeededSize :%x\n", MinimalNeededSize));
|
||||
|
||||
for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) {
|
||||
NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
|
||||
DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr->Name, Depth));
|
||||
// memory node
|
||||
if (AsciiStrnCmp (NodePtr->Name, "memory@", AsciiStrLen ("memory@")) == 0) {
|
||||
for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
|
||||
PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
|
||||
TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
|
||||
if (AsciiStrCmp (TempStr, "reg") == 0) {
|
||||
Data64 = (UINT64 *)(PropertyPtr->Data);
|
||||
StartAddress = Fdt64ToCpu (*Data64);
|
||||
NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
|
||||
DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
|
||||
DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress, NumberOfBytes));
|
||||
if (!IsHobConstructed) {
|
||||
if ((NumberOfBytes > MinimalNeededSize) && (StartAddress < BASE_4GB)) {
|
||||
MemoryBottom = StartAddress + NumberOfBytes - MinimalNeededSize;
|
||||
FreeMemoryBottom = MemoryBottom;
|
||||
FreeMemoryTop = StartAddress + NumberOfBytes;
|
||||
MemoryTop = FreeMemoryTop;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "MemoryBottom :0x%llx\n", MemoryBottom));
|
||||
DEBUG ((DEBUG_INFO, "FreeMemoryBottom :0x%llx\n", FreeMemoryBottom));
|
||||
DEBUG ((DEBUG_INFO, "FreeMemoryTop :0x%llx\n", FreeMemoryTop));
|
||||
DEBUG ((DEBUG_INFO, "MemoryTop :0x%llx\n", MemoryTop));
|
||||
mHobList = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMemoryTop);
|
||||
IsHobConstructed = TRUE;
|
||||
NewHobList = (UINTN)mHobList;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of memory node
|
||||
else {
|
||||
PropertyPtr = FdtGetProperty (Fdt, Node, "compatible", &TempLen);
|
||||
TempStr = (CHAR8 *)(PropertyPtr->Data);
|
||||
if (AsciiStrnCmp (TempStr, "pci-rb", AsciiStrLen ("pci-rb")) == 0) {
|
||||
RootBridgeCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index = RootBridgeCount - 1;
|
||||
Depth = 0;
|
||||
for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) {
|
||||
NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
|
||||
DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr->Name, Depth));
|
||||
|
||||
NodeType = CheckNodeType (NodePtr->Name, Depth);
|
||||
DEBUG ((DEBUG_INFO, "NodeType :0x%x\n", NodeType));
|
||||
switch (NodeType) {
|
||||
case ReservedMemory:
|
||||
DEBUG ((DEBUG_INFO, "ParseReservedMemory\n"));
|
||||
ParseReservedMemory (Fdt, Node);
|
||||
break;
|
||||
case Memory:
|
||||
DEBUG ((DEBUG_INFO, "ParseMemory\n"));
|
||||
if (!CheckMemoryNodeIfInit (Node)) {
|
||||
ParseMemory (Fdt, Node);
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "Memory has initialized\n"));
|
||||
}
|
||||
|
||||
break;
|
||||
case FrameBuffer:
|
||||
DEBUG ((DEBUG_INFO, "ParseFrameBuffer\n"));
|
||||
GmaStr = ParseFrameBuffer (Fdt, Node);
|
||||
break;
|
||||
case PciRootBridge:
|
||||
DEBUG ((DEBUG_INFO, "ParsePciRootBridge, index :%x\n", index));
|
||||
ParsePciRootBridge (Fdt, Node, PciEnumDone, RootBridgeCount, GmaStr, &index);
|
||||
DEBUG ((DEBUG_INFO, "After ParsePciRootBridge, index :%x\n", index));
|
||||
break;
|
||||
case Options:
|
||||
DEBUG ((DEBUG_INFO, "ParseOptions\n"));
|
||||
ParseOptions (Fdt, Node, &PciEnumDone, &BootMode);
|
||||
break;
|
||||
default:
|
||||
DEBUG ((DEBUG_INFO, "ParseNothing\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
((EFI_HOB_HANDOFF_INFO_TABLE *)(mHobList))->BootMode = BootMode;
|
||||
DEBUG ((DEBUG_INFO, "\n"));
|
||||
|
||||
return NewHobList;
|
||||
}
|
||||
|
||||
/**
|
||||
It will Parse FDT -node based on information from bootloaders.
|
||||
@param[in] FdtBase The starting memory address of FdtBase
|
||||
@retval HobList The base address of Hoblist.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
FdtNodeParser (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
return ParseDtb (FdtBase);
|
||||
}
|
||||
|
||||
/**
|
||||
It will initialize HOBs for UPL.
|
||||
|
||||
@param[in] FdtBase Address of the Fdt data.
|
||||
|
||||
@retval EFI_SUCCESS If it completed successfully.
|
||||
@retval Others If it failed to initialize HOBs.
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
UplInitHob (
|
||||
IN VOID *FdtBase
|
||||
)
|
||||
{
|
||||
UINTN NHobAddress;
|
||||
|
||||
NHobAddress = 0;
|
||||
//
|
||||
// Check parameter type(
|
||||
//
|
||||
if (FdtCheckHeader (FdtBase) == 0) {
|
||||
DEBUG ((DEBUG_INFO, "%a() FDT blob\n", __func__));
|
||||
NHobAddress = FdtNodeParser ((VOID *)FdtBase);
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "%a() HOb list\n", __func__));
|
||||
mHobList = FdtBase;
|
||||
|
||||
return (UINTN)(mHobList);
|
||||
}
|
||||
|
||||
return NHobAddress;
|
||||
}
|
280
UefiPayloadPkg/Library/HobParseLib/HobParseLib.c
Normal file
280
UefiPayloadPkg/Library/HobParseLib/HobParseLib.c
Normal file
@ -0,0 +1,280 @@
|
||||
/** @file
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Guid/MemoryAllocationHob.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/CpuLib.h>
|
||||
#include <IndustryStandard/Acpi.h>
|
||||
#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
|
||||
#include <Guid/AcpiBoardInfoGuid.h>
|
||||
#include <UniversalPayload/AcpiTable.h>
|
||||
#include <UniversalPayload/UniversalPayload.h>
|
||||
#include <UniversalPayload/ExtraData.h>
|
||||
|
||||
#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
|
||||
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_TESTED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \
|
||||
EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \
|
||||
EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | \
|
||||
EFI_RESOURCE_ATTRIBUTE_PERSISTENT )
|
||||
|
||||
#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
|
||||
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
|
||||
EFI_RESOURCE_ATTRIBUTE_TESTED )
|
||||
|
||||
extern VOID *mHobList;
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
Build a Handoff Information Table HOB
|
||||
|
||||
This function initialize a HOB region from EfiMemoryBegin to
|
||||
EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
|
||||
be inside the HOB region.
|
||||
|
||||
@param[in] EfiMemoryBottom Total memory start address
|
||||
@param[in] EfiMemoryTop Total memory end address.
|
||||
@param[in] EfiFreeMemoryBottom Free memory start address
|
||||
@param[in] EfiFreeMemoryTop Free memory end address.
|
||||
|
||||
@return The pointer to the handoff HOB table.
|
||||
|
||||
**/
|
||||
EFI_HOB_HANDOFF_INFO_TABLE *
|
||||
EFIAPI
|
||||
HobConstructor (
|
||||
IN VOID *EfiMemoryBottom,
|
||||
IN VOID *EfiMemoryTop,
|
||||
IN VOID *EfiFreeMemoryBottom,
|
||||
IN VOID *EfiFreeMemoryTop
|
||||
);
|
||||
|
||||
/**
|
||||
Build ACPI board info HOB using infomation from ACPI table
|
||||
|
||||
@param AcpiTableBase ACPI table start address in memory
|
||||
|
||||
@retval A pointer to ACPI board HOB ACPI_BOARD_INFO. Null if build HOB failure.
|
||||
**/
|
||||
ACPI_BOARD_INFO *
|
||||
BuildHobFromAcpi (
|
||||
IN UINT64 AcpiTableBase
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
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
|
||||
)
|
||||
{
|
||||
EFI_PEI_HOB_POINTERS NewHob;
|
||||
|
||||
if (Hob->Raw == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header->HobLength);
|
||||
|
||||
if (NewHob.Header != NULL) {
|
||||
CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - sizeof (EFI_HOB_GENERIC_HEADER));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Found the Resource Descriptor HOB that contains a range (Base, Top)
|
||||
|
||||
@param[in] HobList Hob start address
|
||||
@param[in] Base Memory start address
|
||||
@param[in] Top Memory end address.
|
||||
|
||||
@retval The pointer to the Resource Descriptor HOB.
|
||||
**/
|
||||
EFI_HOB_RESOURCE_DESCRIPTOR *
|
||||
FindResourceDescriptorByRange (
|
||||
IN VOID *HobList,
|
||||
IN EFI_PHYSICAL_ADDRESS Base,
|
||||
IN EFI_PHYSICAL_ADDRESS Top
|
||||
)
|
||||
{
|
||||
EFI_PEI_HOB_POINTERS Hob;
|
||||
EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
|
||||
|
||||
for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
|
||||
//
|
||||
// Skip all HOBs except Resource Descriptor HOBs
|
||||
//
|
||||
if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip Resource Descriptor HOBs that do not describe tested system memory
|
||||
//
|
||||
ResourceHob = Hob.ResourceDescriptor;
|
||||
if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
|
||||
//
|
||||
if (Base < ResourceHob->PhysicalStart) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return ResourceHob;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the highest below 4G memory resource descriptor, except the input Resource Descriptor.
|
||||
|
||||
@param[in] HobList Hob start address
|
||||
@param[in] MinimalNeededSize Minimal needed size.
|
||||
@param[in] ExceptResourceHob Ignore this Resource Descriptor.
|
||||
|
||||
@retval The pointer to the Resource Descriptor HOB.
|
||||
**/
|
||||
EFI_HOB_RESOURCE_DESCRIPTOR *
|
||||
FindAnotherHighestBelow4GResourceDescriptor (
|
||||
IN VOID *HobList,
|
||||
IN UINTN MinimalNeededSize,
|
||||
IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob
|
||||
)
|
||||
{
|
||||
EFI_PEI_HOB_POINTERS Hob;
|
||||
EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
|
||||
EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob;
|
||||
|
||||
ReturnResourceHob = NULL;
|
||||
|
||||
for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
|
||||
//
|
||||
// Skip all HOBs except Resource Descriptor HOBs
|
||||
//
|
||||
if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip Resource Descriptor HOBs that do not describe tested system memory
|
||||
//
|
||||
ResourceHob = Hob.ResourceDescriptor;
|
||||
if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip if the Resource Descriptor HOB equals to ExceptResourceHob
|
||||
//
|
||||
if (ResourceHob == ExceptResourceHob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip Resource Descriptor HOBs that are beyond 4G
|
||||
//
|
||||
if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > BASE_4GB) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip Resource Descriptor HOBs that are too small
|
||||
//
|
||||
if (ResourceHob->ResourceLength < MinimalNeededSize) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the topest Resource Descriptor
|
||||
//
|
||||
if (ReturnResourceHob == NULL) {
|
||||
ReturnResourceHob = ResourceHob;
|
||||
} else {
|
||||
if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) {
|
||||
ReturnResourceHob = ResourceHob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ReturnResourceHob;
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
IsHobNeed (
|
||||
EFI_PEI_HOB_POINTERS Hob
|
||||
)
|
||||
{
|
||||
if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
|
||||
if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Arrive here mean the HOB is need
|
||||
return TRUE;
|
||||
}
|
40
UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
Normal file
40
UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
Normal file
@ -0,0 +1,40 @@
|
||||
## @file
|
||||
# UPL Hob Parse Library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = HobParseLib
|
||||
FILE_GUID = EFB05FE7-604B-40DA-9A59-E2F998528754
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = HobParseLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
HobParseLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
UefiPayloadPkg/UefiPayloadPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
IoLib
|
||||
DebugLib
|
||||
PcdLib
|
||||
HobLib
|
||||
|
||||
[Pcd.IA32,Pcd.X64]
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
|
@ -318,6 +318,7 @@
|
||||
FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
|
||||
SmmRelocationLib|UefiCpuPkg/Library/SmmRelocationLib/SmmRelocationLib.inf
|
||||
HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf
|
||||
BuildFdtLib|UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf
|
||||
|
||||
[LibraryClasses.common]
|
||||
!if $(BOOTSPLASH_IMAGE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user