17 #include "tfm_plat_test.h"
24 static int32_t partition_init_done;
26 #define INVALID_NS_CLIENT_ID 0x49abcdef
27 #define EXPECTED_NS_CLIENT_ID (-1)
29 #define IRQ_TEST_TOOL_CODE_LOCATION(name)
35 static int32_t caller_client_id_zi;
42 static int32_t* invalid_addresses [] = {(int32_t*)0x0, (int32_t*)0xFFF12000};
46 static psa_status_t psa_test_common(uint32_t sid, uint32_t version,
72 if ((in_len != 0) || (out_len != 0)) {
76 if (partition_init_done) {
89 struct psa_invec new_vec = {NULL,
sizeof(uint32_t)};
91 if ((in_len != 1) || (out_len != 0) ||
92 (in_vec[0].
len !=
sizeof(uint32_t))) {
96 depth = *((uint32_t *)in_vec[0].
base);
104 new_vec.
base = &depth;
105 int32_t ret = tfm_spm_core_test_sfn_direct_recursion_veneer(&new_vec,
122 #ifdef TFM_ENABLE_PERIPH_ACCESS_TEST
125 uint32_t userled_mask;
127 leds = tfm_plat_test_get_led_status();
128 tfm_plat_test_set_led_status(~leds);
129 invleds = tfm_plat_test_get_led_status();
130 userled_mask = tfm_plat_test_get_userled_mask();
132 if ((invleds & userled_mask) != (~leds & userled_mask)) {
143 #define SS_BUFFER_LEN 16
145 static psa_status_t test_ss_to_ss_buffer(uint32_t *in_ptr, uint32_t *out_ptr,
151 uint32_t slave_buffer [
len];
153 int32_t *result_ptr = &result;
155 psa_invec in_vec[] = { {slave_buffer, len*
sizeof(uint32_t)} };
156 psa_outvec outvec[] = { {slave_buffer, len*
sizeof(uint32_t)},
157 {result_ptr,
sizeof(int32_t)} };
163 for (i = 0; i <
len; i++) {
164 ss_buffer[i] = in_ptr[i];
167 for (i = 0; i <
len; i++) {
168 slave_buffer[i] = ss_buffer[i];
176 in_vec, 1, outvec, 2);
178 res = tfm_spm_core_test_2_sfn_invert_veneer(in_vec, 1, outvec, 2);
185 for (i = 0; i <
len; i++) {
186 if (slave_buffer[i] != ~ss_buffer[i]) {
189 ss_buffer[i] = slave_buffer[i];
192 for (i = 0; i <
len; i++) {
193 out_ptr[i] = ss_buffer[i];
203 uint8_t data_buf [36];
204 uint8_t *data_buf_ptr = data_buf;
212 in_buf_0 = data_buf_ptr;
213 for (i = 0; i < 5; ++i, ++data_buf_ptr)
217 in_vec[0].
base = in_buf_0;
218 in_vec[0].
len = data_buf_ptr - in_buf_0;
220 in_buf_1 = data_buf_ptr;
221 *(data_buf_ptr++) = 1;
222 *(data_buf_ptr++) = 1;
223 for (i = 2; i < 11; ++i, ++data_buf_ptr)
225 *data_buf_ptr = *(data_buf_ptr-1) + *(data_buf_ptr-2);
227 in_vec[1].
base = in_buf_1;
228 in_vec[1].
len = data_buf_ptr - in_buf_1;
230 out_buf_0 = data_buf_ptr;
231 data_buf_ptr += in_vec[0].
len;
232 out_vec[0].
base = out_buf_0;
233 out_vec[0].
len = data_buf_ptr - out_buf_0;
235 out_buf_1 = data_buf_ptr;
236 data_buf_ptr += in_vec[1].
len;
237 out_vec[1].
base = out_buf_1;
238 out_vec[1].
len = data_buf_ptr - out_buf_1;
243 in_vec, 2, out_vec, 2);
245 err = tfm_spm_core_test_2_get_every_second_byte_veneer(in_vec, 2,
253 if (out_vec[0].len != in_vec[0].len/2 ||
254 out_vec[1].len != in_vec[1].len/2) {
257 for (i = 1; i <
sizeof(in_buf_0); i += 2) {
258 if (((uint8_t *)out_vec[0].
base)[i/2] != in_buf_0[i]) {
262 for (i = 1; i <
sizeof(in_buf_1); i += 2) {
263 if (((uint8_t *)out_vec[1].
base)[i/2] != in_buf_1[i]) {
281 ret = tfm_spm_core_test_2_slave_service_veneer(NULL, 0, NULL, 0);
301 ret = tfm_spm_core_test_2_check_caller_client_id_veneer(NULL, 0, NULL, 0);
307 for (i = 0; i <
sizeof(invalid_addresses)/
sizeof(invalid_addresses[0]); ++i)
348 #ifdef CORE_TEST_INTERACTIVE
349 static void wait_button_event(
void)
351 tfm_plat_test_wait_user_button_pressed();
358 tfm_plat_test_wait_user_button_released();
363 TEST_LOG(
"Inside the service, press button to continue...");
372 #ifdef CORE_TEST_INTERACTIVE
374 return test_wait_button();
390 if ((in_len < 1) || (in_vec[0].len !=
sizeof(uint32_t))) {
393 tc = *((uint32_t *)in_vec[0].
base);
397 return test_ss_to_ss();
399 if ((in_len != 3) || (out_len != 1) ||
400 (in_vec[2].len !=
sizeof(int32_t))) {
403 arg3 = *((int32_t *)in_vec[2].base);
404 if ((in_vec[1].len < arg3*
sizeof(int32_t)) ||
405 (out_vec[0].len < arg3*
sizeof(int32_t))) {
408 arg1 = (int32_t)in_vec[1].base;
409 arg2 = (int32_t)out_vec[0].base;
410 return test_ss_to_ss_buffer((uint32_t *)arg1, (uint32_t *)arg2, arg3);
412 return test_outvec_write();
414 return test_peripheral_access();
416 return test_get_caller_client_id();
418 return test_spm_request();
431 #define SS_TO_SS_BUFFER_SIZE (16*4)
447 return test_ss_to_ss();
453 uint32_t inbuf[SS_TO_SS_BUFFER_SIZE/
sizeof(uint32_t)] = {0};
454 uint32_t outbuf[SS_TO_SS_BUFFER_SIZE/
sizeof(uint32_t)] = {0};
458 if ((msg->
in_size[0] > SS_TO_SS_BUFFER_SIZE) ||
459 (msg->
in_size[1] !=
sizeof(int32_t)) ||
460 (msg->
out_size[0] > SS_TO_SS_BUFFER_SIZE)) {
470 if (num !=
sizeof(int32_t)) {
474 if (len > SS_TO_SS_BUFFER_SIZE) {
478 res = test_ss_to_ss_buffer(inbuf, outbuf, len);
490 return test_outvec_write();
495 return test_peripheral_access();
518 static void core_test_signal_handle(
psa_signal_t signal, core_test_func_t pfn)
523 status =
psa_get(signal, &msg);
551 partition_init_done = 1;
557 core_test_signal_handle(SPM_CORE_TEST_INIT_SUCCESS_SIGNAL,
558 tfm_core_test_sfn_wrap_init_success);
560 core_test_signal_handle(SPM_CORE_TEST_DIRECT_RECURSION_SIGNAL,
561 tfm_core_test_sfn_wrap_direct_recursion);
563 core_test_signal_handle(SPM_CORE_TEST_SS_TO_SS_SIGNAL,
564 tfm_core_test_sfn_wrap_ss_to_ss);
566 core_test_signal_handle(SPM_CORE_TEST_SS_TO_SS_BUFFER_SIGNAL,
567 tfm_core_test_sfn_wrap_ss_to_ss_buffer);
569 core_test_signal_handle(SPM_CORE_TEST_OUTVEC_WRITE_SIGNAL,
570 tfm_core_test_sfn_wrap_outvec_write);
572 core_test_signal_handle(SPM_CORE_TEST_PERIPHERAL_ACCESS_SIGNAL,
573 tfm_core_test_sfn_wrap_peripheral_access);
575 core_test_signal_handle(SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SIGNAL,
576 tfm_core_test_sfn_wrap_get_caller_client_id);
578 core_test_signal_handle(SPM_CORE_TEST_SPM_REQUEST_SIGNAL,
579 tfm_core_test_sfn_wrap_spm_request);
581 core_test_signal_handle(SPM_CORE_TEST_BLOCK_SIGNAL,
582 tfm_core_test_sfn_wrap_block);
584 core_test_signal_handle(SPM_CORE_TEST_NS_THREAD_SIGNAL,
585 tfm_core_test_sfn_wrap_ns_thread);
psa_status_t spm_core_test_sfn_init_success(struct psa_invec *in_vec, size_t in_len, struct psa_outvec *out_vec, size_t out_len)
Tests whether the initialisation of the service was successful.
#define SPM_CORE_TEST_2_INVERT_SID
#define INVALID_NS_CLIENT_ID
#define CORE_TEST_ID_PERIPHERAL_ACCESS
#define SPM_CORE_TEST_INIT_SUCCESS_SIGNAL
#define CORE_TEST_ID_BLOCK
#define IRQ_TEST_TOOL_CODE_LOCATION(name)
void psa_close(psa_handle_t handle)
Close a connection to an RoT Service.
#define SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SIGNAL
#define SPM_CORE_TEST_SS_TO_SS_SIGNAL
#define SPM_CORE_TEST_DIRECT_RECURSION_SIGNAL
#define SPM_CORE_TEST_2_SLAVE_SERVICE_VERSION
size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, void *buffer, size_t num_bytes)
Read a message parameter or part of a message parameter from a client input vector.
#define CORE_TEST_ID_NS_THREAD
psa_handle_t psa_connect(uint32_t sid, uint32_t version)
Connect to an RoT Service by its SID.
#define PSA_IPC_DISCONNECT
#define CORE_TEST_ID_SS_TO_SS
psa_status_t core_test_init(void)
#define SPM_CORE_TEST_NS_THREAD_SIGNAL
#define SPM_CORE_TEST_BLOCK_SIGNAL
int32_t tfm_spm_request_reset_vote(void)
Request a vote from SPM on a system reset.
#define SPM_CORE_TEST_PERIPHERAL_ACCESS_SIGNAL
#define SPM_CORE_TEST_2_SLAVE_SERVICE_SID
size_t in_size[PSA_MAX_IOVEC]
int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, const void *buffer, size_t num_bytes)
Write a message response to a client output vector.
void psa_reply(psa_handle_t msg_handle, psa_status_t status)
Complete handling of a specific message and unblock the client.
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
Return the Secure Partition interrupt signals that have been asserted from a subset of signals provid...
#define CORE_TEST_ID_GET_CALLER_CLIENT_ID
#define SPM_CORE_TEST_SS_TO_SS_BUFFER_SIGNAL
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_VERSION
size_t out_size[PSA_MAX_IOVEC]
psa_status_t spm_core_test_sfn(struct psa_invec *in_vec, size_t in_len, struct psa_outvec *out_vec, size_t out_len)
Entry point for multiple test cases to be executed on the secure side.
#define SPM_CORE_TEST_SPM_REQUEST_SIGNAL
psa_status_t spm_core_test_sfn_direct_recursion(struct psa_invec *in_vec, size_t in_len, struct psa_outvec *out_vec, size_t out_len)
Tests what happens when a service calls itself directly.
#define CORE_TEST_ID_SPM_REQUEST
#define SPM_CORE_TEST_2_INVERT_VERSION
psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
Retrieve the message which corresponds to a given RoT Service signal and remove the message from the ...
int32_t psa_status_t
Function return status.
#define EXPECTED_NS_CLIENT_ID
psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len)
Call an RoT Service on an established connection.
#define SPM_CORE_TEST_OUTVEC_WRITE_SIGNAL
#define CORE_TEST_ID_SS_TO_SS_BUFFER
#define CORE_TEST_ID_OUTVEC_WRITE