]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c
ArmPkg/BdsLib: Remove Linux loader from BdsLib
[mirror_edk2.git] / ArmPkg / Library / BdsLib / AArch64 / BdsLinuxLoader.c
diff --git a/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c
deleted file mode 100644 (file)
index 7651597..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/** @file\r
-*\r
-*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
-*\r
-*  This program and the accompanying materials\r
-*  are licensed and made available under the terms and conditions of the BSD License\r
-*  which accompanies this distribution.  The full text of the license may be found at\r
-*  http://opensource.org/licenses/bsd-license.php\r
-*\r
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-#include <Library/ArmGicLib.h>\r
-#include <Ppi/ArmMpCoreInfo.h>\r
-#include <Library/IoLib.h>\r
-#include <Guid/Fdt.h>\r
-#include <libfdt.h>\r
-\r
-#include "BdsInternal.h"\r
-#include "BdsLinuxLoader.h"\r
-\r
-/*\r
-  Linux kernel booting: Look at the doc in the Kernel source :\r
-    Documentation/arm64/booting.txt\r
-  The kernel image must be placed at the start of the memory to be used by the\r
-  kernel (2MB aligned) + 0x80000.\r
-\r
-  The Device tree blob is expected to be under 2MB and be within the first 512MB\r
-  of kernel memory and be 2MB aligned.\r
-\r
-  A Flattened Device Tree (FDT) used to boot linux needs to be updated before\r
-  the kernel is started. It needs to indicate how secondary cores are brought up\r
-  and where they are waiting before loading Linux. The FDT also needs to hold\r
-  the correct kernel command line and filesystem RAM-disk information.\r
-  At the moment we do not fully support generating this FDT information at\r
-  runtime. A prepared FDT should be provided at boot. FDT is the only supported\r
-  method for booting the AArch64 Linux kernel.\r
-\r
-  Linux does not use any runtime services at this time, so we can let it\r
-  overwrite UEFI.\r
-*/\r
-\r
-\r
-#define LINUX_ALIGN_VAL       (0x080000) // 2MB + 0x80000 mask\r
-#define LINUX_ALIGN_MASK      (0x1FFFFF) // Bottom 21bits\r
-#define ALIGN_2MB(addr)       ALIGN_POINTER(addr , (2*1024*1024))\r
-\r
-/* ARM32 and AArch64 kernel handover differ.\r
- * x0 is set to FDT base.\r
- * x1-x3 are reserved for future use and should be set to zero.\r
- */\r
-typedef VOID (*LINUX_KERNEL64)(UINTN ParametersBase, UINTN Reserved0,\r
-                               UINTN Reserved1, UINTN Reserved2);\r
-\r
-/* These externs are used to relocate some ASM code into Linux memory. */\r
-extern VOID  *SecondariesPenStart;\r
-extern VOID  *SecondariesPenEnd;\r
-extern UINTN *AsmMailboxbase;\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-PreparePlatformHardware (\r
-  VOID\r
-  )\r
-{\r
-  //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.\r
-\r
-  // Clean before Disable else the Stack gets corrupted with old data.\r
-  ArmCleanDataCache ();\r
-  ArmDisableDataCache ();\r
-  // Invalidate all the entries that might have snuck in.\r
-  ArmInvalidateDataCache ();\r
-\r
-  // Disable and invalidate the instruction cache\r
-  ArmDisableInstructionCache ();\r
-  ArmInvalidateInstructionCache ();\r
-\r
-  // Turn off MMU\r
-  ArmDisableMmu();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-StartLinux (\r
-  IN  EFI_PHYSICAL_ADDRESS  LinuxImage,\r
-  IN  UINTN                 LinuxImageSize,\r
-  IN  EFI_PHYSICAL_ADDRESS  FdtBlobBase,\r
-  IN  UINTN                 FdtBlobSize\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  LINUX_KERNEL64        LinuxKernel = (LINUX_KERNEL64)LinuxImage;\r
-\r
-  // Send msg to secondary cores to go to the kernel pen.\r
-  ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));\r
-\r
-  // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on\r
-  // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.\r
-  Status = ShutdownUefiBootServices ();\r
-  if(EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));\r
-    goto Exit;\r
-  }\r
-\r
-  // Check if the Linux Image is a uImage\r
-  if (*(UINTN*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {\r
-    // Assume the Image Entry Point is just after the uImage header (64-byte size)\r
-    LinuxKernel = (LINUX_KERNEL64)((UINTN)LinuxKernel + 64);\r
-    LinuxImageSize -= 64;\r
-  }\r
-\r
-  //\r
-  // Switch off interrupts, caches, mmu, etc\r
-  //\r
-  Status = PreparePlatformHardware ();\r
-  ASSERT_EFI_ERROR(Status);\r
-\r
-  // Register and print out performance information\r
-  PERF_END (NULL, "BDS", NULL, 0);\r
-  if (PerformanceMeasurementEnabled ()) {\r
-    PrintPerformance ();\r
-  }\r
-\r
-  //\r
-  // Start the Linux Kernel\r
-  //\r
-\r
-  // x1-x3 are reserved (set to zero) for future use.\r
-  LinuxKernel ((UINTN)FdtBlobBase, 0, 0, 0);\r
-\r
-  // Kernel should never exit\r
-  // After Life services are not provided\r
-  ASSERT(FALSE);\r
-\r
-Exit:\r
-  // Only be here if we fail to start Linux\r
-  Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);\r
-\r
-  // Free Runtimee Memory (kernel and FDT)\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Start a Linux kernel from a Device Path\r
-\r
-  @param  LinuxKernel           Device Path to the Linux Kernel\r
-  @param  Parameters            Linux kernel agruments\r
-  @param  Fdt                   Device Path to the Flat Device Tree\r
-\r
-  @retval EFI_SUCCESS           All drivers have been connected\r
-  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
-  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsBootLinuxAtag (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
-  IN  CONST CHAR8*              Arguments\r
-  )\r
-{\r
-  // NOTE : AArch64 Linux kernel does not support ATAG, FDT only.\r
-  ASSERT(0);\r
-\r
-  return RETURN_UNSUPPORTED;\r
-}\r
-\r
-/**\r
-  Start a Linux kernel from a Device Path\r
-\r
-  @param[in]  LinuxKernelDevicePath  Device Path to the Linux Kernel\r
-  @param[in]  InitrdDevicePath       Device Path to the Initrd\r
-  @param[in]  Arguments              Linux kernel arguments\r
-\r
-  @retval EFI_SUCCESS           All drivers have been connected\r
-  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
-  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsBootLinuxFdt (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
-  IN  CONST CHAR8*              Arguments\r
-  )\r
-{\r
-  EFI_STATUS               Status;\r
-  EFI_STATUS               PenBaseStatus;\r
-  UINTN                    LinuxImageSize;\r
-  UINTN                    InitrdImageSize;\r
-  UINTN                    InitrdImageBaseSize;\r
-  VOID                     *InstalledFdtBase;\r
-  UINTN                    FdtBlobSize;\r
-  EFI_PHYSICAL_ADDRESS     FdtBlobBase;\r
-  EFI_PHYSICAL_ADDRESS     LinuxImage;\r
-  EFI_PHYSICAL_ADDRESS     InitrdImage;\r
-  EFI_PHYSICAL_ADDRESS     InitrdImageBase;\r
-  ARM_PROCESSOR_TABLE      *ArmProcessorTable;\r
-  ARM_CORE_INFO            *ArmCoreInfoTable;\r
-  UINTN                    Index;\r
-  EFI_PHYSICAL_ADDRESS     PenBase;\r
-  UINTN                    PenSize;\r
-  UINTN                    MailBoxBase;\r
-\r
-  PenBaseStatus = EFI_UNSUPPORTED;\r
-  PenSize = 0;\r
-  InitrdImage = 0;\r
-  InitrdImageSize = 0;\r
-  InitrdImageBase = 0;\r
-  InitrdImageBaseSize = 0;\r
-\r
-  PERF_START (NULL, "BDS", NULL, 0);\r
-\r
-  //\r
-  // Load the Linux kernel from a device path\r
-  //\r
-\r
-  // Try to put the kernel at the start of RAM so as to give it access to all memory.\r
-  // If that fails fall back to try loading it within LINUX_KERNEL_MAX_OFFSET of memory start.\r
-  LinuxImage = PcdGet64 (PcdSystemMemoryBase) + 0x80000;\r
-  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateAddress, &LinuxImage, &LinuxImageSize);\r
-  if (EFI_ERROR(Status)) {\r
-    // Try again but give the loader more freedom of where to put the image.\r
-    LinuxImage = LINUX_KERNEL_MAX_OFFSET;\r
-    Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);\r
-    if (EFI_ERROR(Status)) {\r
-      Print (L"ERROR: Did not find Linux kernel (%r).\n", Status);\r
-      return Status;\r
-    }\r
-  }\r
-  // Adjust the kernel location slightly if required. The kernel needs to be placed at start\r
-  //  of memory (2MB aligned) + 0x80000.\r
-  if ((LinuxImage & LINUX_ALIGN_MASK) != LINUX_ALIGN_VAL) {\r
-    LinuxImage = (EFI_PHYSICAL_ADDRESS)CopyMem (ALIGN_2MB(LinuxImage) + 0x80000, (VOID*)(UINTN)LinuxImage, LinuxImageSize);\r
-  }\r
-\r
-  if (InitrdDevicePath) {\r
-    InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;\r
-    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);\r
-    }\r
-    if (EFI_ERROR (Status)) {\r
-      Print (L"ERROR: Did not find initrd image (%r).\n", Status);\r
-      goto EXIT_FREE_LINUX;\r
-    }\r
-\r
-    // Check if the initrd is a uInitrd\r
-    if (*(UINTN*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {\r
-      // Skip the 64-byte image header\r
-      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);\r
-      InitrdImageSize = InitrdImageBaseSize - 64;\r
-    } else {\r
-      InitrdImage = InitrdImageBase;\r
-      InitrdImageSize = InitrdImageBaseSize;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Get the FDT from the Configuration Table.\r
-  // The FDT will be reloaded in PrepareFdt() to a more appropriate\r
-  // location for the Linux Kernel.\r
-  //\r
-  Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &InstalledFdtBase);\r
-  if (EFI_ERROR (Status)) {\r
-    Print (L"ERROR: Did not get the Device Tree blob (%r).\n", Status);\r
-    goto EXIT_FREE_INITRD;\r
-  }\r
-  FdtBlobBase = (EFI_PHYSICAL_ADDRESS)InstalledFdtBase;\r
-  FdtBlobSize = fdt_totalsize (InstalledFdtBase);\r
-\r
-  //\r
-  // Install secondary core pens if the Power State Coordination Interface is not supported\r
-  //\r
-  if (FeaturePcdGet (PcdArmLinuxSpinTable)) {\r
-    // Place Pen at the start of Linux memory. We can then tell Linux to not use this bit of memory\r
-    PenBase  = LinuxImage - 0x80000;\r
-    PenSize  = (UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart;\r
-\r
-    // Reserve the memory as RuntimeServices\r
-    PenBaseStatus = gBS->AllocatePages (AllocateAddress, EfiRuntimeServicesCode, EFI_SIZE_TO_PAGES (PenSize), &PenBase);\r
-    if (EFI_ERROR (PenBaseStatus)) {\r
-      Print (L"Warning: Failed to reserve the memory required for the secondary cores at 0x%lX, Status = %r\n", PenBase, PenBaseStatus);\r
-      // Even if there is a risk of memory corruption we carry on\r
-    }\r
-\r
-    // Put mailboxes below the pen code so we know where they are relative to code.\r
-    MailBoxBase = (UINTN)PenBase + ((UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart);\r
-    // Make sure this is 8 byte aligned.\r
-    if (MailBoxBase % sizeof(MailBoxBase) != 0) {\r
-      MailBoxBase += sizeof(MailBoxBase) - MailBoxBase % sizeof(MailBoxBase);\r
-    }\r
-\r
-    CopyMem ( (VOID*)(PenBase), (VOID*)&SecondariesPenStart, PenSize);\r
-\r
-    // Update the MailboxBase variable used in the pen code\r
-    *(UINTN*)(PenBase + ((UINTN)&AsmMailboxbase - (UINTN)&SecondariesPenStart)) = MailBoxBase;\r
-\r
-    for (Index=0; Index < gST->NumberOfTableEntries; Index++) {\r
-      // Check for correct GUID type\r
-      if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {\r
-        UINTN i;\r
-\r
-        // Get them under our control. Move from depending on 32bit reg(sys_flags) and SWI\r
-        // to 64 bit addr and WFE\r
-        ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable;\r
-        ArmCoreInfoTable = ArmProcessorTable->ArmCpus;\r
-\r
-        for (i = 0; i < ArmProcessorTable->NumberOfEntries; i++ ) {\r
-          // This goes into the SYSFLAGS register for the VE platform. We only have one 32bit reg to use\r
-          MmioWrite32(ArmCoreInfoTable[i].MailboxSetAddress, (UINTN)PenBase);\r
-\r
-          // So FDT can set the mailboxes correctly with the parser. These are 64bit Memory locations.\r
-          ArmCoreInfoTable[i].MailboxSetAddress = (UINTN)MailBoxBase + i*sizeof(MailBoxBase);\r
-\r
-          // Clear the mailboxes for the respective cores\r
-          *((UINTN*)(ArmCoreInfoTable[i].MailboxSetAddress)) = 0x0;\r
-        }\r
-      }\r
-    }\r
-    // Flush caches to make sure our pen gets to mem before we free the cores.\r
-    ArmCleanDataCache();\r
-  }\r
-\r
-  // By setting address=0 we leave the memory allocation to the function\r
-  Status = PrepareFdt (Arguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);\r
-  if (EFI_ERROR(Status)) {\r
-    Print(L"ERROR: Can not load Linux kernel with Device Tree. Status=0x%X\n", Status);\r
-    goto EXIT_FREE_FDT;\r
-  }\r
-\r
-  return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize);\r
-\r
-EXIT_FREE_FDT:\r
-  if (!EFI_ERROR (PenBaseStatus)) {\r
-    gBS->FreePages (PenBase, EFI_SIZE_TO_PAGES (PenSize));\r
-  }\r
-\r
-  gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize));\r
-\r
-EXIT_FREE_INITRD:\r
-  if (InitrdDevicePath) {\r
-    gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));\r
-  }\r
-\r
-EXIT_FREE_LINUX:\r
-  gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));\r
-\r
-  return Status;\r
-}\r