blob: fffad6792d88070a55d4a121f533cb5877d45a54 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
Max Shvetsov103e0562021-02-04 16:58:31 +00002 * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <plat_topology.h>
9#include <platform.h>
10#include <power_management.h>
11#include <test_helpers.h>
12#include <tftf_lib.h>
13
J-Alvesf1126f22020-11-02 17:28:20 +000014static struct mailbox_buffers test_mb = {.send = NULL, .recv = NULL};
15
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020016int is_sys_suspend_state_ready(void)
17{
18 int aff_info;
19 unsigned int target_node;
20 u_register_t target_mpid;
21 u_register_t current_mpid = read_mpidr_el1() & MPID_MASK;
22
23 for_each_cpu(target_node) {
24 target_mpid = tftf_get_mpidr_from_node(target_node);
25
26 /* Skip current CPU, as it is powered on */
27 if (target_mpid == current_mpid)
28 continue;
29
30 aff_info = tftf_psci_affinity_info(target_mpid, MPIDR_AFFLVL0);
31 if (aff_info != PSCI_STATE_OFF)
32 return 0;
33 }
34
35 return 1;
36}
37
38void psci_system_reset(void)
39{
40 smc_args args = { SMC_PSCI_SYSTEM_RESET };
41 smc_ret_values ret;
42
43 ret = tftf_smc(&args);
44
45 /* The PSCI SYSTEM_RESET call is not supposed to return */
46 tftf_testcase_printf("System didn't reboot properly (%d)\n",
47 (unsigned int)ret.ret0);
48}
49
50int psci_mem_protect(int val)
51{
52 smc_args args = { SMC_PSCI_MEM_PROTECT};
53 smc_ret_values ret;
54
55 args.arg1 = val;
56 ret = tftf_smc(&args);
57
58 return ret.ret0;
59}
60
61int psci_mem_protect_check(uintptr_t addr, size_t size)
62{
63 smc_args args = { SMC_PSCI_MEM_PROTECT_CHECK };
64 smc_ret_values ret;
65
66 args.arg1 = addr;
67 args.arg2 = size;
68 ret = tftf_smc(&args);
69 return ret.ret0;
70}
71
72/*
73 * This function returns an address that can be used as
74 * sentinel for mem_protect functions. The logic behind
75 * it is that it has to search one region that doesn't intersect
76 * with the memory used by TFTF.
77 */
78unsigned char *psci_mem_prot_get_sentinel(void)
79{
80 const mem_region_t *ranges, *rp, *lim;
81 int nranges;
82 IMPORT_SYM(uintptr_t, __TFTF_BASE__, tftf_base);
83 IMPORT_SYM(uintptr_t, __TFTF_END__, tftf_end);
84 uintptr_t p = 0;
85
86 ranges = plat_get_prot_regions(&nranges);
87 if (!ranges)
88 return NULL;
89
90 lim = &ranges[nranges];
91 for (rp = ranges ; rp < lim; rp++) {
92 p = rp->addr;
93 if (p < tftf_base || p > tftf_end)
94 break;
95 p = p + (rp->size - 1);
96 if (p < tftf_base || p > tftf_end)
97 break;
98 }
99
100 return (rp == lim) ? NULL : (unsigned char *) p;
101}
102
103/*
104 * This function maps the memory region before the
105 * test and unmap it after the test is run
106 */
107test_result_t map_test_unmap(const map_args_unmap_t *args,
108 test_function_arg_t test)
109{
110 int mmap_ret;
111 test_result_t test_ret;
112
113 mmap_ret = mmap_add_dynamic_region(args->addr, args->addr,
114 args->size, args->attr);
115
116 if (mmap_ret != 0) {
117 tftf_testcase_printf("Couldn't map memory (ret = %d)\n",
118 mmap_ret);
119 return TEST_RESULT_FAIL;
120 }
121
122 test_ret = (*test)(args->arg);
123
124 mmap_ret = mmap_remove_dynamic_region(args->addr, args->size);
125 if (mmap_ret != 0) {
126 tftf_testcase_printf("Couldn't unmap memory (ret = %d)\n",
127 mmap_ret);
128 return TEST_RESULT_FAIL;
129 }
130
131 return test_ret;
132}
J-Alvesf1126f22020-11-02 17:28:20 +0000133
134void set_tftf_mailbox(const struct mailbox_buffers *mb)
135{
136 if (mb != NULL) {
137 test_mb = *mb;
138 }
139}
140
141bool get_tftf_mailbox(struct mailbox_buffers *mb)
142{
143 if ((test_mb.recv != NULL) && (test_mb.send != NULL)) {
144 *mb = test_mb;
145 return true;
146 }
147 return false;
148}
J-Alvesd708c032020-11-19 12:14:21 +0000149
J-Alves04469302021-01-21 14:48:13 +0000150test_result_t check_spmc_testing_set_up(
J-Alvesd708c032020-11-19 12:14:21 +0000151 uint32_t ffa_version_major, uint32_t ffa_version_minor,
152 const struct ffa_uuid *ffa_uuids, size_t ffa_uuids_size)
153{
154 struct mailbox_buffers mb;
155
156 if (ffa_uuids == NULL) {
157 ERROR("Invalid parameter ffa_uuids!\n");
158 return TEST_RESULT_FAIL;
159 }
160
161 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(ffa_version_major,
162 ffa_version_minor);
163
164 /**********************************************************************
165 * If OP-TEE is SPMC skip the current test.
166 **********************************************************************/
167 if (check_spmc_execution_level()) {
168 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
169 return TEST_RESULT_SKIPPED;
170 }
171
172 GET_TFTF_MAILBOX(mb);
173
174 for (unsigned int i = 0U; i < ffa_uuids_size; i++)
Max Shvetsov0b7d25f2021-03-05 13:46:42 +0000175 SKIP_TEST_IF_FFA_ENDPOINT_NOT_DEPLOYED(*mb, ffa_uuids[i]);
J-Alvesd708c032020-11-19 12:14:21 +0000176
177 return TEST_RESULT_SUCCESS;
178}