blob: d409274bdcf911745c1ef83da9af0f96a78cc09d [file] [log] [blame]
Manish Pandey5f513d62022-01-17 11:05:53 +00001/*
2 * Copyright (c) 2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <arch_helpers.h>
9#include <arch_features.h>
10#include <debug.h>
11#ifdef __aarch64__
12#include <sync.h>
13#endif
14#include <test_helpers.h>
15#include <tftf_lib.h>
16
17#include <platform_def.h>
18
19/*
20 * Using "__aarch64__" here looks weird but its unavoidable because of following reason
21 * This test is part of standard test which runs on all platforms but pre-requisite
22 * to run this test (custom sync exception handler) is only implemented for aarch64.
23 * TODO: Write a framework so that tests kept in standard list can be selectively
24 * run on a given architecture
25 */
26#ifdef __aarch64__
27
28#ifndef EL3_MEMORY_ACCESS_ADDR
29#define EL3_MEMORY_ACCESS_ADDR U(0xFFFFFFFF)
30#endif
31
32static volatile bool sync_exception_triggered;
33static volatile bool data_abort_triggered;
34
35static bool data_abort_handler(void)
36{
37 uint64_t esr_elx = IS_IN_EL2() ? read_esr_el2() : read_esr_el1();
38 unsigned int rme_supported = get_armv9_2_feat_rme_support();
39
40 sync_exception_triggered = true;
41
42 VERBOSE("%s esr_elx %llx\n", __func__, esr_elx);
43
44 if (EC_BITS(esr_elx) == EC_DABORT_CUR_EL) {
45 if (rme_supported == 0) {
46 /* Synchronous external data abort triggered by trustzone controller */
47 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_EXT_DABORT) {
48 VERBOSE("%s TZC Data Abort caught\n", __func__);
49 data_abort_triggered = true;
50 return true;
51 }
52 } else {
53 /* Synchronous data abort triggered by Granule protection */
54 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_GPF_DABORT) {
55 VERBOSE("%s GPF Data Abort caught\n", __func__);
56 data_abort_triggered = true;
57 return true;
58 }
59 }
60 }
61
62 return false;
63}
64
65test_result_t access_el3_memory_from_ns(void)
66{
67 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
68
69 SKIP_TEST_IF_INVALID_ADDRESS(test_address);
70
71 VERBOSE("Attempt to access el3 memory (0x%lx)\n", test_address);
72
73 data_abort_triggered = false;
74 register_custom_sync_exception_handler(data_abort_handler);
75 dsbsy();
76
77 *((volatile uint64_t *)test_address);
78
79 dsbsy();
80 unregister_custom_sync_exception_handler();
81
82 if (sync_exception_triggered == false) {
83 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
84 return TEST_RESULT_SKIPPED;
85 }
86
87 if (data_abort_triggered == false) {
88 tftf_testcase_printf("Sync exception is not data abort\n");
89 return TEST_RESULT_FAIL;
90 }
91
92 return TEST_RESULT_SUCCESS;
93}
94#else
95test_result_t access_el3_memory_from_ns(void)
96{
97 tftf_testcase_printf("Test not ported to AArch32\n");
98 return TEST_RESULT_SKIPPED;
99}
100#endif /* __aarch64__ */