From c75d3eb6be41867cc3bfea9f567bf20cdead8966 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Tue, 14 Jul 2015 14:35:20 +0000 Subject: [PATCH] ArmPkg/BdsLib: Remove Linux loader from BdsLib This change removes the embedded Linux Loder from BdsLib. BdsLib becomes OS agnostic. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin Reviewed-by: Ronald Cron git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17969 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Include/Library/BdsLib.h | 37 -- .../Library/BdsLib/AArch64/BdsLinuxLoader.c | 355 ----------- .../BdsLib/AArch64/BdsLinuxLoaderHelper.S | 58 -- ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c | 173 ------ ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c | 323 ---------- ArmPkg/Library/BdsLib/BdsHelper.c | 178 +----- ArmPkg/Library/BdsLib/BdsInternal.h | 13 - ArmPkg/Library/BdsLib/BdsLib.inf | 38 -- ArmPkg/Library/BdsLib/BdsLinuxFdt.c | 572 ------------------ ArmPkg/Library/BdsLib/BdsLinuxLoader.h | 156 ----- ArmPlatformPkg/Bds/Bds.inf | 4 + ArmPlatformPkg/Bds/BootOption.c | 35 +- 12 files changed, 8 insertions(+), 1934 deletions(-) delete mode 100644 ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c delete mode 100644 ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S delete mode 100644 ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c delete mode 100644 ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c delete mode 100644 ArmPkg/Library/BdsLib/BdsLinuxFdt.c delete mode 100644 ArmPkg/Library/BdsLib/BdsLinuxLoader.h diff --git a/ArmPkg/Include/Library/BdsLib.h b/ArmPkg/Include/Library/BdsLib.h index 3d9e1954f3..c58f47eb2a 100644 --- a/ArmPkg/Include/Library/BdsLib.h +++ b/ArmPkg/Include/Library/BdsLib.h @@ -137,43 +137,6 @@ BootOptionAllocateBootIndex ( VOID ); -/** - Start a Linux kernel from a Device Path - - @param LinuxKernel Device Path to the Linux Kernel - @param Parameters Linux kernel arguments - - @retval EFI_SUCCESS All drivers have been connected - @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found - @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. - -**/ -EFI_STATUS -BdsBootLinuxAtag ( - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* Arguments - ); - -/** - Start a Linux kernel from a Device Path - - @param[in] LinuxKernelDevicePath Device Path to the Linux Kernel - @param[in] InitrdDevicePath Device Path to the Initrd - @param[in] Arguments Linux kernel arguments - - @retval EFI_SUCCESS All drivers have been connected - @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found - @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. - -**/ -EFI_STATUS -BdsBootLinuxFdt ( - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* Arguments - ); - /** Start an EFI Application from a Device Path diff --git a/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c deleted file mode 100644 index 76515978fc..0000000000 --- a/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c +++ /dev/null @@ -1,355 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2014, 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 -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ -#include -#include -#include -#include -#include - -#include "BdsInternal.h" -#include "BdsLinuxLoader.h" - -/* - Linux kernel booting: Look at the doc in the Kernel source : - Documentation/arm64/booting.txt - The kernel image must be placed at the start of the memory to be used by the - kernel (2MB aligned) + 0x80000. - - The Device tree blob is expected to be under 2MB and be within the first 512MB - of kernel memory and be 2MB aligned. - - A Flattened Device Tree (FDT) used to boot linux needs to be updated before - the kernel is started. It needs to indicate how secondary cores are brought up - and where they are waiting before loading Linux. The FDT also needs to hold - the correct kernel command line and filesystem RAM-disk information. - At the moment we do not fully support generating this FDT information at - runtime. A prepared FDT should be provided at boot. FDT is the only supported - method for booting the AArch64 Linux kernel. - - Linux does not use any runtime services at this time, so we can let it - overwrite UEFI. -*/ - - -#define LINUX_ALIGN_VAL (0x080000) // 2MB + 0x80000 mask -#define LINUX_ALIGN_MASK (0x1FFFFF) // Bottom 21bits -#define ALIGN_2MB(addr) ALIGN_POINTER(addr , (2*1024*1024)) - -/* ARM32 and AArch64 kernel handover differ. - * x0 is set to FDT base. - * x1-x3 are reserved for future use and should be set to zero. - */ -typedef VOID (*LINUX_KERNEL64)(UINTN ParametersBase, UINTN Reserved0, - UINTN Reserved1, UINTN Reserved2); - -/* These externs are used to relocate some ASM code into Linux memory. */ -extern VOID *SecondariesPenStart; -extern VOID *SecondariesPenEnd; -extern UINTN *AsmMailboxbase; - - -STATIC -EFI_STATUS -PreparePlatformHardware ( - VOID - ) -{ - //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called. - - // Clean before Disable else the Stack gets corrupted with old data. - ArmCleanDataCache (); - ArmDisableDataCache (); - // Invalidate all the entries that might have snuck in. - ArmInvalidateDataCache (); - - // Disable and invalidate the instruction cache - ArmDisableInstructionCache (); - ArmInvalidateInstructionCache (); - - // Turn off MMU - ArmDisableMmu(); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -StartLinux ( - IN EFI_PHYSICAL_ADDRESS LinuxImage, - IN UINTN LinuxImageSize, - IN EFI_PHYSICAL_ADDRESS FdtBlobBase, - IN UINTN FdtBlobSize - ) -{ - EFI_STATUS Status; - LINUX_KERNEL64 LinuxKernel = (LINUX_KERNEL64)LinuxImage; - - // Send msg to secondary cores to go to the kernel pen. - ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId)); - - // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on - // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event. - Status = ShutdownUefiBootServices (); - if(EFI_ERROR(Status)) { - DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status)); - goto Exit; - } - - // Check if the Linux Image is a uImage - if (*(UINTN*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) { - // Assume the Image Entry Point is just after the uImage header (64-byte size) - LinuxKernel = (LINUX_KERNEL64)((UINTN)LinuxKernel + 64); - LinuxImageSize -= 64; - } - - // - // Switch off interrupts, caches, mmu, etc - // - Status = PreparePlatformHardware (); - ASSERT_EFI_ERROR(Status); - - // Register and print out performance information - PERF_END (NULL, "BDS", NULL, 0); - if (PerformanceMeasurementEnabled ()) { - PrintPerformance (); - } - - // - // Start the Linux Kernel - // - - // x1-x3 are reserved (set to zero) for future use. - LinuxKernel ((UINTN)FdtBlobBase, 0, 0, 0); - - // Kernel should never exit - // After Life services are not provided - ASSERT(FALSE); - -Exit: - // Only be here if we fail to start Linux - Print (L"ERROR : Can not start the kernel. Status=0x%X\n", Status); - - // Free Runtimee Memory (kernel and FDT) - return Status; -} - - -/** - Start a Linux kernel from a Device Path - - @param LinuxKernel Device Path to the Linux Kernel - @param Parameters Linux kernel agruments - @param Fdt Device Path to the Flat Device Tree - - @retval EFI_SUCCESS All drivers have been connected - @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found - @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. - -**/ -EFI_STATUS -BdsBootLinuxAtag ( - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* Arguments - ) -{ - // NOTE : AArch64 Linux kernel does not support ATAG, FDT only. - ASSERT(0); - - return RETURN_UNSUPPORTED; -} - -/** - Start a Linux kernel from a Device Path - - @param[in] LinuxKernelDevicePath Device Path to the Linux Kernel - @param[in] InitrdDevicePath Device Path to the Initrd - @param[in] Arguments Linux kernel arguments - - @retval EFI_SUCCESS All drivers have been connected - @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found - @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. - -**/ -EFI_STATUS -BdsBootLinuxFdt ( - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* Arguments - ) -{ - EFI_STATUS Status; - EFI_STATUS PenBaseStatus; - UINTN LinuxImageSize; - UINTN InitrdImageSize; - UINTN InitrdImageBaseSize; - VOID *InstalledFdtBase; - UINTN FdtBlobSize; - EFI_PHYSICAL_ADDRESS FdtBlobBase; - EFI_PHYSICAL_ADDRESS LinuxImage; - EFI_PHYSICAL_ADDRESS InitrdImage; - EFI_PHYSICAL_ADDRESS InitrdImageBase; - ARM_PROCESSOR_TABLE *ArmProcessorTable; - ARM_CORE_INFO *ArmCoreInfoTable; - UINTN Index; - EFI_PHYSICAL_ADDRESS PenBase; - UINTN PenSize; - UINTN MailBoxBase; - - PenBaseStatus = EFI_UNSUPPORTED; - PenSize = 0; - InitrdImage = 0; - InitrdImageSize = 0; - InitrdImageBase = 0; - InitrdImageBaseSize = 0; - - PERF_START (NULL, "BDS", NULL, 0); - - // - // Load the Linux kernel from a device path - // - - // 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. - LinuxImage = PcdGet64 (PcdSystemMemoryBase) + 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; - Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize); - if (EFI_ERROR(Status)) { - Print (L"ERROR: Did not find Linux kernel (%r).\n", Status); - return Status; - } - } - // Adjust the kernel location slightly if required. The kernel needs to be placed at start - // of memory (2MB aligned) + 0x80000. - if ((LinuxImage & LINUX_ALIGN_MASK) != LINUX_ALIGN_VAL) { - LinuxImage = (EFI_PHYSICAL_ADDRESS)CopyMem (ALIGN_2MB(LinuxImage) + 0x80000, (VOID*)(UINTN)LinuxImage, LinuxImageSize); - } - - if (InitrdDevicePath) { - InitrdImageBase = LINUX_KERNEL_MAX_OFFSET; - Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize); - if (Status == EFI_OUT_OF_RESOURCES) { - Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize); - } - if (EFI_ERROR (Status)) { - Print (L"ERROR: Did not find initrd image (%r).\n", Status); - goto EXIT_FREE_LINUX; - } - - // Check if the initrd is a uInitrd - if (*(UINTN*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) { - // Skip the 64-byte image header - InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64); - InitrdImageSize = InitrdImageBaseSize - 64; - } else { - InitrdImage = InitrdImageBase; - InitrdImageSize = InitrdImageBaseSize; - } - } - - // - // Get the FDT from the Configuration Table. - // The FDT will be reloaded in PrepareFdt() to a more appropriate - // location for the Linux Kernel. - // - Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &InstalledFdtBase); - if (EFI_ERROR (Status)) { - Print (L"ERROR: Did not get the Device Tree blob (%r).\n", Status); - goto EXIT_FREE_INITRD; - } - FdtBlobBase = (EFI_PHYSICAL_ADDRESS)InstalledFdtBase; - FdtBlobSize = fdt_totalsize (InstalledFdtBase); - - // - // Install secondary core pens if the Power State Coordination Interface is not supported - // - if (FeaturePcdGet (PcdArmLinuxSpinTable)) { - // Place Pen at the start of Linux memory. We can then tell Linux to not use this bit of memory - PenBase = LinuxImage - 0x80000; - PenSize = (UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart; - - // Reserve the memory as RuntimeServices - PenBaseStatus = gBS->AllocatePages (AllocateAddress, EfiRuntimeServicesCode, EFI_SIZE_TO_PAGES (PenSize), &PenBase); - if (EFI_ERROR (PenBaseStatus)) { - Print (L"Warning: Failed to reserve the memory required for the secondary cores at 0x%lX, Status = %r\n", PenBase, PenBaseStatus); - // Even if there is a risk of memory corruption we carry on - } - - // Put mailboxes below the pen code so we know where they are relative to code. - MailBoxBase = (UINTN)PenBase + ((UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart); - // Make sure this is 8 byte aligned. - if (MailBoxBase % sizeof(MailBoxBase) != 0) { - MailBoxBase += sizeof(MailBoxBase) - MailBoxBase % sizeof(MailBoxBase); - } - - CopyMem ( (VOID*)(PenBase), (VOID*)&SecondariesPenStart, PenSize); - - // Update the MailboxBase variable used in the pen code - *(UINTN*)(PenBase + ((UINTN)&AsmMailboxbase - (UINTN)&SecondariesPenStart)) = MailBoxBase; - - for (Index=0; Index < gST->NumberOfTableEntries; Index++) { - // Check for correct GUID type - if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { - UINTN i; - - // Get them under our control. Move from depending on 32bit reg(sys_flags) and SWI - // to 64 bit addr and WFE - ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable; - ArmCoreInfoTable = ArmProcessorTable->ArmCpus; - - for (i = 0; i < ArmProcessorTable->NumberOfEntries; i++ ) { - // This goes into the SYSFLAGS register for the VE platform. We only have one 32bit reg to use - MmioWrite32(ArmCoreInfoTable[i].MailboxSetAddress, (UINTN)PenBase); - - // So FDT can set the mailboxes correctly with the parser. These are 64bit Memory locations. - ArmCoreInfoTable[i].MailboxSetAddress = (UINTN)MailBoxBase + i*sizeof(MailBoxBase); - - // Clear the mailboxes for the respective cores - *((UINTN*)(ArmCoreInfoTable[i].MailboxSetAddress)) = 0x0; - } - } - } - // Flush caches to make sure our pen gets to mem before we free the cores. - ArmCleanDataCache(); - } - - // By setting address=0 we leave the memory allocation to the function - Status = PrepareFdt (Arguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize); - if (EFI_ERROR(Status)) { - Print(L"ERROR: Can not load Linux kernel with Device Tree. Status=0x%X\n", Status); - goto EXIT_FREE_FDT; - } - - return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize); - -EXIT_FREE_FDT: - if (!EFI_ERROR (PenBaseStatus)) { - gBS->FreePages (PenBase, EFI_SIZE_TO_PAGES (PenSize)); - } - - gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize)); - -EXIT_FREE_INITRD: - if (InitrdDevicePath) { - gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize)); - } - -EXIT_FREE_LINUX: - gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize)); - - return Status; -} diff --git a/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S b/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S deleted file mode 100644 index 525c1287ef..0000000000 --- a/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S +++ /dev/null @@ -1,58 +0,0 @@ -// -// 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 -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// - - -/* Secondary core pens for AArch64 Linux booting. - - This code it placed in Linux kernel memory and marked reserved. UEFI ensures - that the secondary cores get to this pen and the kernel can then start the - cores from here. - NOTE: This code must be self-contained. -*/ - -#include - -.text -.align 3 - -GCC_ASM_EXPORT(SecondariesPenStart) -ASM_GLOBAL SecondariesPenEnd - -ASM_PFX(SecondariesPenStart): - // Registers x0-x3 are reserved for future use and should be set to zero. - mov x0, xzr - mov x1, xzr - mov x2, xzr - mov x3, xzr - - // Get core position. Taken from ArmPlatformGetCorePosition(). - // Assumes max 4 cores per cluster. - mrs x4, mpidr_el1 // Get MPCore register. - and x5, x4, #ARM_CORE_MASK // Get core number. - and x4, x4, #ARM_CLUSTER_MASK // Get cluster number. - add x4, x5, x4, LSR #6 // Add scaled cluster number to core number. - lsl x4, x4, 3 // Get mailbox offset for this core. - ldr x5, AsmMailboxbase // Get mailbox addr relative to pc (36 bytes ahead). - add x4, x4, x5 // Add core mailbox offset to base of mailbox. -1: ldr x5, [x4] // Load value from mailbox. - cmp xzr, x5 // Has the mailbox been set? - b.ne 2f // If so break out of loop. - wfe // If not, wait a bit. - b 1b // Wait over, check if mailbox set again. -2: br x5 // Jump to mailbox value. - -.align 3 // Make sure the variable below is 8 byte aligned. - .global AsmMailboxbase -AsmMailboxbase: .xword 0xdeaddeadbeefbeef - -SecondariesPenEnd: diff --git a/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c b/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c deleted file mode 100644 index 33c27988ad..0000000000 --- a/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c +++ /dev/null @@ -1,173 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2012, 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 -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#include "BdsInternal.h" -#include "BdsLinuxLoader.h" - -// Point to the current ATAG -STATIC LINUX_ATAG *mLinuxKernelCurrentAtag; - -STATIC -VOID -SetupCoreTag ( - IN UINT32 PageSize - ) -{ - mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_CORE); - mLinuxKernelCurrentAtag->header.type = ATAG_CORE; - - mLinuxKernelCurrentAtag->body.core_tag.flags = 1; /* ensure read-only */ - mLinuxKernelCurrentAtag->body.core_tag.pagesize = PageSize; /* systems PageSize (4k) */ - mLinuxKernelCurrentAtag->body.core_tag.rootdev = 0; /* zero root device (typically overridden from kernel command line )*/ - - // move pointer to next tag - mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag); -} - -STATIC -VOID -SetupMemTag ( - IN UINTN StartAddress, - IN UINT32 Size - ) -{ - mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_MEM); - mLinuxKernelCurrentAtag->header.type = ATAG_MEM; - - mLinuxKernelCurrentAtag->body.mem_tag.start = StartAddress; /* Start of memory chunk for AtagMem */ - mLinuxKernelCurrentAtag->body.mem_tag.size = Size; /* Size of memory chunk for AtagMem */ - - // move pointer to next tag - mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag); -} - -STATIC -VOID -SetupCmdlineTag ( - IN CONST CHAR8 *CmdLine - ) -{ - UINT32 LineLength; - - // Increment the line length by 1 to account for the null string terminator character - LineLength = AsciiStrLen(CmdLine) + 1; - - /* Check for NULL strings. - * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer. - * Remember, you have at least one null string terminator character. - */ - if(LineLength > 1) { - mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof(LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2; - mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE; - - /* place CommandLine into tag */ - AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine); - - // move pointer to next tag - mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag); - } -} - -STATIC -VOID -SetupInitrdTag ( - IN UINT32 InitrdImage, - IN UINT32 InitrdImageSize - ) -{ - mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_INITRD2); - mLinuxKernelCurrentAtag->header.type = ATAG_INITRD2; - - mLinuxKernelCurrentAtag->body.initrd2_tag.start = InitrdImage; - mLinuxKernelCurrentAtag->body.initrd2_tag.size = InitrdImageSize; - - // Move pointer to next tag - mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag); -} -STATIC -VOID -SetupEndTag ( - VOID - ) -{ - // Empty tag ends list; this has zero length and no body - mLinuxKernelCurrentAtag->header.type = ATAG_NONE; - mLinuxKernelCurrentAtag->header.size = 0; - - /* We can not calculate the next address by using the standard macro: - * Params = next_tag_address(Params); - * because it relies on the header.size, which here it is 0 (zero). - * The easiest way is to add the sizeof(mLinuxKernelCurrentAtag->header). - */ - mLinuxKernelCurrentAtag = (LINUX_ATAG*)((UINT32)mLinuxKernelCurrentAtag + sizeof(mLinuxKernelCurrentAtag->header)); -} - -EFI_STATUS -PrepareAtagList ( - IN CONST CHAR8* CommandLineString, - IN EFI_PHYSICAL_ADDRESS InitrdImage, - IN UINTN InitrdImageSize, - OUT EFI_PHYSICAL_ADDRESS *AtagBase, - OUT UINT32 *AtagSize - ) -{ - EFI_STATUS Status; - LIST_ENTRY *ResourceLink; - LIST_ENTRY ResourceList; - EFI_PHYSICAL_ADDRESS AtagStartAddress; - BDS_SYSTEM_MEMORY_RESOURCE *Resource; - - AtagStartAddress = LINUX_ATAG_MAX_OFFSET; - 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)); - Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress); - ASSERT_EFI_ERROR(Status); - } - - // Ready to setup the atag list - mLinuxKernelCurrentAtag = (LINUX_ATAG*)(UINTN)AtagStartAddress; - - // Standard core tag 4k PageSize - SetupCoreTag( (UINT32)SIZE_4KB ); - - // Physical memory setup - GetSystemMemoryResources (&ResourceList); - ResourceLink = ResourceList.ForwardLink; - while (ResourceLink != NULL && ResourceLink != &ResourceList) { - Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceLink; - DEBUG((EFI_D_INFO,"- [0x%08X,0x%08X]\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->PhysicalStart+(UINT32)Resource->ResourceLength)); - SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength ); - ResourceLink = ResourceLink->ForwardLink; - } - - // CommandLine setting root device - if (CommandLineString) { - SetupCmdlineTag (CommandLineString); - } - - if (InitrdImageSize > 0 && InitrdImage != 0) { - SetupInitrdTag ((UINT32)InitrdImage, (UINT32)InitrdImageSize); - } - - // End of tags - SetupEndTag(); - - // Calculate atag list size - *AtagBase = AtagStartAddress; - *AtagSize = (UINT32)mLinuxKernelCurrentAtag - (UINT32)AtagStartAddress + 1; - - return EFI_SUCCESS; -} - diff --git a/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c deleted file mode 100644 index e5fda081f8..0000000000 --- a/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c +++ /dev/null @@ -1,323 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2014, 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 -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#include -#include - -#include "BdsInternal.h" -#include "BdsLinuxLoader.h" - -#define ALIGN32_BELOW(addr) ALIGN_POINTER(addr - 32,32) - -#define IS_ADDRESS_IN_REGION(RegionStart, RegionSize, Address) \ - (((UINTN)(RegionStart) <= (UINTN)(Address)) && ((UINTN)(Address) <= ((UINTN)(RegionStart) + (UINTN)(RegionSize)))) - -STATIC -EFI_STATUS -PreparePlatformHardware ( - VOID - ) -{ - //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called. - - // Clean before Disable else the Stack gets corrupted with old data. - ArmCleanDataCache (); - ArmDisableDataCache (); - // Invalidate all the entries that might have snuck in. - ArmInvalidateDataCache (); - - // Invalidate and disable the Instruction cache - ArmDisableInstructionCache (); - ArmInvalidateInstructionCache (); - - // Turn off MMU - ArmDisableMmu(); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -StartLinux ( - IN EFI_PHYSICAL_ADDRESS LinuxImage, - IN UINTN LinuxImageSize, - IN EFI_PHYSICAL_ADDRESS KernelParamsAddress, - IN UINTN KernelParamsSize, - IN UINT32 MachineType - ) -{ - EFI_STATUS Status; - LINUX_KERNEL LinuxKernel; - - // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on - // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event. - Status = ShutdownUefiBootServices (); - if(EFI_ERROR(Status)) { - DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status)); - goto Exit; - } - - // Move the kernel parameters to any address inside the first 1MB. - // This is necessary because the ARM Linux kernel requires - // the FTD / ATAG List to reside entirely inside the first 1MB of - // 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); - } - } 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)LinuxImage > LINUX_KERNEL_MAX_OFFSET) { - //Note: There is no requirement on the alignment - LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize); - } else { - LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage; - } - - // Check if the Linux Image is a uImage - if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) { - // Assume the Image Entry Point is just after the uImage header (64-byte size) - LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64); - LinuxImageSize -= 64; - } - - // Check there is no overlapping between kernel and its parameters - // We can only assert because it is too late to fallback to UEFI (ExitBootServices has been called). - ASSERT (!IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress) && - !IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress + KernelParamsSize)); - - // - // Switch off interrupts, caches, mmu, etc - // - Status = PreparePlatformHardware (); - ASSERT_EFI_ERROR(Status); - - // Register and print out performance information - PERF_END (NULL, "BDS", NULL, 0); - if (PerformanceMeasurementEnabled ()) { - PrintPerformance (); - } - - // - // Start the Linux Kernel - // - - // Outside BootServices, so can't use Print(); - DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n")); - - // Jump to kernel with register set - LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress); - - // Kernel should never exit - // After Life services are not provided - ASSERT(FALSE); - -Exit: - // Only be here if we fail to start Linux - Print (L"ERROR : Can not start the kernel. Status=0x%X\n", Status); - - // Free Runtimee Memory (kernel and FDT) - return Status; -} - -/** - Start a Linux kernel from a Device Path - - @param LinuxKernel Device Path to the Linux Kernel - @param Parameters Linux kernel arguments - @param Fdt Device Path to the Flat Device Tree - - @retval EFI_SUCCESS All drivers have been connected - @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found - @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. - -**/ -EFI_STATUS -BdsBootLinuxAtag ( - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* CommandLineArguments - ) -{ - EFI_STATUS Status; - UINT32 LinuxImageSize; - UINT32 InitrdImageBaseSize = 0; - UINT32 InitrdImageSize = 0; - UINT32 AtagSize; - EFI_PHYSICAL_ADDRESS AtagBase; - EFI_PHYSICAL_ADDRESS LinuxImage; - EFI_PHYSICAL_ADDRESS InitrdImageBase = 0; - EFI_PHYSICAL_ADDRESS InitrdImage = 0; - - PERF_START (NULL, "BDS", NULL, 0); - - // Load the Linux kernel from a device path - LinuxImage = LINUX_KERNEL_MAX_OFFSET; - Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize); - if (EFI_ERROR(Status)) { - Print (L"ERROR: Did not find Linux kernel.\n"); - return Status; - } - - if (InitrdDevicePath) { - // Load the initrd near to the Linux kernel - InitrdImageBase = LINUX_KERNEL_MAX_OFFSET; - Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize); - if (Status == EFI_OUT_OF_RESOURCES) { - Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize); - } - if (EFI_ERROR(Status)) { - Print (L"ERROR: Did not find initrd image.\n"); - goto EXIT_FREE_LINUX; - } - - // Check if the initrd is a uInitrd - if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) { - // Skip the 64-byte image header - InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64); - InitrdImageSize = InitrdImageBaseSize - 64; - } else { - InitrdImage = InitrdImageBase; - InitrdImageSize = InitrdImageBaseSize; - } - } - - // - // Setup the Linux Kernel Parameters - // - - // By setting address=0 we leave the memory allocation to the function - Status = PrepareAtagList (CommandLineArguments, InitrdImage, InitrdImageSize, &AtagBase, &AtagSize); - if (EFI_ERROR(Status)) { - Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status); - goto EXIT_FREE_INITRD; - } - - return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType)); - -EXIT_FREE_INITRD: - if (InitrdDevicePath) { - gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize)); - } - -EXIT_FREE_LINUX: - gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize)); - - return Status; -} - -/** - Start a Linux kernel from a Device Path - - @param LinuxKernelDevicePath Device Path to the Linux Kernel - @param InitrdDevicePath Device Path to the Initrd - @param CommandLineArguments Linux command line - - @retval EFI_SUCCESS All drivers have been connected - @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found - @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. - -**/ -EFI_STATUS -BdsBootLinuxFdt ( - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* CommandLineArguments - ) -{ - EFI_STATUS Status; - UINT32 LinuxImageSize; - UINT32 InitrdImageBaseSize = 0; - UINT32 InitrdImageSize = 0; - VOID *InstalledFdtBase; - UINT32 FdtBlobSize; - EFI_PHYSICAL_ADDRESS FdtBlobBase; - EFI_PHYSICAL_ADDRESS LinuxImage; - EFI_PHYSICAL_ADDRESS InitrdImageBase = 0; - EFI_PHYSICAL_ADDRESS InitrdImage = 0; - - PERF_START (NULL, "BDS", NULL, 0); - - // Load the Linux kernel from a device path - LinuxImage = LINUX_KERNEL_MAX_OFFSET; - Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize); - if (EFI_ERROR(Status)) { - Print (L"ERROR: Did not find Linux kernel.\n"); - return Status; - } - - if (InitrdDevicePath) { - InitrdImageBase = LINUX_KERNEL_MAX_OFFSET; - Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize); - if (Status == EFI_OUT_OF_RESOURCES) { - Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize); - } - if (EFI_ERROR(Status)) { - Print (L"ERROR: Did not find initrd image.\n"); - goto EXIT_FREE_LINUX; - } - - // Check if the initrd is a uInitrd - if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) { - // Skip the 64-byte image header - InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64); - InitrdImageSize = InitrdImageBaseSize - 64; - } else { - InitrdImage = InitrdImageBase; - InitrdImageSize = InitrdImageBaseSize; - } - } - - // - // Get the FDT from the Configuration Table. - // The FDT will be reloaded in PrepareFdt() to a more appropriate - // location for the Linux Kernel. - // - Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &InstalledFdtBase); - if (EFI_ERROR (Status)) { - Print (L"ERROR: Did not get the Device Tree blob (%r).\n", Status); - goto EXIT_FREE_INITRD; - } - FdtBlobBase = (EFI_PHYSICAL_ADDRESS)(UINTN)InstalledFdtBase; - FdtBlobSize = fdt_totalsize (InstalledFdtBase); - - // Update the Fdt with the Initrd information. The FDT will increase in size. - // By setting address=0 we leave the memory allocation to the function - Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize); - if (EFI_ERROR(Status)) { - Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status); - goto EXIT_FREE_FDT; - } - - return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE); - -EXIT_FREE_FDT: - gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize)); - -EXIT_FREE_INITRD: - if (InitrdDevicePath) { - gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize)); - } - -EXIT_FREE_LINUX: - gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize)); - - return Status; -} - diff --git a/ArmPkg/Library/BdsLib/BdsHelper.c b/ArmPkg/Library/BdsLib/BdsHelper.c index 7f83c2be8a..b10fe2074d 100644 --- a/ArmPkg/Library/BdsLib/BdsHelper.c +++ b/ArmPkg/Library/BdsLib/BdsHelper.c @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011-2013, ARM Limited. All rights reserved. +* Copyright (c) 2011-2015, 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 @@ -14,19 +14,6 @@ #include "BdsInternal.h" -#include -#include -#include -#include - -STATIC CHAR8 *mTokenList[] = { - /*"SEC",*/ - "PEI", - "DXE", - "BDS", - NULL -}; - EFI_STATUS ShutdownUefiBootServices ( VOID @@ -129,169 +116,6 @@ BdsConnectAllDrivers ( return EFI_SUCCESS; } -STATIC -EFI_STATUS -InsertSystemMemoryResources ( - LIST_ENTRY *ResourceList, - EFI_HOB_RESOURCE_DESCRIPTOR *ResHob - ) -{ - BDS_SYSTEM_MEMORY_RESOURCE *NewResource; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - LIST_ENTRY AttachedResources; - BDS_SYSTEM_MEMORY_RESOURCE *Resource; - EFI_PHYSICAL_ADDRESS NewResourceEnd; - - if (IsListEmpty (ResourceList)) { - NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE)); - NewResource->PhysicalStart = ResHob->PhysicalStart; - NewResource->ResourceLength = ResHob->ResourceLength; - InsertTailList (ResourceList, &NewResource->Link); - return EFI_SUCCESS; - } - - InitializeListHead (&AttachedResources); - - Link = ResourceList->ForwardLink; - ASSERT (Link != NULL); - while (Link != ResourceList) { - Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link; - - // Sanity Check. The resources should not overlapped. - ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength)))); - ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) && - ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength)))); - - // The new resource is attached after this resource descriptor - if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) { - Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength; - - NextLink = RemoveEntryList (&Resource->Link); - InsertTailList (&AttachedResources, &Resource->Link); - Link = NextLink; - } - // The new resource is attached before this resource descriptor - else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) { - Resource->PhysicalStart = ResHob->PhysicalStart; - Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength; - - NextLink = RemoveEntryList (&Resource->Link); - InsertTailList (&AttachedResources, &Resource->Link); - Link = NextLink; - } else { - Link = Link->ForwardLink; - } - } - - if (!IsListEmpty (&AttachedResources)) { - // See if we can merge the attached resource with other resources - - NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources); - Link = RemoveEntryList (&NewResource->Link); - while (!IsListEmpty (&AttachedResources)) { - // Merge resources - Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link; - - // Ensure they overlap each other - ASSERT( - ((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) || - (((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength))) - ); - - NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength); - NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart); - NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart; - - Link = RemoveEntryList (Link); - } - } else { - // None of the Resource of the list is attached to this ResHob. Create a new entry for it - NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE)); - NewResource->PhysicalStart = ResHob->PhysicalStart; - NewResource->ResourceLength = ResHob->ResourceLength; - } - InsertTailList (ResourceList, &NewResource->Link); - return EFI_SUCCESS; -} - -EFI_STATUS -GetSystemMemoryResources ( - IN LIST_ENTRY *ResourceList - ) -{ - EFI_HOB_RESOURCE_DESCRIPTOR *ResHob; - - InitializeListHead (ResourceList); - - // Find the first System Memory Resource Descriptor - ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); - while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) { - ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); - } - - // Did not find any - if (ResHob == NULL) { - return EFI_NOT_FOUND; - } else { - InsertSystemMemoryResources (ResourceList, ResHob); - } - - ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); - while (ResHob != NULL) { - if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { - InsertSystemMemoryResources (ResourceList, ResHob); - } - ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); - } - - return EFI_SUCCESS; -} - -VOID -PrintPerformance ( - VOID - ) -{ - UINTN Key; - CONST VOID *Handle; - CONST CHAR8 *Token, *Module; - UINT64 Start, Stop, TimeStamp; - UINT64 Delta, TicksPerSecond, Milliseconds; - UINTN Index; - CHAR8 Buffer[100]; - UINTN CharCount; - BOOLEAN CountUp; - - TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop); - if (Start < Stop) { - CountUp = TRUE; - } else { - CountUp = FALSE; - } - - TimeStamp = 0; - Key = 0; - do { - Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop); - if (Key != 0) { - for (Index = 0; mTokenList[Index] != NULL; Index++) { - if (AsciiStriCmp (mTokenList[Index], Token) == 0) { - Delta = CountUp?(Stop - Start):(Start - Stop); - TimeStamp += Delta; - Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL); - CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"%6a %6ld ms\n", Token, Milliseconds); - SerialPortWrite ((UINT8 *) Buffer, CharCount); - break; - } - } - } - } while (Key != 0); - - CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL)); - SerialPortWrite ((UINT8 *) Buffer, CharCount); -} - EFI_STATUS GetGlobalEnvironmentVariable ( IN CONST CHAR16* VariableName, diff --git a/ArmPkg/Library/BdsLib/BdsInternal.h b/ArmPkg/Library/BdsLib/BdsInternal.h index 1fab2aed4a..f70aae603d 100644 --- a/ArmPkg/Library/BdsLib/BdsInternal.h +++ b/ArmPkg/Library/BdsLib/BdsInternal.h @@ -28,11 +28,9 @@ #include #include #include -#include #include #include -#include #include #include @@ -102,17 +100,6 @@ typedef struct { UINT64 LastReportedNbOfBytes; } BDS_TFTP_CONTEXT; -// BdsHelper.c -EFI_STATUS -GetSystemMemoryResources ( - LIST_ENTRY *ResourceList - ); - -VOID -PrintPerformance ( - VOID - ); - EFI_STATUS BdsLoadImage ( IN EFI_DEVICE_PATH *DevicePath, diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf index ecf6de52d0..eb4543eb20 100644 --- a/ArmPkg/Library/BdsLib/BdsLib.inf +++ b/ArmPkg/Library/BdsLib/BdsLib.inf @@ -25,15 +25,6 @@ BdsAppLoader.c BdsHelper.c BdsLoadOption.c - BdsLinuxFdt.c - -[Sources.ARM] - Arm/BdsLinuxLoader.c - Arm/BdsLinuxAtag.c - -[Sources.AARCH64] - AArch64/BdsLinuxLoader.c - AArch64/BdsLinuxLoaderHelper.S [Packages] EmbeddedPkg/EmbeddedPkg.dec @@ -44,26 +35,16 @@ [LibraryClasses] ArmLib - ArmSmcLib BaseLib DebugLib DevicePathLib HobLib PcdLib - PerformanceLib - SerialPortLib - FdtLib - TimerLib NetLib -[LibraryClasses.AARCH64] - ArmGicLib - [Guids] gEfiFileInfoGuid - gArmMpCoreInfoGuid gArmGlobalVariableGuid - gFdtTableGuid [Protocols] gEfiBdsArchProtocolGuid @@ -82,27 +63,8 @@ gEfiMtftp4ServiceBindingProtocolGuid gEfiMtftp4ProtocolGuid -[FeaturePcd] - gArmTokenSpaceGuid.PcdArmLinuxSpinTable - -[Pcd] - gArmTokenSpaceGuid.PcdSystemMemoryBase - gArmTokenSpaceGuid.PcdSystemMemorySize - [FixedPcd] - gArmTokenSpaceGuid.PcdArmMachineType - gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset - gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment - gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset - gArmTokenSpaceGuid.PcdMaxTftpFileSize -[FixedPcd.ARM] - gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset - -[Pcd.AARCH64] - gArmTokenSpaceGuid.PcdGicDistributorBase - gArmTokenSpaceGuid.PcdGicSgiIntId - [Depex] TRUE diff --git a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c deleted file mode 100644 index e3795527f2..0000000000 --- a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c +++ /dev/null @@ -1,572 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2014, 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 -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#include -#include -#include - -#include "BdsInternal.h" -#include "BdsLinuxLoader.h" - -#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) -#define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a)))) -#define GET_CELL(p) (p += 4, *((const UINT32 *)(p-4))) - -STATIC -UINTN -cpu_to_fdtn (UINTN x) { - if (sizeof (UINTN) == sizeof (UINT32)) { - return cpu_to_fdt32 (x); - } else { - return cpu_to_fdt64 (x); - } -} - -typedef struct { - UINTN Base; - UINTN Size; -} FdtRegion; - - -STATIC -UINTN -IsPrintableString ( - IN CONST VOID* data, - IN UINTN len - ) -{ - CONST CHAR8 *s = data; - CONST CHAR8 *ss; - - // Zero length is not - if (len == 0) { - return 0; - } - - // Must terminate with zero - if (s[len - 1] != '\0') { - return 0; - } - - ss = s; - while (*s/* && isprint(*s)*/) { - s++; - } - - // Not zero, or not done yet - if (*s != '\0' || (s + 1 - ss) < len) { - return 0; - } - - return 1; -} - -STATIC -VOID -PrintData ( - IN CONST CHAR8* data, - IN UINTN len - ) -{ - UINTN i; - CONST CHAR8 *p = data; - - // No data, don't print - if (len == 0) - return; - - if (IsPrintableString (data, len)) { - Print(L" = \"%a\"", (const char *)data); - } else if ((len % 4) == 0) { - Print(L" = <"); - for (i = 0; i < len; i += 4) { - Print(L"0x%08x%a", fdt32_to_cpu(GET_CELL(p)),i < (len - 4) ? " " : ""); - } - Print(L">"); - } else { - Print(L" = ["); - for (i = 0; i < len; i++) - Print(L"%02x%a", *p++, i < len - 1 ? " " : ""); - Print(L"]"); - } -} - -VOID -DebugDumpFdt ( - IN VOID* FdtBlob - ) -{ - struct fdt_header *bph; - UINT32 off_dt; - UINT32 off_str; - CONST CHAR8* p_struct; - CONST CHAR8* p_strings; - CONST CHAR8* p; - CONST CHAR8* s; - CONST CHAR8* t; - UINT32 tag; - UINTN sz; - UINTN depth; - UINTN shift; - UINT32 version; - - { - // Can 'memreserve' be printed by below code? - INTN num = fdt_num_mem_rsv(FdtBlob); - INTN i, err; - UINT64 addr = 0,size = 0; - - for (i = 0; i < num; i++) { - err = fdt_get_mem_rsv(FdtBlob, i, &addr, &size); - if (err) { - DEBUG((EFI_D_ERROR, "Error (%d) : Cannot get memreserve section (%d)\n", err, i)); - } - else { - Print(L"/memreserve/ \t0x%lx \t0x%lx;\n",addr,size); - } - } - } - - depth = 0; - shift = 4; - - bph = FdtBlob; - off_dt = fdt32_to_cpu(bph->off_dt_struct); - off_str = fdt32_to_cpu(bph->off_dt_strings); - p_struct = (CONST CHAR8*)FdtBlob + off_dt; - p_strings = (CONST CHAR8*)FdtBlob + off_str; - version = fdt32_to_cpu(bph->version); - - p = p_struct; - while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) { - if (tag == FDT_BEGIN_NODE) { - s = p; - p = PALIGN(p + AsciiStrLen (s) + 1, 4); - - if (*s == '\0') - s = "/"; - - Print(L"%*s%a {\n", depth * shift, L" ", s); - - depth++; - continue; - } - - if (tag == FDT_END_NODE) { - depth--; - - Print(L"%*s};\n", depth * shift, L" "); - continue; - } - - if (tag == FDT_NOP) { - Print(L"%*s// [NOP]\n", depth * shift, L" "); - continue; - } - - if (tag != FDT_PROP) { - Print(L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag); - break; - } - sz = fdt32_to_cpu(GET_CELL(p)); - s = p_strings + fdt32_to_cpu(GET_CELL(p)); - if (version < 16 && sz >= 8) - p = PALIGN(p, 8); - t = p; - - p = PALIGN(p + sz, 4); - - Print(L"%*s%a", depth * shift, L" ", s); - PrintData(t, sz); - Print(L";\n"); - } -} - -STATIC -BOOLEAN -IsLinuxReservedRegion ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - switch(MemoryType) { - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - case EfiUnusableMemory: - case EfiACPIReclaimMemory: - case EfiACPIMemoryNVS: - case EfiReservedMemoryType: - return TRUE; - default: - return FALSE; - } -} - -/** -** Relocate the FDT blob to a more appropriate location for the Linux kernel. -** This function will allocate memory for the relocated FDT blob. -** -** @retval EFI_SUCCESS on success. -** @retval EFI_OUT_OF_RESOURCES or EFI_INVALID_PARAMETER on failure. -*/ -STATIC -EFI_STATUS -RelocateFdt ( - EFI_PHYSICAL_ADDRESS OriginalFdt, - UINTN OriginalFdtSize, - EFI_PHYSICAL_ADDRESS *RelocatedFdt, - UINTN *RelocatedFdtSize, - EFI_PHYSICAL_ADDRESS *RelocatedFdtAlloc - ) -{ - 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; - } - - // Try below a watermark address. - Status = EFI_NOT_FOUND; - if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) { - *RelocatedFdt = LINUX_FDT_MAX_OFFSET; - Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, - EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_WARN, "Warning: Failed to load FDT below address 0x%lX (%r). Will try again at a random address anywhere.\n", *RelocatedFdt, Status)); - } - } - - // Try anywhere there is available space. - if (EFI_ERROR (Status)) { - Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, - EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return EFI_OUT_OF_RESOURCES; - } else { - DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", *RelocatedFdt)); - } - } - - *RelocatedFdtAlloc = *RelocatedFdt; - if (FdtAlignment != 0) { - *RelocatedFdt = ALIGN (*RelocatedFdt, FdtAlignment); - } - - // Load the Original FDT tree into the new region - Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt, - (VOID*)(UINTN)(*RelocatedFdt), *RelocatedFdtSize); - if (Error) { - DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Error))); - gBS->FreePages (*RelocatedFdtAlloc, EFI_SIZE_TO_PAGES (*RelocatedFdtSize)); - return EFI_INVALID_PARAMETER; - } - - DEBUG_CODE_BEGIN(); - //DebugDumpFdt (fdt); - DEBUG_CODE_END(); - - return EFI_SUCCESS; -} - - -EFI_STATUS -PrepareFdt ( - IN CONST CHAR8* CommandLineArguments, - IN EFI_PHYSICAL_ADDRESS InitrdImage, - IN UINTN InitrdImageSize, - IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase, - IN OUT UINTN *FdtBlobSize - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS NewFdtBlobBase; - EFI_PHYSICAL_ADDRESS NewFdtBlobAllocation; - UINTN NewFdtBlobSize; - VOID* fdt; - INTN err; - INTN node; - INTN cpu_node; - INT32 lenp; - CONST VOID* BootArg; - CONST VOID* Method; - EFI_PHYSICAL_ADDRESS InitrdImageStart; - EFI_PHYSICAL_ADDRESS InitrdImageEnd; - FdtRegion Region; - UINTN Index; - CHAR8 Name[10]; - LIST_ENTRY ResourceList; - BDS_SYSTEM_MEMORY_RESOURCE *Resource; - ARM_PROCESSOR_TABLE *ArmProcessorTable; - ARM_CORE_INFO *ArmCoreInfoTable; - UINT32 MpId; - UINT32 ClusterId; - UINT32 CoreId; - UINT64 CpuReleaseAddr; - UINTN MemoryMapSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - EFI_MEMORY_DESCRIPTOR *MemoryMapPtr; - UINTN MapKey; - UINTN DescriptorSize; - UINT32 DescriptorVersion; - UINTN Pages; - UINTN OriginalFdtSize; - BOOLEAN CpusNodeExist; - UINTN CoreMpId; - - NewFdtBlobAllocation = 0; - - // - // Sanity checks on the original FDT blob. - // - err = fdt_check_header ((VOID*)(UINTN)(*FdtBlobBase)); - if (err != 0) { - Print (L"ERROR: Device Tree header not valid (err:%d)\n", err); - return EFI_INVALID_PARAMETER; - } - - // The original FDT blob might have been loaded partially. - // Check that it is not the case. - OriginalFdtSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase)); - if (OriginalFdtSize > *FdtBlobSize) { - Print (L"ERROR: Incomplete FDT. Only %d/%d bytes have been loaded.\n", - *FdtBlobSize, OriginalFdtSize); - return EFI_INVALID_PARAMETER; - } - - // - // Relocate the FDT to its final location. - // - Status = RelocateFdt (*FdtBlobBase, OriginalFdtSize, - &NewFdtBlobBase, &NewFdtBlobSize, &NewFdtBlobAllocation); - if (EFI_ERROR (Status)) { - goto FAIL_RELOCATE_FDT; - } - - fdt = (VOID*)(UINTN)NewFdtBlobBase; - - node = fdt_subnode_offset (fdt, 0, "chosen"); - if (node < 0) { - // The 'chosen' node does not exist, create it - node = fdt_add_subnode(fdt, 0, "chosen"); - if (node < 0) { - DEBUG((EFI_D_ERROR,"Error on finding 'chosen' node\n")); - Status = EFI_INVALID_PARAMETER; - goto FAIL_COMPLETE_FDT; - } - } - - DEBUG_CODE_BEGIN(); - BootArg = fdt_getprop(fdt, node, "bootargs", &lenp); - if (BootArg != NULL) { - DEBUG((EFI_D_ERROR,"BootArg: %a\n",BootArg)); - } - DEBUG_CODE_END(); - - // - // Set Linux CmdLine - // - if ((CommandLineArguments != NULL) && (AsciiStrLen (CommandLineArguments) > 0)) { - err = fdt_setprop(fdt, node, "bootargs", CommandLineArguments, AsciiStrSize(CommandLineArguments)); - if (err) { - DEBUG((EFI_D_ERROR,"Fail to set new 'bootarg' (err:%d)\n",err)); - } - } - - // - // Set Linux Initrd - // - if (InitrdImageSize != 0) { - InitrdImageStart = cpu_to_fdt64 (InitrdImage); - err = fdt_setprop(fdt, node, "linux,initrd-start", &InitrdImageStart, sizeof(EFI_PHYSICAL_ADDRESS)); - if (err) { - DEBUG((EFI_D_ERROR,"Fail to set new 'linux,initrd-start' (err:%d)\n",err)); - } - InitrdImageEnd = cpu_to_fdt64 (InitrdImage + InitrdImageSize); - err = fdt_setprop(fdt, node, "linux,initrd-end", &InitrdImageEnd, sizeof(EFI_PHYSICAL_ADDRESS)); - if (err) { - DEBUG((EFI_D_ERROR,"Fail to set new 'linux,initrd-start' (err:%d)\n",err)); - } - } - - // - // Set Physical memory setup if does not exist - // - node = fdt_subnode_offset(fdt, 0, "memory"); - if (node < 0) { - // The 'memory' node does not exist, create it - node = fdt_add_subnode(fdt, 0, "memory"); - if (node >= 0) { - fdt_setprop_string(fdt, node, "name", "memory"); - fdt_setprop_string(fdt, node, "device_type", "memory"); - - GetSystemMemoryResources (&ResourceList); - Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink; - - Region.Base = cpu_to_fdtn ((UINTN)Resource->PhysicalStart); - Region.Size = cpu_to_fdtn ((UINTN)Resource->ResourceLength); - - err = fdt_setprop(fdt, node, "reg", &Region, sizeof(Region)); - if (err) { - DEBUG((EFI_D_ERROR,"Fail to set new 'memory region' (err:%d)\n",err)); - } - } - } - - // - // Add the memory regions reserved by the UEFI Firmware - // - - // Retrieve the UEFI Memory Map - MemoryMap = NULL; - MemoryMapSize = 0; - Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion); - if (Status == EFI_BUFFER_TOO_SMALL) { - // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive - // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size. - Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1; - MemoryMap = AllocatePages (Pages); - if (MemoryMap == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto FAIL_COMPLETE_FDT; - } - Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion); - } - - // Go through the list and add the reserved region to the Device Tree - if (!EFI_ERROR(Status)) { - MemoryMapPtr = MemoryMap; - for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) { - if (IsLinuxReservedRegion ((EFI_MEMORY_TYPE)MemoryMapPtr->Type)) { - DEBUG((DEBUG_VERBOSE, "Reserved region of type %d [0x%lX, 0x%lX]\n", - MemoryMapPtr->Type, - (UINTN)MemoryMapPtr->PhysicalStart, - (UINTN)(MemoryMapPtr->PhysicalStart + MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE))); - err = fdt_add_mem_rsv(fdt, MemoryMapPtr->PhysicalStart, MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE); - if (err != 0) { - Print(L"Warning: Fail to add 'memreserve' (err:%d)\n", err); - } - } - MemoryMapPtr = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + DescriptorSize); - } - } - - // - // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms. - // - // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file - // in the kernel documentation: - // Documentation/devicetree/bindings/arm/cpus.txt - // - for (Index=0; Index < gST->NumberOfTableEntries; Index++) { - // Check for correct GUID type - if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { - MpId = ArmReadMpidr (); - ClusterId = GET_CLUSTER_ID(MpId); - CoreId = GET_CORE_ID(MpId); - - node = fdt_subnode_offset(fdt, 0, "cpus"); - if (node < 0) { - // Create the /cpus node - node = fdt_add_subnode(fdt, 0, "cpus"); - fdt_setprop_string(fdt, node, "name", "cpus"); - fdt_setprop_cell (fdt, node, "#address-cells", sizeof (UINTN) / 4); - fdt_setprop_cell(fdt, node, "#size-cells", 0); - CpusNodeExist = FALSE; - } else { - CpusNodeExist = TRUE; - } - - // Get pointer to ARM processor table - ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable; - ArmCoreInfoTable = ArmProcessorTable->ArmCpus; - - for (Index = 0; Index < ArmProcessorTable->NumberOfEntries; Index++) { - CoreMpId = (UINTN) GET_MPID (ArmCoreInfoTable[Index].ClusterId, - ArmCoreInfoTable[Index].CoreId); - AsciiSPrint (Name, 10, "cpu@%x", CoreMpId); - - // If the 'cpus' node did not exist then create all the 'cpu' nodes. - // In case 'cpus' node is provided in the original FDT then we do not add - // any 'cpu' node. - if (!CpusNodeExist) { - cpu_node = fdt_add_subnode (fdt, node, Name); - if (cpu_node < 0) { - DEBUG ((EFI_D_ERROR, "Error on creating '%s' node\n", Name)); - Status = EFI_INVALID_PARAMETER; - goto FAIL_COMPLETE_FDT; - } - - fdt_setprop_string (fdt, cpu_node, "device_type", "cpu"); - - CoreMpId = cpu_to_fdtn (CoreMpId); - fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId)); - } else { - cpu_node = fdt_subnode_offset(fdt, node, Name); - } - - if (cpu_node >= 0) { - Method = fdt_getprop (fdt, cpu_node, "enable-method", &lenp); - // We only care when 'enable-method' == 'spin-table'. If the enable-method is not defined - // or defined as 'psci' then we ignore its properties. - if ((Method != NULL) && (AsciiStrCmp ((CHAR8 *)Method, "spin-table") == 0)) { - // There are two cases; - // - UEFI firmware parked the secondary cores and/or UEFI firmware is aware of the CPU - // release addresses (PcdArmLinuxSpinTable == TRUE) - // - the parking of the secondary cores has been managed before starting UEFI and/or UEFI - // does not anything about the CPU release addresses - in this case we do nothing - if (FeaturePcdGet (PcdArmLinuxSpinTable)) { - CpuReleaseAddr = cpu_to_fdt64 (ArmCoreInfoTable[Index].MailboxSetAddress); - fdt_setprop (fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof(CpuReleaseAddr)); - - // If it is not the primary core than the cpu should be disabled - if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) { - fdt_setprop_string(fdt, cpu_node, "status", "disabled"); - } - } - } - } - } - break; - } - } - - DEBUG_CODE_BEGIN(); - //DebugDumpFdt (fdt); - DEBUG_CODE_END(); - - // If we succeeded to generate the new Device Tree then free the old Device Tree - gBS->FreePages (*FdtBlobBase, EFI_SIZE_TO_PAGES (*FdtBlobSize)); - - // Update the real size of the Device Tree - fdt_pack ((VOID*)(UINTN)(NewFdtBlobBase)); - - *FdtBlobBase = NewFdtBlobBase; - *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase)); - return EFI_SUCCESS; - -FAIL_COMPLETE_FDT: - gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); - -FAIL_RELOCATE_FDT: - *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase)); - // Return success even if we failed to update the FDT blob. - // The original one is still valid. - return EFI_SUCCESS; -} diff --git a/ArmPkg/Library/BdsLib/BdsLinuxLoader.h b/ArmPkg/Library/BdsLib/BdsLinuxLoader.h deleted file mode 100644 index b78f606129..0000000000 --- a/ArmPkg/Library/BdsLib/BdsLinuxLoader.h +++ /dev/null @@ -1,156 +0,0 @@ -/** @file -* -* 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 -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - -#ifndef __BDSLINUXLOADER_H -#define __BDSLINUXLOADER_H - -#define LINUX_UIMAGE_SIGNATURE 0x56190527 -#define LINUX_KERNEL_MAX_OFFSET (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxKernelMaxOffset)) -#define LINUX_ATAG_MAX_OFFSET (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxAtagMaxOffset)) -#define LINUX_FDT_MAX_OFFSET (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxFdtMaxOffset)) - -// Additional size that could be used for FDT entries added by the UEFI OS Loader -// Estimation based on: EDID (300bytes) + bootargs (200bytes) + initrd region (20bytes) -// + system memory region (20bytes) + mp_core entries (200 bytes) -#define FDT_ADDITIONAL_ENTRIES_SIZE 0x300 - -#define ARM_FDT_MACHINE_TYPE 0xFFFFFFFF - -typedef VOID (*LINUX_KERNEL)(UINT32 Zero, UINT32 Arch, UINTN ParametersBase); - -// -// ATAG Definitions -// - -#define ATAG_MAX_SIZE 0x3000 - -/* ATAG : list of possible tags */ -#define ATAG_NONE 0x00000000 -#define ATAG_CORE 0x54410001 -#define ATAG_MEM 0x54410002 -#define ATAG_VIDEOTEXT 0x54410003 -#define ATAG_RAMDISK 0x54410004 -#define ATAG_INITRD2 0x54420005 -#define ATAG_SERIAL 0x54410006 -#define ATAG_REVISION 0x54410007 -#define ATAG_VIDEOLFB 0x54410008 -#define ATAG_CMDLINE 0x54410009 -#define ATAG_ARM_MP_CORE 0x5441000A - -#define next_tag_address(t) ((LINUX_ATAG*)((UINT32)(t) + (((t)->header.size) << 2) )) -#define tag_size(type) ((UINT32)((sizeof(LINUX_ATAG_HEADER) + sizeof(type)) >> 2)) - -typedef struct { - UINT32 size; /* length of tag in words including this header */ - UINT32 type; /* tag type */ -} LINUX_ATAG_HEADER; - -typedef struct { - UINT32 flags; - UINT32 pagesize; - UINT32 rootdev; -} LINUX_ATAG_CORE; - -typedef struct { - UINT32 size; - UINTN start; -} LINUX_ATAG_MEM; - -typedef struct { - UINT8 x; - UINT8 y; - UINT16 video_page; - UINT8 video_mode; - UINT8 video_cols; - UINT16 video_ega_bx; - UINT8 video_lines; - UINT8 video_isvga; - UINT16 video_points; -} LINUX_ATAG_VIDEOTEXT; - -typedef struct { - UINT32 flags; - UINT32 size; - UINTN start; -} LINUX_ATAG_RAMDISK; - -typedef struct { - UINT32 start; - UINT32 size; -} LINUX_ATAG_INITRD2; - -typedef struct { - UINT32 low; - UINT32 high; -} LINUX_ATAG_SERIALNR; - -typedef struct { - UINT32 rev; -} LINUX_ATAG_REVISION; - -typedef struct { - UINT16 lfb_width; - UINT16 lfb_height; - UINT16 lfb_depth; - UINT16 lfb_linelength; - UINT32 lfb_base; - UINT32 lfb_size; - UINT8 red_size; - UINT8 red_pos; - UINT8 green_size; - UINT8 green_pos; - UINT8 blue_size; - UINT8 blue_pos; - UINT8 rsvd_size; - UINT8 rsvd_pos; -} LINUX_ATAG_VIDEOLFB; - -typedef struct { - CHAR8 cmdline[1]; -} LINUX_ATAG_CMDLINE; - -typedef struct { - LINUX_ATAG_HEADER header; - union { - LINUX_ATAG_CORE core_tag; - LINUX_ATAG_MEM mem_tag; - LINUX_ATAG_VIDEOTEXT videotext_tag; - LINUX_ATAG_RAMDISK ramdisk_tag; - LINUX_ATAG_INITRD2 initrd2_tag; - LINUX_ATAG_SERIALNR serialnr_tag; - LINUX_ATAG_REVISION revision_tag; - LINUX_ATAG_VIDEOLFB videolfb_tag; - LINUX_ATAG_CMDLINE cmdline_tag; - } body; -} LINUX_ATAG; - -EFI_STATUS -PrepareAtagList ( - IN CONST CHAR8* CommandLineString, - IN EFI_PHYSICAL_ADDRESS InitrdImage, - IN UINTN InitrdImageSize, - OUT EFI_PHYSICAL_ADDRESS *AtagBase, - OUT UINT32 *AtagSize - ); - -EFI_STATUS -PrepareFdt ( - IN CONST CHAR8* CommandLineArguments, - IN EFI_PHYSICAL_ADDRESS InitrdImage, - IN UINTN InitrdImageSize, - IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase, - IN OUT UINTN *FdtBlobSize - ); - -#endif diff --git a/ArmPlatformPkg/Bds/Bds.inf b/ArmPlatformPkg/Bds/Bds.inf index 76a45e03e5..9639f1424e 100644 --- a/ArmPlatformPkg/Bds/Bds.inf +++ b/ArmPlatformPkg/Bds/Bds.inf @@ -39,6 +39,9 @@ EmbeddedPkg/EmbeddedPkg.dec IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec +[Guids] + gFdtTableGuid + [LibraryClasses] BdsLib TimerLib @@ -49,6 +52,7 @@ DebugLib PrintLib BaseLib + FdtLib NetLib [Guids] diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c index bb218f82aa..342d441f05 100644 --- a/ArmPlatformPkg/Bds/BootOption.c +++ b/ArmPlatformPkg/Bds/BootOption.c @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011-2014, ARM Limited. All rights reserved. +* Copyright (c) 2011-2015, 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 @@ -23,10 +23,6 @@ BootOptionStart ( EFI_STATUS Status; UINT32 LoaderType; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; - ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; - UINTN CmdLineSize; - UINTN InitrdSize; - EFI_DEVICE_PATH* Initrd; UINT16 LoadOptionIndexSize; if (IS_ARM_BDS_BOOTENTRY (BootOption)) { @@ -42,34 +38,9 @@ BootOptionStart ( Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL); } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { - LinuxArguments = &(OptionalData->Arguments.LinuxArguments); - CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); - InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); - - if (InitrdSize > 0) { - Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); - } else { - Initrd = NULL; - } - - Status = BdsBootLinuxAtag (BootOption->FilePathList, - Initrd, // Initrd - (CHAR8*)(LinuxArguments + 1)); // CmdLine + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { - LinuxArguments = &(OptionalData->Arguments.LinuxArguments); - CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); - InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); - - if (InitrdSize > 0) { - Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); - } else { - Initrd = NULL; - } - Status = BdsBootLinuxFdt ( - BootOption->FilePathList, - Initrd, - (CHAR8*)(LinuxArguments + 1) - ); + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); } } else { // Connect all the drivers if the EFI Application is not a EFI OS Loader