mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-24 13:55:56 +00:00

* Currently, EL1 context is included in cpu_context_t by default for all the build configurations. As part of the cpu context structure, we hold a copy of EL1, EL2 system registers, per world per PE. This context structure is enormous and will continue to grow bigger with the addition of new features incorporating new registers. * Ideally, EL3 should save and restore the system registers at its next lower exception level, which is EL2 in majority of the configurations. * This patch aims at optimising the memory allocation in cases, when the members from the context structure are unused. So el1 system register context must be omitted when lower EL is always x-EL2. * "CTX_INCLUDE_EL2_REGS" is the internal build flag which gets set, when SPD=spmd and SPMD_SPM_AT_SEL2=1 or ENABLE_RME=1. It indicates, the system registers at EL2 are context switched for the respective build configuration. Here, there is no need to save and restore EL1 system registers, while x-EL2 is enabled. Henceforth, this patch addresses this issue, by taking out the EL1 context at all possible places, while EL2 (CTX_INCLUDE_EL2_REGS) is enabled, there by saving memory. Change-Id: Ifddc497d3c810e22a15b1c227a731bcc133c2f4a Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
103 lines
3.3 KiB
C
103 lines
3.3 KiB
C
/*
|
|
* Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#ifndef CONTEXT_MGMT_H
|
|
#define CONTEXT_MGMT_H
|
|
|
|
#include <assert.h>
|
|
#include <context.h>
|
|
#include <stdint.h>
|
|
|
|
#include <arch.h>
|
|
|
|
/*******************************************************************************
|
|
* Forward declarations
|
|
******************************************************************************/
|
|
struct entry_point_info;
|
|
|
|
/*******************************************************************************
|
|
* Function & variable prototypes
|
|
******************************************************************************/
|
|
void cm_init(void);
|
|
void *cm_get_context_by_index(unsigned int cpu_idx,
|
|
unsigned int security_state);
|
|
void cm_set_context_by_index(unsigned int cpu_idx,
|
|
void *context,
|
|
unsigned int security_state);
|
|
void *cm_get_context(uint32_t security_state);
|
|
void cm_set_context(void *context, uint32_t security_state);
|
|
void cm_init_my_context(const struct entry_point_info *ep);
|
|
void cm_setup_context(cpu_context_t *ctx, const struct entry_point_info *ep);
|
|
void cm_prepare_el3_exit(uint32_t security_state);
|
|
void cm_prepare_el3_exit_ns(void);
|
|
|
|
#if !IMAGE_BL1
|
|
void cm_init_context_by_index(unsigned int cpu_idx,
|
|
const struct entry_point_info *ep);
|
|
#endif /* !IMAGE_BL1 */
|
|
|
|
#ifdef __aarch64__
|
|
#if IMAGE_BL31
|
|
void cm_manage_extensions_el3(void);
|
|
void manage_extensions_nonsecure_per_world(void);
|
|
void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx);
|
|
void cm_handle_asymmetric_features(void);
|
|
#endif
|
|
|
|
#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
|
|
void cm_el2_sysregs_context_save(uint32_t security_state);
|
|
void cm_el2_sysregs_context_restore(uint32_t security_state);
|
|
#else
|
|
void cm_el1_sysregs_context_save(uint32_t security_state);
|
|
void cm_el1_sysregs_context_restore(uint32_t security_state);
|
|
#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
|
|
|
|
void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint);
|
|
void cm_set_elr_spsr_el3(uint32_t security_state,
|
|
uintptr_t entrypoint, uint32_t spsr);
|
|
void cm_write_scr_el3_bit(uint32_t security_state,
|
|
uint32_t bit_pos,
|
|
uint32_t value);
|
|
void cm_set_next_eret_context(uint32_t security_state);
|
|
u_register_t cm_get_scr_el3(uint32_t security_state);
|
|
|
|
/* Inline definitions */
|
|
|
|
/*******************************************************************************
|
|
* This function is used to program the context that's used for exception
|
|
* return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for
|
|
* the required security state
|
|
******************************************************************************/
|
|
static inline void cm_set_next_context(void *context)
|
|
{
|
|
#if ENABLE_ASSERTIONS
|
|
uint64_t sp_mode;
|
|
|
|
/*
|
|
* Check that this function is called with SP_EL0 as the stack
|
|
* pointer
|
|
*/
|
|
__asm__ volatile("mrs %0, SPSel\n"
|
|
: "=r" (sp_mode));
|
|
|
|
assert(sp_mode == MODE_SP_EL0);
|
|
#endif /* ENABLE_ASSERTIONS */
|
|
|
|
__asm__ volatile("msr spsel, #1\n"
|
|
"mov sp, %0\n"
|
|
"msr spsel, #0\n"
|
|
: : "r" (context));
|
|
}
|
|
|
|
#else
|
|
void *cm_get_next_context(void);
|
|
void cm_set_next_context(void *context);
|
|
static inline void cm_manage_extensions_el3(void) {}
|
|
static inline void manage_extensions_nonsecure_per_world(void) {}
|
|
static inline void cm_handle_asymmetric_features(void) {}
|
|
#endif /* __aarch64__ */
|
|
|
|
#endif /* CONTEXT_MGMT_H */
|