From 306551362c15c3be7d118b549c7c99290716d5d6 Mon Sep 17 00:00:00 2001 From: Govindraj Raja Date: Fri, 6 Sep 2024 15:43:43 +0100 Subject: [PATCH] feat(d128): add support for FEAT_D128 This patch disables trapping to EL3 when the FEAT_D128 specific registers are accessed by setting the SCR_EL3.D128En bit. If FEAT_D128 is implemented, then FEAT_SYSREG128 is implemented. With FEAT_SYSREG128 certain system registers are treated as 128-bit, so we should be context saving and restoring 128-bits instead of 64-bit when FEAT_D128 is enabled. FEAT_SYSREG128 adds support for MRRS and MSRR instruction which helps us to read write to 128-bit system register. Refer to Arm Architecture Manual for further details. Change the FVP platform to default to handling this as a dynamic option so the right decision can be made by the code at runtime. Change-Id: I1a53db5eac29e56c8fbdcd4961ede3abfcb2411a Signed-off-by: Jayanth Dodderi Chidanand Signed-off-by: Govindraj Raja --- Makefile | 9 ++ common/feat_detect.c | 10 ++ docs/getting_started/build-options.rst | 9 ++ include/arch/aarch32/arch.h | 3 +- include/arch/aarch32/arch_features.h | 2 + include/arch/aarch64/arch.h | 11 +- include/arch/aarch64/arch_features.h | 7 + include/arch/aarch64/arch_helpers.h | 28 +++- include/common/par.h | 30 ++++ include/lib/el3_runtime/context_el1.h | 12 +- include/lib/el3_runtime/context_el2.h | 15 +- include/lib/extensions/sysreg128.h | 36 +++++ lib/el3_runtime/aarch64/context_mgmt.c | 16 +- lib/extensions/sysreg128/sysreg128.S | 139 ++++++++++++++++++ lib/xlat_tables/aarch64/xlat_tables.c | 2 +- lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 2 +- make_helpers/arch_features.mk | 6 + plat/arm/board/fvp/platform.mk | 1 + plat/arm/common/arm_common.c | 7 +- services/spd/tlkd/tlkd.mk | 4 +- 20 files changed, 324 insertions(+), 25 deletions(-) create mode 100644 include/common/par.h create mode 100644 include/lib/extensions/sysreg128.h create mode 100644 lib/extensions/sysreg128/sysreg128.S diff --git a/Makefile b/Makefile index 4f3f26123..f736a3bc3 100644 --- a/Makefile +++ b/Makefile @@ -645,6 +645,13 @@ ifeq (${CTX_INCLUDE_EL2_REGS}, 1) endif endif +################################################################################ +# Make 128-Bit sysreg read/writes availabe when FEAT_D128 is enabled. +################################################################################ +ifneq (${ENABLE_FEAT_D128}, 0) + BL_COMMON_SOURCES += lib/extensions/sysreg128/sysreg128.S +endif + ################################################################################ # Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come # up with appropriate march values for compiler. @@ -1263,6 +1270,7 @@ $(eval $(call assert_numerics,\ ENABLE_FEAT_S2POE \ ENABLE_FEAT_S1POE \ ENABLE_FEAT_SCTLR2 \ + ENABLE_FEAT_D128 \ ENABLE_FEAT_GCS \ ENABLE_FEAT_VHE \ ENABLE_FEAT_MPAM \ @@ -1421,6 +1429,7 @@ $(eval $(call add_defines,\ ENABLE_FEAT_S2POE \ ENABLE_FEAT_S1POE \ ENABLE_FEAT_SCTLR2 \ + ENABLE_FEAT_D128 \ ENABLE_FEAT_GCS \ ENABLE_FEAT_MTE2 \ FEATURE_DETECTION \ diff --git a/common/feat_detect.c b/common/feat_detect.c index e63eec408..6aa5e2e50 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -269,6 +269,12 @@ static unsigned int read_feat_sctlr2_id_field(void) ID_AA64MMFR3_EL1_SCTLR2_MASK); } +static unsigned int read_feat_d128_id_field(void) +{ + return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_D128_SHIFT, + ID_AA64MMFR3_EL1_D128_MASK); +} + /*********************************************************************************** * TF-A supports many Arm architectural features starting from arch version * (8.0 till 8.7+). These features are mostly enabled through build flags. This @@ -394,6 +400,10 @@ void detect_arch_features(void) check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(), "SME2", 2, 2); + /* v9.3 features */ + check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(), + "D128", 1, 1); + /* v9.4 features */ check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1); check_feature(ENABLE_RME, read_feat_rme_id_field(), "RME", 1, 1); diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 7776f5bca..772447abb 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -471,6 +471,15 @@ Common build options This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism. Default value is ``0``. +- ``ENABLE_FEAT_D128``: Numeric value to enable support for FEAT_D128 + at EL2 and below, setting the bit SCT_EL3.D128En in EL3 to allow access to + 128 bit version of system registers like PAR_EL1, TTBR0_EL1, TTBR1_EL1, + TTBR0_EL2, TTBR1_EL2, TTBR0_EL12, TTBR1_EL12 , VTTBR_EL2, RCWMASK_EL1, and + RCWSMASK_EL1. Its an optional architectural feature and is available from + 9.3 and upwards. + This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT`` + 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/aarch32/arch.h b/include/arch/aarch32/arch.h index d32ead4a2..d2591ddb0 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -697,8 +697,7 @@ /* PAR fields */ #define PAR_F_SHIFT U(0) #define PAR_F_MASK ULL(0x1) -#define PAR_ADDR_SHIFT U(12) -#define PAR_ADDR_MASK (BIT_64(40) - ULL(1)) /* 40-bits-wide page address */ +#define PAR_ADDR_MASK GENMASK_64(39, 12) /* 28-bits-wide page address */ /******************************************************************************* * Definitions for system register interface to AMU for FEAT_AMUv1 diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h index abe34a436..a29b67224 100644 --- a/include/arch/aarch32/arch_features.h +++ b/include/arch/aarch32/arch_features.h @@ -194,5 +194,7 @@ __attribute__((always_inline)) static inline bool is_feat_ebep_present(void) { return false; } __attribute__((always_inline)) static inline bool is_feat_sebep_present(void) { return false; } +__attribute__((always_inline)) +static inline bool is_feat_d128_present(void) { return false; } #endif /* ARCH_FEATURES_H */ diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 6a198224d..3f0120c47 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -331,6 +331,7 @@ #define PARANGE_0100 U(44) #define PARANGE_0101 U(48) #define PARANGE_0110 U(52) +#define PARANGE_0111 U(56) #define ID_AA64MMFR0_EL1_ECV_SHIFT U(60) #define ID_AA64MMFR0_EL1_ECV_MASK ULL(0xf) @@ -394,6 +395,10 @@ /* ID_AA64MMFR3_EL1 definitions */ #define ID_AA64MMFR3_EL1 S3_0_C0_C7_3 +#define ID_AA64MMFR3_EL1_D128_SHIFT U(32) +#define ID_AA64MMFR3_EL1_D128_MASK ULL(0xf) +#define D128_IMPLEMENTED ULL(0x1) + #define ID_AA64MMFR3_EL1_S2POE_SHIFT U(20) #define ID_AA64MMFR3_EL1_S2POE_MASK ULL(0xf) @@ -594,6 +599,7 @@ #define SCR_FGTEN2_BIT (UL(1) << 59) #define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT) #define SCR_GPF_BIT (UL(1) << 48) +#define SCR_D128En_BIT (UL(1) << 47) #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) #define SCR_PIEN_BIT (UL(1) << 45) @@ -1179,8 +1185,9 @@ /* PAR_EL1 fields */ #define PAR_F_SHIFT U(0) #define PAR_F_MASK ULL(0x1) -#define PAR_ADDR_SHIFT U(12) -#define PAR_ADDR_MASK (BIT(40) - ULL(1)) /* 40-bits-wide page address */ + +#define PAR_D128_ADDR_MASK GENMASK(55, 12) /* 44-bits-wide page address */ +#define PAR_ADDR_MASK GENMASK(51, 12) /* 40-bits-wide page address */ /******************************************************************************* * Definitions for system register interface to SPE diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index de21feab7..ec38d7615 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -138,6 +138,8 @@ CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard) * +----------------------------+ * | FEAT_SCTLR2 | * +----------------------------+ + * | FEAT_D128 | + * +----------------------------+ */ __attribute__((always_inline)) @@ -275,6 +277,11 @@ CREATE_FEATURE_FUNCS(feat_sctlr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_SCTLR2_SHIF ID_AA64MMFR3_EL1_SCTLR2_MASK, SCTLR2_IMPLEMENTED, ENABLE_FEAT_SCTLR2) +/* FEAT_D128 */ +CREATE_FEATURE_FUNCS(feat_d128, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_D128_SHIFT, + ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED, + ENABLE_FEAT_D128) + __attribute__((always_inline)) static inline bool is_feat_sxpie_supported(void) { diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index acaa1b8ee..9c36e4baf 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -13,6 +13,7 @@ #include #include +#include /********************************************************************** * Macros which create inline functions to read or write CPU system @@ -263,7 +264,12 @@ void disable_mpu_icache_el2(void); #define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val) #define write_daifset(val) SYSREG_WRITE_CONST(daifset, val) +#if ENABLE_FEAT_D128 +DECLARE_SYSREG128_RW_FUNCS(par_el1) +#else DEFINE_SYSREG_RW_FUNCS(par_el1) +#endif + DEFINE_IDREG_READ_FUNC(id_pfr1_el1) DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1) DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1) @@ -443,13 +449,21 @@ DEFINE_SYSREG_RW_FUNCS(tcr_el1) DEFINE_SYSREG_RW_FUNCS(tcr_el2) DEFINE_SYSREG_RW_FUNCS(tcr_el3) +#if ENABLE_FEAT_D128 +DECLARE_SYSREG128_RW_FUNCS(ttbr0_el1) +DECLARE_SYSREG128_RW_FUNCS(ttbr1_el1) +DECLARE_SYSREG128_RW_FUNCS(ttbr0_el2) +DECLARE_SYSREG128_RW_FUNCS(ttbr1_el2) +DECLARE_SYSREG128_RW_FUNCS(vttbr_el2) +#else DEFINE_SYSREG_RW_FUNCS(ttbr0_el1) -DEFINE_SYSREG_RW_FUNCS(ttbr0_el2) -DEFINE_SYSREG_RW_FUNCS(ttbr0_el3) - DEFINE_SYSREG_RW_FUNCS(ttbr1_el1) - +DEFINE_SYSREG_RW_FUNCS(ttbr0_el2) +DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2) DEFINE_SYSREG_RW_FUNCS(vttbr_el2) +#endif + +DEFINE_SYSREG_RW_FUNCS(ttbr0_el3) DEFINE_SYSREG_RW_FUNCS(cptr_el2) DEFINE_SYSREG_RW_FUNCS(cptr_el3) @@ -574,7 +588,6 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el0, SCXTNUM_EL0) /* Armv8.1 VHE Registers */ DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2) -DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2) /* Armv8.2 ID Registers */ DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1) @@ -671,8 +684,13 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0) /* FEAT_THE Registers */ +#if ENABLE_FEAT_D128 +DECLARE_SYSREG128_RW_FUNCS(rcwmask_el1) +DECLARE_SYSREG128_RW_FUNCS(rcwsmask_el1) +#else DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1) +#endif /* FEAT_SCTLR2 Registers */ DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1) diff --git a/include/common/par.h b/include/common/par.h new file mode 100644 index 000000000..c8d67a38f --- /dev/null +++ b/include/common/par.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PAR_H +#define PAR_H + +#include +#include + +static inline uint64_t get_par_el1_pa(sysreg_t par) +{ + uint64_t pa = par & UINT64_MAX; + /* PA, bits [51:12] is Output address */ + uint64_t mask = PAR_ADDR_MASK; + +#if ENABLE_FEAT_D128 + /* If D128 is in use, the PA is in the upper 64-bit word of PAR_EL1 */ + if (is_feat_d128_supported() && (par & PAR_EL1_D128)) { + pa = (par >> 64) & UINT64_MAX; + /* PA, bits [55:12] is Output address */ + mask = PAR_D128_ADDR_MASK; + } +#endif + return pa & mask; +} + +#endif /* PAR_H */ diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h index 94af21080..4379bcf78 100644 --- a/include/lib/el3_runtime/context_el1.h +++ b/include/lib/el3_runtime/context_el1.h @@ -7,6 +7,8 @@ #ifndef CONTEXT_EL1_H #define CONTEXT_EL1_H +#include + #ifndef __ASSEMBLER__ /******************************************************************************* @@ -28,15 +30,12 @@ typedef struct el1_common_regs { uint64_t csselr_el1; uint64_t sp_el1; uint64_t esr_el1; - uint64_t ttbr0_el1; - uint64_t ttbr1_el1; uint64_t mair_el1; uint64_t amair_el1; uint64_t actlr_el1; uint64_t tpidr_el1; uint64_t tpidr_el0; uint64_t tpidrro_el0; - uint64_t par_el1; uint64_t far_el1; uint64_t afsr0_el1; uint64_t afsr1_el1; @@ -44,6 +43,9 @@ typedef struct el1_common_regs { uint64_t vbar_el1; uint64_t mdccint_el1; uint64_t mdscr_el1; + sysreg_t par_el1; + sysreg_t ttbr0_el1; + sysreg_t ttbr1_el1; } el1_common_regs_t; typedef struct el1_aarch32_regs { @@ -108,8 +110,8 @@ typedef struct el1_gcs_regs { } el1_gcs_regs_t; typedef struct el1_the_regs { - uint64_t rcwmask_el1; - uint64_t rcwsmask_el1; + sysreg_t rcwmask_el1; + sysreg_t rcwsmask_el1; } el1_the_regs_t; typedef struct el1_sctlr2_regs { diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h index ad0b68f7c..7374e39d8 100644 --- a/include/lib/el3_runtime/context_el2.h +++ b/include/lib/el3_runtime/context_el2.h @@ -7,7 +7,10 @@ #ifndef CONTEXT_EL2_H #define CONTEXT_EL2_H +#include + #ifndef __ASSEMBLER__ + /******************************************************************************* * EL2 Registers: * AArch64 EL2 system register context structure for preserving the @@ -40,12 +43,12 @@ typedef struct el2_common_regs { 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; + sysreg_t vttbr_el2; + sysreg_t ttbr0_el2; } el2_common_regs_t; typedef struct el2_mte2_regs { @@ -75,7 +78,7 @@ typedef struct el2_ecv_regs { typedef struct el2_vhe_regs { uint64_t contextidr_el2; - uint64_t ttbr1_el2; + sysreg_t ttbr1_el2; } el2_vhe_regs_t; typedef struct el2_ras_regs { @@ -222,6 +225,9 @@ typedef struct el2_sysregs { #define write_el2_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \ = (uint64_t) (val)) +#define write_el2_ctx_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \ + = (sysreg_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) \ @@ -262,6 +268,9 @@ typedef struct el2_sysregs { #define read_el2_ctx_vhe(ctx, reg) (((ctx)->vhe).reg) #define write_el2_ctx_vhe(ctx, reg, val) ((((ctx)->vhe).reg) \ = (uint64_t) (val)) + +#define write_el2_ctx_vhe_sysreg128(ctx, reg, val) ((((ctx)->vhe).reg) \ + = (sysreg_t) (val)) #else #define read_el2_ctx_vhe(ctx, reg) ULL(0) #define write_el2_ctx_vhe(ctx, reg, val) diff --git a/include/lib/extensions/sysreg128.h b/include/lib/extensions/sysreg128.h new file mode 100644 index 000000000..8854856b6 --- /dev/null +++ b/include/lib/extensions/sysreg128.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SYSREG128_H +#define SYSREG128_H + +#ifndef __ASSEMBLER__ + +#if ENABLE_FEAT_D128 +#include + +typedef uint128_t sysreg_t; + +#define PAR_EL1_D128 (((sysreg_t)(1ULL)) << (64)) + +#define _DECLARE_SYSREG128_READ_FUNC(_name) \ +uint128_t read_ ## _name(void); + +#define _DECLARE_SYSREG128_WRITE_FUNC(_name) \ +void write_ ## _name(uint128_t v); + +#define DECLARE_SYSREG128_RW_FUNCS(_name) \ + _DECLARE_SYSREG128_READ_FUNC(_name) \ + _DECLARE_SYSREG128_WRITE_FUNC(_name) +#else + +typedef uint64_t sysreg_t; + +#endif /* ENABLE_FEAT_D128 */ + +#endif /* __ASSEMBLER__ */ + +#endif /* SYSREG128_H */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 003cb25b9..d2222fab2 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -275,6 +276,14 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info * scr_el3 |= SCR_SCTLR2En_BIT; } + if (is_feat_d128_supported()) { + /* Set the D128En bit in SCR_EL3 to enable access to 128-bit + * versions of TTBR0_EL1, TTBR1_EL1, RCWMASK_EL1, RCWSMASK_EL1, + * PAR_EL1 and TTBR1_EL2, TTBR0_EL2 and VTTBR_EL2 registers. + */ + scr_el3 |= SCR_D128En_BIT; + } + write_ctx_reg(state, CTX_SCR_EL3, scr_el3); /* Initialize EL2 context registers */ @@ -1322,12 +1331,13 @@ static void el2_sysregs_context_save_common(el2_sysregs_t *ctx) write_el2_ctx_common(ctx, sp_el2, read_sp_el2()); write_el2_ctx_common(ctx, tcr_el2, read_tcr_el2()); write_el2_ctx_common(ctx, tpidr_el2, read_tpidr_el2()); - write_el2_ctx_common(ctx, ttbr0_el2, read_ttbr0_el2()); write_el2_ctx_common(ctx, vbar_el2, read_vbar_el2()); write_el2_ctx_common(ctx, vmpidr_el2, read_vmpidr_el2()); write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2()); write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2()); - write_el2_ctx_common(ctx, vttbr_el2, read_vttbr_el2()); + + write_el2_ctx_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2()); + write_el2_ctx_sysreg128(ctx, vttbr_el2, read_vttbr_el2()); } static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx) @@ -1403,7 +1413,7 @@ void cm_el2_sysregs_context_save(uint32_t security_state) if (is_feat_vhe_supported()) { write_el2_ctx_vhe(el2_sysregs_ctx, contextidr_el2, read_contextidr_el2()); - write_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2()); + write_el2_ctx_vhe_sysreg128(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2()); } if (is_feat_ras_supported()) { diff --git a/lib/extensions/sysreg128/sysreg128.S b/lib/extensions/sysreg128/sysreg128.S new file mode 100644 index 000000000..08cff2fb2 --- /dev/null +++ b/lib/extensions/sysreg128/sysreg128.S @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .global read_par_el1 + .global write_par_el1 + .global read_ttbr0_el1 + .global write_ttbr0_el1 + .global read_ttbr1_el1 + .global write_ttbr1_el1 + .global read_ttbr0_el2 + .global write_ttbr0_el2 + .global read_ttbr1_el2 + .global write_ttbr1_el2 + .global read_vttbr_el2 + .global write_vttbr_el2 + .global read_rcwmask_el1 + .global write_rcwmask_el1 + .global read_rcwsmask_el1 + .global write_rcwsmask_el1 + +/* + * _mrrs - Move System register to two adjacent general-purpose + * registers. + * Instruction: MRRS , , (|S____) + * + * Arguments/Opcode bit field: + * regins: System register opcode. + * + * Clobbers: x0,x1,x2 + */ +.macro _mrrs regins:req +#if ENABLE_FEAT_D128 == 2 + mrs x0, ID_AA64MMFR3_EL1 + tst x0, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT) + bne 1f + /* If FEAT_D128 is not implemented then use mrs */ + .inst 0xD5300000 | (\regins) + ret +#endif +1: + .inst 0xD5700000 | (\regins) + ret +.endm + +/* + * _msrr - Move two adjacent general-purpose registers to System register. + * Instruction: MSRR (|S____), , + * + * Arguments/Opcode bit field: + * regins: System register opcode. + * + * Clobbers: x0,x1,x2 + */ +.macro _msrr regins:req + /* If FEAT_D128 is not implemented use msr, dont tamper + * x0, x1 as they maybe used for mrrs */ +#if ENABLE_FEAT_D128 == 2 + mrs x2, ID_AA64MMFR3_EL1 + tst x2, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT) + bne 1f + /* If FEAT_D128 is not implemented then use msr */ + .inst 0xD5100000 | (\regins) + ret +#endif +1: + .inst 0xD5500000 | (\regins) + ret +.endm + +func read_par_el1 + _mrrs 0x87400 /* S3_0_C7_C4_0 */ +endfunc read_par_el1 + +func write_par_el1 + _msrr 0x87400 +endfunc write_par_el1 + +func read_ttbr0_el1 + _mrrs 0x82000 /* S3_0_C2_C0_0 */ +endfunc read_ttbr0_el1 + +func write_ttbr0_el1 + _msrr 0x82000 +endfunc write_ttbr0_el1 + +func read_ttbr1_el1 + _mrrs 0x82020 /* S3_0_C2_C0_1 */ +endfunc read_ttbr1_el1 + +func write_ttbr1_el1 + _msrr 0x82020 +endfunc write_ttbr1_el1 + +func read_ttbr0_el2 + _mrrs 0xC2000 /* S3_4_C2_C0_0 */ +endfunc read_ttbr0_el2 + +func write_ttbr0_el2 + _msrr 0xC2000 +endfunc write_ttbr0_el2 + +func read_ttbr1_el2 + _mrrs 0xC2020 /* S3_4_C2_C0_1 */ +endfunc read_ttbr1_el2 + +func write_ttbr1_el2 + _msrr 0xC2020 +endfunc write_ttbr1_el2 + +func read_vttbr_el2 + _mrrs 0xC2100 /* S3_4_C2_C1_0 */ +endfunc read_vttbr_el2 + +func write_vttbr_el2 + _msrr 0xC2100 +endfunc write_vttbr_el2 + +func read_rcwmask_el1 + _mrrs 0x8D0C0 /* S3_0_C13_C0_6 */ +endfunc read_rcwmask_el1 + +func write_rcwmask_el1 + _msrr 0x8D0C0 +endfunc write_rcwmask_el1 + +func read_rcwsmask_el1 + _mrrs 0x8D060 /* S3_0_C13_C0_3 */ +endfunc read_rcwsmask_el1 + +func write_rcwsmask_el1 + _msrr 0x8D060 +endfunc write_rcwsmask_el1 diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c index f4195f4c7..f20726624 100644 --- a/lib/xlat_tables/aarch64/xlat_tables.c +++ b/lib/xlat_tables/aarch64/xlat_tables.c @@ -66,7 +66,7 @@ static unsigned long long calc_physical_addr_size_bits( */ static const unsigned int pa_range_bits_arr[] = { PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100, - PARANGE_0101, PARANGE_0110 + PARANGE_0101, PARANGE_0110, PARANGE_0111 }; static unsigned long long get_max_supported_pa(void) diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index 18e001b1f..7321fd721 100644 --- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c @@ -109,7 +109,7 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr) */ static const unsigned int pa_range_bits_arr[] = { PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100, - PARANGE_0101, PARANGE_0110 + PARANGE_0101, PARANGE_0110, PARANGE_0111 }; unsigned long long xlat_arch_get_max_supported_pa(void) diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk index 9533e986c..42f969b4a 100644 --- a/make_helpers/arch_features.mk +++ b/make_helpers/arch_features.mk @@ -412,6 +412,12 @@ ENABLE_SME_FOR_SWD ?= 0 # if FEAT_BRBE is implemented. ENABLE_BRBE_FOR_NS ?= 0 +#---- +# 9.3 +#---- +# Flag to enable access to Arm v9.3 FEAT_D128 extension +ENABLE_FEAT_D128 ?= 0 + #---- #9.4 #---- diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 7cb398210..6f53a81ce 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -56,6 +56,7 @@ endif ENABLE_BRBE_FOR_NS := 2 ENABLE_TRBE_FOR_NS := 2 + ENABLE_FEAT_D128 := 2 endif ENABLE_SYS_REG_TRACE_FOR_NS := 2 diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 21cc39ccf..2d4165c44 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -196,7 +198,8 @@ unsigned int plat_get_syscnt_freq2(void) */ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) { - uint64_t par, pa; + uint64_t pa; + sysreg_t par; u_register_t scr_el3; /* Doing Non-secure address translation requires SCR_EL3.NS set */ @@ -230,7 +233,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) return -1; /* Extract Physical Address from PAR */ - pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT)); + pa = get_par_el1_pa(par); /* Perform NS entry point validation on the physical address */ return arm_validate_ns_entrypoint(pa); diff --git a/services/spd/tlkd/tlkd.mk b/services/spd/tlkd/tlkd.mk index 56de0a642..fc8840d67 100644 --- a/services/spd/tlkd/tlkd.mk +++ b/services/spd/tlkd/tlkd.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,7 +8,9 @@ ifeq (${ERROR_DEPRECATED},0) SPD_INCLUDES := -Iinclude/bl32/payloads endif +ifeq (${ENABLE_FEAT_D128}, 0) SPD_SOURCES := services/spd/tlkd/tlkd_common.c \ services/spd/tlkd/tlkd_helpers.S \ services/spd/tlkd/tlkd_main.c \ services/spd/tlkd/tlkd_pm.c +endif \ No newline at end of file