/** @file\r
*\r
-* Copyright (c) 2011-2013, ARM Limited. All rights reserved.\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
#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
IN EFI_PHYSICAL_ADDRESS LinuxImage,\r
IN UINTN LinuxImageSize,\r
IN EFI_PHYSICAL_ADDRESS FdtBlobBase,\r
- IN UINTN FdtBlobSize,\r
- IN UINT32 MachineType\r
+ IN UINTN FdtBlobSize\r
)\r
{\r
EFI_STATUS Status;\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
+ @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
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
+ IN CONST CHAR8* Arguments\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
+ 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
- FdtMachineType = 0xFFFFFFFF;\r
InitrdImage = 0;\r
InitrdImageSize = 0;\r
InitrdImageBase = 0;\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
+ 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.\n");\r
+ Print (L"ERROR: Did not find Linux kernel (%r).\n", Status);\r
return Status;\r
}\r
}\r
Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);\r
}\r
if (EFI_ERROR (Status)) {\r
- Print (L"ERROR: Did not find initrd image.\n");\r
+ Print (L"ERROR: Did not find initrd image (%r).\n", Status);\r
goto EXIT_FREE_LINUX;\r
}\r
\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
+ //\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 (PcdArmPsciSupport) == FALSE) {\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
// 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
}\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
goto EXIT_FREE_FDT;\r
}\r
\r
- return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, FdtMachineType);\r
+ return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize);\r
\r
EXIT_FREE_FDT:\r
if (!EFI_ERROR (PenBaseStatus)) {\r