Merge pull request #178 from soby-mathew/sm/optmize_el3_context
Optimize EL3 register state stored in cpu_context structure
This commit is contained in:
commit
319609ae7a
|
@ -32,45 +32,6 @@
|
||||||
#include <asm_macros.S>
|
#include <asm_macros.S>
|
||||||
#include <context.h>
|
#include <context.h>
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
|
||||||
* 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
|
* The following function strictly follows the AArch64
|
||||||
* PCS to use x9-x17 (temporary caller-saved registers)
|
* PCS to use x9-x17 (temporary caller-saved registers)
|
||||||
|
|
|
@ -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
|
* The next four functions are used by runtime services to save and restore
|
||||||
* and EL1 contexts on the 'cpu_context' structure for the specified security
|
* EL1 context on the 'cpu_context' structure for the specified security
|
||||||
* state.
|
* 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)
|
void cm_el1_sysregs_context_save(uint32_t security_state)
|
||||||
{
|
{
|
||||||
cpu_context_t *ctx;
|
cpu_context_t *ctx;
|
||||||
|
|
|
@ -80,9 +80,7 @@
|
||||||
#define CTX_RUNTIME_SP 0x8
|
#define CTX_RUNTIME_SP 0x8
|
||||||
#define CTX_SPSR_EL3 0x10
|
#define CTX_SPSR_EL3 0x10
|
||||||
#define CTX_ELR_EL3 0x18
|
#define CTX_ELR_EL3 0x18
|
||||||
#define CTX_CPTR_EL3 0x20
|
#define CTX_EL3STATE_END 0x20
|
||||||
#define CTX_CNTFRQ_EL0 0x28
|
|
||||||
#define CTX_EL3STATE_END 0x30
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Constants that allow assembler code to access members of and the
|
* 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
|
* 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_save(el1_sys_regs_t *regs);
|
||||||
void el1_sysregs_context_restore(el1_sys_regs_t *regs);
|
void el1_sysregs_context_restore(el1_sys_regs_t *regs);
|
||||||
#if CTX_INCLUDE_FPREGS
|
#if CTX_INCLUDE_FPREGS
|
||||||
|
|
|
@ -49,10 +49,8 @@ void cm_set_context_by_mpidr(uint64_t mpidr,
|
||||||
void *context,
|
void *context,
|
||||||
uint32_t security_state);
|
uint32_t security_state);
|
||||||
static inline void cm_set_context(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_init_context(uint64_t mpidr, const struct entry_point_info *ep);
|
||||||
void cm_prepare_el3_exit(uint32_t security_state);
|
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_save(uint32_t security_state);
|
||||||
void cm_el1_sysregs_context_restore(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);
|
void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint);
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <arch_helpers.h>
|
#include <arch_helpers.h>
|
||||||
#include <context.h>
|
#include <context.h>
|
||||||
#include <context_mgmt.h>
|
#include <context_mgmt.h>
|
||||||
|
#include <platform.h>
|
||||||
#include <runtime_svc.h>
|
#include <runtime_svc.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "psci_private.h"
|
#include "psci_private.h"
|
||||||
|
@ -162,13 +163,6 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
|
||||||
if (rc != PSCI_E_SUCCESS)
|
if (rc != PSCI_E_SUCCESS)
|
||||||
return rc;
|
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 */
|
/* Set the secure world (EL3) re-entry point after BL1 */
|
||||||
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
|
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;
|
unsigned int plat_state, state, rc;
|
||||||
int32_t suspend_level;
|
int32_t suspend_level;
|
||||||
|
uint64_t counter_freq;
|
||||||
|
|
||||||
assert(cpu_node->level == MPIDR_AFFLVL0);
|
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.
|
* structure for this cpu.
|
||||||
*/
|
*/
|
||||||
psci_do_pwrup_cache_maintenance();
|
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
|
* Call the cpu suspend finish handler registered by the Secure Payload
|
||||||
|
|
Loading…
Reference in New Issue