]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/BdsLib: Added Aarch64 support for booting Linux
authorHarry Liebel <Harry.Liebel@arm.com>
Thu, 18 Jul 2013 18:13:02 +0000 (18:13 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 18 Jul 2013 18:13:02 +0000 (18:13 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Harry Liebel <Harry.Liebel@arm.com>
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14487 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/ArmPkg.dec
ArmPkg/ArmPkg.dsc
ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsLib.inf

index 1012329013a193af841238e5a8e576437afd1621..3326e7b584b59db3fced3f2984872bc0266d8f50 100644 (file)
   # Other modes include using SP0 or switching to Aarch32, but these are\r
   # not currently supported.\r
   gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x3c9|UINT32|0x0000003E\r
+  # If the fixed FDT address is not available, then it should be loaded above the kernel.\r
+  # The recommendation from the AArch64 Linux kernel is to have the FDT below 512MB.\r
+  # (see the kernel doc: Documentation/arm64/booting.txt)\r
+  gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x20000000|UINT32|0x00000023\r
+  # The FDT blob must be loaded at a 2MB aligned address.\r
+  gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x00200000|UINT32|0x00000026\r
index 638054d325180e64885355f77b4bbfd334039da0..eb9791c58280f3749b1ace073bac9a8c4bef9150 100644 (file)
 \r
   ArmPkg/Filesystem/SemihostFs/SemihostFs.inf\r
 \r
-  ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf\r
   ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf\r
 \r
 [Components.ARM]\r
   ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf\r
   ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf\r
 \r
+  ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf\r
+\r
 [Components.AARCH64]\r
   ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf\r
   ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf\r
diff --git a/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c
new file mode 100644 (file)
index 0000000..b66d96f
--- /dev/null
@@ -0,0 +1,353 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011-2013, 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
+\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
+  IN  UINT32                MachineType\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  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
+BdsBootLinuxFdt (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
+  IN  CONST CHAR8*              Arguments,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_STATUS            PenBaseStatus;\r
+  UINTN                 LinuxImageSize;\r
+  UINTN                 InitrdImageSize;\r
+  UINTN                 InitrdImageBaseSize;\r
+  UINTN                 FdtBlobSize;\r
+  EFI_PHYSICAL_ADDRESS  FdtBlobBase;\r
+  UINT32                FdtMachineType;\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
+  FdtMachineType = 0xFFFFFFFF;\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 = PcdGet32(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.\n");\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.\n");\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
+  // Load the FDT binary from a device path.\r
+  // The FDT will be reloaded later to a more appropriate location for the Linux kernel.\r
+  FdtBlobBase = LINUX_KERNEL_MAX_OFFSET;\r
+  Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &FdtBlobBase, &FdtBlobSize);\r
+  if (EFI_ERROR(Status)) {\r
+    Print (L"ERROR: Did not find Device Tree blob.\n");\r
+    goto EXIT_FREE_INITRD;\r
+  }\r
+\r
+  //\r
+  // Install secondary core pens if the Power State Coordination Interface is not supported\r
+  //\r
+  if (FeaturePcdGet (PcdArmPsciSupport) == FALSE) {\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
+    // Flush caches to make sure our pen gets to mem before we free the cores.\r
+    ArmCleanDataCache();\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
+  }\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, FdtMachineType);\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
diff --git a/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S b/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S
new file mode 100644 (file)
index 0000000..f97bf15
--- /dev/null
@@ -0,0 +1,58 @@
+//\r
+//  Copyright (c) 2011-2013, 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
+\r
+\r
+/* Secondary core pens for AArch64 Linux booting.\r
+\r
+   This code it placed in Linux kernel memory and marked reserved. UEFI ensures\r
+   that the secondary cores get to this pen and the kernel can then start the\r
+   cores from here.\r
+   NOTE: This code must be self-contained.\r
+*/\r
+\r
+#include <Library/ArmLib.h>\r
+\r
+.text\r
+.align 3\r
+\r
+ASM_GLOBAL ASM_PFX(SecondariesPenStart)\r
+ASM_GLOBAL SecondariesPenEnd\r
+\r
+ASM_PFX(SecondariesPenStart):\r
+   // Registers x0-x3 are reserved for future use and should be set to zero.\r
+   mov x0, xzr\r
+   mov x1, xzr\r
+   mov x2, xzr\r
+   mov x3, xzr\r
+\r
+   // Get core position. Taken from ArmPlatformGetCorePosition().\r
+   // Assumes max 4 cores per cluster.\r
+   mrs x4, mpidr_el1             // Get MPCore register.\r
+   and x5, x4, #ARM_CORE_MASK    // Get core number.\r
+   and x4, x4, #ARM_CLUSTER_MASK // Get cluster number.\r
+   add x4, x5, x4, LSR #6        // Add scaled cluster number to core number.\r
+   lsl x4, x4, 3            // Get mailbox offset for this core.\r
+   ldr x5, AsmMailboxbase   // Get mailbox addr relative to pc (36 bytes ahead).\r
+   add x4, x4, x5           // Add core mailbox offset to base of mailbox.\r
+1: ldr x5, [x4]             // Load value from mailbox.\r
+   cmp xzr, x5              // Has the mailbox been set?\r
+   b.ne 2f                  // If so break out of loop.\r
+   wfe                      // If not, wait a bit.\r
+   b 1b                     // Wait over, check if mailbox set again.\r
+2: br x5                    // Jump to mailbox value.\r
+\r
+.align 3 // Make sure the variable below is 8 byte aligned.\r
+                .global     AsmMailboxbase\r
+AsmMailboxbase: .xword      0xdeaddeadbeefbeef\r
+\r
+SecondariesPenEnd:\r
index 6b0426c0ad8c701df5ee90450ccf86220c9c55d7..6f295ffe56076bddee6ca6d4d6db9d575541f895 100644 (file)
   Arm/BdsLinuxLoader.c\r
   Arm/BdsLinuxAtag.c\r
 \r
+[Sources.AARCH64]\r
+  AArch64/BdsLinuxLoader.c\r
+  AArch64/BdsLinuxLoaderHelper.S  | GCC\r
+\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   EmbeddedPkg/EmbeddedPkg.dec\r
@@ -49,6 +53,9 @@
   FdtLib\r
   TimerLib\r
 \r
+[LibraryClasses.AARCH64]\r
+  ArmGicLib\r
+\r
 [Guids]\r
   gEfiFileInfoGuid\r
   gArmMpCoreInfoGuid\r
@@ -82,5 +89,9 @@
 [FixedPcd.ARM]\r
   gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset\r
 \r
+[FixedPcd.AARCH64]\r
+  gArmTokenSpaceGuid.PcdGicDistributorBase\r
+  gArmTokenSpaceGuid.PcdGicSgiIntId\r
+\r
 [Depex]\r
   TRUE\r