BdsLib was using fixed PCDs where constants could easily perform that same function.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ryan Harkin ryan.harkin@linaro.org --- .../Application/LinuxLoader/AArch64/LinuxStarter.c | 8 +++--- ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.c | 2 +- ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c | 22 +++++++-------- ArmPkg/Application/LinuxLoader/LinuxLoader.h | 32 ++++++++++++++++++++-- ArmPkg/Application/LinuxLoader/LinuxLoader.inf | 8 ------ ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c | 14 +++------- ArmPkg/ArmPkg.dec | 19 ------------- 7 files changed, 49 insertions(+), 56 deletions(-)
diff --git a/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarter.c b/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarter.c index e72537f..317e73e 100644 --- a/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarter.c +++ b/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarter.c @@ -229,12 +229,12 @@ BootLinuxFdt ( //
// Try to put the kernel at the start of RAM so as to give it access to all memory. - // If that fails fall back to try loading it within LINUX_KERNEL_MAX_OFFSET of memory start. + // If that fails fall back to try loading it within LINUX_KERNEL_MAX_ADDR of memory start. LinuxImage = SystemMemoryBase + 0x80000; Status = BdsLoadImage (LinuxKernelDevicePath, AllocateAddress, &LinuxImage, &LinuxImageSize); if (EFI_ERROR (Status)) { // Try again but give the loader more freedom of where to put the image. - LinuxImage = LINUX_KERNEL_MAX_OFFSET; + LinuxImage = LINUX_KERNEL_MAX_ADDR; Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize); if (EFI_ERROR (Status)) { Print (L"ERROR: Did not find Linux kernel (%r).\n", Status); @@ -248,7 +248,7 @@ BootLinuxFdt ( }
if (InitrdDevicePath) { - InitrdImageBase = LINUX_FDT_MAX_OFFSET; + InitrdImageBase = LINUX_INITRD_MAX_ADDR; Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize); if (Status == EFI_OUT_OF_RESOURCES) { Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize); @@ -287,7 +287,7 @@ BootLinuxFdt ( // FDT device path explicitly defined. The FDT is relocated later to a // more appropriate location for the Linux kernel. // - FdtBlobBase = LINUX_KERNEL_MAX_OFFSET; + FdtBlobBase = LINUX_KERNEL_MAX_ADDR; Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &FdtBlobBase, &FdtBlobSize); if (EFI_ERROR (Status)) { Print (L"ERROR: Did not find Device Tree blob (%r).\n", Status); diff --git a/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.c b/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.c index fd7ee9c..a6dbf7a 100644 --- a/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.c +++ b/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.c @@ -129,7 +129,7 @@ PrepareAtagList ( EFI_PHYSICAL_ADDRESS AtagStartAddress; SYSTEM_MEMORY_RESOURCE *Resource;
- AtagStartAddress = LINUX_ATAG_MAX_OFFSET; + AtagStartAddress = LINUX_ATAG_MAX_ADDR; Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES (ATAG_MAX_SIZE), &AtagStartAddress); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "Warning: Failed to allocate Atag at 0x%lX (%r). The Atag will be allocated somewhere else in System Memory.\n", AtagStartAddress, Status)); diff --git a/ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c b/ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c index ca6331a..11be291 100644 --- a/ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c +++ b/ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c @@ -84,18 +84,18 @@ StartLinux ( // physical memory. //Note: There is no requirement on the alignment if (MachineType != ARM_FDT_MACHINE_TYPE) { - if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32 (PcdArmLinuxAtagMaxOffset))) { - KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW (LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize); + if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_ADDR) && (KernelParamsSize < LINUX_ATAG_MAX_OFFSET)) { + KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW (LINUX_ATAG_MAX_ADDR - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize); } } else { - if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32 (PcdArmLinuxFdtMaxOffset))) { - KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW (LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize); + if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_ADDR) && (KernelParamsSize < LINUX_FDT_MAX_OFFSET)) { + KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW (LINUX_FDT_MAX_ADDR - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize); } }
- if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) { + if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_ADDR) { //Note: There is no requirement on the alignment - LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW (LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize); + LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW (LINUX_KERNEL_MAX_ADDR - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize); } else { LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage; } @@ -183,7 +183,7 @@ BootLinuxAtag ( PERF_START (NULL, "BDS", NULL, 0);
// Load the Linux kernel from a device path - LinuxImage = LINUX_KERNEL_MAX_OFFSET; + LinuxImage = LINUX_KERNEL_MAX_ADDR; Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize); if (EFI_ERROR (Status)) { Print (L"ERROR: Did not find Linux kernel.\n"); @@ -192,7 +192,7 @@ BootLinuxAtag (
if (InitrdDevicePath) { // Load the initrd near to the Linux kernel - InitrdImageBase = LINUX_FDT_MAX_OFFSET; + InitrdImageBase = LINUX_FDT_MAX_ADDR; Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize); if (Status == EFI_OUT_OF_RESOURCES) { Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize); @@ -272,7 +272,7 @@ BootLinuxFdt ( PERF_START (NULL, "BDS", NULL, 0);
// Load the Linux kernel from a device path - LinuxImage = LINUX_KERNEL_MAX_OFFSET; + LinuxImage = LINUX_KERNEL_MAX_ADDR; Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize); if (EFI_ERROR (Status)) { Print (L"ERROR: Did not find Linux kernel.\n"); @@ -280,7 +280,7 @@ BootLinuxFdt ( }
if (InitrdDevicePath) { - InitrdImageBase = LINUX_FDT_MAX_OFFSET; + InitrdImageBase = LINUX_FDT_MAX_ADDR; Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize); if (Status == EFI_OUT_OF_RESOURCES) { Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize); @@ -319,7 +319,7 @@ BootLinuxFdt ( // FDT device path explicitly defined. The FDT is relocated later to a // more appropriate location for the Linux kernel. // - FdtBlobBase = LINUX_KERNEL_MAX_OFFSET; + FdtBlobBase = LINUX_KERNEL_MAX_ADDR; Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &FdtBlobBase, &FdtBlobSize); if (EFI_ERROR (Status)) { Print (L"ERROR: Did not find Device Tree blob (%r).\n", Status); diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoader.h b/ArmPkg/Application/LinuxLoader/LinuxLoader.h index 8a23d7f..2544147 100644 --- a/ArmPkg/Application/LinuxLoader/LinuxLoader.h +++ b/ArmPkg/Application/LinuxLoader/LinuxLoader.h @@ -37,9 +37,35 @@ #define MAX_MSG_LEN 80
#define LINUX_UIMAGE_SIGNATURE 0x56190527 -#define LINUX_KERNEL_MAX_OFFSET (SystemMemoryBase + PcdGet32(PcdArmLinuxKernelMaxOffset)) -#define LINUX_ATAG_MAX_OFFSET (SystemMemoryBase + PcdGet32(PcdArmLinuxAtagMaxOffset)) -#define LINUX_FDT_MAX_OFFSET (SystemMemoryBase + PcdGet32(PcdArmLinuxFdtMaxOffset)) + +#if defined (MDE_CPU_ARM) + // On ARM, the kernel recommendations say that the kernel should live before + // the 128MiB (0x08000000) boundary. + #define LINUX_KERNEL_MAX_OFFSET 0x08000000 + + // ATAGS data should be in the first 16KB + #define LINUX_ATAG_MAX_OFFSET 0x00004000 + + // The device tree and initrd should live after the 128MiB boundary. + #define LINUX_FDT_MAX_OFFSET 0x08400000 + #define LINUX_INITRD_MAX_OFFSET 0x08400000 + #define LINUX_FDT_ALIGNMENT 0x00000008 +#elif defined (MDE_CPU_AARCH64) + #define LINUX_KERNEL_MAX_OFFSET 0x08000000 + + // arm64 Kernels prior to v4.2 required the device tree to reside in the + // first 512MB of memory + #define LINUX_FDT_MAX_OFFSET 0x20000000 + #define LINUX_INITRD_MAX_OFFSET 0x20000000 + + // Recommendations are to align the FDT to 2MiB + #define LINUX_FDT_ALIGNMENT 0x00200000 +#endif + +#define LINUX_KERNEL_MAX_ADDR (SystemMemoryBase + LINUX_KERNEL_MAX_OFFSET) +#define LINUX_ATAG_MAX_ADDR (SystemMemoryBase + LINUX_ATAG_MAX_OFFSET) +#define LINUX_FDT_MAX_ADDR (SystemMemoryBase + LINUX_FDT_MAX_OFFSET) +#define LINUX_INITRD_MAX_ADDR (SystemMemoryBase + LINUX_INITRD_MAX_OFFSET)
#define ARM_FDT_MACHINE_TYPE 0xFFFFFFFF
diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoader.inf b/ArmPkg/Application/LinuxLoader/LinuxLoader.inf index 59ab99c..3b640b8 100644 --- a/ArmPkg/Application/LinuxLoader/LinuxLoader.inf +++ b/ArmPkg/Application/LinuxLoader/LinuxLoader.inf @@ -78,14 +78,6 @@ [FeaturePcd] gArmTokenSpaceGuid.PcdArmLinuxSpinTable
-[FixedPcd] - gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset - gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment - gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset - -[FixedPcd.ARM] - gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset - [Pcd.AARCH64] gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicSgiIntId diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c b/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c index 0f53784..6f7bcdc 100644 --- a/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c +++ b/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c @@ -78,20 +78,16 @@ RelocateFdt ( { EFI_STATUS Status; INTN Error; - UINT64 FdtAlignment;
*RelocatedFdtSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE;
// If FDT load address needs to be aligned, allocate more space. - FdtAlignment = PcdGet32 (PcdArmLinuxFdtAlignment); - if (FdtAlignment != 0) { - *RelocatedFdtSize += FdtAlignment; - } + *RelocatedFdtSize += LINUX_FDT_ALIGNMENT;
// Try below a watermark address. Status = EFI_NOT_FOUND; - if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) { - *RelocatedFdt = LINUX_FDT_MAX_OFFSET; + if (LINUX_FDT_MAX_OFFSET != 0) { + *RelocatedFdt = LINUX_FDT_MAX_ADDR; Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt); if (EFI_ERROR (Status)) { @@ -112,9 +108,7 @@ RelocateFdt ( }
*RelocatedFdtAlloc = *RelocatedFdt; - if (FdtAlignment != 0) { - *RelocatedFdt = ALIGN (*RelocatedFdt, FdtAlignment); - } + *RelocatedFdt = ALIGN (*RelocatedFdt, LINUX_FDT_ALIGNMENT);
// Load the Original FDT tree into the new region Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt, diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index b2122b1..59916d2 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -115,8 +115,6 @@ # # BdsLib # - # The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory - gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F # Maximum file size for TFTP servers that do not support 'tsize' extension gArmTokenSpaceGuid.PcdMaxTftpFileSize|0x01000000|UINT32|0x00000000
@@ -152,16 +150,6 @@ # By default we do not do a transition to non-secure mode gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E
- # 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 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|0x08400000|UINT32|0x00000023 - # The FDT blob must be loaded at a 64bit aligned address. - gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x8|UINT32|0x00000026 - # Non Secure Access Control Register # - BIT15 : NSASEDIS - Disable Non-secure Advanced SIMD functionality # - BIT14 : NSD32DIS - Disable Non-secure use of D16-D31 @@ -200,13 +188,6 @@ # Other modes include using SP0 or switching to Aarch32, but these are # not currently supported. gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x3c9|UINT32|0x0000003E - # If the fixed FDT address is not available, then it should be loaded above the kernel. - # The recommendation from the AArch64 Linux kernel is to have the FDT below 512MB. - # (see the kernel doc: Documentation/arm64/booting.txt) - gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x20000000|UINT32|0x00000023 - # The FDT blob must be loaded at a 2MB aligned address. - gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x00200000|UINT32|0x00000026 -
# # These PCDs are also defined as 'PcdsDynamic' or 'PcdsPatchableInModule' to be