blob: 09482f2bdb4b97056294f0844f3179c010f6f8f2 [file] [log] [blame]
Daniel Boulby82bf3392023-07-28 18:32:27 +01001/*
2 * Copyright (c) 2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdlib.h>
8
9#include <power_management.h>
10#include <spm_test_helpers.h>
11#include <test_helpers.h>
12#include <tftf_lib.h>
13
14static struct mailbox_buffers test_mb = {.send = NULL, .recv = NULL};
15
16bool reset_tftf_mailbox(void)
17{
18 if (is_ffa_call_error(ffa_rxtx_unmap())) {
19 return false;
20 }
21
22 test_mb.send = NULL;
23 test_mb.recv = NULL;
24
25 return true;
26}
27
28bool get_tftf_mailbox(struct mailbox_buffers *mb)
29{
30 struct ffa_value ret;
31
32 if (test_mb.recv == NULL || test_mb.send == NULL) {
33 CONFIGURE_AND_MAP_MAILBOX(test_mb, PAGE_SIZE, ret);
34 if (is_ffa_call_error(ret)) {
35 return false;
36 }
37 }
38
39 *mb = test_mb;
40
41 return true;
42}
43
44test_result_t check_spmc_testing_set_up(
45 uint32_t ffa_version_major, uint32_t ffa_version_minor,
46 const struct ffa_uuid *ffa_uuids, size_t ffa_uuids_size)
47{
48 struct mailbox_buffers mb;
49
50 if (ffa_uuids == NULL) {
51 ERROR("Invalid parameter ffa_uuids!\n");
52 return TEST_RESULT_FAIL;
53 }
54
55 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(ffa_version_major,
56 ffa_version_minor);
57
58 /**********************************************************************
59 * If OP-TEE is SPMC skip the current test.
60 **********************************************************************/
61 if (check_spmc_execution_level()) {
62 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
63 return TEST_RESULT_SKIPPED;
64 }
65
66 GET_TFTF_MAILBOX(mb);
67
68 for (unsigned int i = 0U; i < ffa_uuids_size; i++)
69 SKIP_TEST_IF_FFA_ENDPOINT_NOT_DEPLOYED(*mb, ffa_uuids[i]);
70
71 return TEST_RESULT_SUCCESS;
72}
73
74test_result_t spm_run_multi_core_test(uintptr_t cpu_on_handler,
75 event_t *cpu_done)
76{
77 unsigned int lead_mpid = read_mpidr_el1() & MPID_MASK;
78 unsigned int core_pos, cpu_node, mpidr;
79 int32_t ret;
80
81 VERBOSE("Powering on all cpus.\n");
82
83 for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
84 tftf_init_event(&cpu_done[i]);
85 }
86
87 /* Power on each secondary CPU one after the other. */
88 for_each_cpu(cpu_node) {
89 mpidr = tftf_get_mpidr_from_node(cpu_node);
90 if (mpidr == lead_mpid) {
91 continue;
92 }
93
94 ret = tftf_cpu_on(mpidr, cpu_on_handler, 0U);
95 if (ret != 0) {
96 ERROR("tftf_cpu_on mpidr 0x%x returns %d\n",
97 mpidr, ret);
98 }
99
100 /* Wait for the secondary CPU to be ready. */
101 core_pos = platform_get_core_pos(mpidr);
102 tftf_wait_for_event(&cpu_done[core_pos]);
103 }
104
105 VERBOSE("Done exiting.\n");
106
107 return TEST_RESULT_SUCCESS;
108}