feat(cpufeat): add support for FEAT_PAUTH_LR
This patch enables FEAT_PAUTH_LR at EL3 on systems that support it when
the new ENABLE_FEAT_PAUTH_LR flag is set.
Currently, PAUTH_LR is only supported by arm clang compiler and not GCC.
Change-Id: I7db1e34b661ed95cad75850b62878ac5d98466ea
Signed-off-by: John Powell <john.powell@arm.com>
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 3707520..83e5867 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -606,6 +606,11 @@
#define SCTLR_EPAN_BIT (ULL(1) << 57)
#define SCTLR_RESET_VAL SCTLR_EL3_RES1
+#define SCTLR2_EnPACM_BIT (ULL(1) << 7)
+
+/* SCTLR2 currently has no RES1 fields so reset to 0 */
+#define SCTLR2_RESET_VAL ULL(0)
+
/* CPACR_EL1 definitions */
#define CPACR_EL1_FPEN(x) ((x) << 20)
#define CPACR_EL1_FP_TRAP_EL0 UL(0x1)
@@ -855,6 +860,7 @@
#define SPSR_PPEND_BIT BIT(33)
#define SPSR_EXLOCK_BIT_AARCH64 BIT_64(34)
#define SPSR_NZCV (SPSR_V_BIT | SPSR_C_BIT | SPSR_Z_BIT | SPSR_N_BIT)
+#define SPSR_PACM_BIT_AARCH64 BIT_64(35)
#define DISABLE_ALL_EXCEPTIONS \
(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
@@ -1531,6 +1537,7 @@
/*******************************************************************************
* FEAT_SCTLR2 - Extension to SCTLR_ELx Registers
******************************************************************************/
+#define SCTLR2_EL3 S3_6_C1_C0_3
#define SCTLR2_EL2 S3_4_C1_C0_3
#define SCTLR2_EL1 S3_0_C1_C0_3
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index e3068d1..757ce06 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -146,6 +146,8 @@
* +----------------------------+
* | FEAT_MOPS |
* +----------------------------+
+ * | FEAT_PAUTH_LR |
+ * +----------------------------+
*/
__attribute__((always_inline))
@@ -196,6 +198,35 @@
CREATE_FEATURE_SUPPORTED(feat_pauth, is_feat_pauth_present, ENABLE_PAUTH)
CREATE_FEATURE_SUPPORTED(ctx_pauth, is_feat_pauth_present, CTX_INCLUDE_PAUTH_REGS)
+/*
+ * FEAT_PAUTH_LR
+ * This feature has a non-standard discovery method so define this function
+ * manually then call use the CREATE_FEATURE_SUPPORTED macro with it. This
+ * feature is enabled with ENABLE_PAUTH when present.
+ */
+__attribute__((always_inline))
+static inline bool is_feat_pauth_lr_present(void)
+{
+ /*
+ * FEAT_PAUTH_LR support is indicated by up to 3 fields, if one or more
+ * of these is 0b0110 then the feature is present.
+ * 1) id_aa64isr1_el1.api
+ * 2) id_aa64isr1_el1.apa
+ * 3) id_aa64isr2_el1.apa3
+ */
+ if (ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_API_SHIFT, ID_AA64ISAR1_API_MASK) == 0b0110) {
+ return true;
+ }
+ if (ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_APA_SHIFT, ID_AA64ISAR1_APA_MASK) == 0b0110) {
+ return true;
+ }
+ if (ISOLATE_FIELD(read_id_aa64isar2_el1(), ID_AA64ISAR2_APA3_SHIFT, ID_AA64ISAR2_APA3_MASK) == 0b0110) {
+ return true;
+ }
+ return false;
+}
+CREATE_FEATURE_SUPPORTED(feat_pauth_lr, is_feat_pauth_lr_present, ENABLE_FEAT_PAUTH_LR)
+
/* FEAT_TTST: Small translation tables */
CREATE_FEATURE_PRESENT(feat_ttst, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_ST_SHIFT,
ID_AA64MMFR2_EL1_ST_MASK, 1U)
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 9419583..50a5832 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -733,6 +733,7 @@
/* FEAT_SCTLR2 Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el3, SCTLR2_EL3)
/* FEAT_LS64_ACCDATA Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(accdata_el1, ACCDATA_EL1)
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index da51bf8..078c414 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -351,6 +351,11 @@
tst \reg, \clobber
.endm
+ .macro is_feat_sctlr2_present_asm reg:req
+ mrs \reg, ID_AA64MMFR3_EL1
+ ands \reg, \reg, #(ID_AA64MMFR3_EL1_SCTLR2_MASK << ID_AA64MMFR3_EL1_SCTLR2_SHIFT)
+ .endm
+
.macro call_reset_handler
#if !(defined(IMAGE_BL2) && ENABLE_RME)
/* ---------------------------------------------------------------------
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 07dffb1..fce0f2c 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -45,6 +45,16 @@
msr sctlr_el3, x0
isb
+#if ENABLE_FEAT_SCTLR2
+#if ENABLE_FEAT_SCTLR2 > 1
+ is_feat_sctlr2_present_asm x1
+ beq feat_sctlr2_not_supported\@
+#endif
+ mov x1, #SCTLR2_RESET_VAL
+ msr SCTLR2_EL3, x1
+feat_sctlr2_not_supported\@:
+#endif
+
#ifdef IMAGE_BL31
/* ---------------------------------------------------------------------
* Initialise the per-cpu cache pointer to the CPU.