From e359565ec271d7a3fc863293e9f1f607c938f0ce Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Sun, 12 May 2013 23:56:35 +0000 Subject: [PATCH] ArmPkg/BdsLinuxFdt.c: Fix creation of 'cpu' and 'psci' device tree nodes. * Fix name of 'device_type' and 'migrate' properties. * Fix 'reg' property. It is supposed to contain the CPU MPIDR of the CPU being described. * Fix byte ordering of data in 'psci' node. * Fix some problems regarding the size of data. In a number of places it was assumed data would be 32-bits wide. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14351 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Include/Library/ArmLib.h | 1 + ArmPkg/Library/BdsLib/BdsLinuxFdt.c | 53 ++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h index 75f7755362..5663844b1f 100644 --- a/ArmPkg/Include/Library/ArmLib.h +++ b/ArmPkg/Include/Library/ArmLib.h @@ -116,6 +116,7 @@ typedef enum { #define ARM_CLUSTER_MASK (0xFF << 8) #define GET_CORE_ID(MpId) ((MpId) & ARM_CORE_MASK) #define GET_CLUSTER_ID(MpId) (((MpId) & ARM_CLUSTER_MASK) >> 8) +#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId)) // Get the position of the core for the Stack Offset (4 Core per Cluster) // Position = (ClusterId * 4) + CoreId #define GET_CORE_POS(MpId) ((((MpId) & ARM_CLUSTER_MASK) >> 6) + ((MpId) & ARM_CORE_MASK)) diff --git a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c index b07b3e465d..4ff0afeb7d 100644 --- a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c +++ b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c @@ -361,6 +361,8 @@ PrepareFdt ( BOOLEAN PsciSmcSupported; UINTN OriginalFdtSize; BOOLEAN CpusNodeExist; + UINTN CoreMpId; + UINTN Smc; NewFdtBlobAllocation = 0; @@ -503,7 +505,11 @@ PrepareFdt ( } // - // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms + // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms. + // + // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file + // in the kernel documentation: + // Documentation/devicetree/bindings/arm/cpus.txt // for (Index=0; Index < gST->NumberOfTableEntries; Index++) { // Check for correct GUID type @@ -517,7 +523,7 @@ PrepareFdt ( // 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, "#address-cells", sizeof (UINTN) / 4); fdt_setprop_cell(fdt, node, "#size-cells", 0); CpusNodeExist = FALSE; } else { @@ -531,12 +537,25 @@ PrepareFdt ( for (Index = 0; Index < ArmProcessorTable->NumberOfEntries; Index++) { AsciiSPrint (Name, 10, "cpu@%d", Index); - // If the 'cpus' node did not exist then creates the 'cpu' nodes. In case 'cpus' node - // is provided in the original FDT then we do not add any 'cpu' node. + // If the 'cpus' node did not exist then create all the 'cpu' nodes. + // In case 'cpus' node is provided in the original FDT then we do not add + // any 'cpu' node. if (!CpusNodeExist) { - cpu_node = fdt_add_subnode(fdt, node, Name); - fdt_setprop_string(fdt, cpu_node, "device-type", "cpu"); - fdt_setprop(fdt, cpu_node, "reg", &Index, sizeof(Index)); + cpu_node = fdt_add_subnode (fdt, node, Name); + if (cpu_node < 0) { + DEBUG ((EFI_D_ERROR, "Error on creating '%s' node\n", Name)); + Status = EFI_INVALID_PARAMETER; + goto FAIL_COMPLETE_FDT; + } + + fdt_setprop_string (fdt, cpu_node, "device_type", "cpu"); + CoreMpId = (UINTN) GET_MPID (ArmCoreInfoTable[Index].ClusterId, + ArmCoreInfoTable[Index].CoreId); + CoreMpId = cpu_to_fdtn (CoreMpId); + fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId)); + if (PsciSmcSupported) { + fdt_setprop_string (fdt, cpu_node, "enable-method", "psci"); + } } else { cpu_node = fdt_subnode_offset(fdt, node, Name); } @@ -578,12 +597,20 @@ PrepareFdt ( Status = EFI_INVALID_PARAMETER; goto FAIL_COMPLETE_FDT; } else { - fdt_setprop_string(fdt, node, "compatible", "arm,psci"); - fdt_setprop_string(fdt, node, "method", "smc"); - fdt_setprop_cell(fdt, node, "cpu_suspend", ARM_SMC_ARM_CPU_SUSPEND); - fdt_setprop_cell(fdt, node, "cpu_off", ARM_SMC_ARM_CPU_OFF); - fdt_setprop_cell(fdt, node, "cpu_on", ARM_SMC_ARM_CPU_ON); - fdt_setprop_cell(fdt, node, "cpu_migrate", ARM_SMC_ARM_MIGRATE); + fdt_setprop_string (fdt, node, "compatible", "arm,psci"); + fdt_setprop_string (fdt, node, "method", "smc"); + + Smc = cpu_to_fdtn (ARM_SMC_ARM_CPU_SUSPEND); + fdt_setprop (fdt, node, "cpu_suspend", &Smc, sizeof (Smc)); + + Smc = cpu_to_fdtn (ARM_SMC_ARM_CPU_OFF); + fdt_setprop (fdt, node, "cpu_off", &Smc, sizeof (Smc)); + + Smc = cpu_to_fdtn (ARM_SMC_ARM_CPU_ON); + fdt_setprop (fdt, node, "cpu_on", &Smc, sizeof (Smc)); + + Smc = cpu_to_fdtn (ARM_SMC_ARM_MIGRATE); + fdt_setprop (fdt, node, "migrate", &Smc, sizeof (Smc)); } } } -- 2.39.2