From 387653a431766dbaaf76f7743cefc7aa5350b967 Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Sun, 14 Apr 2013 09:36:41 +0000 Subject: [PATCH] ArmPkg/BdsLib: Added support for FDT alignment through PcdArmLinuxFdtAlignment Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14274 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/ArmPkg.dec | 17 +++++++++++------ ArmPkg/Library/BdsLib/BdsLib.inf | 1 + ArmPkg/Library/BdsLib/BdsLinuxFdt.c | 17 +++++++++++++++-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index cb711b2e31..81c4db6a6f 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -2,7 +2,7 @@ # ARM processor package. # # Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
-# Copyright (c) 2011 - 2012, ARM Limited. All rights reserved. +# Copyright (c) 2011 - 2013, ARM Limited. All rights reserved. # # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -137,8 +137,6 @@ # 0xC00 = cp10 | cp11 gArmTokenSpaceGuid.PcdArmNsacr|0xC00|UINT32|0x00000039 - gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E - # System Memory (DRAM): These PCDs define the region of in-built system memory # Some platforms can get DRAM extensions, these additional regions will be declared # to UEFI by ArmPLatformPlib @@ -167,9 +165,6 @@ gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F # The Linux ATAGs are expected to be under 0x4000 (16KB) from the beginning of the System Memory gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset|0x4000|UINT32|0x00000020 - # If the fixed FDT address is not available, then it should be loaded the below the kernel - # The recommandation from the Linux kernel is to have the FDT below 16KB - gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x4000|UINT32|0x00000023 # # ARM Architectural Timer @@ -178,3 +173,13 @@ # ARM Architectural Timer Interrupt(GIC PPI) number gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035 gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036 + +[PcdsFixedAtBuild.ARM] + # By default we do not do a transition to non-secure mode + gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E + # If the fixed FDT address is not available, then it should be loaded below the kernel. + # The recommendation from the Linux kernel is to have the FDT below 16KB. + # (see the kernel doc: Documentation/arm/Booting) + gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x4000|UINT32|0x00000023 + # The FDT blob must be loaded at a 64bit aligned address. + gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x8|UINT32|0x00000026 diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf index 335f4d6c59..b6712a4fe2 100644 --- a/ArmPkg/Library/BdsLib/BdsLib.inf +++ b/ArmPkg/Library/BdsLib/BdsLib.inf @@ -76,6 +76,7 @@ gArmTokenSpaceGuid.PcdArmMachineType gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset + gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset diff --git a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c index b6d08944ab..43daf5dd2a 100644 --- a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c +++ b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c @@ -214,7 +214,9 @@ PrepareFdt ( { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS NewFdtBlobBase; + EFI_PHYSICAL_ADDRESS NewFdtBlobAllocation; UINTN NewFdtBlobSize; + UINT32 FdtAlignment; VOID* fdt; INTN err; INTN node; @@ -295,9 +297,15 @@ PrepareFdt ( // NewFdtBlobSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE; + // If FDT load address needs to be aligned, allocate more space. + FdtAlignment = PcdGet32 (PcdArmLinuxFdtAlignment); + if (FdtAlignment != 0) { + NewFdtBlobSize += FdtAlignment; + } + // Try below a watermark address Status = EFI_NOT_FOUND; - if (PcdGet32(PcdArmLinuxFdtMaxOffset) != 0) { + if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) { NewFdtBlobBase = LINUX_FDT_MAX_OFFSET; Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase); if (EFI_ERROR(Status)) { @@ -316,6 +324,11 @@ PrepareFdt ( } } + NewFdtBlobAllocation = NewFdtBlobBase; + if (FdtAlignment != 0) { + NewFdtBlobBase = ALIGN (NewFdtBlobBase, FdtAlignment); + } + // Load the Original FDT tree into the new region fdt = (VOID*)(UINTN)NewFdtBlobBase; err = fdt_open_into((VOID*)(UINTN)(*FdtBlobBase), fdt, NewFdtBlobSize); @@ -530,7 +543,7 @@ PrepareFdt ( return EFI_SUCCESS; FAIL_NEW_FDT: - gBS->FreePages (NewFdtBlobBase, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); + gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); FAIL_ALLOCATE_NEW_FDT: *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase)); -- 2.39.2