diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | common/feat_detect.c | 8 | ||||
-rw-r--r-- | docs/getting_started/build-options.rst | 20 | ||||
-rw-r--r-- | include/arch/aarch64/arch.h | 22 | ||||
-rw-r--r-- | include/arch/aarch64/arch_features.h | 82 | ||||
-rw-r--r-- | include/arch/aarch64/arch_helpers.h | 8 | ||||
-rw-r--r-- | include/lib/el3_runtime/aarch64/context.h | 6 | ||||
-rw-r--r-- | lib/el3_runtime/aarch64/context_mgmt.c | 28 | ||||
-rw-r--r-- | make_helpers/defaults.mk | 12 | ||||
-rw-r--r-- | plat/arm/board/fvp/platform.mk | 4 |
10 files changed, 197 insertions, 1 deletions
@@ -1185,6 +1185,10 @@ $(eval $(call assert_numerics,\ ENABLE_FEAT_RNG_TRAP \ ENABLE_FEAT_SEL2 \ ENABLE_FEAT_TCR2 \ + ENABLE_FEAT_S2PIE \ + ENABLE_FEAT_S1PIE \ + ENABLE_FEAT_S2POE \ + ENABLE_FEAT_S1POE \ ENABLE_FEAT_VHE \ ENABLE_MPAM_FOR_LOWER_ELS \ ENABLE_RME \ @@ -1321,6 +1325,10 @@ $(eval $(call add_defines,\ ENABLE_FEAT_CSV2_2 \ ENABLE_FEAT_PAN \ ENABLE_FEAT_TCR2 \ + ENABLE_FEAT_S2PIE \ + ENABLE_FEAT_S1PIE \ + ENABLE_FEAT_S2POE \ + ENABLE_FEAT_S1POE \ FEATURE_DETECTION \ TWED_DELAY \ ENABLE_FEAT_TWED \ diff --git a/common/feat_detect.c b/common/feat_detect.c index 9394304bf..1582b9dcb 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -210,6 +210,14 @@ void detect_arch_features(void) /* v8.9 features */ check_feature(ENABLE_FEAT_TCR2, read_feat_tcrx_id_field(), "TCR2", 1, 1); + check_feature(ENABLE_FEAT_S2PIE, read_feat_s2pie_id_field(), + "S2PIE", 1, 1); + check_feature(ENABLE_FEAT_S1PIE, read_feat_s1pie_id_field(), + "S1PIE", 1, 1); + check_feature(ENABLE_FEAT_S2POE, read_feat_s2poe_id_field(), + "S2POE", 1, 1); + check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(), + "S1POE", 1, 1); /* v9.0 features */ check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(), diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index e078e47c6..03be7862e 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -354,6 +354,26 @@ Common build options flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. Default value is ``0``. +- ``ENABLE_FEAT_S2PIE``: Numeric value to enable support for FEAT_S2PIE + at EL2 and below, and context switch relevant registers. This flag + can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_S1PIE``: Numeric value to enable support for FEAT_S1PIE + at EL2 and below, and context switch relevant registers. This flag + can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_S2POE``: Numeric value to enable support for FEAT_S2POE + at EL2 and below, and context switch relevant registers. This flag + can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_S1POE``: Numeric value to enable support for FEAT_S1POE + at EL2 and below, and context switch relevant registers. This flag + can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + - ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO) support in GCC for TF-A. This option is currently only supported for AArch64. Default is 0. diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index dee7fdcff..9b55658ff 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -355,6 +355,18 @@ /* ID_AA64MMFR3_EL1 definitions */ #define ID_AA64MMFR3_EL1 S3_0_C0_C7_3 +#define ID_AA64MMFR3_EL1_S2POE_SHIFT U(20) +#define ID_AA64MMFR3_EL1_S2POE_MASK ULL(0xf) + +#define ID_AA64MMFR3_EL1_S1POE_SHIFT U(16) +#define ID_AA64MMFR3_EL1_S1POE_MASK ULL(0xf) + +#define ID_AA64MMFR3_EL1_S2PIE_SHIFT U(12) +#define ID_AA64MMFR3_EL1_S2PIE_MASK ULL(0xf) + +#define ID_AA64MMFR3_EL1_S1PIE_SHIFT U(8) +#define ID_AA64MMFR3_EL1_S1PIE_MASK ULL(0xf) + #define ID_AA64MMFR3_EL1_TCRX_SHIFT U(0) #define ID_AA64MMFR3_EL1_TCRX_MASK ULL(0xf) @@ -512,6 +524,7 @@ #define SCR_GPF_BIT (UL(1) << 48) #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) +#define SCR_PIEN_BIT (UL(1) << 45) #define SCR_TCR2EN_BIT (UL(1) << 43) #define SCR_TRNDR_BIT (UL(1) << 40) #define SCR_HXEn_BIT (UL(1) << 38) @@ -1321,6 +1334,15 @@ #define TCR2_EL2 S3_4_C2_C0_3 /******************************************************************************* + * Permission indirection and overlay + ******************************************************************************/ + +#define PIRE0_EL2 S3_4_C10_C2_2 +#define PIR_EL2 S3_4_C10_C2_3 +#define POR_EL2 S3_4_C10_C2_4 +#define S2PIR_EL2 S3_4_C10_C2_5 + +/******************************************************************************* * Definitions for DynamicIQ Shared Unit registers ******************************************************************************/ #define CLUSTERPWRDN_EL1 S3_0_c15_c3_6 diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 3ea08a665..840b117a0 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -234,6 +234,88 @@ static inline bool is_feat_tcr2_supported(void) return read_feat_tcrx_id_field() != 0U; } +static unsigned int read_feat_s2poe_id_field(void) +{ + return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE); +} + +static inline bool is_feat_s2poe_supported(void) +{ + if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_s2poe_id_field() != 0U; +} + +static unsigned int read_feat_s1poe_id_field(void) +{ + return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE); +} + +static inline bool is_feat_s1poe_supported(void) +{ + if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_s1poe_id_field() != 0U; +} + +static inline bool is_feat_sxpoe_supported(void) +{ + return is_feat_s1poe_supported() || is_feat_s2poe_supported(); +} + +static unsigned int read_feat_s2pie_id_field(void) +{ + return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE); +} + +static inline bool is_feat_s2pie_supported(void) +{ + if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_s2pie_id_field() != 0U; +} + +static unsigned int read_feat_s1pie_id_field(void) +{ + return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE); +} + +static inline bool is_feat_s1pie_supported(void) +{ + if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_s1pie_id_field() != 0U; +} + +static inline bool is_feat_sxpie_supported(void) +{ + return is_feat_s1pie_supported() || is_feat_s2pie_supported(); +} + /******************************************************************************* * Functions to identify the presence of the Activity Monitors Extension ******************************************************************************/ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 04b64be5c..f877f5bc8 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -605,6 +605,14 @@ DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1) /* FEAT_TCR2 Register */ DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2) +/* FEAT_SxPIE Registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el2, PIRE0_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el2, PIR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2) + +/* FEAT_SxPOE Registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2) + /* DynamIQ Shared Unit power management */ DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index e5e7e7422..a8e6d8ad2 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -230,9 +230,13 @@ // Starting with Armv8.9 #define CTX_TCR2_EL2 U(0x1d8) +#define CTX_POR_EL2 U(0x1e0) +#define CTX_PIRE0_EL2 U(0x1e8) +#define CTX_PIR_EL2 U(0x1f0) +#define CTX_S2PIR_EL2 U(0x1f8) /* Align to the next 16 byte boundary */ -#define CTX_EL2_SYSREGS_END U(0x1e0) +#define CTX_EL2_SYSREGS_END U(0x200) #endif /* CTX_INCLUDE_EL2_REGS */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 42166eb99..94d5ee1d2 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -355,6 +355,14 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e } /* + * SCR_EL3.PIEN: Enable permission indirection and overlay + * registers for AArch64 if present. + */ + if (is_feat_sxpie_supported() || is_feat_sxpoe_supported()) { + scr_el3 |= SCR_PIEN_BIT; + } + + /* * CPTR_EL3 was initialized out of reset, copy that value to the * context register. */ @@ -994,6 +1002,16 @@ void cm_el2_sysregs_context_save(uint32_t security_state) if (is_feat_tcr2_supported()) { write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2()); } + if (is_feat_sxpie_supported()) { + write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2()); + write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2()); + } + if (is_feat_s2pie_supported()) { + write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2()); + } + if (is_feat_sxpoe_supported()) { + write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2()); + } } } @@ -1061,6 +1079,16 @@ void cm_el2_sysregs_context_restore(uint32_t security_state) if (is_feat_tcr2_supported()) { write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2)); } + if (is_feat_sxpie_supported()) { + write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2)); + write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2)); + } + if (is_feat_s2pie_supported()) { + write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2)); + } + if (is_feat_sxpoe_supported()) { + write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2)); + } } } #endif /* CTX_INCLUDE_EL2_REGS */ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index af980f518..808a058b2 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -176,6 +176,18 @@ ENABLE_FEAT_TWED := 0 # Flag to enable access to TCR2 (FEAT_TCR2) ENABLE_FEAT_TCR2 := 0 +# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE) +ENABLE_FEAT_S2PIE := 0 + +# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE) +ENABLE_FEAT_S1PIE := 0 + +# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE) +ENABLE_FEAT_S2POE := 0 + +# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE) +ENABLE_FEAT_S1POE := 0 + # By default BL31 encryption disabled ENCRYPT_BL31 := 0 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index ab6e0bf5e..3fb323bd4 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -77,6 +77,10 @@ ENABLE_TRF_FOR_NS := 2 ENABLE_FEAT_ECV := 2 ENABLE_FEAT_FGT := 2 ENABLE_FEAT_TCR2 := 2 +ENABLE_FEAT_S2PIE := 2 +ENABLE_FEAT_S1PIE := 2 +ENABLE_FEAT_S2POE := 2 +ENABLE_FEAT_S1POE := 2 endif # The FVP platform depends on this macro to build with correct GIC driver. |