ArmPkg/BdsLib: Removed PSCI discoverability from the Linux loader

Some platforms might decide to not support PSCI in their FDT-aware Linux
system even if their firmware supports it.
It is the responsibility of the platform engineer to provide the appropriate FDT.

The PCD gArmTokenSpaceGuid.PcdArmPsciSupport is not required anymore.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15658 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Olivier Martin 2014-07-15 09:21:41 +00:00 committed by oliviermartin
parent 6913a68302
commit 9232ee5338
6 changed files with 30 additions and 109 deletions

View File

@ -65,8 +65,9 @@
# it has been configured by the CPU DXE # it has been configured by the CPU DXE
gArmTokenSpaceGuid.PcdDebuggerExceptionSupport|FALSE|BOOLEAN|0x00000032 gArmTokenSpaceGuid.PcdDebuggerExceptionSupport|FALSE|BOOLEAN|0x00000032
# Define if the Power State Coordination Interface (PSCI) is supported by the Platform Trusted Firmware # Define if the spin-table mechanism is used by the secondary cores when booting
gArmTokenSpaceGuid.PcdArmPsciSupport|FALSE|BOOLEAN|0x00000033 # Linux (instead of PSCI)
gArmTokenSpaceGuid.PcdArmLinuxSpinTable|FALSE|BOOLEAN|0x00000033
[PcdsFixedAtBuild.common] [PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006 gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006

View File

@ -271,7 +271,7 @@ BdsBootLinuxFdt (
// //
// Install secondary core pens if the Power State Coordination Interface is not supported // Install secondary core pens if the Power State Coordination Interface is not supported
// //
if (FeaturePcdGet (PcdArmPsciSupport) == FALSE) { if (FeaturePcdGet (PcdArmLinuxSpinTable)) {
// Place Pen at the start of Linux memory. We can then tell Linux to not use this bit of memory // Place Pen at the start of Linux memory. We can then tell Linux to not use this bit of memory
PenBase = LinuxImage - 0x80000; PenBase = LinuxImage - 0x80000;
PenSize = (UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart; PenSize = (UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart;

View File

@ -75,7 +75,7 @@
gEfiSimpleNetworkProtocolGuid gEfiSimpleNetworkProtocolGuid
[FeaturePcd] [FeaturePcd]
gArmTokenSpaceGuid.PcdArmPsciSupport gArmTokenSpaceGuid.PcdArmLinuxSpinTable
[FixedPcd] [FixedPcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase gArmTokenSpaceGuid.PcdSystemMemoryBase

View File

@ -1,6 +1,6 @@
/** @file /** @file
* *
* Copyright (c) 2011-2013, ARM Limited. All rights reserved. * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
* *
* This program and the accompanying materials * This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License * are licensed and made available under the terms and conditions of the BSD License
@ -16,8 +16,6 @@
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <libfdt.h> #include <libfdt.h>
#include <IndustryStandard/ArmSmc.h>
#include "BdsInternal.h" #include "BdsInternal.h"
#include "BdsLinuxLoader.h" #include "BdsLinuxLoader.h"
@ -214,38 +212,6 @@ IsLinuxReservedRegion (
} }
} }
STATIC
BOOLEAN
IsPsciSmcSupported (
VOID
)
{
BOOLEAN PsciSmcSupported;
UINTN Rx;
PsciSmcSupported = FALSE;
// Check the SMC response to the Presence SMC
Rx = ARM_SMC_ID_PRESENCE;
ArmCallSmc (&Rx);
if (Rx == 1) {
// Check the SMC UID
Rx = ARM_SMC_ID_UID;
ArmCallSmc (&Rx);
if (Rx == ARM_TRUSTZONE_UID_4LETTERID) {
Rx = ARM_SMC_ID_UID + 1;
ArmCallSmc (&Rx);
if (Rx == ARM_TRUSTZONE_ARM_UID) {
PsciSmcSupported = TRUE;
}
}
}
return PsciSmcSupported;
}
/** /**
** Relocate the FDT blob to a more appropriate location for the Linux kernel. ** Relocate the FDT blob to a more appropriate location for the Linux kernel.
** This function will allocate memory for the relocated FDT blob. ** This function will allocate memory for the relocated FDT blob.
@ -360,11 +326,9 @@ PrepareFdt (
UINTN DescriptorSize; UINTN DescriptorSize;
UINT32 DescriptorVersion; UINT32 DescriptorVersion;
UINTN Pages; UINTN Pages;
BOOLEAN PsciSmcSupported;
UINTN OriginalFdtSize; UINTN OriginalFdtSize;
BOOLEAN CpusNodeExist; BOOLEAN CpusNodeExist;
UINTN CoreMpId; UINTN CoreMpId;
UINTN Smc;
NewFdtBlobAllocation = 0; NewFdtBlobAllocation = 0;
@ -395,17 +359,6 @@ PrepareFdt (
goto FAIL_RELOCATE_FDT; goto FAIL_RELOCATE_FDT;
} }
//
// Ensure the Power State Coordination Interface (PSCI) SMCs are there if supported
//
PsciSmcSupported = FALSE;
if (FeaturePcdGet (PcdArmPsciSupport) == TRUE) {
PsciSmcSupported = IsPsciSmcSupported();
if (PsciSmcSupported == FALSE) {
DEBUG ((EFI_D_ERROR, "Warning: The Power State Coordination Interface (PSCI) is not supported by your platform Trusted Firmware.\n"));
}
}
fdt = (VOID*)(UINTN)NewFdtBlobBase; fdt = (VOID*)(UINTN)NewFdtBlobBase;
node = fdt_subnode_offset (fdt, 0, "chosen"); node = fdt_subnode_offset (fdt, 0, "chosen");
@ -564,31 +517,29 @@ PrepareFdt (
CoreMpId = cpu_to_fdtn (CoreMpId); CoreMpId = cpu_to_fdtn (CoreMpId);
fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId)); fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId));
if (PsciSmcSupported) {
fdt_setprop_string (fdt, cpu_node, "enable-method", "psci");
}
} else { } else {
cpu_node = fdt_subnode_offset(fdt, node, Name); cpu_node = fdt_subnode_offset(fdt, node, Name);
} }
// If Power State Coordination Interface (PSCI) is not supported then it is expected the secondary if (cpu_node >= 0) {
// cores are spinning waiting for the Operating System to release them Method = fdt_getprop (fdt, cpu_node, "enable-method", &lenp);
if ((PsciSmcSupported == FALSE) && (cpu_node >= 0)) { // We only care when 'enable-method' == 'spin-table'. If the enable-method is not defined
// We as the bootloader are responsible for either creating or updating // or defined as 'psci' then we ignore its properties.
// these entries. Do not trust the entries in the DT. We only know about if ((Method != NULL) && (AsciiStrCmp ((CHAR8 *)Method, "spin-table") == 0)) {
// 'spin-table' type. Do not try to update other types if defined. // There are two cases;
Method = fdt_getprop(fdt, cpu_node, "enable-method", &lenp); // - UEFI firmware parked the secondary cores and/or UEFI firmware is aware of the CPU
if ( (Method == NULL) || (!AsciiStrCmp((CHAR8 *)Method, "spin-table")) ) { // release addresses (PcdArmLinuxSpinTable == TRUE)
fdt_setprop_string(fdt, cpu_node, "enable-method", "spin-table"); // - the parking of the secondary cores has been managed before starting UEFI and/or UEFI
CpuReleaseAddr = cpu_to_fdt64(ArmCoreInfoTable[Index].MailboxSetAddress); // does not anything about the CPU release addresses - in this case we do nothing
fdt_setprop(fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof(CpuReleaseAddr)); if (FeaturePcdGet (PcdArmLinuxSpinTable)) {
CpuReleaseAddr = cpu_to_fdt64 (ArmCoreInfoTable[Index].MailboxSetAddress);
fdt_setprop (fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof(CpuReleaseAddr));
// If it is not the primary core than the cpu should be disabled // If it is not the primary core than the cpu should be disabled
if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) { if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) {
fdt_setprop_string(fdt, cpu_node, "status", "disabled"); fdt_setprop_string(fdt, cpu_node, "status", "disabled");
} }
} else { }
Print(L"Warning: Unsupported enable-method type for CPU[%d] : %a\n", Index, (CHAR8 *)Method);
} }
} }
} }
@ -596,36 +547,6 @@ PrepareFdt (
} }
} }
// If the Power State Coordination Interface is supported then we signal it in the Device Tree
if (PsciSmcSupported == TRUE) {
// Before to create it we check if the node is not already defined in the Device Tree
node = fdt_subnode_offset(fdt, 0, "psci");
if (node < 0) {
// The 'psci' node does not exist, create it
node = fdt_add_subnode(fdt, 0, "psci");
if (node < 0) {
DEBUG((EFI_D_ERROR,"Error on creating 'psci' node\n"));
Status = EFI_INVALID_PARAMETER;
goto FAIL_COMPLETE_FDT;
} else {
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));
}
}
}
DEBUG_CODE_BEGIN(); DEBUG_CODE_BEGIN();
//DebugDumpFdt (fdt); //DebugDumpFdt (fdt);
DEBUG_CODE_END(); DEBUG_CODE_END();

View File

@ -72,10 +72,6 @@
# It could be set FALSE to save size. # It could be set FALSE to save size.
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
## FVP platforms support hardware power control
# Disabled for now as we have a version mismatch.
gArmTokenSpaceGuid.PcdArmPsciSupport|FALSE
[PcdsFixedAtBuild.common] [PcdsFixedAtBuild.common]
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Fixed Virtual Platform" gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Fixed Virtual Platform"
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ARM-FVP" gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ARM-FVP"

View File

@ -60,7 +60,6 @@
################################################################################ ################################################################################
[PcdsFeatureFlag.common] [PcdsFeatureFlag.common]
!ifdef $(EDK2_SKIP_PEICORE) !ifdef $(EDK2_SKIP_PEICORE)
gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|TRUE gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|TRUE
@ -70,6 +69,10 @@
# It could be set FALSE to save size. # It could be set FALSE to save size.
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
# UEFI firmware is responsible to park the secondary cores on this platform.
# This PCD ensures the secondary cores are parked into the AArch64 Linux parking protocol.
gArmTokenSpaceGuid.PcdArmLinuxSpinTable|TRUE
[PcdsFixedAtBuild.common] [PcdsFixedAtBuild.common]
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express" gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmVExpress-RTSM" gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmVExpress-RTSM"