aboutsummaryrefslogtreecommitdiff
path: root/tftf
diff options
context:
space:
mode:
authorjohpow01 <john.powell@arm.com>2020-10-08 17:29:11 -0500
committerJohn <john.powell@arm.com>2021-03-02 21:14:59 +0100
commitb7d752a1006a6f7965023cb22b271ab161ca7e83 (patch)
tree166fdc121f32f595bf247c6e3659f789634b8719 /tftf
parentc078faa139387484a5edaa67b40e61114aac8cf1 (diff)
downloadtf-a-tests-b7d752a1006a6f7965023cb22b271ab161ca7e83.tar.gz
TFTF tests for v8.6 AMU enhancements (FEAT_AMUv1p1)
Not much can be done with the new AMU offsets running at EL2 (virtual offsets apply at EL0 and EL1) but we can make sure they are being saved and restored properly, so that's what this patch does. Signed-off-by: John Powell <john.powell@arm.com> Change-Id: I5aef85021e875be2109bb9bd7cdbdbe31580394e
Diffstat (limited to 'tftf')
-rw-r--r--tftf/tests/extensions/amu/test_amu.c82
1 files changed, 72 insertions, 10 deletions
diff --git a/tftf/tests/extensions/amu/test_amu.c b/tftf/tests/extensions/amu/test_amu.c
index 8799aa5f..8d5c92ba 100644
--- a/tftf/tests/extensions/amu/test_amu.c
+++ b/tftf/tests/extensions/amu/test_amu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -104,8 +104,9 @@ static int amu_group0_cnt_valid(unsigned int idx, uint64_t value)
{
int answer = 0;
- if ((idx <= 2) && (value == 0))
+ if ((idx <= 2) && (value == 0)) {
answer = -1;
+ }
return answer;
}
@@ -117,16 +118,18 @@ static int amu_group0_cnt_valid(unsigned int idx, uint64_t value)
*/
test_result_t test_amu_valid_ctr(void)
{
- int i;
+ unsigned int i;
- if (!amu_supported())
+ if (amu_get_version() == 0U) {
return TEST_RESULT_SKIPPED;
+ }
/* If counters are not enabled, then skip the test */
- if (read_amcntenset0_el0() != AMU_GROUP0_COUNTERS_MASK)
+ if (read_amcntenset0_el0() != AMU_GROUP0_COUNTERS_MASK) {
return TEST_RESULT_SKIPPED;
+ }
- for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++) {
+ for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
uint64_t value;
value = amu_group0_cnt_read(i);
@@ -145,19 +148,49 @@ test_result_t test_amu_valid_ctr(void)
*/
test_result_t test_amu_suspend_resume(void)
{
- uint64_t group0_ctrs[AMU_GROUP0_MAX_NR_COUNTERS];
- int i;
+ uint64_t group0_ctrs[AMU_GROUP0_NR_COUNTERS];
+ unsigned int i;
- if (!amu_supported())
+ if (amu_get_version() == 0U) {
return TEST_RESULT_SKIPPED;
+ }
/* If counters are not enabled, then skip the test */
if (read_amcntenset0_el0() != AMU_GROUP0_COUNTERS_MASK)
return TEST_RESULT_SKIPPED;
/* Save counters values before suspend */
- for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++)
+ for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
group0_ctrs[i] = amu_group0_cnt_read(i);
+ }
+
+ /*
+ * If FEAT_AMUv1p1 supported then make sure the save/restore works for
+ * virtual counter values. Write known values into the virtual offsets
+ * and then make sure they are still there after resume. The virtual
+ * offset registers are only accessible in AARCH64 mode in EL2 or EL3.
+ */
+#if __aarch64__
+ if (amu_get_version() >= ID_AA64PFR0_AMU_V1P1) {
+ /* Enabling voffsets in HCR_EL2. */
+ write_hcr_el2(read_hcr_el2() | HCR_AMVOFFEN_BIT);
+
+ /* Writing known values into voffset registers. */
+ amu_group0_voffset_write(0U, 0xDEADBEEF);
+ amu_group0_voffset_write(2U, 0xDEADBEEF);
+ amu_group0_voffset_write(3U, 0xDEADBEEF);
+
+#if AMU_GROUP1_NR_COUNTERS
+ u_register_t amcg1idr = read_amcg1idr_el0() >> 16;
+
+ for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) {
+ if (((amcg1idr >> i) & 1U) != 0U) {
+ amu_group1_voffset_write(i, 0xDEADBEEF);
+ }
+ }
+#endif
+ }
+#endif
/* Suspend/resume current core */
suspend_and_resume_this_cpu();
@@ -178,5 +211,34 @@ test_result_t test_amu_suspend_resume(void)
}
}
+#if __aarch64__
+ if (amu_get_version() >= ID_AA64PFR0_AMU_V1P1) {
+ for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
+ if ((i != 1U) &&
+ (amu_group0_voffset_read(i) != 0xDEADBEEF)) {
+ tftf_testcase_printf(
+ "Invalid G0 voffset %u: 0x%llx\n", i,
+ amu_group0_voffset_read(i));
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+#if AMU_GROUP1_NR_COUNTERS
+ u_register_t amcg1idr = read_amcg1idr_el0() >> 16;
+
+ for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) {
+ if (((amcg1idr >> i) & 1U) != 0U) {
+ if (amu_group1_voffset_read(i) != 0xDEADBEEF) {
+ tftf_testcase_printf("Invalid G1 " \
+ "voffset %u: 0x%llx\n", i,
+ amu_group1_voffset_read(i));
+ return TEST_RESULT_FAIL;
+ }
+ }
+ }
+#endif
+ }
+#endif
+
return TEST_RESULT_SUCCESS;
}