fix(sea_inject): setup missing bits on PSTATE for abort injection
Bits TCO, DIT, UAO, PAN, SSBS and BTYPE are missing from PSTATE
when injecting an abort to R-EL1.
Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I027ef4cb5899bcb7e76072129ea98f15a5696e8f
diff --git a/lib/arch/include/arch.h b/lib/arch/include/arch.h
index 37c2ff9..aed5db8 100644
--- a/lib/arch/include/arch.h
+++ b/lib/arch/include/arch.h
@@ -495,8 +495,18 @@
#define ID_AA64PFR0_EL1_AMU_WIDTH UL(4)
/* ID_AA64PFR1_EL1 definitions */
-#define ID_AA64PFR1_EL1_MTE_SHIFT UL(8)
-#define ID_AA64PFR1_EL1_MTE_WIDTH UL(4)
+#define ID_AA64PFR1_EL1_SSBS_SHIFT UL(4)
+#define ID_AA64PFR1_EL1_SSBS_WIDTH UL(4)
+#define ID_AA64PFR1_EL1_SSBS_NOT_IMPLEMENTED UL(0)
+#define ID_AA64PFR1_EL1_FEAT_SSBS UL(1)
+#define ID_AA64PFR1_EL1_FEAT_SSBS2 UL(2)
+
+#define ID_AA64PFR1_EL1_MTE_SHIFT UL(8)
+#define ID_AA64PFR1_EL1_MTE_WIDTH UL(4)
+#define ID_AA64PFR1_EL1_MTE_NOT_IMPLEMENTED UL(0)
+#define ID_AA64PFR1_EL1_MTE1 UL(1)
+#define ID_AA64PFR1_EL1_MTE2 UL(2)
+#define ID_AA64PFR1_EL1_MTE3 UL(3)
#define ID_AA64PFR1_EL1_SME_SHIFT UL(24)
#define ID_AA64PFR1_EL1_SME_WIDTH UL(4)
@@ -504,6 +514,12 @@
#define ID_AA64PFR1_EL1_SME_IMPLEMENTED UL(1)
#define ID_AA64PFR1_EL1_SME2_IMPLEMENTED UL(2)
+#define ID_AA64PFR1_EL1_NMI_SHIFT UL(36)
+#define ID_AA64PFR1_EL1_NMI_WIDTH UL(4)
+
+#define ID_AA64PFR1_EL1_GCS_SHIFT UL(44)
+#define ID_AA64PFR1_EL1_GCS_WIDTH UL(4)
+
#define ID_AA64PFR1_EL1_DF2_SHIFT UL(56)
#define ID_AA64PFR1_EL1_DF2_WIDTH UL(4)
@@ -603,8 +619,15 @@
#define SPSR_EL2_nRW_AARCH32 INPLACE(SPSR_EL2_nRW, UL(1))
#define SPSR_EL2_DAIF_SHIFT 6
+#define SPSR_EL2_DAIF_WIDTH U(4)
#define SPSR_EL2_AIF_SHIFT U(6)
+#define SPSR_EL2_BTYPE_SHIFT U(10)
+#define SPSR_EL2_BTYPE_WIDTH U(2)
+
+#define SPSR_EL2_NZCV_BITS_SHIFT U(28)
+#define SPSR_EL2_NZCV_BITS_WIDTH U(4)
+
#define DAIF_FIQ_BIT (UL(1) << 0)
#define DAIF_IRQ_BIT (UL(1) << 1)
#define DAIF_ABT_BIT (UL(1) << 2)
@@ -628,6 +651,7 @@
#define SPSR_EL2_N_BIT (UL(1) << 31)
#define SPSR_EL2_PM_BIT (UL(1) << 32)
#define SPSR_EL2_PPEND_BIT (UL(1) << 33)
+#define SPSR_EL2_EXLOCK_BIT (UL(1) << 34)
/* Floating point control and status register */
#define FPCR S3_3_C4_C4_0
@@ -771,6 +795,8 @@
#define SCTLR_ELx_EnIA_BIT (UL(1) << 31)
#define SCTLR_ELx_BT0_BIT (UL(1) << 35)
#define SCTLR_ELx_BT1_BIT (UL(1) << 36)
+#define SCTLR_ELx_DSSBS_BIT (UL(1) << 44)
+#define SCTLR_ELx_SPINTMASK_BIT (UL(1) << 62)
#define SCTLR_EL1_FLAGS (SCTLR_ELx_SPAN_BIT | SCTLR_ELx_EIS_BIT | SCTLR_ELx_nTWE_BIT | \
SCTLR_ELx_nTWI_BIT | SCTLR_ELx_EOS_BIT | SCTLR_ELx_nAA_BIT | \
@@ -1128,4 +1154,11 @@
#define MODE_SP_EL0 UL(0)
#define MODE_SP_ELX UL(1)
+/*******************************************************************************
+ * FEAT_GCS - Guarded Control Stack Registers
+ ******************************************************************************/
+#define ID_GCSCR_EL12 S3_5_C2_C5_0
+#define GCSCR_EXLOCK_EN_BIT (UL(1) << 6)
+
+
#endif /* ARCH_H */
diff --git a/lib/arch/include/arch_features.h b/lib/arch/include/arch_features.h
index 25d8433..4ad34b1 100644
--- a/lib/arch/include/arch_features.h
+++ b/lib/arch/include/arch_features.h
@@ -169,9 +169,83 @@
read_id_aa64mmfr3_el1()) == 1UL);
}
-DEFINE_CONDITIONAL_SYSREG_RW_FUNCS(sctlr2_el12, if_present, \
- is_feat_sctlr2x_present, 0UL)
+/*
+ * Check if FEAT_MTE2 is implemented.
+ * ID_AA64PFR1_EL1.MTE, bits [11:8]:
+ * 0b0000 FEAT_MTE is not implemented.
+ * 0b0001 FEAT_MTE is implemented.
+ * 0b0010 FEAT_MTE2 is implemented.
+ * 0b0011 FEAT_MTE3 is implemented.
+ */
+static inline bool is_feat_mte2_present(void)
+{
+ unsigned long mte = EXTRACT(ID_AA64PFR1_EL1_MTE, read_id_aa64pfr1_el1());
+
+ return ((mte >= ID_AA64PFR1_EL1_MTE2) && (mte <= ID_AA64PFR1_EL1_MTE3));
+}
+
+/*
+ * Check if FEAT_SSBS is implemented.
+ * ID_AA64PFR1_EL1, bits [7:4]:
+ * 0b0000: FEAT_SSBS is not implemented.
+ * 0b0001: FEAT_SSBS is implemented.
+ * 0b0010: FEAT_SSBS2 is implemented.
+ */
+static inline bool is_feat_ssbs_present(void)
+{
+ unsigned long ssbs = EXTRACT(ID_AA64PFR1_EL1_SSBS, read_id_aa64pfr1_el1());
+
+ return ((ssbs >= ID_AA64PFR1_EL1_FEAT_SSBS) &&
+ (ssbs <= ID_AA64PFR1_EL1_FEAT_SSBS2));
+}
+
+/*
+ * Check if FEAT_NMI is implemented.
+ * ID_AA64PFR1_EL1, bits [39:36]:
+ * 0b0000: FEAT_NMI is not implemented.
+ * 0b0001: FEAT_NMI is implemented.
+ */
+static inline bool is_feat_nmi_present(void)
+{
+ return (EXTRACT(ID_AA64PFR1_EL1_NMI, read_id_aa64pfr1_el1()) == 1UL);
+}
+
+/*
+ * Check if FEAT_EBEP is implemented.
+ * ID_AA64DFR1_EL1, bits [51:48]:
+ * 0b0000: FEAT_EBEP is not implemented.
+ * 0b0001: FEAT_EBEP is implemented.
+ */
+static inline bool is_feat_ebep_present(void)
+{
+ return (EXTRACT(ID_AA64DFR1_EL1_EBEP, read_id_aa64dfr1_el1()) == 1UL);
+}
+
+/*
+ * Check if FEAT_SEBEP is implemented.
+ * ID_AA64DFR0_EL1, bits [27:24]:
+ * 0b0000: FEAT_SEBEP is not implemented.
+ * 0b0001: FEAT_SEBEP is implemented.
+ */
+static inline bool is_feat_sebep_present(void)
+{
+ return (EXTRACT(ID_AA64DFR0_EL1_SEBEP, read_id_aa64dfr0_el1()) == 1UL);
+}
+
+/*
+ * Check if FEAT_GCS is implemented.
+ * ID_AA64PFR1_EL1, bits [47:44}:
+ * 0b0000: FEAT_GCS is not implemented.
+ * 0b0001: FEAT_GCS is implemented.
+ */
+static inline bool is_feat_gcs_present(void)
+{
+ return (EXTRACT(ID_AA64PFR1_EL1_GCS, read_id_aa64pfr1_el1()) == 1UL);
+}
unsigned int arch_feat_get_pa_width(void);
+DEFINE_CONDITIONAL_SYSREG_RW_FUNCS(sctlr2_el12, if_present, \
+ is_feat_sctlr2x_present, 0UL)
+
#endif /* ARCH_FEATURES_H */
diff --git a/lib/arch/include/arch_helpers.h b/lib/arch/include/arch_helpers.h
index b3ffdf4..9c49b61 100644
--- a/lib/arch/include/arch_helpers.h
+++ b/lib/arch/include/arch_helpers.h
@@ -428,6 +428,7 @@
DEFINE_RENAME_SYSREG_RW_FUNCS(dit, DIT)
+DEFINE_RENAME_SYSREG_READ_FUNC(gcscr_el12, ID_GCSCR_EL12)
/*******************************************************************************
* Timer register accessor prototypes
******************************************************************************/