blob: 420f9423968256f1eb78156a17cdb0ee8b41b92e [file] [log] [blame]
J-Alvesb4e89a22021-03-09 10:04:39 +00001/*
Daniel Boulbyce386b12022-03-29 18:36:36 +01002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
J-Alvesb4e89a22021-03-09 10:04:39 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "cactus_message_loop.h"
8#include "cactus_test_cmds.h"
Daniel Boulbyf3da5912022-04-01 12:31:52 +01009#include "sp_tests.h"
10
J-Alvesb4e89a22021-03-09 10:04:39 +000011#include <ffa_helpers.h>
Olivier Deprez19626b42023-12-21 18:29:05 +010012#include <spm_helpers.h>
J-Alvesa076d4c2021-10-19 16:06:15 +010013#include <debug.h>
J-Alvesa076d4c2021-10-19 16:06:15 +010014
15/* Booleans to keep track of which CPUs handled NPI. */
16static bool npi_handled[PLATFORM_CORE_COUNT];
17
18/**
19 * Helper to access the above array and set the boolean for the specific CPU.
20 */
21void set_npi_handled(uint32_t vcpu_id, bool val)
22{
23 npi_handled[vcpu_id] = val;
24}
25
26/**
27 * Helper to get state of the boolean from `npi_handled` from the respective
28 * CPU.
29 */
30bool get_npi_handled(uint32_t vcpu_id)
31{
32 return npi_handled[vcpu_id];
33}
34
35void notification_pending_interrupt_handler(void)
36{
Olivier Deprez19626b42023-12-21 18:29:05 +010037 /* Get vCPU index for currently running vCPU. */
38 unsigned int core_pos = spm_get_my_core_pos();
J-Alvesa076d4c2021-10-19 16:06:15 +010039
40 VERBOSE("NPI handled in core %u\n", core_pos);
41
42 set_npi_handled(core_pos, true);
43}
44
J-Alvesb4e89a22021-03-09 10:04:39 +000045
46CACTUS_CMD_HANDLER(notifications_bind, CACTUS_NOTIFICATION_BIND_CMD)
47{
48 ffa_id_t source = ffa_dir_msg_source(*args);
49 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
50 ffa_id_t receiver = cactus_notification_get_receiver(*args);
51 ffa_id_t sender = cactus_notification_get_sender(*args);
52 ffa_notification_bitmap_t notifications =
53 cactus_notification_get_notifications(*args);
54 uint32_t flags = cactus_notification_get_flags(*args);
Daniel Boulbyce386b12022-03-29 18:36:36 +010055 struct ffa_value ret;
J-Alvesb4e89a22021-03-09 10:04:39 +000056
57 VERBOSE("Partition %x requested to bind notifications '%llx' to %x\n",
58 source, notifications, receiver);
59
60 ret = ffa_notification_bind(sender, receiver, flags, notifications);
61
62 if (is_ffa_call_error(ret)) {
63 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
64 }
65
66 return cactus_response(vm_id, source, CACTUS_SUCCESS);
67}
68
69CACTUS_CMD_HANDLER(notifications_unbind, CACTUS_NOTIFICATION_UNBIND_CMD)
70{
71 ffa_id_t source = ffa_dir_msg_source(*args);
72 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
73 ffa_id_t receiver = cactus_notification_get_receiver(*args);
74 ffa_id_t sender = cactus_notification_get_sender(*args);
75 ffa_notification_bitmap_t notifications =
76 cactus_notification_get_notifications(*args);
Daniel Boulbyce386b12022-03-29 18:36:36 +010077 struct ffa_value ret;
J-Alvesb4e89a22021-03-09 10:04:39 +000078
79 VERBOSE("Partition %x requested to unbind notifications '%llx' to %x\n",
80 source, notifications, receiver);
81
82 ret = ffa_notification_unbind(sender, receiver, notifications);
83
84 if (is_ffa_call_error(ret)) {
85 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
86 }
87
88 return cactus_response(vm_id, source, CACTUS_SUCCESS);
89}
J-Alvesab775912021-03-29 15:22:33 +010090
91CACTUS_CMD_HANDLER(notifications_get, CACTUS_NOTIFICATION_GET_CMD)
92{
93 ffa_id_t source = ffa_dir_msg_source(*args);
94 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
95 ffa_id_t notification_receiver =
96 cactus_notification_get_receiver(*args);
97 uint32_t flags = cactus_notification_get_flags(*args);
98 uint32_t vcpu_id = cactus_notification_get_vcpu(*args);
Daniel Boulbyce386b12022-03-29 18:36:36 +010099 struct ffa_value ret;
J-Alvesab775912021-03-29 15:22:33 +0100100
101 VERBOSE("Partition %x requested to get notifications.\n", source);
102
103 ret = ffa_notification_get(notification_receiver, vcpu_id, flags);
104
105 if (is_ffa_call_error(ret)) {
106 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
107 }
108
109 VERBOSE("Notifications returned:\n"
110 " from sp: %llx\n"
111 " from vm: %llx\n",
J-Alvesc6b92d52024-04-05 14:16:00 +0100112 ffa_notification_get_from_sp(ret),
113 ffa_notification_get_from_vm(ret));
J-Alvesab775912021-03-29 15:22:33 +0100114
J-Alvesa076d4c2021-10-19 16:06:15 +0100115 /* If requested to check the status of NPI, for the respective CPU. */
116 if (cactus_notifications_check_npi_handled(*args)) {
117
118 /* If NPI hasn't been handled return error for this test. */
119 if (!get_npi_handled(vcpu_id)) {
120 return cactus_error_resp(vm_id, source,
121 CACTUS_ERROR_TEST);
122 }
123
124 /* Reset NPI flag for the respective core. */
125 set_npi_handled(vcpu_id, false);
126 }
127
J-Alvesab775912021-03-29 15:22:33 +0100128 return cactus_notifications_get_success_resp(
J-Alvesc6b92d52024-04-05 14:16:00 +0100129 vm_id, source, ffa_notification_get_from_sp(ret),
130 ffa_notification_get_from_vm(ret));
J-Alvesab775912021-03-29 15:22:33 +0100131}
132
133CACTUS_CMD_HANDLER(notifications_set, CACTUS_NOTIFICATIONS_SET_CMD)
134{
135 ffa_id_t source = ffa_dir_msg_source(*args);
136 ffa_id_t vm_id = ffa_dir_msg_dest(*args);
J-Alvesa076d4c2021-10-19 16:06:15 +0100137 ffa_notification_bitmap_t notifications =
138 cactus_notification_get_notifications(*args);
J-Alvesfbbbf622021-07-30 16:43:36 +0100139 ffa_id_t receiver = cactus_notifications_set_get_receiver(*args);
140 ffa_id_t sender = cactus_notifications_set_get_sender(*args);
141 ffa_id_t echo_dest = cactus_req_echo_get_echo_dest(*args);
J-Alvesab775912021-03-29 15:22:33 +0100142 uint32_t flags = cactus_notification_get_flags(*args);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100143 struct ffa_value ret;
J-Alvesab775912021-03-29 15:22:33 +0100144
145 VERBOSE("Partition %x requested to set notifications.\n", source);
146
147 ret = ffa_notification_set(sender, receiver, flags, notifications);
148
149 if (is_ffa_call_error(ret)) {
150 return cactus_error_resp(vm_id, source, ffa_error_code(ret));
151 }
152
J-Alvesfbbbf622021-07-30 16:43:36 +0100153 /*
154 * If flag to delay notification pending interrupt, an echo test command
155 * should be sent to another SP, to validate SWd is not preempted.
156 */
157 if ((flags & FFA_NOTIFICATIONS_FLAG_DELAY_SRI) != 0 &&
158 IS_SP_ID(echo_dest)) {
159 VERBOSE("Delay SRI. Test Echo to %x.\n", echo_dest);
160 ret = cactus_echo_send_cmd(vm_id, echo_dest,
161 FFA_NOTIFICATION_SET);
162
163 if (!is_expected_cactus_response(ret, CACTUS_SUCCESS,
164 FFA_NOTIFICATION_SET)) {
165 ERROR("Echo Failed!\n");
166 return cactus_error_resp(vm_id, source,
167 CACTUS_ERROR_TEST);
168 }
169 }
170
J-Alvesbe2daa62021-11-04 17:06:57 +0000171 VERBOSE("Set notifications handled (core %u)!\n", get_current_core_id());
J-Alvesfbbbf622021-07-30 16:43:36 +0100172
J-Alvesab775912021-03-29 15:22:33 +0100173 return cactus_response(vm_id, source, CACTUS_SUCCESS);
174}