diff options
Diffstat (limited to 'EmbeddedPkg/Library/FdtLib/0002-ArmPkg-BdsLib-Added-support-for-modifying-the-passed.patch')
-rw-r--r-- | EmbeddedPkg/Library/FdtLib/0002-ArmPkg-BdsLib-Added-support-for-modifying-the-passed.patch | 489 |
1 files changed, 0 insertions, 489 deletions
diff --git a/EmbeddedPkg/Library/FdtLib/0002-ArmPkg-BdsLib-Added-support-for-modifying-the-passed.patch b/EmbeddedPkg/Library/FdtLib/0002-ArmPkg-BdsLib-Added-support-for-modifying-the-passed.patch deleted file mode 100644 index 66ea902875..0000000000 --- a/EmbeddedPkg/Library/FdtLib/0002-ArmPkg-BdsLib-Added-support-for-modifying-the-passed.patch +++ /dev/null @@ -1,489 +0,0 @@ -From 9c16a23fba659cdf0ce798aa085a4fb8c3bd47d1 Mon Sep 17 00:00:00 2001 -From: Olivier Martin <olivier.martin@arm.com> -Date: Thu, 16 Feb 2012 15:50:59 +0000 -Subject: [PATCH 2/3] ArmPkg/BdsLib: Added support for modifying the passed FDT blob - -- Add Linux CmdLine if not defined -- Add initrd if not defined -- Add CPU parking address if not defined -- Add System Memory info if not defined ---- - ArmPkg/ArmPkg.dsc | 1 + - ArmPkg/Library/BdsLib/BdsInternal.h | 9 + - ArmPkg/Library/BdsLib/BdsLib.inf | 3 + - ArmPkg/Library/BdsLib/BdsLinuxFdt.c | 353 ++++++++++++++++++++++++++++++++ - ArmPkg/Library/BdsLib/BdsLinuxLoader.c | 8 + - ArmPkg/Library/BdsLib/BdsLinuxLoader.h | 10 +- - 6 files changed, 383 insertions(+), 1 deletions(-) - mode change 100644 => 100755 ArmPkg/ArmPkg.dsc - mode change 100644 => 100755 ArmPkg/Library/BdsLib/BdsInternal.h - mode change 100644 => 100755 ArmPkg/Library/BdsLib/BdsLib.inf - create mode 100755 ArmPkg/Library/BdsLib/BdsLinuxFdt.c - -diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc -old mode 100644 -new mode 100755 -index f4989a6..07c825d ---- a/ArmPkg/ArmPkg.dsc -+++ b/ArmPkg/ArmPkg.dsc -@@ -72,6 +72,7 @@ - SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf - - BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf -+ FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf - - IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf - -diff --git a/ArmPkg/Library/BdsLib/BdsInternal.h b/ArmPkg/Library/BdsLib/BdsInternal.h -old mode 100644 -new mode 100755 -index 880d780..80d21b2 ---- a/ArmPkg/Library/BdsLib/BdsInternal.h -+++ b/ArmPkg/Library/BdsLib/BdsInternal.h -@@ -103,4 +103,13 @@ PrepareAtagList ( - OUT UINT32 *AtagSize - ); - -+EFI_STATUS -+PrepareFdt ( -+ IN CONST CHAR8* CommandLineString, -+ IN EFI_PHYSICAL_ADDRESS InitrdImage, -+ IN UINTN InitrdImageSize, -+ IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase, -+ IN OUT UINT32 *FdtBlobSize -+ ); -+ - #endif -diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf -old mode 100644 -new mode 100755 -index 20644f1..b3cab21 ---- a/ArmPkg/Library/BdsLib/BdsLib.inf -+++ b/ArmPkg/Library/BdsLib/BdsLib.inf -@@ -27,6 +27,7 @@ - - BdsLinuxLoader.c - BdsLinuxAtag.c -+ BdsLinuxFdt.c - - [Packages] - MdePkg/MdePkg.dec -@@ -41,9 +42,11 @@ - HobLib - PerformanceLib - SerialPortLib -+ FdtLib - - [Guids] - gEfiFileInfoGuid -+ gArmMpCoreInfoGuid - - [Protocols] - gEfiBdsArchProtocolGuid -diff --git a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c -new file mode 100755 -index 0000000..5c14b65 ---- /dev/null -+++ b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c -@@ -0,0 +1,353 @@ -+/** @file -+* -+* Copyright (c) 2011-2012, 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 <Library/PcdLib.h> -+#include <libfdt.h> -+ -+#include "BdsInternal.h" -+ -+#define LINUX_FDT_MAX_OFFSET (PcdGet32(PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxAtagMaxOffset)) -+ -+#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 -+IsPrintableString ( -+ IN CONST VOID* data, -+ IN UINTN len -+ ) -+{ -+ CONST CHAR8 *s = data; -+ CONST CHAR8 *ss; -+ -+ // zero length is not -+ if (len == 0) { -+ return 0; -+ } -+ -+ // must terminate with zero -+ if (s[len - 1] != '\0') { -+ return 0; -+ } -+ -+ ss = s; -+ while (*s/* && isprint(*s)*/) { -+ s++; -+ } -+ -+ // not zero, or not done yet -+ if (*s != '\0' || (s + 1 - ss) < len) { -+ return 0; -+ } -+ -+ return 1; -+} -+ -+STATIC -+VOID -+PrintData ( -+ IN CONST CHAR8* data, -+ IN UINTN len -+ ) -+{ -+ UINTN i; -+ CONST CHAR8 *p = data; -+ -+ // no data, don't print -+ if (len == 0) -+ return; -+ -+ if (IsPrintableString (data, len)) { -+ Print(L" = \"%a\"", (const char *)data); -+ } else if ((len % 4) == 0) { -+ Print(L" = <"); -+ for (i = 0; i < len; i += 4) { -+ Print(L"0x%08x%a", fdt32_to_cpu(GET_CELL(p)),i < (len - 4) ? " " : ""); -+ } -+ Print(L">"); -+ } else { -+ Print(L" = ["); -+ for (i = 0; i < len; i++) -+ Print(L"%02x%a", *p++, i < len - 1 ? " " : ""); -+ Print(L"]"); -+ } -+} -+ -+VOID -+DebugDumpFdt ( -+ IN VOID* FdtBlob -+ ) -+{ -+ struct fdt_header *bph; -+ UINT32 off_dt; -+ UINT32 off_str; -+ CONST CHAR8* p_struct; -+ CONST CHAR8* p_strings; -+ CONST CHAR8* p; -+ CONST CHAR8* s; -+ CONST CHAR8* t; -+ UINT32 tag; -+ UINTN sz; -+ UINTN depth; -+ UINTN shift; -+ UINT32 version; -+ -+ depth = 0; -+ shift = 4; -+ -+ bph = FdtBlob; -+ off_dt = fdt32_to_cpu(bph->off_dt_struct); -+ off_str = fdt32_to_cpu(bph->off_dt_strings); -+ p_struct = (CONST CHAR8*)FdtBlob + off_dt; -+ p_strings = (CONST CHAR8*)FdtBlob + off_str; -+ version = fdt32_to_cpu(bph->version); -+ -+ p = p_struct; -+ while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) { -+ -+ //printf("tag: 0x%08x (%d)\n", tag, p - p_struct); -+ -+ if (tag == FDT_BEGIN_NODE) { -+ s = p; -+ p = PALIGN(p + AsciiStrLen (s) + 1, 4); -+ -+ if (*s == '\0') -+ s = "/"; -+ -+ Print(L"%*s%a {\n", depth * shift, L" ", s); -+ -+ depth++; -+ continue; -+ } -+ -+ if (tag == FDT_END_NODE) { -+ depth--; -+ -+ Print(L"%*s};\n", depth * shift, L" "); -+ continue; -+ } -+ -+ if (tag == FDT_NOP) { -+ Print(L"%*s// [NOP]\n", depth * shift, L" "); -+ continue; -+ } -+ -+ if (tag != FDT_PROP) { -+ Print(L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag); -+ break; -+ } -+ sz = fdt32_to_cpu(GET_CELL(p)); -+ s = p_strings + fdt32_to_cpu(GET_CELL(p)); -+ if (version < 16 && sz >= 8) -+ p = PALIGN(p, 8); -+ t = p; -+ -+ p = PALIGN(p + sz, 4); -+ -+ Print(L"%*s%a", depth * shift, L" ", s); -+ PrintData(t, sz); -+ Print(L";\n"); -+ } -+} -+ -+typedef struct { -+ UINTN Base; -+ UINTN Size; -+} FdtRegion; -+ -+EFI_STATUS -+PrepareFdt ( -+ IN CONST CHAR8* CommandLineString, -+ IN EFI_PHYSICAL_ADDRESS InitrdImage, -+ IN UINTN InitrdImageSize, -+ IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase, -+ IN OUT UINT32 *FdtBlobSize -+ ) -+{ -+ EFI_STATUS Status; -+ EFI_PHYSICAL_ADDRESS NewFdtBlobBase; -+ UINTN NewFdtBlobSize; -+ VOID* fdt; -+ INTN err; -+ INTN node; -+ INTN cpu_node; -+ INTN lenp; -+ CONST VOID* BootArg; -+ EFI_PHYSICAL_ADDRESS InitrdImageStart; -+ EFI_PHYSICAL_ADDRESS InitrdImageEnd; -+ FdtRegion Region; -+ UINTN Index; -+ CHAR8 Name[10]; -+ LIST_ENTRY ResourceList; -+ BDS_SYSTEM_MEMORY_RESOURCE *Resource; -+ ARM_PROCESSOR_TABLE *ArmProcessorTable; -+ ARM_CORE_INFO *ArmCoreInfoTable; -+ UINT32 MpId; -+ UINT32 ClusterId; -+ UINT32 CoreId; -+ UINT64 CpuReleaseAddr; -+ -+ 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; -+ } -+ -+ // Allocate memory for the new FDT -+ NewFdtBlobBase = LINUX_FDT_MAX_OFFSET; -+ NewFdtBlobSize = *FdtBlobSize + FDT_ADDITIONAL_ENTRIES_SIZE; -+ Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase); -+ if (EFI_ERROR(Status)) { -+ DEBUG ((EFI_D_WARN, "Warning: Failed to allocate Fdt below 0x%lX (%r). The Fdt will be allocated somewhere else in System Memory.\n",NewFdtBlobBase,Status)); -+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase); -+ ASSERT_EFI_ERROR(Status); -+ goto FAIL_NEW_FDT; -+ } -+ -+ // Load the Original FDT tree into the new region -+ fdt = (VOID*)(UINTN)NewFdtBlobBase; -+ err = fdt_open_into((VOID*)(UINTN)(*FdtBlobBase), fdt, NewFdtBlobSize); -+ if (err) { -+ DEBUG((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror(err))); -+ Status = EFI_INVALID_PARAMETER; -+ goto FAIL_NEW_FDT; -+ } -+ -+ DEBUG_CODE_BEGIN(); -+ DebugDumpFdt (fdt); -+ DEBUG_CODE_END(); -+ -+ 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_NEW_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 ((CommandLineString != NULL) && (AsciiStrLen (CommandLineString) > 0)) { -+ err = fdt_setprop(fdt, node, "bootargs", CommandLineString, AsciiStrSize(CommandLineString)); -+ 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 'chosen' 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 = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink; -+ -+ if (sizeof(UINTN) == sizeof(UINT32)) { -+ Region.Base = cpu_to_fdt32((UINTN)Resource->PhysicalStart); -+ Region.Size = cpu_to_fdt32((UINTN)Resource->ResourceLength); -+ } else { -+ Region.Base = cpu_to_fdt64((UINTN)Resource->PhysicalStart); -+ Region.Size = cpu_to_fdt64((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)); -+ } -+ } -+ } -+ -+ // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms -+ 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", 1); -+ fdt_setprop_cell(fdt, node, "#size-cells", 0); -+ } -+ -+ // Get pointer to ARM processor table -+ ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable; -+ ArmCoreInfoTable = ArmProcessorTable->ArmCpus; -+ -+ for (Index = 0; Index < ArmProcessorTable->NumberOfEntries; Index++) { -+ if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) { -+ AsciiSPrint (Name, 10, "cpu@%d", Index); -+ cpu_node = fdt_subnode_offset(fdt, node, Name); -+ if (cpu_node < 0) { -+ cpu_node = fdt_add_subnode(fdt, node, Name); -+ } -+ fdt_setprop_string(fdt, cpu_node, "device-type", "cpu"); -+ fdt_setprop_string(fdt, cpu_node, "enable-method", "spin-table"); -+ fdt_setprop_string(fdt, cpu_node, "status", "disabled"); -+ CpuReleaseAddr = cpu_to_fdt64(ArmCoreInfoTable[Index].MailboxSetAddress); -+ fdt_setprop(fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof(CpuReleaseAddr)); -+ } -+ } -+ break; -+ } -+ } -+ -+ DEBUG_CODE_BEGIN(); -+ DebugDumpFdt (fdt); -+ DEBUG_CODE_END(); -+ -+ *FdtBlobBase = NewFdtBlobBase; -+ *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase));; -+ return EFI_SUCCESS; -+ -+FAIL_NEW_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/Library/BdsLib/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/BdsLinuxLoader.c -index 12a8862..82fa811 100755 ---- a/ArmPkg/Library/BdsLib/BdsLinuxLoader.c -+++ b/ArmPkg/Library/BdsLib/BdsLinuxLoader.c -@@ -241,6 +241,14 @@ BdsBootLinuxFdt ( - Print (L"ERROR: Did not find Device Tree blob.\n"); - return Status; - } -+ -+ // By setting address=0 we leave the memory allocation to the function -+ Status = PrepareFdt (Arguments, InitrdImage, InitrdImageSize, &KernelParamsAddress, &KernelParamsSize); -+ if (EFI_ERROR(Status)) { -+ Print(L"ERROR: Can not load Linux kernel with Device Tree. Status=0x%X\n", Status); -+ return Status; -+ } -+ - return StartLinux (LinuxImage, LinuxImageSize, KernelParamsAddress, KernelParamsSize, FdtMachineType); - } - -diff --git a/ArmPkg/Library/BdsLib/BdsLinuxLoader.h b/ArmPkg/Library/BdsLib/BdsLinuxLoader.h -index 8d58ce1..9e45e03 100755 ---- a/ArmPkg/Library/BdsLib/BdsLinuxLoader.h -+++ b/ArmPkg/Library/BdsLib/BdsLinuxLoader.h -@@ -15,12 +15,20 @@ - #ifndef __BDSLINUXLOADER_H - #define __BDSLINUXLOADER_H - -+#include <Guid/ArmMpCoreInfo.h> -+ - #define LINUX_UIMAGE_SIGNATURE 0x56190527 - - #define LINUX_ATAG_MAX_OFFSET (PcdGet32(PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxAtagMaxOffset)) - #define LINUX_KERNEL_MAX_OFFSET (PcdGet32(PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxKernelMaxOffset)) - --#define ATAG_MAX_SIZE 0x3000 -+// Size allocated for the Atag list -+#define ATAG_MAX_SIZE 0x3000 -+ -+// 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 - - /* ATAG : list of possible tags */ - #define ATAG_NONE 0x00000000 --- -1.7.0.4 - |