blob: bd293f9f73b703eddf39b46ff78f85dd07423e9f [file] [log] [blame]
J-Alvesb4e89a22021-03-09 10:04:39 +00001/*
2 * Copyright (c) 2021, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "cactus_message_loop.h"
8#include "cactus_test_cmds.h"
9#include "cactus_tests.h"
J-Alvesb4e89a22021-03-09 10:04:39 +000010#include <ffa_helpers.h>
J-Alvesa076d4c2021-10-19 16:06:15 +010011#include <debug.h>
J-Alvesa076d4c2021-10-19 16:06:15 +010012
13/* Booleans to keep track of which CPUs handled NPI. */
14static bool npi_handled[PLATFORM_CORE_COUNT];
15
16/**
17 * Helper to access the above array and set the boolean for the specific CPU.
18 */
19void set_npi_handled(uint32_t vcpu_id, bool val)
20{
21 npi_handled[vcpu_id] = val;
22}
23
24/**
25 * Helper to get state of the boolean from `npi_handled` from the respective
26 * CPU.
27 */
28bool get_npi_handled(uint32_t vcpu_id)
29{
30 return npi_handled[vcpu_id];
31}
32
33void notification_pending_interrupt_handler(void)
34{
35 /* Get which core it is running from. */
36 unsigned int core_pos = platform_get_core_pos(
37 read_mpidr_el1() & MPID_MASK);
38
39 VERBOSE("NPI handled in core %u\n", core_pos);
40
41 set_npi_handled(core_pos, true);
42}
43
J-Alvesb4e89a22021-03-09 10:04:39 +000044
45CACTUS_CMD_HANDLER(notifications_bind, CACTUS_NOTIFICATION_BIND_CMD)
46{
47 ffa_id_t source = ffa_dir_msg_source(*args);
48 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
49 ffa_id_t receiver = cactus_notification_get_receiver(*args);
50 ffa_id_t sender = cactus_notification_get_sender(*args);
51 ffa_notification_bitmap_t notifications =
52 cactus_notification_get_notifications(*args);
53 uint32_t flags = cactus_notification_get_flags(*args);
54 smc_ret_values ret;
55
56 VERBOSE("Partition %x requested to bind notifications '%llx' to %x\n",
57 source, notifications, receiver);
58
59 ret = ffa_notification_bind(sender, receiver, flags, notifications);
60
61 if (is_ffa_call_error(ret)) {
62 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
63 }
64
65 return cactus_response(vm_id, source, CACTUS_SUCCESS);
66}
67
68CACTUS_CMD_HANDLER(notifications_unbind, CACTUS_NOTIFICATION_UNBIND_CMD)
69{
70 ffa_id_t source = ffa_dir_msg_source(*args);
71 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
72 ffa_id_t receiver = cactus_notification_get_receiver(*args);
73 ffa_id_t sender = cactus_notification_get_sender(*args);
74 ffa_notification_bitmap_t notifications =
75 cactus_notification_get_notifications(*args);
76 smc_ret_values ret;
77
78 VERBOSE("Partition %x requested to unbind notifications '%llx' to %x\n",
79 source, notifications, receiver);
80
81 ret = ffa_notification_unbind(sender, receiver, notifications);
82
83 if (is_ffa_call_error(ret)) {
84 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
85 }
86
87 return cactus_response(vm_id, source, CACTUS_SUCCESS);
88}
J-Alvesab775912021-03-29 15:22:33 +010089
90CACTUS_CMD_HANDLER(notifications_get, CACTUS_NOTIFICATION_GET_CMD)
91{
92 ffa_id_t source = ffa_dir_msg_source(*args);
93 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
94 ffa_id_t notification_receiver =
95 cactus_notification_get_receiver(*args);
96 uint32_t flags = cactus_notification_get_flags(*args);
97 uint32_t vcpu_id = cactus_notification_get_vcpu(*args);
98 smc_ret_values ret;
99
100 VERBOSE("Partition %x requested to get notifications.\n", source);
101
102 ret = ffa_notification_get(notification_receiver, vcpu_id, flags);
103
104 if (is_ffa_call_error(ret)) {
105 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
106 }
107
108 VERBOSE("Notifications returned:\n"
109 " from sp: %llx\n"
110 " from vm: %llx\n",
111 ffa_notifications_get_from_sp(ret),
112 ffa_notifications_get_from_vm(ret));
113
J-Alvesa076d4c2021-10-19 16:06:15 +0100114 /* If requested to check the status of NPI, for the respective CPU. */
115 if (cactus_notifications_check_npi_handled(*args)) {
116
117 /* If NPI hasn't been handled return error for this test. */
118 if (!get_npi_handled(vcpu_id)) {
119 return cactus_error_resp(vm_id, source,
120 CACTUS_ERROR_TEST);
121 }
122
123 /* Reset NPI flag for the respective core. */
124 set_npi_handled(vcpu_id, false);
125 }
126
J-Alvesab775912021-03-29 15:22:33 +0100127 return cactus_notifications_get_success_resp(
128 vm_id, source, ffa_notifications_get_from_sp(ret),
129 ffa_notifications_get_from_vm(ret));
130}
131
132CACTUS_CMD_HANDLER(notifications_set, CACTUS_NOTIFICATIONS_SET_CMD)
133{
134 ffa_id_t source = ffa_dir_msg_source(*args);
135 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
J-Alvesa076d4c2021-10-19 16:06:15 +0100136 ffa_notification_bitmap_t notifications =
137 cactus_notification_get_notifications(*args);
J-Alvesfbbbf622021-07-30 16:43:36 +0100138 ffa_id_t receiver = cactus_notifications_set_get_receiver(*args);
139 ffa_id_t sender = cactus_notifications_set_get_sender(*args);
140 ffa_id_t echo_dest = cactus_req_echo_get_echo_dest(*args);
J-Alvesab775912021-03-29 15:22:33 +0100141 uint32_t flags = cactus_notification_get_flags(*args);
142 smc_ret_values ret;
143
144 VERBOSE("Partition %x requested to set notifications.\n", source);
145
146 ret = ffa_notification_set(sender, receiver, flags, notifications);
147
148 if (is_ffa_call_error(ret)) {
149 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
150 }
151
J-Alvesfbbbf622021-07-30 16:43:36 +0100152 /*
153 * If flag to delay notification pending interrupt, an echo test command
154 * should be sent to another SP, to validate SWd is not preempted.
155 */
156 if ((flags & FFA_NOTIFICATIONS_FLAG_DELAY_SRI) != 0 &&
157 IS_SP_ID(echo_dest)) {
158 VERBOSE("Delay SRI. Test Echo to %x.\n", echo_dest);
159 ret = cactus_echo_send_cmd(vm_id, echo_dest,
160 FFA_NOTIFICATION_SET);
161
162 if (!is_expected_cactus_response(ret, CACTUS_SUCCESS,
163 FFA_NOTIFICATION_SET)) {
164 ERROR("Echo Failed!\n");
165 return cactus_error_resp(vm_id, source,
166 CACTUS_ERROR_TEST);
167 }
168 }
169
J-Alvesbe2daa62021-11-04 17:06:57 +0000170 VERBOSE("Set notifications handled (core %u)!\n", get_current_core_id());
J-Alvesfbbbf622021-07-30 16:43:36 +0100171
J-Alvesab775912021-03-29 15:22:33 +0100172 return cactus_response(vm_id, source, CACTUS_SUCCESS);
173}