mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-26 23:04:50 +00:00
refactor(cm): introduce a real manage_extensions_nonsecure()
manage_extensions_nonsecure() is problematic because it updates both context and in-place registers (unlike its secure/realm counterparts). The in-place register updates make it particularly tricky, as those never change for the lifetime of TF-A. However, they are only set when exiting to NS world. As such, all of TF-A's execution before that operates under a different context. This is inconsistent and could cause problems. This patch Introduce a real manage_extensions_nonsecure() which only operates on the context structure. It also introduces a cm_manage_extensions_el3() which only operates on register in-place that are not context switched. It is called in BL31's entrypoints so that all of TF-A executes with the same environment once all features have been converted. Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com> Change-Id: Ic579f86c41026d2054863ef44893e0ba4c591da9
This commit is contained in:
parent
098312edf7
commit
24a70738b2
4 changed files with 51 additions and 4 deletions
|
@ -112,6 +112,9 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void bl31_main(void)
|
void bl31_main(void)
|
||||||
{
|
{
|
||||||
|
/* Init registers that never change for the lifetime of TF-A */
|
||||||
|
cm_manage_extensions_el3();
|
||||||
|
|
||||||
NOTICE("BL31: %s\n", version_string);
|
NOTICE("BL31: %s\n", version_string);
|
||||||
NOTICE("BL31: %s\n", build_message);
|
NOTICE("BL31: %s\n", build_message);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ void cm_prepare_el3_exit(uint32_t security_state);
|
||||||
void cm_prepare_el3_exit_ns(void);
|
void cm_prepare_el3_exit_ns(void);
|
||||||
|
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
|
#if IMAGE_BL31
|
||||||
|
void cm_manage_extensions_el3(void);
|
||||||
|
#endif
|
||||||
#if CTX_INCLUDE_EL2_REGS
|
#if CTX_INCLUDE_EL2_REGS
|
||||||
void cm_el2_sysregs_context_save(uint32_t security_state);
|
void cm_el2_sysregs_context_save(uint32_t security_state);
|
||||||
void cm_el2_sysregs_context_restore(uint32_t security_state);
|
void cm_el2_sysregs_context_restore(uint32_t security_state);
|
||||||
|
@ -84,6 +87,7 @@ static inline void cm_set_next_context(void *context)
|
||||||
#else
|
#else
|
||||||
void *cm_get_next_context(void);
|
void *cm_get_next_context(void);
|
||||||
void cm_set_next_context(void *context);
|
void cm_set_next_context(void *context);
|
||||||
|
static inline void cm_manage_extensions_el3(void) {}
|
||||||
#endif /* __aarch64__ */
|
#endif /* __aarch64__ */
|
||||||
|
|
||||||
#endif /* CONTEXT_MGMT_H */
|
#endif /* CONTEXT_MGMT_H */
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
CASSERT(((TWED_DELAY & ~SCR_TWEDEL_MASK) == 0U), assert_twed_delay_value_check);
|
CASSERT(((TWED_DELAY & ~SCR_TWEDEL_MASK) == 0U), assert_twed_delay_value_check);
|
||||||
#endif /* ENABLE_FEAT_TWED */
|
#endif /* ENABLE_FEAT_TWED */
|
||||||
|
|
||||||
|
static void manage_extensions_nonsecure(cpu_context_t *ctx);
|
||||||
static void manage_extensions_secure(cpu_context_t *ctx);
|
static void manage_extensions_secure(cpu_context_t *ctx);
|
||||||
|
|
||||||
static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info *ep)
|
static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info *ep)
|
||||||
|
@ -288,6 +289,8 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
|
||||||
HCRX_EL2_INIT_VAL);
|
HCRX_EL2_INIT_VAL);
|
||||||
}
|
}
|
||||||
#endif /* CTX_INCLUDE_EL2_REGS */
|
#endif /* CTX_INCLUDE_EL2_REGS */
|
||||||
|
|
||||||
|
manage_extensions_nonsecure(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -504,9 +507,11 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Enable architecture extensions on first entry to Non-secure world.
|
* Enable architecture extensions on first entry to Non-secure world.
|
||||||
* When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
|
* When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
|
||||||
* it is zero.
|
* it is zero. This function updates some registers in-place and its contents
|
||||||
|
* are being prepared to be moved to cm_manage_extensions_el3 and
|
||||||
|
* cm_manage_extensions_nonsecure.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
|
static void manage_extensions_nonsecure_mixed(bool el2_unused, cpu_context_t *ctx)
|
||||||
{
|
{
|
||||||
#if IMAGE_BL31
|
#if IMAGE_BL31
|
||||||
if (is_feat_spe_supported()) {
|
if (is_feat_spe_supported()) {
|
||||||
|
@ -548,6 +553,36 @@ static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Enable architecture extensions for EL3 execution. This function only updates
|
||||||
|
* registers in-place which are expected to either never change or be
|
||||||
|
* overwritten by el3_exit.
|
||||||
|
******************************************************************************/
|
||||||
|
#if IMAGE_BL31
|
||||||
|
void cm_manage_extensions_el3(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* IMAGE_BL31 */
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Enable architecture extensions on first entry to Non-secure world.
|
||||||
|
******************************************************************************/
|
||||||
|
static void manage_extensions_nonsecure(cpu_context_t *ctx)
|
||||||
|
{
|
||||||
|
#if IMAGE_BL31
|
||||||
|
#endif /* IMAGE_BL31 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Enable architecture extensions in-place at EL2 on first entry to Non-secure
|
||||||
|
* world when EL2 is empty and unused.
|
||||||
|
******************************************************************************/
|
||||||
|
static void manage_extensions_nonsecure_el2_unused(void)
|
||||||
|
{
|
||||||
|
#if IMAGE_BL31
|
||||||
|
#endif /* IMAGE_BL31 */
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Enable architecture extensions on first entry to Secure world.
|
* Enable architecture extensions on first entry to Secure world.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -845,8 +880,10 @@ void cm_prepare_el3_exit(uint32_t security_state)
|
||||||
*/
|
*/
|
||||||
write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
|
write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
|
||||||
~(CNTHP_CTL_ENABLE_BIT));
|
~(CNTHP_CTL_ENABLE_BIT));
|
||||||
|
|
||||||
|
manage_extensions_nonsecure_el2_unused();
|
||||||
}
|
}
|
||||||
manage_extensions_nonsecure(el2_unused, ctx);
|
manage_extensions_nonsecure_mixed(el2_unused, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
cm_el1_sysregs_context_restore(security_state);
|
cm_el1_sysregs_context_restore(security_state);
|
||||||
|
@ -1167,7 +1204,7 @@ void cm_prepare_el3_exit_ns(void)
|
||||||
* direct register updates. Therefore, do this here
|
* direct register updates. Therefore, do this here
|
||||||
* instead of when setting up context.
|
* instead of when setting up context.
|
||||||
*/
|
*/
|
||||||
manage_extensions_nonsecure(0, ctx);
|
manage_extensions_nonsecure_mixed(0, ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the NS bit to be able to access the ICC_SRE_EL2
|
* Set the NS bit to be able to access the ICC_SRE_EL2
|
||||||
|
|
|
@ -985,6 +985,9 @@ void psci_warmboot_entrypoint(void)
|
||||||
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
|
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
|
||||||
psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
|
psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
|
||||||
|
|
||||||
|
/* Init registers that never change for the lifetime of TF-A */
|
||||||
|
cm_manage_extensions_el3();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify that we have been explicitly turned ON or resumed from
|
* Verify that we have been explicitly turned ON or resumed from
|
||||||
* suspend.
|
* suspend.
|
||||||
|
|
Loading…
Add table
Reference in a new issue