ArmPkg/BdsLib: Added support for FDT alignment through PcdArmLinuxFdtAlignment

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14274 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin 2013-04-14 09:36:41 +00:00
parent ac0fb62f03
commit 387653a431
3 changed files with 27 additions and 8 deletions

View File

@ -2,7 +2,7 @@
# ARM processor package. # ARM processor package.
# #
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR> # Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# Copyright (c) 2011 - 2012, ARM Limited. All rights reserved. # Copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
# #
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License
@ -137,8 +137,6 @@
# 0xC00 = cp10 | cp11 # 0xC00 = cp10 | cp11
gArmTokenSpaceGuid.PcdArmNsacr|0xC00|UINT32|0x00000039 gArmTokenSpaceGuid.PcdArmNsacr|0xC00|UINT32|0x00000039
gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E
# System Memory (DRAM): These PCDs define the region of in-built system memory # 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 # Some platforms can get DRAM extensions, these additional regions will be declared
# to UEFI by ArmPLatformPlib # to UEFI by ArmPLatformPlib
@ -167,9 +165,6 @@
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F
# The Linux ATAGs are expected to be under 0x4000 (16KB) from the beginning of the System Memory # The Linux ATAGs are expected to be under 0x4000 (16KB) from the beginning of the System Memory
gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset|0x4000|UINT32|0x00000020 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 # ARM Architectural Timer
@ -178,3 +173,13 @@
# ARM Architectural Timer Interrupt(GIC PPI) number # ARM Architectural Timer Interrupt(GIC PPI) number
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035 gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036 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

View File

@ -76,6 +76,7 @@
gArmTokenSpaceGuid.PcdArmMachineType gArmTokenSpaceGuid.PcdArmMachineType
gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset
gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset
gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset

View File

@ -214,7 +214,9 @@ PrepareFdt (
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS NewFdtBlobBase; EFI_PHYSICAL_ADDRESS NewFdtBlobBase;
EFI_PHYSICAL_ADDRESS NewFdtBlobAllocation;
UINTN NewFdtBlobSize; UINTN NewFdtBlobSize;
UINT32 FdtAlignment;
VOID* fdt; VOID* fdt;
INTN err; INTN err;
INTN node; INTN node;
@ -295,9 +297,15 @@ PrepareFdt (
// //
NewFdtBlobSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE; 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 // Try below a watermark address
Status = EFI_NOT_FOUND; Status = EFI_NOT_FOUND;
if (PcdGet32(PcdArmLinuxFdtMaxOffset) != 0) { if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) {
NewFdtBlobBase = LINUX_FDT_MAX_OFFSET; NewFdtBlobBase = LINUX_FDT_MAX_OFFSET;
Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase); Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase);
if (EFI_ERROR(Status)) { 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 // Load the Original FDT tree into the new region
fdt = (VOID*)(UINTN)NewFdtBlobBase; fdt = (VOID*)(UINTN)NewFdtBlobBase;
err = fdt_open_into((VOID*)(UINTN)(*FdtBlobBase), fdt, NewFdtBlobSize); err = fdt_open_into((VOID*)(UINTN)(*FdtBlobBase), fdt, NewFdtBlobSize);
@ -530,7 +543,7 @@ PrepareFdt (
return EFI_SUCCESS; return EFI_SUCCESS;
FAIL_NEW_FDT: FAIL_NEW_FDT:
gBS->FreePages (NewFdtBlobBase, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize));
FAIL_ALLOCATE_NEW_FDT: FAIL_ALLOCATE_NEW_FDT:
*FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase)); *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));