Merge "feat(d128): add support for FEAT_D128" into integration
diff --git a/Makefile b/Makefile
index 4f3f261..f736a3b 100644
--- a/Makefile
+++ b/Makefile
@@ -646,6 +646,13 @@
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 @@
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 @@
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 e63eec4..6aa5e2e 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -269,6 +269,12 @@
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 @@
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 7776f5b..772447a 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -471,6 +471,15 @@
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 d32ead4..d2591dd 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 abe34a4..a29b672 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -194,5 +194,7 @@
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 6a19822..3f0120c 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 de21fea..ec38d76 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -138,6 +138,8 @@
* +----------------------------+
* | FEAT_SCTLR2 |
* +----------------------------+
+ * | FEAT_D128 |
+ * +----------------------------+
*/
__attribute__((always_inline))
@@ -275,6 +277,11 @@
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 acaa1b8..9c36e4b 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -13,6 +13,7 @@
#include <string.h>
#include <arch.h>
+#include <lib/extensions/sysreg128.h>
/**********************************************************************
* Macros which create inline functions to read or write CPU system
@@ -263,7 +264,12 @@
#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_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 @@
/* 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_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 0000000..c8d67a3
--- /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<arch_features.h>
+#include<lib/extensions/sysreg128.h>
+
+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 94af210..4379bcf 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 <lib/extensions/sysreg128.h>
+
#ifndef __ASSEMBLER__
/*******************************************************************************
@@ -28,15 +30,12 @@
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 @@
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 @@
} 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 ad0b68f..7374e39 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 <lib/extensions/sysreg128.h>
+
#ifndef __ASSEMBLER__
+
/*******************************************************************************
* EL2 Registers:
* AArch64 EL2 system register context structure for preserving the
@@ -40,12 +43,12 @@
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_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 @@
#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 @@
#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 0000000..8854856
--- /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 <stdint.h>
+
+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 003cb25..d2222fa 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -33,6 +33,7 @@
#include <lib/extensions/sme.h>
#include <lib/extensions/spe.h>
#include <lib/extensions/sve.h>
+#include <lib/extensions/sysreg128.h>
#include <lib/extensions/sys_reg_trace.h>
#include <lib/extensions/tcr2.h>
#include <lib/extensions/trbe.h>
@@ -275,6 +276,14 @@
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 @@
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 @@
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 0000000..08cff2f
--- /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 <arch.h>
+#include <asm_macros.S>
+#include <lib/extensions/sysreg128.h>
+
+ .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 <Xt>, <Xt+1>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)
+ *
+ * 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 (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>, <Xt+1>
+ *
+ * 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 f4195f4..f207266 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -66,7 +66,7 @@
*/
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 18e001b..7321fd7 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 @@
*/
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 6c893f4..39f6223 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -406,6 +406,12 @@
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 7cb3982..6f53a81 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -56,6 +56,7 @@
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 21cc39c..2d4165c 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -12,6 +12,8 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/romlib.h>
+#include <common/par.h>
+#include <lib/extensions/sysreg128.h>
#include <lib/mmio.h>
#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
@@ -196,7 +198,8 @@
*/
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 @@
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 56de0a6..fc8840d 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 @@
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