2 * Copyright (c) 2016, Linaro Limited
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
28 #include <kernel/interrupt.h>
29 #include <kernel/misc.h>
30 #include <kernel/pseudo_ta.h>
31 #include <kernel/tee_time.h>
32 #include <kernel/thread.h>
33 #include <platform_config.h>
35 #include <tee/tee_cryp_provider.h>
38 #define TA_NAME "interrupt_tests.ta"
40 #define INTERRUPT_TESTS_UUID \
41 { 0x48d58475, 0x3d5e, 0x4202, \
42 { 0xa7, 0x75, 0x97, 0x85, 0xd2, 0x0f, 0x78, 0xae } }
44 #define CMD_INTERRUPT_TESTS 0
50 #define TEST_SGI_ID 11
53 #define TEST_PPI_ID 29
56 #define TEST_SPI_ID 61
63 * Trusted Application Entry Points
66 static size_t test_sgi_value[CFG_TEE_CORE_NB_CORE];
67 static size_t test_spi_value[CFG_TEE_CORE_NB_CORE];
68 static size_t test_ppi_value[CFG_TEE_CORE_NB_CORE];
69 static size_t expect_sgi_value[CFG_TEE_CORE_NB_CORE];
70 static size_t expect_spi_value[CFG_TEE_CORE_NB_CORE];
71 static size_t expect_ppi_value[CFG_TEE_CORE_NB_CORE];
73 static enum itr_return __maybe_unused ihandler_ok(struct itr_handler *handler)
75 size_t core_num = get_core_pos();
77 assert(core_num < CFG_TEE_CORE_NB_CORE);
79 if (handler->it < SGI_NUM)
80 test_sgi_value[core_num]++;
81 else if (handler->it < PPI_NUM)
82 test_ppi_value[core_num]++;
84 test_spi_value[core_num]++;
88 KEEP_PAGER(ihandler_ok);
90 struct itr_handler sgi_handler = {
92 .handler = ihandler_ok,
95 struct itr_handler spi_handler = {
97 .handler = ihandler_ok,
100 struct itr_handler ppi_handler = {
102 .handler = ihandler_ok,
105 static TEE_Result test_sgi(void)
113 itr_add(&sgi_handler);
114 itr_enable(TEST_SGI_ID);
116 for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++)
117 expect_sgi_value[i]++;
118 itr_raise_sgi(TEST_SGI_ID,
119 (uint8_t)(SHIFT_U32(1, CFG_TEE_CORE_NB_CORE) - 1));
121 if (memcmp(test_sgi_value, expect_sgi_value, sizeof(test_sgi_value)))
122 return TEE_ERROR_GENERIC;
124 for (i = 0; i < TEST_TIMES; i++) {
125 res = crypto_ops.prng.read(&num, 1);
126 if (res != TEE_SUCCESS)
127 return TEE_ERROR_GENERIC;
128 num = num % CFG_TEE_CORE_NB_CORE;
130 for (j = 0; j < num; j++) {
131 expect_sgi_value[j]++;
132 cpu_mask |= (0x1 << j);
134 itr_raise_sgi(TEST_SGI_ID, cpu_mask);
136 if (memcmp(test_sgi_value, expect_sgi_value,
137 sizeof(test_sgi_value)))
138 return TEE_ERROR_GENERIC;
144 static TEE_Result test_spi(void)
150 itr_add(&spi_handler);
151 itr_enable(TEST_SPI_ID);
153 for (i = 0; i < TEST_TIMES; i++) {
154 res = crypto_ops.prng.read(&num, 1);
155 if (res != TEE_SUCCESS)
156 return TEE_ERROR_GENERIC;
157 num = num % CFG_TEE_CORE_NB_CORE;
158 expect_spi_value[num]++;
159 itr_set_affinity(TEST_SPI_ID, 0x1 << num);
160 itr_raise_pi(TEST_SPI_ID);
162 if (memcmp(test_spi_value, expect_spi_value,
163 sizeof(test_spi_value)))
164 return TEE_ERROR_GENERIC;
170 static TEE_Result test_ppi(void)
174 itr_add(&ppi_handler);
175 itr_enable(TEST_PPI_ID);
177 exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
178 expect_ppi_value[get_core_pos()]++;
179 itr_raise_pi(TEST_PPI_ID);
180 thread_unmask_exceptions(exceptions);
182 if (memcmp(test_ppi_value, expect_ppi_value, sizeof(test_ppi_value)))
183 return TEE_ERROR_GENERIC;
188 static TEE_Result interrupt_tests(uint32_t nParamTypes __unused,
189 TEE_Param pParams[TEE_NUM_PARAMS]__unused)
193 assert(crypto_ops.prng.read);
196 if (res != TEE_SUCCESS)
200 if (res != TEE_SUCCESS)
204 if (res != TEE_SUCCESS)
210 static TEE_Result invoke_command(void *psess __unused,
211 uint32_t cmd, uint32_t ptypes,
218 case CMD_INTERRUPT_TESTS:
219 res = interrupt_tests(ptypes, params);
220 DMSG("test value: sgi spi ppi");
221 for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++)
222 DMSG("------------[%zu] [%zu] [%zu]",
223 test_sgi_value[i], test_spi_value[i],
225 DMSG("expc value: sgi spi ppi");
226 for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++)
227 DMSG("------------[%zu] [%zu] [%zu]",
228 expect_sgi_value[i], expect_spi_value[i],
229 expect_ppi_value[i]);
234 return TEE_ERROR_BAD_PARAMETERS;
237 pseudo_ta_register(.uuid = INTERRUPT_TESTS_UUID, .name = TA_NAME,
238 .flags = PTA_DEFAULT_FLAGS,
239 .invoke_command_entry_point = invoke_command);