diff --git a/Makefile b/Makefile index 20b2aa296..d2427227c 100644 --- a/Makefile +++ b/Makefile @@ -1106,7 +1106,6 @@ $(eval $(call assert_booleans,\ ENABLE_PSCI_STAT \ ENABLE_RUNTIME_INSTRUMENTATION \ ENABLE_SME_FOR_SWD \ - ENABLE_SVE_FOR_NS \ ENABLE_SVE_FOR_SWD \ ERROR_DEPRECATED \ FAULT_INJECTION_SUPPORT \ @@ -1193,6 +1192,7 @@ $(eval $(call assert_numerics,\ ENABLE_SPE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_SME_FOR_NS \ + ENABLE_SVE_FOR_NS \ ENABLE_TRF_FOR_NS \ FW_ENC_STATUS \ NR_OF_FW_BANKS \ diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 8f3725ad5..4d151ab45 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -103,7 +103,7 @@ ifneq (${ENABLE_SME_FOR_NS},0) BL31_SOURCES += lib/extensions/sme/sme.c BL31_SOURCES += lib/extensions/sve/sve.c else -ifeq (${ENABLE_SVE_FOR_NS},1) +ifneq (${ENABLE_SVE_FOR_NS},0) BL31_SOURCES += lib/extensions/sve/sve.c endif endif diff --git a/common/feat_detect.c b/common/feat_detect.c index 609a38888..9394304bf 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -171,6 +171,8 @@ void detect_arch_features(void) /* v8.2 features */ read_feat_ras(); + check_feature(ENABLE_SVE_FOR_NS, read_feat_sve_id_field(), + "SVE", 1, 1); /* v8.3 features */ read_feat_pauth(); diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 4483dd424..1ee07d9ac 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -428,7 +428,7 @@ Common build options mechanism. The default is 2 but is automatically disabled when the target architecture is AArch32. -- ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension +- ``ENABLE_SVE_FOR_NS``: Numeric value to enable Scalable Vector Extension (SVE) for the Non-secure world only. SVE is an optional architectural feature for AArch64. Note that when SVE is enabled for the Non-secure world, access to SIMD and floating-point functionality from the Secure world is disabled by @@ -437,9 +437,10 @@ Common build options which are aliased by the SIMD and FP registers. The build option is not compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to - 1. The default is 1 but is automatically disabled when ENABLE_SME_FOR_NS=1 - since SME encompasses SVE. At this time, this build option cannot be used on - systems that have SPM_MM enabled. + 1. This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. The default is 1 but is automatically disabled when + ENABLE_SME_FOR_NS=1 since SME encompasses SVE. At this time, this build + option cannot be used on systems that have SPM_MM enabled. - ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world. SVE is an optional architectural feature for AArch64. Note that this option diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index a01dfe783..3ea08a665 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -387,10 +387,22 @@ static inline bool is_feat_spe_supported(void) /******************************************************************************* * Function to identify the presence of FEAT_SVE (Scalable Vector Extension) ******************************************************************************/ -static inline bool is_armv8_2_feat_sve_present(void) +static inline unsigned int read_feat_sve_id_field(void) { - return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) & - ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED); + return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SVE); +} + +static inline bool is_feat_sve_supported(void) +{ + if (ENABLE_SVE_FOR_NS == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_SVE_FOR_NS == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_sve_id_field() >= ID_AA64PFR0_SVE_SUPPORTED; } /******************************************************************************* diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h index 4b66cdb09..1faed2d23 100644 --- a/include/lib/extensions/sve.h +++ b/include/lib/extensions/sve.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,16 @@ #include +#if (ENABLE_SME_FOR_NS || ENABLE_SVE_FOR_NS) void sve_enable(cpu_context_t *context); void sve_disable(cpu_context_t *context); +#else +static inline void sve_enable(cpu_context_t *context) +{ +} +static inline void sve_disable(cpu_context_t *context) +{ +} +#endif /* ( ENABLE_SME_FOR_NS | ENABLE_SVE_FOR_NS ) */ #endif /* SVE_H */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 7fbbd8171..42166eb99 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -492,11 +492,10 @@ static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) /* Enable SME, SVE, and FPU/SIMD for non-secure world. */ if (is_feat_sme_supported()) { sme_enable(ctx); + } else if (is_feat_sve_supported()) { + /* Enable SVE and FPU/SIMD for non-secure world. */ + sve_enable(ctx); } -#if ENABLE_SVE_FOR_NS - /* Enable SVE and FPU/SIMD for non-secure world. */ - sve_enable(ctx); -#endif if (is_feat_mpam_supported()) { mpam_enable(el2_unused); @@ -526,35 +525,38 @@ static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) static void manage_extensions_secure(cpu_context_t *ctx) { #if IMAGE_BL31 - #if ENABLE_SME_FOR_NS - #if ENABLE_SME_FOR_SWD - /* - * Enable SME, SVE, FPU/SIMD in secure context, secure manager must - * ensure SME, SVE, and FPU/SIMD context properly managed. - */ - sme_enable(ctx); - #else /* ENABLE_SME_FOR_SWD */ - /* - * Disable SME, SVE, FPU/SIMD in secure context so non-secure world can - * safely use the associated registers. - */ - sme_disable(ctx); - #endif /* ENABLE_SME_FOR_SWD */ - #elif ENABLE_SVE_FOR_NS - #if ENABLE_SVE_FOR_SWD - /* - * Enable SVE and FPU in secure context, secure manager must ensure that - * the SVE and FPU register contexts are properly managed. - */ - sve_enable(ctx); - #else /* ENABLE_SVE_FOR_SWD */ - /* - * Disable SVE and FPU in secure context so non-secure world can safely - * use them. - */ - sve_disable(ctx); - #endif /* ENABLE_SVE_FOR_SWD */ - #endif /* ENABLE_SVE_FOR_NS */ + + if (is_feat_sme_supported()) { + if (ENABLE_SME_FOR_SWD) { + /* + * Enable SME, SVE, FPU/SIMD in secure context, secure manager + * must ensure SME, SVE, and FPU/SIMD context properly managed. + */ + sme_enable(ctx); + } else { + /* + * Disable SME, SVE, FPU/SIMD in secure context so non-secure + * world can safely use the associated registers. + */ + sme_disable(ctx); + } + } else if (is_feat_sve_supported()) { + if (ENABLE_SVE_FOR_SWD) { + /* + * Enable SVE and FPU in secure context, secure manager must + * ensure that the SVE and FPU register contexts are properly + * managed. + */ + sve_enable(ctx); + } else { + /* + * Disable SVE and FPU in secure context so non-secure world + * can safely use them. + */ + sve_disable(ctx); + } + } + #endif /* IMAGE_BL31 */ } diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c index 1846e003a..29034fdc4 100644 --- a/lib/extensions/sme/sme.c +++ b/lib/extensions/sme/sme.c @@ -20,13 +20,6 @@ void sme_enable(cpu_context_t *context) u_register_t cptr_el3; el3_state_t *state; - /* Make sure SME is implemented in hardware before continuing. */ - if (!is_feat_sme_supported()) { - /* Perhaps the hardware supports SVE only */ - sve_enable(context); - return; - } - /* Get the context state. */ state = get_el3state_ctx(context); @@ -70,13 +63,6 @@ void sme_disable(cpu_context_t *context) u_register_t reg; el3_state_t *state; - /* Make sure SME is implemented in hardware before continuing. */ - if (!is_feat_sme_supported()) { - /* Perhaps the hardware supports SVE only */ - sve_disable(context); - return; - } - /* Get the context state. */ state = get_el3state_ctx(context); diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c index f7dcc767a..f551ca7e6 100644 --- a/lib/extensions/sve/sve.c +++ b/lib/extensions/sve/sve.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,22 +22,10 @@ CASSERT((SVE_VECTOR_LEN % 128) == 0, assert_sve_vl_granule); */ #define CONVERT_SVE_LENGTH(x) (((x / 128) - 1)) -static bool sve_supported(void) -{ - uint64_t features; - - features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT; - return (features & ID_AA64PFR0_SVE_MASK) == 1U; -} - void sve_enable(cpu_context_t *context) { u_register_t cptr_el3; - if (!sve_supported()) { - return; - } - cptr_el3 = read_ctx_reg(get_el3state_ctx(context), CTX_CPTR_EL3); /* Enable access to SVE functionality for all ELs. */ @@ -54,11 +42,6 @@ void sve_disable(cpu_context_t *context) u_register_t reg; el3_state_t *state; - /* Make sure SME is implemented in hardware before continuing. */ - if (!sve_supported()) { - return; - } - /* Get the context state. */ state = get_el3state_ctx(context); diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index ef917f65b..63617b2ae 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -373,7 +373,7 @@ ENABLE_AMU_FCONF := 0 AMU_RESTRICT_COUNTERS := 0 # Enable SVE for non-secure world by default -ENABLE_SVE_FOR_NS := 1 +ENABLE_SVE_FOR_NS := 2 # SVE is only supported on AArch64 so disable it on AArch32. ifeq (${ARCH},aarch32) override ENABLE_SVE_FOR_NS := 0 diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c index e12eae79f..24f6c4127 100644 --- a/services/std_svc/rmmd/rmmd_main.c +++ b/services/std_svc/rmmd/rmmd_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -117,19 +117,14 @@ static void rmm_el2_context_init(el2_sysregs_t *regs) ******************************************************************************/ static void manage_extensions_realm(cpu_context_t *ctx) { -#if ENABLE_SVE_FOR_NS + if (is_feat_sve_supported()) { /* * Enable SVE and FPU in realm context when it is enabled for NS. * Realm manager must ensure that the SVE and FPU register * contexts are properly managed. */ - sve_enable(ctx); -#else - /* - * Disable SVE and FPU in realm context when it is disabled for NS. - */ - sve_disable(ctx); -#endif /* ENABLE_SVE_FOR_NS */ + sve_enable(ctx); + } } /******************************************************************************* diff --git a/services/std_svc/spm/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk index b1f045ee6..513e8ef96 100644 --- a/services/std_svc/spm/spm_mm/spm_mm.mk +++ b/services/std_svc/spm/spm_mm/spm_mm.mk @@ -10,7 +10,7 @@ endif ifneq (${ARCH},aarch64) $(error "Error: SPM_MM is only supported on aarch64.") endif -ifeq (${ENABLE_SVE_FOR_NS},1) +ifneq (${ENABLE_SVE_FOR_NS},0) $(error "Error: SPM_MM is not compatible with ENABLE_SVE_FOR_NS") endif ifneq (${ENABLE_SME_FOR_NS},0)