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 <jayanthdodderi.chidanand@arm.com>
Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
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 */