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
gArmTokenSpaceGuid.PcdDebuggerExceptionSupport|FALSE|BOOLEAN|0x00000032
# Define if the Power State Coordination Interface (PSCI) is supported by the Platform Trusted Firmware
gArmTokenSpaceGuid.PcdArmPsciSupport|FALSE|BOOLEAN|0x00000033
# Define if the spin-table mechanism is used by the secondary cores when booting
# Linux (instead of PSCI)
gArmTokenSpaceGuid.PcdArmLinuxSpinTable|FALSE|BOOLEAN|0x00000033
[PcdsFixedAtBuild.common]
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
//
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
PenBase = LinuxImage - 0x80000;
PenSize = (UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart;

View File

@ -73,9 +73,9 @@
gEfiUsbIoProtocolGuid
gEfiLoadedImageProtocolGuid
gEfiSimpleNetworkProtocolGuid
[FeaturePcd]
gArmTokenSpaceGuid.PcdArmPsciSupport
gArmTokenSpaceGuid.PcdArmLinuxSpinTable
[FixedPcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase

View File

@ -1,6 +1,6 @@
/** @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
* are licensed and made available under the terms and conditions of the BSD License
@ -16,8 +16,6 @@
#include <Library/PcdLib.h>
#include <libfdt.h>
#include <IndustryStandard/ArmSmc.h>
#include "BdsInternal.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.
** This function will allocate memory for the relocated FDT blob.
@ -360,11 +326,9 @@ PrepareFdt (
UINTN DescriptorSize;
UINT32 DescriptorVersion;
UINTN Pages;
BOOLEAN PsciSmcSupported;
UINTN OriginalFdtSize;
BOOLEAN CpusNodeExist;
UINTN CoreMpId;
UINTN Smc;
NewFdtBlobAllocation = 0;
@ -395,17 +359,6 @@ PrepareFdt (
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;
node = fdt_subnode_offset (fdt, 0, "chosen");
@ -564,31 +517,29 @@ PrepareFdt (
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);
}
// If Power State Coordination Interface (PSCI) is not supported then it is expected the secondary
// cores are spinning waiting for the Operating System to release them
if ((PsciSmcSupported == FALSE) && (cpu_node >= 0)) {
// We as the bootloader are responsible for either creating or updating
// these entries. Do not trust the entries in the DT. We only know about
// 'spin-table' type. Do not try to update other types if defined.
Method = fdt_getprop(fdt, cpu_node, "enable-method", &lenp);
if ( (Method == NULL) || (!AsciiStrCmp((CHAR8 *)Method, "spin-table")) ) {
fdt_setprop_string(fdt, cpu_node, "enable-method", "spin-table");
CpuReleaseAddr = cpu_to_fdt64(ArmCoreInfoTable[Index].MailboxSetAddress);
fdt_setprop(fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof(CpuReleaseAddr));
if (cpu_node >= 0) {
Method = fdt_getprop (fdt, cpu_node, "enable-method", &lenp);
// We only care when 'enable-method' == 'spin-table'. If the enable-method is not defined
// or defined as 'psci' then we ignore its properties.
if ((Method != NULL) && (AsciiStrCmp ((CHAR8 *)Method, "spin-table") == 0)) {
// There are two cases;
// - UEFI firmware parked the secondary cores and/or UEFI firmware is aware of the CPU
// release addresses (PcdArmLinuxSpinTable == TRUE)
// - the parking of the secondary cores has been managed before starting UEFI and/or UEFI
// does not anything about the CPU release addresses - in this case we do nothing
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 (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) {
fdt_setprop_string(fdt, cpu_node, "status", "disabled");
// If it is not the primary core than the cpu should be disabled
if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) {
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();
//DebugDumpFdt (fdt);
DEBUG_CODE_END();

View File

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

View File

@ -60,16 +60,19 @@
################################################################################
[PcdsFeatureFlag.common]
!ifdef $(EDK2_SKIP_PEICORE)
gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|TRUE
!endif
## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
# It could be set FALSE to save size.
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]
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmVExpress-RTSM"