blob: 67122f257811744bb39428671f421504aca26e0f [file] [log] [blame]
Jayanth Dodderi Chidanand95d5d272023-01-16 17:58:47 +00001/*
2 * Copyright (c) 2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdio.h>
8#include <stdlib.h>
9
10#include <arch_features.h>
11#include <arch_helpers.h>
12#include <lib/extensions/sme.h>
13#include <test_helpers.h>
14#include <tftf_lib.h>
15
16#ifdef __aarch64__
17
18#define SME2_ARRAYSIZE (512/64)
19#define SME2_INPUT_DATA (0x1fffffffffffffff)
20
21/* Global buffers */
22static uint64_t sme2_input_buffer[SME2_ARRAYSIZE] = {0};
23static uint64_t sme2_output_buffer[SME2_ARRAYSIZE] = {0};
24
25/*
26 * clear_ZT0: ZERO all bytes of the ZT0 register.
27 *
28 */
29static void clear_ZT0(void)
30{
31 /**
32 * Due to the lack of support from the toolchain, instruction
33 * opcodes are used here.
34 * TODO: Further, once the toolchain adds support for SME features
35 * this could be replaced with the instruction ZERO {ZT0}.
36 */
37 asm volatile(".inst 0xc0480001" : : : );
38}
39
40#endif /* __aarch64__ */
41
42/*
43 * test_sme2_support: Test SME2 support when the extension is enabled.
44 *
45 * Execute some SME2 instructions. These should not be trapped to EL3,
46 * as TF-A is responsible for enabling SME2 for Non-secure world.
47 *
48 */
49test_result_t test_sme2_support(void)
50{
51 /* SME2 is an AArch64-only feature.*/
52 SKIP_TEST_IF_AARCH32();
53
54#ifdef __aarch64__
55 /* Skip the test if SME2 is not supported. */
56 SKIP_TEST_IF_SME2_NOT_SUPPORTED();
57
58 /* Enable SME2 for use at NS EL2. */
59 sme2_enable();
60
61 /*
62 * FEAT_SME2 adds a 512 BIT architectural register ZT0 to support
63 * the lookup-table feature.
64 * System register SMCR_ELx defines a bit SMCR_ELx.EZT0 bit [30] to
65 * enable/disable access to this register.
66 *
67 * Instructions to access ZT0 register are being tested to ensure
68 * SMCR_ELx.EZT0 bit is set at( EL-3 as well as EL-2), so that
69 * they are not trapped.
70 */
71
72 /* Make sure we can acesss SME2 ZT0 storage, PSTATE.ZA = 1*/
73 VERBOSE("Enabling SME ZA storage and ZT0 storage.\n");
74
75 sme_smstart(SMSTART_ZA);
76
77 /*
78 * LDR (ZT0) : Load ZT0 register.
79 * Load the 64-byte ZT0 register from the memory address
80 * provided in the 64-bit scalar base register.
81 */
82 for (int i = 0; i < SME2_ARRAYSIZE; i++) {
83 sme2_input_buffer[i] = SME2_INPUT_DATA;
84 }
85 sme2_load_zt0_instruction(sme2_input_buffer);
86
87 /*
88 * STR (ZT0) : Store ZT0 register.
89 * Store the 64-byte ZT0 register to the memory address
90 * provided in the 64-bit scalar base register
91 */
92
93 sme2_store_zt0_instruction(sme2_output_buffer);
94
95 /**
96 * compare the input and output buffer to verify the operations of
97 * LDR and STR instructions with ZT0 register.
98 */
99 for (int i = 0; i < SME2_ARRAYSIZE; i++) {
100 if (sme2_input_buffer[i] != sme2_output_buffer[i]) {
101 return TEST_RESULT_FAIL;
102 }
103 }
104
105 /* ZER0 (ZT0) */
106 clear_ZT0();
107
108 /* Finally disable the acesss to SME2 ZT0 storage, PSTATE.ZA = 0*/
109 VERBOSE("Disabling SME ZA storage and ZT0 storage.\n");
110
111 sme_smstop(SMSTOP_ZA);
112
113 return TEST_RESULT_SUCCESS;
114#endif /* __aarch64__ */
115}