arm-trusted-firmware/include/lib/el3_runtime/context_el2.h
Jayanth Dodderi Chidanand a0674ab081 refactor(cm): remove el1 context when SPMD_SPM_AT_SEL2=1
* 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>
2024-08-21 16:35:27 +01:00

365 lines
8.8 KiB
C

/*
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef CONTEXT_EL2_H
#define CONTEXT_EL2_H
#ifndef __ASSEMBLER__
/*******************************************************************************
* EL2 Registers:
* AArch64 EL2 system register context structure for preserving the
* architectural state during world switches.
******************************************************************************/
typedef struct el2_common_regs {
uint64_t actlr_el2;
uint64_t afsr0_el2;
uint64_t afsr1_el2;
uint64_t amair_el2;
uint64_t cnthctl_el2;
uint64_t cntvoff_el2;
uint64_t cptr_el2;
uint64_t dbgvcr32_el2;
uint64_t elr_el2;
uint64_t esr_el2;
uint64_t far_el2;
uint64_t hacr_el2;
uint64_t hcr_el2;
uint64_t hpfar_el2;
uint64_t hstr_el2;
uint64_t icc_sre_el2;
uint64_t ich_hcr_el2;
uint64_t ich_vmcr_el2;
uint64_t mair_el2;
uint64_t mdcr_el2;
uint64_t pmscr_el2;
uint64_t sctlr_el2;
uint64_t spsr_el2;
uint64_t sp_el2;
uint64_t tcr_el2;
uint64_t tpidr_el2;
uint64_t ttbr0_el2;
uint64_t vbar_el2;
uint64_t vmpidr_el2;
uint64_t vpidr_el2;
uint64_t vtcr_el2;
uint64_t vttbr_el2;
} el2_common_regs_t;
typedef struct el2_mte2_regs {
uint64_t tfsr_el2;
} el2_mte2_regs_t;
typedef struct el2_fgt_regs {
uint64_t hdfgrtr_el2;
uint64_t hafgrtr_el2;
uint64_t hdfgwtr_el2;
uint64_t hfgitr_el2;
uint64_t hfgrtr_el2;
uint64_t hfgwtr_el2;
} el2_fgt_regs_t;
typedef struct el2_fgt2_regs {
uint64_t hdfgrtr2_el2;
uint64_t hdfgwtr2_el2;
uint64_t hfgitr2_el2;
uint64_t hfgrtr2_el2;
uint64_t hfgwtr2_el2;
} el2_fgt2_regs_t;
typedef struct el2_ecv_regs {
uint64_t cntpoff_el2;
} el2_ecv_regs_t;
typedef struct el2_vhe_regs {
uint64_t contextidr_el2;
uint64_t ttbr1_el2;
} el2_vhe_regs_t;
typedef struct el2_ras_regs {
uint64_t vdisr_el2;
uint64_t vsesr_el2;
} el2_ras_regs_t;
typedef struct el2_neve_regs {
uint64_t vncr_el2;
} el2_neve_regs_t;
typedef struct el2_trf_regs {
uint64_t trfcr_el2;
} el2_trf_regs_t;
typedef struct el2_csv2_regs {
uint64_t scxtnum_el2;
} el2_csv2_regs_t;
typedef struct el2_hcx_regs {
uint64_t hcrx_el2;
} el2_hcx_regs_t;
typedef struct el2_tcr2_regs {
uint64_t tcr2_el2;
} el2_tcr2_regs_t;
typedef struct el2_sxpoe_regs {
uint64_t por_el2;
} el2_sxpoe_regs_t;
typedef struct el2_sxpie_regs {
uint64_t pire0_el2;
uint64_t pir_el2;
} el2_sxpie_regs_t;
typedef struct el2_s2pie_regs {
uint64_t s2pir_el2;
} el2_s2pie_regs_t;
typedef struct el2_gcs_regs {
uint64_t gcscr_el2;
uint64_t gcspr_el2;
} el2_gcs_regs_t;
typedef struct el2_mpam_regs {
uint64_t mpam2_el2;
uint64_t mpamhcr_el2;
uint64_t mpamvpm0_el2;
uint64_t mpamvpm1_el2;
uint64_t mpamvpm2_el2;
uint64_t mpamvpm3_el2;
uint64_t mpamvpm4_el2;
uint64_t mpamvpm5_el2;
uint64_t mpamvpm6_el2;
uint64_t mpamvpm7_el2;
uint64_t mpamvpmv_el2;
} el2_mpam_regs_t;
typedef struct el2_sysregs {
el2_common_regs_t common;
#if ENABLE_FEAT_MTE2
el2_mte2_regs_t mte2;
#endif
#if ENABLE_FEAT_FGT
el2_fgt_regs_t fgt;
#endif
#if ENABLE_FEAT_FGT2
el2_fgt2_regs_t fgt2;
#endif
#if ENABLE_FEAT_ECV
el2_ecv_regs_t ecv;
#endif
#if ENABLE_FEAT_VHE
el2_vhe_regs_t vhe;
#endif
#if ENABLE_FEAT_RAS
el2_ras_regs_t ras;
#endif
#if CTX_INCLUDE_NEVE_REGS
el2_neve_regs_t neve;
#endif
#if ENABLE_TRF_FOR_NS
el2_trf_regs_t trf;
#endif
#if ENABLE_FEAT_CSV2_2
el2_csv2_regs_t csv2;
#endif
#if ENABLE_FEAT_HCX
el2_hcx_regs_t hcx;
#endif
#if ENABLE_FEAT_TCR2
el2_tcr2_regs_t tcr2;
#endif
#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
el2_sxpoe_regs_t sxpoe;
#endif
#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
el2_sxpie_regs_t sxpie;
#endif
#if ENABLE_FEAT_S2PIE
el2_s2pie_regs_t s2pie;
#endif
#if ENABLE_FEAT_GCS
el2_gcs_regs_t gcs;
#endif
#if CTX_INCLUDE_MPAM_REGS
el2_mpam_regs_t mpam;
#endif
} el2_sysregs_t;
/*
* Macros to access members related to individual features of the el2_sysregs_t
* structures.
*/
#define read_el2_ctx_common(ctx, reg) (((ctx)->common).reg)
#define write_el2_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \
= (uint64_t) (val))
#if ENABLE_FEAT_MTE2
#define read_el2_ctx_mte2(ctx, reg) (((ctx)->mte2).reg)
#define write_el2_ctx_mte2(ctx, reg, val) ((((ctx)->mte2).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_mte2(ctx, reg) ULL(0)
#define write_el2_ctx_mte2(ctx, reg, val)
#endif /* ENABLE_FEAT_MTE2 */
#if ENABLE_FEAT_FGT
#define read_el2_ctx_fgt(ctx, reg) (((ctx)->fgt).reg)
#define write_el2_ctx_fgt(ctx, reg, val) ((((ctx)->fgt).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_fgt(ctx, reg) ULL(0)
#define write_el2_ctx_fgt(ctx, reg, val)
#endif /* ENABLE_FEAT_FGT */
#if ENABLE_FEAT_FGT2
#define read_el2_ctx_fgt2(ctx, reg) (((ctx)->fgt2).reg)
#define write_el2_ctx_fgt2(ctx, reg, val) ((((ctx)->fgt2).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_fgt2(ctx, reg) ULL(0)
#define write_el2_ctx_fgt2(ctx, reg, val)
#endif /* ENABLE_FEAT_FGT */
#if ENABLE_FEAT_ECV
#define read_el2_ctx_ecv(ctx, reg) (((ctx)->ecv).reg)
#define write_el2_ctx_ecv(ctx, reg, val) ((((ctx)->ecv).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_ecv(ctx, reg) ULL(0)
#define write_el2_ctx_ecv(ctx, reg, val)
#endif /* ENABLE_FEAT_ECV */
#if ENABLE_FEAT_VHE
#define read_el2_ctx_vhe(ctx, reg) (((ctx)->vhe).reg)
#define write_el2_ctx_vhe(ctx, reg, val) ((((ctx)->vhe).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_vhe(ctx, reg) ULL(0)
#define write_el2_ctx_vhe(ctx, reg, val)
#endif /* ENABLE_FEAT_VHE */
#if ENABLE_FEAT_RAS
#define read_el2_ctx_ras(ctx, reg) (((ctx)->ras).reg)
#define write_el2_ctx_ras(ctx, reg, val) ((((ctx)->ras).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_ras(ctx, reg) ULL(0)
#define write_el2_ctx_ras(ctx, reg, val)
#endif /* ENABLE_FEAT_RAS */
#if CTX_INCLUDE_NEVE_REGS
#define read_el2_ctx_neve(ctx, reg) (((ctx)->neve).reg)
#define write_el2_ctx_neve(ctx, reg, val) ((((ctx)->neve).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_neve(ctx, reg) ULL(0)
#define write_el2_ctx_neve(ctx, reg, val)
#endif /* CTX_INCLUDE_NEVE_REGS */
#if ENABLE_TRF_FOR_NS
#define read_el2_ctx_trf(ctx, reg) (((ctx)->trf).reg)
#define write_el2_ctx_trf(ctx, reg, val) ((((ctx)->trf).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_trf(ctx, reg) ULL(0)
#define write_el2_ctx_trf(ctx, reg, val)
#endif /* ENABLE_TRF_FOR_NS */
#if ENABLE_FEAT_CSV2_2
#define read_el2_ctx_csv2_2(ctx, reg) (((ctx)->csv2).reg)
#define write_el2_ctx_csv2_2(ctx, reg, val) ((((ctx)->csv2).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_csv2_2(ctx, reg) ULL(0)
#define write_el2_ctx_csv2_2(ctx, reg, val)
#endif /* ENABLE_FEAT_CSV2_2 */
#if ENABLE_FEAT_HCX
#define read_el2_ctx_hcx(ctx, reg) (((ctx)->hcx).reg)
#define write_el2_ctx_hcx(ctx, reg, val) ((((ctx)->hcx).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_hcx(ctx, reg) ULL(0)
#define write_el2_ctx_hcx(ctx, reg, val)
#endif /* ENABLE_FEAT_HCX */
#if ENABLE_FEAT_TCR2
#define read_el2_ctx_tcr2(ctx, reg) (((ctx)->tcr2).reg)
#define write_el2_ctx_tcr2(ctx, reg, val) ((((ctx)->tcr2).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_tcr2(ctx, reg) ULL(0)
#define write_el2_ctx_tcr2(ctx, reg, val)
#endif /* ENABLE_FEAT_TCR2 */
#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
#define read_el2_ctx_sxpoe(ctx, reg) (((ctx)->sxpoe).reg)
#define write_el2_ctx_sxpoe(ctx, reg, val) ((((ctx)->sxpoe).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_sxpoe(ctx, reg) ULL(0)
#define write_el2_ctx_sxpoe(ctx, reg, val)
#endif /*(ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE) */
#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
#define read_el2_ctx_sxpie(ctx, reg) (((ctx)->sxpie).reg)
#define write_el2_ctx_sxpie(ctx, reg, val) ((((ctx)->sxpie).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_sxpie(ctx, reg) ULL(0)
#define write_el2_ctx_sxpie(ctx, reg, val)
#endif /*(ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE) */
#if ENABLE_FEAT_S2PIE
#define read_el2_ctx_s2pie(ctx, reg) (((ctx)->s2pie).reg)
#define write_el2_ctx_s2pie(ctx, reg, val) ((((ctx)->s2pie).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_s2pie(ctx, reg) ULL(0)
#define write_el2_ctx_s2pie(ctx, reg, val)
#endif /* ENABLE_FEAT_S2PIE */
#if ENABLE_FEAT_GCS
#define read_el2_ctx_gcs(ctx, reg) (((ctx)->gcs).reg)
#define write_el2_ctx_gcs(ctx, reg, val) ((((ctx)->gcs).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_gcs(ctx, reg) ULL(0)
#define write_el2_ctx_gcs(ctx, reg, val)
#endif /* ENABLE_FEAT_GCS */
#if CTX_INCLUDE_MPAM_REGS
#define read_el2_ctx_mpam(ctx, reg) (((ctx)->mpam).reg)
#define write_el2_ctx_mpam(ctx, reg, val) ((((ctx)->mpam).reg) \
= (uint64_t) (val))
#else
#define read_el2_ctx_mpam(ctx, reg) ULL(0)
#define write_el2_ctx_mpam(ctx, reg, val)
#endif /* CTX_INCLUDE_MPAM_REGS */
/******************************************************************************/
#endif /* __ASSEMBLER__ */
#endif /* CONTEXT_EL2_H */