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
diff --git a/bl31/aarch64/context.S b/bl31/aarch64/context.S
index 79b5d19..1117026 100644
--- a/bl31/aarch64/context.S
+++ b/bl31/aarch64/context.S
@@ -35,45 +35,6 @@
/* -----------------------------------------------------
* 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)
* to save EL1 system register context. It assumes that
* 'x0' is pointing to a 'el1_sys_regs' structure where
* the register context will be saved.
diff --git a/bl31/context_mgmt.c b/bl31/context_mgmt.c
index 4502e5d..489d454 100644
--- a/bl31/context_mgmt.c
+++ b/bl31/context_mgmt.c
@@ -259,30 +259,10 @@
}
/*******************************************************************************
- * 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 3bf4980..0dfebe0 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 @@
/*******************************************************************************
* 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 6127b74..6e82fb7 100644
--- a/include/bl31/context_mgmt.h
+++ b/include/bl31/context_mgmt.h
@@ -49,10 +49,8 @@
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 1e60276..70f90a1 100644
--- a/services/std_svc/psci/psci_afflvl_suspend.c
+++ b/services/std_svc/psci/psci_afflvl_suspend.c
@@ -34,6 +34,7 @@
#include <arch_helpers.h>
#include <context.h>
#include <context_mgmt.h>
+#include <platform.h>
#include <runtime_svc.h>
#include <stddef.h>
#include "psci_private.h"
@@ -162,13 +163,6 @@
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 @@
{
unsigned int plat_state, state, rc;
int32_t suspend_level;
+ uint64_t counter_freq;
assert(cpu_node->level == MPIDR_AFFLVL0);
@@ -445,7 +440,10 @@
* 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