fix(spe): invoke spe_disable during power domain off/suspend

spe_disable function, disables profiling and flushes all the buffers and
hence needs to be called on power-off/suspend path.
It needs to be invoked as SPE feature writes to memory as part of
regular operation and not disabling before exiting coherency
could potentially cause issues.

Currently, this is handled only for the FVP. Other platforms need
to replicate this behaviour and is covered as part of this patch.

Calling it from generic psci library code, before the platform specific
actions to turn off the CPUs, will make it applicable for all the
platforms which have ported the PSCI library.

Change-Id: I90b24c59480357e2ebfa3dfc356c719ca935c13d
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
This commit is contained in:
Jayanth Dodderi Chidanand 2023-07-18 14:48:09 +01:00
parent 160e8434ba
commit 777f1f6897
3 changed files with 51 additions and 13 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -12,6 +12,14 @@
#include <lib/el3_runtime/pubsub.h>
#include <lib/extensions/spe.h>
#include <plat/common/platform.h>
typedef struct spe_ctx {
u_register_t pmblimitr_el1;
} spe_ctx_t;
static struct spe_ctx spe_ctxs[PLATFORM_CORE_COUNT];
static inline void psb_csync(void)
{
/*
@ -89,4 +97,35 @@ static void *spe_drain_buffers_hook(const void *arg)
return (void *)0;
}
static void *spe_context_save(const void *arg)
{
unsigned int core_pos;
struct spe_ctx *ctx;
if (is_feat_spe_supported()) {
core_pos = plat_my_core_pos();
ctx = &spe_ctxs[core_pos];
ctx->pmblimitr_el1 = read_pmblimitr_el1();
}
return NULL;
}
static void *spe_context_restore(const void *arg)
{
unsigned int core_pos;
struct spe_ctx *ctx;
if (is_feat_spe_supported()) {
core_pos = plat_my_core_pos();
ctx = &spe_ctxs[core_pos];
write_pmblimitr_el1(ctx->pmblimitr_el1);
}
return NULL;
}
SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);
SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, spe_context_save);
SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, spe_context_restore);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -8,12 +8,14 @@
#include <string.h>
#include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <context.h>
#include <drivers/delay_timer.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/extensions/spe.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
@ -1293,5 +1295,12 @@ bool psci_are_all_cpus_on_safe(void)
******************************************************************************/
void psci_do_manage_extensions(void)
{
/*
* On power down we need to disable statistical profiling extensions
* before exiting coherency.
*/
if (is_feat_spe_supported()) {
spe_disable();
}
}

View File

@ -1,17 +1,15 @@
/*
* Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <arch_features.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/gicv3.h>
#include <drivers/arm/fvp/fvp_pwrc.h>
#include <lib/extensions/spe.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <plat/arm/common/arm_config.h>
@ -54,14 +52,6 @@ static void fvp_cluster_pwrdwn_common(void)
{
uint64_t mpidr = read_mpidr_el1();
/*
* On power down we need to disable statistical profiling extensions
* before exiting coherency.
*/
if (is_feat_spe_supported()) {
spe_disable();
}
/* Disable coherency if this cluster is to be turned off */
fvp_interconnect_disable();