From fdfabec10ce9d6d56691007dce3bc2599baeb0f0 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Fri, 4 Jul 2014 16:02:26 +0100 Subject: [PATCH] Optimize EL3 register state stored in cpu_context structure This patch further optimizes the EL3 register state stored in cpu_context. The 2 registers which are removed from cpu_context are: * cntfrq_el0 is the system timer register which is writable only in EL3 and it can be programmed during cold/warm boot. Hence it need not be saved to cpu_context. * cptr_el3 controls access to Trace, Floating-point, and Advanced SIMD functionality and it is programmed every time during cold and warm boot. The current BL3-1 implementation does not need to modify the access controls during normal execution and hence they are expected to remain static. Fixes ARM-software/tf-issues#197 Change-Id: I599ceee3b73a7dcfd37069fd41b60e3d397a7b18 --- bl31/aarch64/context.S | 39 --------------------- bl31/context_mgmt.c | 24 ++----------- include/bl31/context.h | 6 +--- include/bl31/context_mgmt.h | 2 -- services/std_svc/psci/psci_afflvl_suspend.c | 14 ++++---- 5 files changed, 9 insertions(+), 76 deletions(-) diff --git a/bl31/aarch64/context.S b/bl31/aarch64/context.S index 79b5d19c..1117026d 100644 --- a/bl31/aarch64/context.S +++ b/bl31/aarch64/context.S @@ -32,45 +32,6 @@ #include #include -/* ----------------------------------------------------- - * The following function strictly follows the AArch64 - * PCS to use x9-x17 (temporary caller-saved registers) - * to save essential EL3 system register context. It - * assumes that 'x0' is pointing to a 'el1_sys_regs' - * structure where the register context will be saved. - * ----------------------------------------------------- - */ - .global el3_sysregs_context_save -func el3_sysregs_context_save - - mrs x10, cptr_el3 - mrs x11, cntfrq_el0 - stp x10, x11, [x0, #CTX_CPTR_EL3] - - ret - -/* ----------------------------------------------------- - * The following function strictly follows the AArch64 - * PCS to use x9-x17 (temporary caller-saved registers) - * to restore essential EL3 system register context. It - * assumes that 'x0' is pointing to a 'el1_sys_regs' - * structure from where the register context will be - * restored. - * - * Note that the sequence differs from that of the save - * function as we want the MMU to be enabled last - * ----------------------------------------------------- - */ - .global el3_sysregs_context_restore -func el3_sysregs_context_restore - - ldp x13, x14, [x0, #CTX_CPTR_EL3] - msr cptr_el3, x13 - msr cntfrq_el0, x14 - isb - - ret - /* ----------------------------------------------------- * The following function strictly follows the AArch64 * PCS to use x9-x17 (temporary caller-saved registers) diff --git a/bl31/context_mgmt.c b/bl31/context_mgmt.c index 4502e5dc..489d4544 100644 --- a/bl31/context_mgmt.c +++ b/bl31/context_mgmt.c @@ -259,30 +259,10 @@ void cm_prepare_el3_exit(uint32_t security_state) } /******************************************************************************* - * The next four functions are used by runtime services to save and restore EL3 - * and EL1 contexts on the 'cpu_context' structure for the specified security + * The next four functions are used by runtime services to save and restore + * EL1 context on the 'cpu_context' structure for the specified security * state. ******************************************************************************/ -void cm_el3_sysregs_context_save(uint32_t security_state) -{ - cpu_context_t *ctx; - - ctx = cm_get_context(security_state); - assert(ctx); - - el3_sysregs_context_save(get_el3state_ctx(ctx)); -} - -void cm_el3_sysregs_context_restore(uint32_t security_state) -{ - cpu_context_t *ctx; - - ctx = cm_get_context(security_state); - assert(ctx); - - el3_sysregs_context_restore(get_el3state_ctx(ctx)); -} - void cm_el1_sysregs_context_save(uint32_t security_state) { cpu_context_t *ctx; diff --git a/include/bl31/context.h b/include/bl31/context.h index 3bf49806..0dfebe0b 100644 --- a/include/bl31/context.h +++ b/include/bl31/context.h @@ -80,9 +80,7 @@ #define CTX_RUNTIME_SP 0x8 #define CTX_SPSR_EL3 0x10 #define CTX_ELR_EL3 0x18 -#define CTX_CPTR_EL3 0x20 -#define CTX_CNTFRQ_EL0 0x28 -#define CTX_EL3STATE_END 0x30 +#define CTX_EL3STATE_END 0x20 /******************************************************************************* * Constants that allow assembler code to access members of and the @@ -323,8 +321,6 @@ CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx), /******************************************************************************* * Function prototypes ******************************************************************************/ -void el3_sysregs_context_save(el3_state_t *regs); -void el3_sysregs_context_restore(el3_state_t *regs); void el1_sysregs_context_save(el1_sys_regs_t *regs); void el1_sysregs_context_restore(el1_sys_regs_t *regs); #if CTX_INCLUDE_FPREGS diff --git a/include/bl31/context_mgmt.h b/include/bl31/context_mgmt.h index 6127b74b..6e82fb70 100644 --- a/include/bl31/context_mgmt.h +++ b/include/bl31/context_mgmt.h @@ -49,10 +49,8 @@ void cm_set_context_by_mpidr(uint64_t mpidr, void *context, uint32_t security_state); static inline void cm_set_context(void *context, uint32_t security_state); -void cm_el3_sysregs_context_save(uint32_t security_state); void cm_init_context(uint64_t mpidr, const struct entry_point_info *ep); void cm_prepare_el3_exit(uint32_t security_state); -void cm_el3_sysregs_context_restore(uint32_t security_state); void cm_el1_sysregs_context_save(uint32_t security_state); void cm_el1_sysregs_context_restore(uint32_t security_state); void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint); diff --git a/services/std_svc/psci/psci_afflvl_suspend.c b/services/std_svc/psci/psci_afflvl_suspend.c index 1e60276c..70f90a15 100644 --- a/services/std_svc/psci/psci_afflvl_suspend.c +++ b/services/std_svc/psci/psci_afflvl_suspend.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include "psci_private.h" @@ -162,13 +163,6 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node, if (rc != PSCI_E_SUCCESS) return rc; - /* - * Arch. management: Save the EL3 state in the 'cpu_context' - * structure that has been allocated for this cpu, flush the - * L1 caches and exit intra-cluster coherency et al - */ - cm_el3_sysregs_context_save(NON_SECURE); - /* Set the secure world (EL3) re-entry point after BL1 */ psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; @@ -414,6 +408,7 @@ static unsigned int psci_afflvl0_suspend_finish(aff_map_node_t *cpu_node) { unsigned int plat_state, state, rc; int32_t suspend_level; + uint64_t counter_freq; assert(cpu_node->level == MPIDR_AFFLVL0); @@ -445,7 +440,10 @@ static unsigned int psci_afflvl0_suspend_finish(aff_map_node_t *cpu_node) * structure for this cpu. */ psci_do_pwrup_cache_maintenance(); - cm_el3_sysregs_context_restore(NON_SECURE); + + /* Re-init the cntfrq_el0 register */ + counter_freq = plat_get_syscnt_freq(); + write_cntfrq_el0(counter_freq); /* * Call the cpu suspend finish handler registered by the Secure Payload -- 2.30.2