feat(sme): update sme/mortlach tests
FEAT_SME is an optional architectural extension from v9.2.
Previously due to the lack of support in toolchain, testing
SME instructions were overlooked and minimal tests were added.
This patch addresses them, with additional tests to test
the SME instructions. In order to avoid toolchain requirements
we manually encode the instructions for accessing ZA array.
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
Change-Id: Ia9edd2711d548757b96495498bf9d47b9db68a09
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index 66a5f27..04b8625 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,7 @@
#include <events.h>
#include <plat_topology.h>
#include <psci.h>
+#include <sme.h>
#include <spm_common.h>
#include <tftf_lib.h>
#include <trusted_os.h>
@@ -341,6 +342,14 @@
} \
} while (false)
+#define SKIP_TEST_IF_SME_NOT_SUPPORTED() \
+ do { \
+ if(!is_feat_sme_supported()) { \
+ tftf_testcase_printf("FEAT_SME not supported\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (false)
+
/* Helper macro to verify if system suspend API is supported */
#define is_psci_sys_susp_supported() \
(tftf_get_psci_feature_info(SMC_PSCI_SYSTEM_SUSPEND) \
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index f43bc8a..2f4b0c9 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -328,8 +328,10 @@
#define MTE_IMPLEMENTED_EL0 ULL(1) /* MTE is only implemented at EL0 */
#define MTE_IMPLEMENTED_ELX ULL(2) /* MTE is implemented at all ELs */
-#define ID_AA64PFR1_EL1_SME_SHIFT U(24)
-#define ID_AA64PFR1_EL1_SME_MASK ULL(0xf)
+#define ID_AA64PFR1_EL1_SME_SHIFT U(24)
+#define ID_AA64PFR1_EL1_SME_MASK ULL(0xf)
+#define ID_AA64PFR1_EL1_SME_NOT_SUPPORTED ULL(0x0)
+#define ID_AA64PFR1_EL1_SME_SUPPORTED ULL(0x1)
/* ID_PFR1_EL1 definitions */
#define ID_PFR1_VIRTEXT_SHIFT U(12)
diff --git a/include/lib/aarch64/arch_features.h b/include/lib/aarch64/arch_features.h
index a6ce5ae..bb1d156 100644
--- a/include/lib/aarch64/arch_features.h
+++ b/include/lib/aarch64/arch_features.h
@@ -215,4 +215,21 @@
return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_HPMN0_SHIFT) &
ID_AA64DFR0_HPMN0_MASK) == ID_AA64DFR0_HPMN0_SUPPORTED);
}
+
+static inline bool is_feat_sme_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
+ return (features & ID_AA64PFR1_EL1_SME_MASK) >= ID_AA64PFR1_EL1_SME_SUPPORTED;
+}
+
+static inline bool is_feat_sme_fa64_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64smfr0_el1();
+ return (features & ID_AA64SMFR0_EL1_FA64_BIT) != 0U;
+}
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/lib/extensions/sme.h b/include/lib/extensions/sme.h
index d1a17c5..f443cea 100644
--- a/include/lib/extensions/sme.h
+++ b/include/lib/extensions/sme.h
@@ -7,16 +7,31 @@
#ifndef SME_H
#define SME_H
-#define SME_SMCR_LEN_MAX U(0x1FF)
+#define MAX_VL (512)
+#define MAX_VL_B (MAX_VL / 8)
+#define SME_SMCR_LEN_MAX U(0x1FF)
-bool feat_sme_supported(void);
-bool feat_sme_fa64_supported(void);
-int sme_enable(void);
-void sme_smstart(bool enable_za);
-void sme_smstop(bool disable_za);
+typedef enum {
+ SMSTART, /* enters streaming sve mode and enables SME ZA array */
+ SMSTART_SM, /* enters streaming sve mode only */
+ SMSTART_ZA, /* enables SME ZA array storage only */
+} smestart_instruction_type_t;
-/* Assembly function prototypes */
+typedef enum {
+ SMSTOP, /* exits streaming sve mode, & disables SME ZA array */
+ SMSTOP_SM, /* exits streaming sve mode only */
+ SMSTOP_ZA, /* disables SME ZA array storage only */
+} smestop_instruction_type_t;
+
+/* SME feature related prototypes. */
+void sme_enable(void);
+void sme_smstart(smestart_instruction_type_t smstart_type);
+void sme_smstop(smestop_instruction_type_t smstop_type);
+
+/* Assembly function prototypes. */
uint64_t sme_rdvl_1(void);
void sme_try_illegal_instruction(void);
+void sme_vector_to_ZA(const uint64_t *input_vector);
+void sme_ZA_to_vector(const uint64_t *output_vector);
#endif /* SME_H */