]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c
ArmPkg: remove the LinuxLoader application
[mirror_edk2.git] / ArmPkg / Application / LinuxLoader / LinuxLoaderFdt.c
diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c b/ArmPkg/Application/LinuxLoader/LinuxLoaderFdt.c
deleted file mode 100644 (file)
index 0f53784..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/** @file\r
-*\r
-*  Copyright (c) 2011-2015, 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
-#include <PiDxe.h>\r
-#include <Library/ArmLib.h>\r
-#include <Library/HobLib.h>\r
-\r
-#include <Guid/ArmMpCoreInfo.h>\r
-\r
-#include "LinuxLoader.h"\r
-\r
-#define ALIGN(x, a)     (((x) + ((a) - 1)) & ~((a) - 1))\r
-#define PALIGN(p, a)    ((void *)(ALIGN ((unsigned long)(p), (a))))\r
-#define GET_CELL(p)     (p += 4, *((const UINT32 *)(p-4)))\r
-\r
-STATIC\r
-UINTN\r
-cpu_to_fdtn (UINTN x) {\r
-  if (sizeof (UINTN) == sizeof (UINT32)) {\r
-    return cpu_to_fdt32 (x);\r
-  } else {\r
-    return cpu_to_fdt64 (x);\r
-  }\r
-}\r
-\r
-typedef struct {\r
-  UINTN   Base;\r
-  UINTN   Size;\r
-} FDT_REGION;\r
-\r
-STATIC\r
-BOOLEAN\r
-IsLinuxReservedRegion (\r
-  IN EFI_MEMORY_TYPE MemoryType\r
-  )\r
-{\r
-  switch (MemoryType) {\r
-  case EfiRuntimeServicesCode:\r
-  case EfiRuntimeServicesData:\r
-  case EfiUnusableMemory:\r
-  case EfiACPIReclaimMemory:\r
-  case EfiACPIMemoryNVS:\r
-  case EfiReservedMemoryType:\r
-    return TRUE;\r
-  default:\r
-    return FALSE;\r
-  }\r
-}\r
-\r
-/**\r
-** Relocate the FDT blob to a more appropriate location for the Linux kernel.\r
-** This function will allocate memory for the relocated FDT blob.\r
-**\r
-** @retval EFI_SUCCESS on success.\r
-** @retval EFI_OUT_OF_RESOURCES or EFI_INVALID_PARAMETER on failure.\r
-*/\r
-STATIC\r
-EFI_STATUS\r
-RelocateFdt (\r
-  EFI_PHYSICAL_ADDRESS   SystemMemoryBase,\r
-  EFI_PHYSICAL_ADDRESS   OriginalFdt,\r
-  UINTN                  OriginalFdtSize,\r
-  EFI_PHYSICAL_ADDRESS   *RelocatedFdt,\r
-  UINTN                  *RelocatedFdtSize,\r
-  EFI_PHYSICAL_ADDRESS   *RelocatedFdtAlloc\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  INTN                  Error;\r
-  UINT64                FdtAlignment;\r
-\r
-  *RelocatedFdtSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE;\r
-\r
-  // If FDT load address needs to be aligned, allocate more space.\r
-  FdtAlignment = PcdGet32 (PcdArmLinuxFdtAlignment);\r
-  if (FdtAlignment != 0) {\r
-    *RelocatedFdtSize += FdtAlignment;\r
-  }\r
-\r
-  // Try below a watermark address.\r
-  Status = EFI_NOT_FOUND;\r
-  if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) {\r
-    *RelocatedFdt = LINUX_FDT_MAX_OFFSET;\r
-    Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData,\r
-                    EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);\r
-    if (EFI_ERROR (Status)) {\r
-      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));\r
-    }\r
-  }\r
-\r
-  // Try anywhere there is available space.\r
-  if (EFI_ERROR (Status)) {\r
-    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData,\r
-                    EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);\r
-    if (EFI_ERROR (Status)) {\r
-      ASSERT_EFI_ERROR (Status);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    } else {\r
-      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));\r
-    }\r
-  }\r
-\r
-  *RelocatedFdtAlloc = *RelocatedFdt;\r
-  if (FdtAlignment != 0) {\r
-    *RelocatedFdt = ALIGN (*RelocatedFdt, FdtAlignment);\r
-  }\r
-\r
-  // Load the Original FDT tree into the new region\r
-  Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt,\r
-            (VOID*)(UINTN)(*RelocatedFdt), *RelocatedFdtSize);\r
-  if (Error) {\r
-    DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Error)));\r
-    gBS->FreePages (*RelocatedFdtAlloc, EFI_SIZE_TO_PAGES (*RelocatedFdtSize));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PrepareFdt (\r
-  IN     EFI_PHYSICAL_ADDRESS SystemMemoryBase,\r
-  IN     CONST CHAR8*         CommandLineArguments,\r
-  IN     EFI_PHYSICAL_ADDRESS InitrdImage,\r
-  IN     UINTN                InitrdImageSize,\r
-  IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase,\r
-  IN OUT UINTN                *FdtBlobSize\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  EFI_PHYSICAL_ADDRESS  NewFdtBlobBase;\r
-  EFI_PHYSICAL_ADDRESS  NewFdtBlobAllocation;\r
-  UINTN                 NewFdtBlobSize;\r
-  VOID*                 fdt;\r
-  INTN                  err;\r
-  INTN                  node;\r
-  INTN                  cpu_node;\r
-  INT32                 lenp;\r
-  CONST VOID*           BootArg;\r
-  CONST VOID*           Method;\r
-  EFI_PHYSICAL_ADDRESS  InitrdImageStart;\r
-  EFI_PHYSICAL_ADDRESS  InitrdImageEnd;\r
-  FDT_REGION            Region;\r
-  UINTN                 Index;\r
-  CHAR8                 Name[10];\r
-  LIST_ENTRY            ResourceList;\r
-  SYSTEM_MEMORY_RESOURCE  *Resource;\r
-  ARM_PROCESSOR_TABLE   *ArmProcessorTable;\r
-  ARM_CORE_INFO         *ArmCoreInfoTable;\r
-  UINT32                MpId;\r
-  UINT32                ClusterId;\r
-  UINT32                CoreId;\r
-  UINT64                CpuReleaseAddr;\r
-  UINTN                 MemoryMapSize;\r
-  EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
-  EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;\r
-  UINTN                 MapKey;\r
-  UINTN                 DescriptorSize;\r
-  UINT32                DescriptorVersion;\r
-  UINTN                 Pages;\r
-  UINTN                 OriginalFdtSize;\r
-  BOOLEAN               CpusNodeExist;\r
-  UINTN                 CoreMpId;\r
-\r
-  NewFdtBlobAllocation = 0;\r
-\r
-  //\r
-  // Sanity checks on the original FDT blob.\r
-  //\r
-  err = fdt_check_header ((VOID*)(UINTN)(*FdtBlobBase));\r
-  if (err != 0) {\r
-    Print (L"ERROR: Device Tree header not valid (err:%d)\n", err);\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  // The original FDT blob might have been loaded partially.\r
-  // Check that it is not the case.\r
-  OriginalFdtSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));\r
-  if (OriginalFdtSize > *FdtBlobSize) {\r
-    Print (L"ERROR: Incomplete FDT. Only %d/%d bytes have been loaded.\n",\r
-           *FdtBlobSize, OriginalFdtSize);\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Relocate the FDT to its final location.\r
-  //\r
-  Status = RelocateFdt (SystemMemoryBase, *FdtBlobBase, OriginalFdtSize,\r
-             &NewFdtBlobBase, &NewFdtBlobSize, &NewFdtBlobAllocation);\r
-  if (EFI_ERROR (Status)) {\r
-    goto FAIL_RELOCATE_FDT;\r
-  }\r
-\r
-  fdt = (VOID*)(UINTN)NewFdtBlobBase;\r
-\r
-  node = fdt_subnode_offset (fdt, 0, "chosen");\r
-  if (node < 0) {\r
-    // The 'chosen' node does not exist, create it\r
-    node = fdt_add_subnode (fdt, 0, "chosen");\r
-    if (node < 0) {\r
-      DEBUG ((EFI_D_ERROR, "Error on finding 'chosen' node\n"));\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto FAIL_COMPLETE_FDT;\r
-    }\r
-  }\r
-\r
-  DEBUG_CODE_BEGIN ();\r
-    BootArg = fdt_getprop (fdt, node, "bootargs", &lenp);\r
-    if (BootArg != NULL) {\r
-      DEBUG ((EFI_D_ERROR, "BootArg: %a\n", BootArg));\r
-    }\r
-  DEBUG_CODE_END ();\r
-\r
-  //\r
-  // Set Linux CmdLine\r
-  //\r
-  if ((CommandLineArguments != NULL) && (AsciiStrLen (CommandLineArguments) > 0)) {\r
-    err = fdt_setprop (fdt, node, "bootargs", CommandLineArguments, AsciiStrSize (CommandLineArguments));\r
-    if (err) {\r
-      DEBUG ((EFI_D_ERROR, "Fail to set new 'bootarg' (err:%d)\n", err));\r
-    }\r
-  }\r
-\r
-  //\r
-  // Set Linux Initrd\r
-  //\r
-  if (InitrdImageSize != 0) {\r
-    InitrdImageStart = cpu_to_fdt64 (InitrdImage);\r
-    err = fdt_setprop (fdt, node, "linux,initrd-start", &InitrdImageStart, sizeof (EFI_PHYSICAL_ADDRESS));\r
-    if (err) {\r
-      DEBUG ((EFI_D_ERROR, "Fail to set new 'linux,initrd-start' (err:%d)\n", err));\r
-    }\r
-    InitrdImageEnd = cpu_to_fdt64 (InitrdImage + InitrdImageSize);\r
-    err = fdt_setprop (fdt, node, "linux,initrd-end", &InitrdImageEnd, sizeof (EFI_PHYSICAL_ADDRESS));\r
-    if (err) {\r
-      DEBUG ((EFI_D_ERROR, "Fail to set new 'linux,initrd-start' (err:%d)\n", err));\r
-    }\r
-  }\r
-\r
-  //\r
-  // Set Physical memory setup if does not exist\r
-  //\r
-  node = fdt_subnode_offset (fdt, 0, "memory");\r
-  if (node < 0) {\r
-    // The 'memory' node does not exist, create it\r
-    node = fdt_add_subnode (fdt, 0, "memory");\r
-    if (node >= 0) {\r
-      fdt_setprop_string (fdt, node, "name", "memory");\r
-      fdt_setprop_string (fdt, node, "device_type", "memory");\r
-\r
-      GetSystemMemoryResources (&ResourceList);\r
-      Resource = (SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink;\r
-\r
-      Region.Base = cpu_to_fdtn ((UINTN)Resource->PhysicalStart);\r
-      Region.Size = cpu_to_fdtn ((UINTN)Resource->ResourceLength);\r
-\r
-      err = fdt_setprop (fdt, node, "reg", &Region, sizeof (Region));\r
-      if (err) {\r
-        DEBUG ((EFI_D_ERROR, "Fail to set new 'memory region' (err:%d)\n", err));\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Add the memory regions reserved by the UEFI Firmware\r
-  //\r
-\r
-  // Retrieve the UEFI Memory Map\r
-  MemoryMap = NULL;\r
-  MemoryMapSize = 0;\r
-  Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive\r
-    // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size.\r
-    Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;\r
-    MemoryMap = AllocatePages (Pages);\r
-    if (MemoryMap == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto FAIL_COMPLETE_FDT;\r
-    }\r
-    Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);\r
-  }\r
-\r
-  // Go through the list and add the reserved region to the Device Tree\r
-  if (!EFI_ERROR (Status)) {\r
-    MemoryMapPtr = MemoryMap;\r
-    for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {\r
-      if (IsLinuxReservedRegion ((EFI_MEMORY_TYPE)MemoryMapPtr->Type)) {\r
-        DEBUG ((DEBUG_VERBOSE, "Reserved region of type %d [0x%lX, 0x%lX]\n",\r
-            MemoryMapPtr->Type,\r
-            (UINTN)MemoryMapPtr->PhysicalStart,\r
-            (UINTN)(MemoryMapPtr->PhysicalStart + MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE)));\r
-        err = fdt_add_mem_rsv (fdt, MemoryMapPtr->PhysicalStart, MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE);\r
-        if (err != 0) {\r
-          Print (L"Warning: Fail to add 'memreserve' (err:%d)\n", err);\r
-        }\r
-      }\r
-      MemoryMapPtr = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + DescriptorSize);\r
-    }\r
-  }\r
-\r
-  //\r
-  // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms.\r
-  //\r
-  // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file\r
-  // in the kernel documentation:\r
-  // Documentation/devicetree/bindings/arm/cpus.txt\r
-  //\r
-  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {\r
-    // Check for correct GUID type\r
-    if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {\r
-      MpId = ArmReadMpidr ();\r
-      ClusterId = GET_CLUSTER_ID (MpId);\r
-      CoreId    = GET_CORE_ID (MpId);\r
-\r
-      node = fdt_subnode_offset (fdt, 0, "cpus");\r
-      if (node < 0) {\r
-        // Create the /cpus node\r
-        node = fdt_add_subnode (fdt, 0, "cpus");\r
-        fdt_setprop_string (fdt, node, "name", "cpus");\r
-        fdt_setprop_cell (fdt, node, "#address-cells", sizeof (UINTN) / 4);\r
-        fdt_setprop_cell (fdt, node, "#size-cells", 0);\r
-        CpusNodeExist = FALSE;\r
-      } else {\r
-        CpusNodeExist = TRUE;\r
-      }\r
-\r
-      // Get pointer to ARM processor table\r
-      ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable;\r
-      ArmCoreInfoTable = ArmProcessorTable->ArmCpus;\r
-\r
-      for (Index = 0; Index < ArmProcessorTable->NumberOfEntries; Index++) {\r
-        CoreMpId = (UINTN) GET_MPID (ArmCoreInfoTable[Index].ClusterId,\r
-                             ArmCoreInfoTable[Index].CoreId);\r
-        AsciiSPrint (Name, 10, "cpu@%x", CoreMpId);\r
-\r
-        // If the 'cpus' node did not exist then create all the 'cpu' nodes.\r
-        // In case 'cpus' node is provided in the original FDT then we do not add\r
-        // any 'cpu' node.\r
-        if (!CpusNodeExist) {\r
-          cpu_node = fdt_add_subnode (fdt, node, Name);\r
-          if (cpu_node < 0) {\r
-            DEBUG ((EFI_D_ERROR, "Error on creating '%s' node\n", Name));\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto FAIL_COMPLETE_FDT;\r
-          }\r
-\r
-          fdt_setprop_string (fdt, cpu_node, "device_type", "cpu");\r
-\r
-          CoreMpId = cpu_to_fdtn (CoreMpId);\r
-          fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId));\r
-        } else {\r
-          cpu_node = fdt_subnode_offset (fdt, node, Name);\r
-        }\r
-\r
-        if (cpu_node >= 0) {\r
-          Method = fdt_getprop (fdt, cpu_node, "enable-method", &lenp);\r
-          // We only care when 'enable-method' == 'spin-table'. If the enable-method is not defined\r
-          // or defined as 'psci' then we ignore its properties.\r
-          if ((Method != NULL) && (AsciiStrCmp ((CHAR8 *)Method, "spin-table") == 0)) {\r
-            // There are two cases;\r
-            //  - UEFI firmware parked the secondary cores and/or UEFI firmware is aware of the CPU\r
-            //    release addresses (PcdArmLinuxSpinTable == TRUE)\r
-            //  - the parking of the secondary cores has been managed before starting UEFI and/or UEFI\r
-            //    does not anything about the CPU release addresses - in this case we do nothing\r
-            if (FeaturePcdGet (PcdArmLinuxSpinTable)) {\r
-              CpuReleaseAddr = cpu_to_fdt64 (ArmCoreInfoTable[Index].MailboxSetAddress);\r
-              fdt_setprop (fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof (CpuReleaseAddr));\r
-\r
-              // If it is not the primary core than the cpu should be disabled\r
-              if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) {\r
-                fdt_setprop_string (fdt, cpu_node, "status", "disabled");\r
-              }\r
-            }\r
-          }\r
-        }\r
-      }\r
-      break;\r
-    }\r
-  }\r
-\r
-  // If we succeeded to generate the new Device Tree then free the old Device Tree\r
-  gBS->FreePages (*FdtBlobBase, EFI_SIZE_TO_PAGES (*FdtBlobSize));\r
-\r
-  // Update the real size of the Device Tree\r
-  fdt_pack ((VOID*)(UINTN)(NewFdtBlobBase));\r
-\r
-  *FdtBlobBase = NewFdtBlobBase;\r
-  *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase));\r
-  return EFI_SUCCESS;\r
-\r
-FAIL_COMPLETE_FDT:\r
-  gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize));\r
-\r
-FAIL_RELOCATE_FDT:\r
-  *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));\r
-  // Return success even if we failed to update the FDT blob.\r
-  // The original one is still valid.\r
-  return EFI_SUCCESS;\r
-}\r