diff --git a/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarter.c b/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarter.c deleted file mode 100644 index d82cf85111..0000000000 --- a/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarter.c +++ /dev/null @@ -1,370 +0,0 @@ -/** @file -* -* 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 -* 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 - -#include "LinuxLoader.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 -VOID -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 (); -} - -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 (PcdGet64 (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)); - return Status; - } - - // 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 - // - PreparePlatformHardware (); - - // 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); - - // We cannot recover the execution at this stage - while (1); -} - -/** - Start a Linux kernel from a Device Path - - @param SystemMemoryBase Base of the system memory - @param LinuxKernel Device Path to the Linux Kernel - @param Parameters Linux kernel arguments - @param Fdt Device Path to the Flat Device Tree - @param MachineType ARM machine type value - - @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. - @retval RETURN_UNSUPPORTED ATAG is not support by this architecture - -**/ -EFI_STATUS -BootLinuxAtag ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* CommandLineArguments, - IN UINTN MachineType - ) -{ - // NOTE : AArch64 Linux kernel does not support ATAG, FDT only. - ASSERT (0); - - return EFI_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 -BootLinuxFdt ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath, - 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 = 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; - 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; - } - } - - if (FdtDevicePath == NULL) { - // - // 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); - } else { - // - // FDT device path explicitly defined. The FDT is relocated later to a - // more appropriate location for the Linux kernel. - // - FdtBlobBase = LINUX_KERNEL_MAX_OFFSET; - Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &FdtBlobBase, &FdtBlobSize); - if (EFI_ERROR (Status)) { - Print (L"ERROR: Did not find Device Tree blob (%r).\n", Status); - goto EXIT_FREE_INITRD; - } - } - - // - // 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 (SystemMemoryBase, 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/Application/LinuxLoader/AArch64/LinuxStarterHelper.S b/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarterHelper.S deleted file mode 100644 index 525c1287ef..0000000000 --- a/ArmPkg/Application/LinuxLoader/AArch64/LinuxStarterHelper.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/Application/LinuxLoader/Arm/LinuxAtag.c b/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.c deleted file mode 100644 index 0b3e2489c7..0000000000 --- a/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.c +++ /dev/null @@ -1,177 +0,0 @@ -/** @file -* -* 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 -* 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 "LinuxAtag.h" -#include "LinuxLoader.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 */ - AsciiStrCpyS (mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, LineLength, 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 EFI_PHYSICAL_ADDRESS SystemMemoryBase, - 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; - 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); - if (EFI_ERROR (Status)) { - return 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 = (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/Application/LinuxLoader/Arm/LinuxAtag.h b/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.h deleted file mode 100644 index b4c7e5986e..0000000000 --- a/ArmPkg/Application/LinuxLoader/Arm/LinuxAtag.h +++ /dev/null @@ -1,124 +0,0 @@ -/** @file -* -* 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 -* 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 __LINUX_ATAG_H__ -#define __LINUX_ATAG_H__ - -// -// 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; - -#endif /* __LINUX_ATAG_H__ */ diff --git a/ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c b/ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c deleted file mode 100644 index 960fdd6b3c..0000000000 --- a/ArmPkg/Application/LinuxLoader/Arm/LinuxStarter.c +++ /dev/null @@ -1,346 +0,0 @@ -/** @file -* -* 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 -* 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 "LinuxLoader.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)))) - -EFI_STATUS -PrepareAtagList ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN CONST CHAR8* CommandLineString, - IN EFI_PHYSICAL_ADDRESS InitrdImage, - IN UINTN InitrdImageSize, - OUT EFI_PHYSICAL_ADDRESS *AtagBase, - OUT UINT32 *AtagSize - ); - -STATIC -VOID -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 (); -} - -STATIC -EFI_STATUS -StartLinux ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - 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)); - return Status; - } - - // 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 - // - PreparePlatformHardware (); - - // 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); - // We cannot recover the execution at this stage - while (1); -} - -/** - Start a Linux kernel from a Device Path - - @param SystemMemoryBase Base of the system memory - @param LinuxKernel Device Path to the Linux Kernel - @param Parameters Linux kernel arguments - @param Fdt Device Path to the Flat Device Tree - @param MachineType ARM machine type value - - @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. - @retval RETURN_UNSUPPORTED ATAG is not support by this architecture - -**/ -EFI_STATUS -BootLinuxAtag ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* CommandLineArguments, - IN UINTN MachineType - ) -{ - 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 (SystemMemoryBase, 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 (SystemMemoryBase, LinuxImage, LinuxImageSize, AtagBase, AtagSize, MachineType); - -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 -BootLinuxFdt ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath, - 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; - } - } - - if (FdtDevicePath == NULL) { - // - // 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); - } else { - // - // FDT device path explicitly defined. The FDT is relocated later to a - // more appropriate location for the Linux kernel. - // - FdtBlobBase = LINUX_KERNEL_MAX_OFFSET; - Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &FdtBlobBase, &FdtBlobSize); - if (EFI_ERROR (Status)) { - Print (L"ERROR: Did not find Device Tree blob (%r).\n", Status); - goto EXIT_FREE_INITRD; - } - } - - // 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 (SystemMemoryBase, 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 (SystemMemoryBase, 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/Application/LinuxLoader/LinuxLoader.c b/ArmPkg/Application/LinuxLoader/LinuxLoader.c deleted file mode 100644 index 76697c3a8c..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoader.c +++ /dev/null @@ -1,248 +0,0 @@ -/** @file -* -* 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 -* 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 "LinuxLoader.h" - -/** - The user Entry Point for Application. The user code starts with this function - as the real entry point for the application. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point was executed successfully. - @retval EFI_NOT_FOUND Protocol not found. - @retval EFI_NOT_FOUND Path to the Linux kernel not found. - @retval EFI_ABORTED The initialisation of the Shell Library failed. - @retval EFI_INVALID_PARAMETER At least one parameter is not valid or there is a - conflict between two parameters. - @retval EFI_OUT_OF_RESOURCES A memory allocation failed. - -**/ -EFI_STATUS -EFIAPI -LinuxLoaderEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; - EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters; - CHAR16 *KernelPath; - CHAR16 *FdtPath; - CHAR16 *InitrdPath; - CHAR16 *KernelTextDevicePath; - CHAR16 *FdtTextDevicePath; - CHAR16 *InitrdTextDevicePath; - CHAR16 *LinuxCommandLine; - UINTN AtagMachineType; - EFI_DEVICE_PATH *KernelDevicePath; - EFI_DEVICE_PATH *FdtDevicePath; - EFI_DEVICE_PATH *InitrdDevicePath; - CHAR8 *AsciiLinuxCommandLine; - LIST_ENTRY ResourceList; - LIST_ENTRY *ResourceLink; - SYSTEM_MEMORY_RESOURCE *Resource; - EFI_PHYSICAL_ADDRESS SystemMemoryBase; - UINTN Length; - - Status = gBS->LocateProtocol ( - &gEfiDevicePathFromTextProtocolGuid, - NULL, - (VOID **)&EfiDevicePathFromTextProtocol - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // Register the strings for the user interface in the HII Database. - // This shows the way to the multi-language support, even if - // only the English language is actually supported. The strings to register - // are stored in the "LinuxLoaderStrings[]" array. This array is - // built by the building process from the "*.uni" file associated to - // the present application (cf. LinuxLoader.inf). Examine the Build - // folder of the application and you will find the array defined in the - // LinuxLoaderStrDefs.h file. - // - mLinuxLoaderHiiHandle = HiiAddPackages ( - &mLinuxLoaderHiiGuid, - ImageHandle, - LinuxLoaderStrings, - NULL - ); - if (mLinuxLoaderHiiHandle == NULL) { - return EFI_NOT_FOUND; - } - - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiShellParametersProtocolGuid, - (VOID**)&ShellParameters - ); - - KernelDevicePath = NULL; - FdtDevicePath = NULL; - InitrdDevicePath = NULL; - AsciiLinuxCommandLine = NULL; - - // - // Call the proper function to handle the command line - // depending on whether the application has been called - // from the Shell or not. - // - - if (!EFI_ERROR (Status)) { - KernelTextDevicePath = NULL; - FdtTextDevicePath = NULL; - InitrdTextDevicePath = NULL; - - Status = ProcessShellParameters ( - &KernelPath, &FdtPath, &InitrdPath, &LinuxCommandLine, &AtagMachineType - ); - if (EFI_ERROR (Status)) { - goto Error; - } - - KernelDevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (KernelPath); - if (KernelDevicePath != NULL) { - FreePool (KernelPath); - } else { - KernelTextDevicePath = KernelPath; - } - - if (FdtPath != NULL) { - FdtDevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (FdtPath); - if (FdtDevicePath != NULL) { - FreePool (FdtPath); - } else { - FdtTextDevicePath = FdtPath; - } - } - - if (InitrdPath != NULL) { - InitrdDevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (InitrdPath); - if (InitrdDevicePath != NULL) { - FreePool (InitrdPath); - } else { - InitrdTextDevicePath = InitrdPath; - } - } - - } else { - Status = ProcessAppCommandLine ( - &KernelTextDevicePath, &FdtTextDevicePath, - &InitrdTextDevicePath, &LinuxCommandLine, &AtagMachineType - ); - if (EFI_ERROR (Status)) { - goto Error; - } - } - - Status = EFI_INVALID_PARAMETER; - if (KernelTextDevicePath != NULL) { - KernelDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ( - KernelTextDevicePath - ); - if (KernelDevicePath == NULL) { - goto Error; - } - } - if (FdtTextDevicePath != NULL) { - FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ( - FdtTextDevicePath - ); - if (FdtDevicePath == NULL) { - goto Error; - } - } - if (InitrdTextDevicePath != NULL) { - InitrdDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ( - InitrdTextDevicePath - ); - if (InitrdDevicePath == NULL) { - goto Error; - } - } - - if (LinuxCommandLine != NULL) { - Length = StrLen (LinuxCommandLine) + 1; - AsciiLinuxCommandLine = AllocatePool (Length); - if (AsciiLinuxCommandLine == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - UnicodeStrToAsciiStrS (LinuxCommandLine, AsciiLinuxCommandLine, Length); - } - - // - // Find Base of System Memory - we keep the lowest physical address - // - SystemMemoryBase = ~0; - GetSystemMemoryResources (&ResourceList); - ResourceLink = ResourceList.ForwardLink; - while (ResourceLink != NULL && ResourceLink != &ResourceList) { - Resource = (SYSTEM_MEMORY_RESOURCE*)ResourceLink; - if (Resource->PhysicalStart < SystemMemoryBase) { - SystemMemoryBase = Resource->PhysicalStart; - } - ResourceLink = ResourceLink->ForwardLink; - } - - if (AtagMachineType != ARM_FDT_MACHINE_TYPE) { - Status = BootLinuxAtag (SystemMemoryBase, KernelDevicePath, InitrdDevicePath, AsciiLinuxCommandLine, AtagMachineType); - } else { - Status = BootLinuxFdt (SystemMemoryBase, KernelDevicePath, InitrdDevicePath, FdtDevicePath, AsciiLinuxCommandLine); - } - -Error: - if (KernelTextDevicePath != NULL) { - FreePool (KernelTextDevicePath); - } - if (FdtTextDevicePath != NULL) { - FreePool (FdtTextDevicePath); - } - if (InitrdTextDevicePath != NULL) { - FreePool (InitrdTextDevicePath); - } - if (LinuxCommandLine != NULL) { - FreePool (LinuxCommandLine); - } - if (KernelDevicePath != NULL) { - FreePool (KernelDevicePath); - } - if (FdtDevicePath != NULL) { - FreePool (FdtDevicePath); - } - if (InitrdDevicePath != NULL) { - FreePool (InitrdDevicePath); - } - if (AsciiLinuxCommandLine != NULL) { - FreePool (AsciiLinuxCommandLine); - } - - if (EFI_ERROR (Status)) { - PrintHii (NULL, STRING_TOKEN (STR_ERROR), Status); - } - - HiiRemovePackages (mLinuxLoaderHiiHandle); - - return Status; -} diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoader.h b/ArmPkg/Application/LinuxLoader/LinuxLoader.h deleted file mode 100644 index 0d18c2446d..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoader.h +++ /dev/null @@ -1,166 +0,0 @@ -/** @file -* -* 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 -* 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 __LINUX_LOADER_H__ -#define __LINUX_LOADER_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -// -// Definitions -// - -#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)) - -#define ARM_FDT_MACHINE_TYPE 0xFFFFFFFF - -// 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 - -// -// Global variables -// -extern CONST EFI_GUID mLinuxLoaderHiiGuid; -extern EFI_HANDLE mLinuxLoaderHiiHandle; - -// -// Local Types -// -typedef struct _SYSTEM_MEMORY_RESOURCE { - LIST_ENTRY Link; // This attribute must be the first entry of this structure (to avoid pointer computation) - EFI_PHYSICAL_ADDRESS PhysicalStart; - UINT64 ResourceLength; -} SYSTEM_MEMORY_RESOURCE; - -typedef VOID (*LINUX_KERNEL)(UINT32 Zero, UINT32 Arch, UINTN ParametersBase); - -// -// Functions -// -EFI_STATUS -PrintHii ( - IN CONST CHAR8 *Language OPTIONAL, - IN CONST EFI_STRING_ID HiiFormatStringId, - ... - ); - -VOID -PrintHelp ( - IN CONST CHAR8 *Language OPTIONAL - ); - -EFI_STATUS -ProcessShellParameters ( - OUT CHAR16 **KernelPath, - OUT CHAR16 **FdtPath, - OUT CHAR16 **InitrdPath, - OUT CHAR16 **LinuxCommandLine, - OUT UINTN *AtagMachineType - ); - -EFI_STATUS -ProcessAppCommandLine ( - OUT CHAR16 **KernelTextDevicePath, - OUT CHAR16 **FdtTextDevicePath, - OUT CHAR16 **InitrdTextDevicePath, - OUT CHAR16 **LinuxCommandLine, - OUT UINTN *AtagMachineType - ); - -VOID -PrintPerformance ( - VOID - ); - -EFI_STATUS -GetSystemMemoryResources ( - IN LIST_ENTRY *ResourceList - ); - -EFI_STATUS -PrepareFdt ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN CONST CHAR8* CommandLineArguments, - IN EFI_PHYSICAL_ADDRESS InitrdImage, - IN UINTN InitrdImageSize, - IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase, - IN OUT UINTN *FdtBlobSize - ); - -/** - Start a Linux kernel from a Device Path - - @param SystemMemoryBase Base of the system memory - @param LinuxKernel Device Path to the Linux Kernel - @param Parameters Linux kernel arguments - @param Fdt Device Path to the Flat Device Tree - @param MachineType ARM machine type value - - @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. - @retval RETURN_UNSUPPORTED ATAG is not support by this architecture - -**/ -EFI_STATUS -BootLinuxAtag ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN CONST CHAR8* CommandLineArguments, - IN UINTN MachineType - ); - -/** - 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 -BootLinuxFdt ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath, - IN CONST CHAR8* Arguments - ); - -#endif /* __LINUX_LOADER_H__ */ diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoader.inf b/ArmPkg/Application/LinuxLoader/LinuxLoader.inf deleted file mode 100644 index 59ab99c968..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoader.inf +++ /dev/null @@ -1,91 +0,0 @@ -#/* @file -# Copyright (c) 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 -# 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. -# -#*/ - -[Defines] - INF_VERSION = 0x00010006 - BASE_NAME = LinuxLoader - MODULE_UNI_FILE = LinuxLoader.uni - FILE_GUID = 701f54f2-0d70-4b89-bc0a-d9ca25379059 - MODULE_TYPE = UEFI_APPLICATION - VERSION_STRING = 0.1 - ENTRY_POINT = LinuxLoaderEntryPoint - -[Sources] - LinuxLoader.c - LinuxLoader.h - LinuxLoader.uni - LinuxLoaderFdt.c - LinuxLoaderHelper.c - LinuxLoaderEfiApp.c - LinuxLoaderShellApp.c - -[Sources.AARCH64] - AArch64/LinuxStarter.c - AArch64/LinuxStarterHelper.S - -[Sources.ARM] - Arm/LinuxAtag.h - Arm/LinuxAtag.c - Arm/LinuxStarter.c - -[Packages] - ArmPkg/ArmPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ShellPkg/ShellPkg.dec - -[Guids] - gFdtTableGuid - -[Guids] - gArmMpCoreInfoGuid - -[LibraryClasses] - ArmLib - BdsLib - DebugLib - DxeServicesTableLib - FdtLib - HiiLib - HobLib - PerformanceLib - ShellLib - SerialPortLib - TimerLib - UefiApplicationEntryPoint - UefiLib - -[LibraryClasses.AARCH64] - ArmGicLib - PcdLib - -[Protocols] - gEfiLoadedImageProtocolGuid - gEfiDevicePathToTextProtocolGuid - gEfiShellParametersProtocolGuid - -[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/LinuxLoader.uni b/ArmPkg/Application/LinuxLoader/LinuxLoader.uni deleted file mode 100644 index d8c0f213c8..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoader.uni +++ /dev/null @@ -1,87 +0,0 @@ -// *++ -// -// Copyright (c) 2014-2015, ARM Ltd. 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. -// -// -// Module Name: -// -// LinuxLoader -// -// Abstract: -// -// String definitions for the LinuxLoader UEFI application -// -// Revision History: -// -// --*/ - -/=# - -#langdef en-US "English" - -#string STR_SHELL_INVALID_PARAMETER #language en-US "Invalid parameter : '%s'\r\n" -#string STR_ERROR #language en-US "Linux boot loader error - %r.\r\n" - -#string STR_INVALID_FLAG #language en-US "Invalid flag or flag value '%c%c'.\r\n" -#string STR_INVALID_PARAMETER #language en-US "Invalid parameter.\r\n" -#string STR_MISSING_KERNEL_PATH #language en-US "Path to the Linux kernel not defined.\r\n" -#string STR_MISSING_VALUE #language en-US "Missing value for flag '-%c'\r\n" -#string STR_ATAG_FDT_CONFLICT #language en-US "The Linux Kernel can not have both ATAG and FDT support.\r\n" - - - -#string STR_HELP #language en-US "USAGE:\r\n" -"LinuxLoader KernelPath [-f InitrdPath] [-a | -d FdtPath] [-c CommandLine]\r\n" -"\r\n" -" -f Path to the RAM root file system.\r\n" -" -a Indicate a Linux kernel with ATAG support.\r\n" -" -d Path to the Flat Device Tree.\r\n" -" -c Linux Kernel command line.\r\n" -"\r\n" -"The 'LinuxLoader.efi' UEFI application is intended to boot Linux Kernel\r\n" -"images containing or not an 'EFI Boot Stub' (see www.kernel.org/doc/\r\n" -"Documentation/efi-stub.txt for more information).\r\n" -"\r\n" -"This application can be called either from the EFI Shell or during the\r\n" -"Boot Device Selection (BDS) phase of the boot flow.\r\n" -"\r\n" -"If the application is called during the BDS phase then all the paths\r\n" -"must be device paths in the text form.\r\n" -"\r\n" -"If the application is called from the EFI Shell, the usual alias\r\n" -"and variable substitutions apply. Moreover, each path can be either\r\n" -"an EFI Shell file path or a device path in the text form. The application\r\n" -"first tries to interpret the path as an EFI Shell file path. If the\r\n" -"interpretation fails then the path is handled as a device path in the\r\n" -"text form.\r\n" -"\r\n" -"EXAMPLES:\r\n" -" * Boot from the EFI Shell the Linux kernel 'Image' with the command\r\n" -" line 'console=ttyAMA0,115200 earlycon=pl011,0x7ff80000' using the FDT\r\n" -" 'fdt.dtb' and the RAM boot file system 'ramdisk.img', all files\r\n" -" being located at the root of the 'fs2:' volume :\r\n" -" Shell> LinuxLoader fs2:Image -d fs2:fdt.dtb -f fs2:ramdisk.img \\\r\n" -" -c "console=ttyAMA0,115200 earlycon=pl011,0x7ff80000"\r\n" -" or -" fs2:\> LinuxLoader Image -d fdt.dtb -f ramdisk.img \\\r\n" -" -c "console=ttyAMA0,115200 earlycon=pl011,0x7ff80000"\r\n" -" * Arguments to pass to the application for the same boot but from\r\n" -" the boot manager, the device path to the 'fs2:' volume being \r\n" -" VenHw(E7223039-5836-41E1-B542-D7EC736C5E59) :\r\n" -" VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/Image \\\r\n" -" -d VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/fdt.dtb \\\r\n" -" -f VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/ramdisk.img \\\r\n" -" -c "console=ttyAMA0,115200 earlycon=pl011,0x7ff80000"\r\n" -" * Arguments to pass to boot ATAG linux kernel:\r\n" -" VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/Image \\\r\n" -" -a 2272 \\\r\n" -" -f VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/ramdisk.img \\\r\n" -" -c "console=ttyAMA0,115200 earlycon=pl011,0x7ff80000"\r\n" diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoaderEfiApp.c b/ArmPkg/Application/LinuxLoader/LinuxLoaderEfiApp.c deleted file mode 100644 index 57a9cd38cf..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoaderEfiApp.c +++ /dev/null @@ -1,303 +0,0 @@ -/** @file -* -* 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 -* 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 "LinuxLoader.h" - -/** - Extract the next item from the command line. - - The items are separated by spaces. Quotation marks (") are used for argument - grouping and the escaping character is "^" as for the EFI Shell command lines. - - @param[in out] CommandLine Command line pointer. - @param[out] Item Pointer to the allocated buffer where the - item is stored. - - @retval EFI_SUCCESS The token was found and extracted. - @retval EFI_NOT_FOUND No item found. - @retval EFI_OUT_OF_RESOURCES The memory allocation failed. - -**/ -STATIC -EFI_STATUS -ExtractNextItem ( - IN OUT CONST CHAR16 **CommandLine, - OUT CHAR16 **Item - ) -{ - CONST CHAR16 *Walker; - VOID *Buffer; - CHAR16 *WritePtr; - BOOLEAN InQuotedString; - BOOLEAN Interpret; - - for (Walker = *CommandLine; *Walker == L' '; Walker++) { - ; - } - - Buffer = AllocatePool (StrSize (Walker)); - if (Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - for (WritePtr = Buffer, Interpret = TRUE, InQuotedString = FALSE; - ((*Walker != L' ') || InQuotedString) && (*Walker != L'\0'); - Walker++ - ) { - if (Interpret) { - if (*Walker == L'^') { - Interpret = FALSE; - continue; - } - if (*Walker == L'"') { - InQuotedString = !InQuotedString; - continue; - } - } else { - Interpret = TRUE; - } - *(WritePtr++) = *Walker; - } - - if (WritePtr == Buffer) { - FreePool (Buffer); - return EFI_NOT_FOUND; - } - - *WritePtr = L'\0'; - *CommandLine = Walker; - *Item = Buffer; - - return EFI_SUCCESS; -} - -/** - Check if an item of the command line is a flag or not. - - @param[in] Item Command line item. - - @retval TRUE The item is a flag. - @retval FALSE The item is not a flag. - -**/ -STATIC -BOOLEAN -IsFlag ( - IN CONST CHAR16 *Item - ) -{ - return ((Item[0] == L'-') && (Item[2] == L'\0')); -} - -/** - Process the application command line. - - @param[out] KernelTextDevicePath A pointer to the buffer where the device - path to the Linux kernel is stored. The - address of the buffer is NULL in case of - an error. Otherwise, the returned address - is the address of a buffer allocated with - a call to AllocatePool() that has to be - freed by the caller. - @param[out] FdtTextDevicePath A pointer to the buffer where the device - path to the FDT is stored. The address of - the buffer is NULL in case of an error or - if the device path to the FDT is not - defined. Otherwise, the returned address - is the address of a buffer allocated with - a call to AllocatePool() that has to be - freed by the caller. - @param[out] InitrdTextDevicePath A pointer to the buffer where the device - path to the RAM root file system is stored. - The address of the buffer is NULL in case - of an error or if the device path to the - RAM root file system is not defined. - Otherwise, the returned address is the - address of a buffer allocated with a call - to AllocatePool() that has to be freed by - the caller. - @param[out] LinuxCommandLine A pointer to the buffer where the Linux - kernel command line is stored. The address - of the buffer is NULL in case of an error - or if the Linux command line is not - defined. Otherwise, the returned address - is the address of a buffer allocated with - a call to AllocatePool() that has to be - freed by the caller. - - @param[out] AtagMachineType Value of the ARM Machine Type - - @retval EFI_SUCCESS The processing was successfull. - @retval EFI_NOT_FOUND EFI_LOADED_IMAGE_PROTOCOL not found. - @retval EFI_NOT_FOUND Path to the Linux kernel not found. - @retval EFI_INVALID_PARAMETER At least one parameter is not valid or there is a - conflict between two parameters. - @retval EFI_OUT_OF_RESOURCES A memory allocation failed. - -**/ -EFI_STATUS -ProcessAppCommandLine ( - OUT CHAR16 **KernelTextDevicePath, - OUT CHAR16 **FdtTextDevicePath, - OUT CHAR16 **InitrdTextDevicePath, - OUT CHAR16 **LinuxCommandLine, - OUT UINTN *AtagMachineType - ) -{ - EFI_STATUS Status; - EFI_STATUS Status2; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - CONST CHAR16 *Walker; - CHAR16 *Item; - CHAR16 Flag; - BOOLEAN HasAtagSupport; - BOOLEAN HasFdtSupport; - - *KernelTextDevicePath = NULL; - *FdtTextDevicePath = NULL; - *InitrdTextDevicePath = NULL; - *LinuxCommandLine = NULL; - *AtagMachineType = ARM_FDT_MACHINE_TYPE; - - HasAtagSupport = FALSE; - HasFdtSupport = FALSE; - - Status = gBS->HandleProtocol ( - gImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID**)&LoadedImage - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - - Walker = (CHAR16*)LoadedImage->LoadOptions; - if (Walker == NULL) { - PrintHelp (NULL); - return EFI_INVALID_PARAMETER; - } - - // - // Get the device path to the Linux kernel. - // - - Status = ExtractNextItem (&Walker, &Item); - if (!EFI_ERROR (Status)) { - if (!IsFlag (Item)) { - *KernelTextDevicePath = Item; - } else { - PrintHii (NULL, STRING_TOKEN (STR_MISSING_KERNEL_PATH)); - FreePool (Item); - return EFI_NOT_FOUND; - } - } else { - if (Status != EFI_NOT_FOUND) { - return Status; - } - PrintHelp (NULL); - return EFI_INVALID_PARAMETER; - } - - Status = EFI_INVALID_PARAMETER; - while (*Walker != L'\0') { - Status2 = ExtractNextItem (&Walker, &Item); - if (Status2 == EFI_NOT_FOUND) { - break; - } - if (EFI_ERROR (Status2)) { - Status = Status2; - goto Error; - } - - if (!IsFlag (Item)) { - PrintHii (NULL, STRING_TOKEN (STR_INVALID_FLAG), Item[0], Item[1]); - FreePool (Item); - goto Error; - } - Flag = Item[1]; - FreePool (Item); - - Status2 = ExtractNextItem (&Walker, &Item); - if (Status2 == EFI_NOT_FOUND) { - PrintHii (NULL, STRING_TOKEN (STR_MISSING_VALUE), Flag); - goto Error; - } - if (EFI_ERROR (Status2)) { - Status = Status2; - goto Error; - } - if (IsFlag (Item)) { - PrintHii (NULL, STRING_TOKEN (STR_MISSING_VALUE), Flag); - FreePool (Item); - goto Error; - } - - switch (Flag) { - case L'a': - if (HasFdtSupport) { - PrintHii (NULL, STRING_TOKEN (STR_ATAG_FDT_CONFLICT)); - goto Error; - } - *AtagMachineType = StrDecimalToUintn (Item); - HasAtagSupport = TRUE; - break; - case L'd': - *FdtTextDevicePath = Item; - if (HasAtagSupport) { - PrintHii (NULL, STRING_TOKEN (STR_ATAG_FDT_CONFLICT)); - goto Error; - } - HasFdtSupport = TRUE; - break; - - case L'c': - *LinuxCommandLine = Item; - break; - - case L'f': - *InitrdTextDevicePath = Item; - break; - - default: - PrintHii (NULL, STRING_TOKEN (STR_INVALID_FLAG), L'-', Flag); - FreePool (Item); - goto Error; - } - } - - Status = EFI_SUCCESS; - -Error: - if (EFI_ERROR (Status)) { - if (*KernelTextDevicePath != NULL) { - FreePool (*KernelTextDevicePath); - *KernelTextDevicePath = NULL; - } - if (*FdtTextDevicePath != NULL) { - FreePool (*FdtTextDevicePath); - *FdtTextDevicePath = NULL; - } - if (*InitrdTextDevicePath != NULL) { - FreePool (*InitrdTextDevicePath); - *InitrdTextDevicePath = NULL; - } - if (*LinuxCommandLine != NULL) { - FreePool (*LinuxCommandLine); - *LinuxCommandLine = NULL; - } - } - - return Status; -} diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c b/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c deleted file mode 100644 index 0f5378403f..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c +++ /dev/null @@ -1,411 +0,0 @@ -/** @file -* -* 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 -* 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 "LinuxLoader.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; -} FDT_REGION; - -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 SystemMemoryBase, - 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; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PrepareFdt ( - IN EFI_PHYSICAL_ADDRESS SystemMemoryBase, - 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; - FDT_REGION Region; - UINTN Index; - CHAR8 Name[10]; - LIST_ENTRY ResourceList; - 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 (SystemMemoryBase, *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 = (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; - } - } - - // 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/Application/LinuxLoader/LinuxLoaderHelper.c b/ArmPkg/Application/LinuxLoader/LinuxLoaderHelper.c deleted file mode 100644 index 4d7a844584..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoaderHelper.c +++ /dev/null @@ -1,192 +0,0 @@ -/** @file -* -* 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 -* 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 "LinuxLoader.h" - -STATIC CONST CHAR8 *mTokenList[] = { - /*"SEC",*/ - "PEI", - "DXE", - "BDS", - NULL -}; - -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); -} - -STATIC -EFI_STATUS -InsertSystemMemoryResources ( - LIST_ENTRY *ResourceList, - EFI_HOB_RESOURCE_DESCRIPTOR *ResHob - ) -{ - SYSTEM_MEMORY_RESOURCE *NewResource; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - LIST_ENTRY AttachedResources; - SYSTEM_MEMORY_RESOURCE *Resource; - EFI_PHYSICAL_ADDRESS NewResourceEnd; - - if (IsListEmpty (ResourceList)) { - NewResource = AllocateZeroPool (sizeof (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 = (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 = (SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources); - Link = RemoveEntryList (&NewResource->Link); - while (!IsListEmpty (&AttachedResources)) { - // Merge resources - Resource = (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 (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; -} diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c b/ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c deleted file mode 100644 index 2245185394..0000000000 --- a/ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c +++ /dev/null @@ -1,298 +0,0 @@ -/** @file -* -* 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 -* 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 "LinuxLoader.h" - -// -// Internal variables -// - -CONST EFI_GUID mLinuxLoaderHiiGuid = { - 0xd5d16edc, 0x35c5, 0x4866, - {0xbd, 0xe5, 0x2b, 0x64, 0xa2, 0x26, 0x55, 0x6e} - }; -EFI_HANDLE mLinuxLoaderHiiHandle; - -STATIC CONST SHELL_PARAM_ITEM ParamList[] = { - {L"-f", TypeValue}, - {L"-d", TypeValue}, - {L"-c", TypeValue}, - {L"-a", TypeValue}, - {NULL , TypeMax } - }; - -/** - Print a string given the "HII Id" of the format string and a list of - arguments. - - @param[in] Language The language of the string to retrieve. If - this parameter is NULL, then the current - platform language is used. - @param[in] HiiFormatStringId The format string Id for getting from Hii. - @param[in] ... The variable argument list. - - @retval EFI_SUCCESS The printing was successful. - @retval EFI_OUT_OF_RESOURCES A memory allocation failed. - -**/ -EFI_STATUS -PrintHii ( - IN CONST CHAR8 *Language OPTIONAL, - IN CONST EFI_STRING_ID HiiFormatStringId, - ... - ) -{ - VA_LIST Marker; - CHAR16 *HiiFormatString; - CHAR16 Buffer[MAX_MSG_LEN]; - - VA_START (Marker, HiiFormatStringId); - - HiiFormatString = HiiGetString (mLinuxLoaderHiiHandle, HiiFormatStringId, Language); - if (HiiFormatString != NULL) { - UnicodeVSPrint (Buffer, sizeof (Buffer), HiiFormatString, Marker); - Print (L"%s", Buffer); - FreePool (HiiFormatString); - } else { - ASSERT (FALSE); - return EFI_OUT_OF_RESOURCES; - } - - VA_END (Marker); - - return EFI_SUCCESS; -} - -/** - Print the help. - - @param[in] Language The language of the string to retrieve. If this - parameter is NULL, then the current platform - language is used. -**/ -VOID -PrintHelp ( - IN CONST CHAR8 *Language OPTIONAL - ) -{ - CHAR16 *Help; - CHAR16 *Walker; - CHAR16 *LineEnd; - - // - // Print the help line by line as it is too big to be printed at once. - // - - Help = HiiGetString (mLinuxLoaderHiiHandle, STRING_TOKEN (STR_HELP), Language); - if (Help != NULL) { - Walker = Help; - while (*Walker != L'\0') { - LineEnd = StrStr (Walker, L"\r\n"); - if (LineEnd != NULL) { - *LineEnd = L'\0'; - } - Print (L"%s\r\n", Walker); - if (LineEnd == NULL) { - break; - } - Walker = LineEnd + 2; - } - FreePool (Help); - } - -} - -/** - Process the Shell parameters in the case the application has been called - from the EFI Shell. - - @param[out] KernelPath A pointer to the buffer where the path - to the Linux kernel (EFI Shell file path - or device path is stored. The address of - the buffer is NULL in case of an error. - Otherwise, the returned address is the - address of a buffer allocated with - a call to AllocatePool() that has to be - freed by the caller. - @param[out] FdtPath A pointer to the buffer where the path - to the FDT (EFI Shell file path or - device path) is stored. The address of - the buffer is NULL in case of an error or - if the path to the FDT is not defined. - Otherwise, the returned address is the - address of a buffer allocated with a call - to AllocatePool() that has to be freed by - the caller. - @param[out] InitrdPath A pointer to the buffer where the path - (EFI Shell file path or device path) - to the RAM root file system is stored. - The address of the buffer is NULL in case - of an error or if the path to the RAM root - file system is not defined. Otherwise, the - returned address is the address of a - buffer allocated with a call to - AllocatePool() that has to be freed by - the caller. - @param[out] LinuxCommandLine A pointer to the buffer where the Linux - kernel command line is stored. The address - of the buffer is NULL in case of an error - or if the Linux command line is not - defined. Otherwise, the returned address - is the address of a buffer allocated with - a call to AllocatePool() that has to be - freed by the caller. - @param[out] AtagMachineType Value of the ARM Machine Type - - @retval EFI_SUCCESS The processing was successfull. - @retval EFI_ABORTED The initialisation of the Shell Library failed. - @retval EFI_NOT_FOUND Path to the Linux kernel not found. - @retval EFI_INVALID_PARAMETER At least one parameter is not valid or there is a - conflict between two parameters. - @retval EFI_OUT_OF_RESOURCES A memory allocation failed. - -**/ -EFI_STATUS -ProcessShellParameters ( - OUT CHAR16 **KernelPath, - OUT CHAR16 **FdtPath, - OUT CHAR16 **InitrdPath, - OUT CHAR16 **LinuxCommandLine, - OUT UINTN *AtagMachineType - ) -{ - EFI_STATUS Status; - LIST_ENTRY *CheckPackage; - CHAR16 *ProblemParam; - CONST CHAR16 *FlagValue; - CONST CHAR16 *ParameterValue; - UINTN LinuxCommandLineLen; - - - *KernelPath = NULL; - *FdtPath = NULL; - *InitrdPath = NULL; - *LinuxCommandLine = NULL; - *AtagMachineType = ARM_FDT_MACHINE_TYPE; - - // - // Initialise the Shell Library as we are going to use it. - // Assert that the return code is EFI_SUCCESS as it should. - // To anticipate any change is the codes returned by - // ShellInitialize(), leave in case of error. - // - Status = ShellInitialize (); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return EFI_ABORTED; - } - - Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE); - if (EFI_ERROR (Status)) { - if ((Status == EFI_VOLUME_CORRUPTED) && - (ProblemParam != NULL) ) { - PrintHii ( - NULL, STRING_TOKEN (STR_SHELL_INVALID_PARAMETER), ProblemParam - ); - FreePool (ProblemParam); - } else { - ASSERT (FALSE); - } - goto Error; - } - - Status = EFI_INVALID_PARAMETER; - if (ShellCommandLineGetCount (CheckPackage) != 2) { - PrintHelp (NULL); - goto Error; - } - - Status = EFI_OUT_OF_RESOURCES; - - FlagValue = ShellCommandLineGetValue (CheckPackage, L"-a"); - if (FlagValue != NULL) { - if (ShellCommandLineGetFlag (CheckPackage, L"-d")) { - PrintHii (NULL, STRING_TOKEN (STR_ATAG_FDT_CONFLICT)); - goto Error; - } - *AtagMachineType = StrDecimalToUintn (FlagValue); - } - - ParameterValue = ShellCommandLineGetRawValue (CheckPackage, 1); - *KernelPath = AllocateCopyPool (StrSize (ParameterValue), ParameterValue); - if (*KernelPath == NULL) { - goto Error; - } - - FlagValue = ShellCommandLineGetValue (CheckPackage, L"-d"); - if (FlagValue != NULL) { - *FdtPath = AllocateCopyPool (StrSize (FlagValue), FlagValue); - if (*FdtPath == NULL) { - goto Error; - } - } - - FlagValue = ShellCommandLineGetValue (CheckPackage, L"-f"); - if (FlagValue != NULL) { - *InitrdPath = AllocateCopyPool (StrSize (FlagValue), FlagValue); - if (*InitrdPath == NULL) { - goto Error; - } - } - - FlagValue = ShellCommandLineGetValue (CheckPackage, L"-c"); - if (FlagValue != NULL) { - LinuxCommandLineLen = StrLen (FlagValue); - if ((LinuxCommandLineLen != 0) && - (FlagValue[0] == L'"' ) && - (FlagValue[LinuxCommandLineLen - 1] == L'"')) { - FlagValue++; - LinuxCommandLineLen -= 2; - } - - *LinuxCommandLine = AllocateCopyPool ( - (LinuxCommandLineLen + 1) * sizeof (CHAR16), - FlagValue - ); - if (*LinuxCommandLine == NULL) { - goto Error; - } - (*LinuxCommandLine)[LinuxCommandLineLen] = L'\0'; - } - - Status = EFI_SUCCESS; - -Error: - ShellCommandLineFreeVarList (CheckPackage); - - if (EFI_ERROR (Status)) { - if (*KernelPath != NULL) { - FreePool (*KernelPath); - *KernelPath = NULL; - } - if (*FdtPath != NULL) { - FreePool (*FdtPath); - *FdtPath = NULL; - } - if (*InitrdPath != NULL) { - FreePool (*InitrdPath); - *InitrdPath = NULL; - } - if (*LinuxCommandLine != NULL) { - FreePool (*LinuxCommandLine); - *LinuxCommandLine = NULL; - } - } - - return Status; -} diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 64bc799b8e..0db33eb865 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -140,8 +140,6 @@ ArmPkg/Filesystem/SemihostFs/SemihostFs.inf - ArmPkg/Application/LinuxLoader/LinuxLoader.inf - ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf