blob: b7085aeb3f39ed1cbfe6195eca0d95e491735055 [file] [log] [blame]
Andrew Scull2e7a76d2019-01-24 11:47:26 +00001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2019 The Hafnium Authors.
Andrew Scull2e7a76d2019-01-24 11:47:26 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdint.h>
18
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010019#include "hf/ffa.h"
Andrew Scull8d9e1212019-04-05 13:52:55 +010020#include "hf/std.h"
Jose Marinhoa1dfeda2019-02-27 16:46:03 +000021
Andrew Scull2e7a76d2019-01-24 11:47:26 +000022#include "vmapi/hf/call.h"
23
Andrew Scull2e7a76d2019-01-24 11:47:26 +000024#include "primary_with_secondary.h"
Andrew Walbran1e7c7742019-12-13 17:10:02 +000025#include "test/hftest.h"
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010026#include "test/vmapi/ffa.h"
Andrew Scull2e7a76d2019-01-24 11:47:26 +000027
28/**
29 * Reverses the order of the elements in the given array.
30 */
31static void reverse(char *s, size_t len)
32{
33 size_t i;
34
35 for (i = 0; i < len / 2; i++) {
36 char t = s[i];
37 s[i] = s[len - 1 - i];
38 s[len - 1 - i] = t;
39 }
40}
41
42/**
43 * Finds the next lexicographic permutation of the given array, if there is one.
44 */
45static void next_permutation(char *s, size_t len)
46{
Andrew Walbrane52006c2019-10-22 18:01:28 +010047 size_t i;
48 size_t j;
Andrew Scull2e7a76d2019-01-24 11:47:26 +000049
50 for (i = len - 2; i < len; i--) {
51 const char t = s[i];
52 if (t >= s[i + 1]) {
53 continue;
54 }
55
56 for (j = len - 1; t >= s[j]; j--) {
57 }
58
59 s[i] = s[j];
60 s[j] = t;
61 reverse(s + i + 1, len - i - 1);
62 return;
63 }
64}
65
Andrew Walbrana0168d52019-12-16 11:55:06 +000066TEAR_DOWN(mailbox)
67{
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010068 EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
Andrew Walbrana0168d52019-12-16 11:55:06 +000069}
70
Andrew Scull2e7a76d2019-01-24 11:47:26 +000071/**
Andrew Walbrana36f7592019-12-13 18:43:38 +000072 * Clearing an empty mailbox is an error.
Andrew Scullaa7db8e2019-02-01 14:12:19 +000073 */
74TEST(mailbox, clear_empty)
75{
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010076 EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
77 EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
78 EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
Andrew Scullaa7db8e2019-02-01 14:12:19 +000079}
80
81/**
Andrew Scull2e7a76d2019-01-24 11:47:26 +000082 * Send and receive the same message from the echo VM.
83 */
84TEST(mailbox, echo)
85{
86 const char message[] = "Echo this back to me!";
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010087 struct ffa_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +000088 struct mailbox_buffers mb = set_up_mailbox();
89
Fuad Tabba7bd14132019-11-07 14:18:52 +000090 SERVICE_SELECT(SERVICE_VM1, "echo", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000091
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010092 run_res = ffa_run(SERVICE_VM1, 0);
93 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
94 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000095
96 /* Set the message, echo it and check it didn't change. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010097 memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message, sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +010098 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010099 ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100100 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100101 FFA_SUCCESS_32);
102 run_res = ffa_run(SERVICE_VM1, 0);
103 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
104 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran27faff32019-10-02 18:20:57 +0100105 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100106 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000107}
108
109/**
110 * Repeatedly send a message and receive it back from the echo VM.
111 */
112TEST(mailbox, repeated_echo)
113{
114 char message[] = "Echo this back to me!";
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100115 struct ffa_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000116 uint8_t i;
117 struct mailbox_buffers mb = set_up_mailbox();
118
Fuad Tabba7bd14132019-11-07 14:18:52 +0000119 SERVICE_SELECT(SERVICE_VM1, "echo", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000120
121 for (i = 0; i < 100; i++) {
122 /* Run secondary until it reaches the wait for messages. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100123 run_res = ffa_run(SERVICE_VM1, 0);
124 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
125 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000126
127 /* Set the message, echo it and check it didn't change. */
128 next_permutation(message, sizeof(message) - 1);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100129 memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message,
Andrew Sculla1aa2ba2019-04-05 11:49:02 +0100130 sizeof(message));
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100131 EXPECT_EQ(ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
132 sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100133 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100134 FFA_SUCCESS_32);
135 run_res = ffa_run(SERVICE_VM1, 0);
136 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
137 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100138 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100139 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000140 }
141}
142
143/**
144 * Send a message to relay_a which will forward it to relay_b where it will be
145 * sent back here.
146 */
147TEST(mailbox, relay)
148{
149 const char message[] = "Send this round the relay!";
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100150 struct ffa_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000151 struct mailbox_buffers mb = set_up_mailbox();
152
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000153 SERVICE_SELECT(SERVICE_VM1, "relay", mb.send);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000154 SERVICE_SELECT(SERVICE_VM2, "relay", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000155
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100156 run_res = ffa_run(SERVICE_VM1, 0);
157 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
158 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
159 run_res = ffa_run(SERVICE_VM2, 0);
160 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
161 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000162
163 /*
164 * Build the message chain so the message is sent from here to
Fuad Tabba7bd14132019-11-07 14:18:52 +0000165 * SERVICE_VM1, then to SERVICE_VM2 and finally back to here.
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000166 */
167 {
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100168 ffa_vm_id_t *chain = (ffa_vm_id_t *)mb.send;
Fuad Tabba7bd14132019-11-07 14:18:52 +0000169 *chain++ = htole32(SERVICE_VM2);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000170 *chain++ = htole32(HF_PRIMARY_VM_ID);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100171 memcpy_s(chain, FFA_MSG_PAYLOAD_MAX - (2 * sizeof(ffa_vm_id_t)),
Andrew Sculla1aa2ba2019-04-05 11:49:02 +0100172 message, sizeof(message));
Jose Marinhoa1dfeda2019-02-27 16:46:03 +0000173
Andrew Walbran70bc8622019-10-07 14:15:58 +0100174 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100175 ffa_msg_send(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000176 HF_PRIMARY_VM_ID, SERVICE_VM1,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100177 sizeof(message) + (2 * sizeof(ffa_vm_id_t)), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100178 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100179 FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000180 }
181
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000182 /* Let SERVICE_VM1 forward the message. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100183 run_res = ffa_run(SERVICE_VM1, 0);
184 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
185 EXPECT_EQ(ffa_msg_send_receiver(run_res), SERVICE_VM2);
186 EXPECT_EQ(ffa_msg_send_size(run_res), 0);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000187
188 /* Let SERVICE_VM2 forward the message. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100189 run_res = ffa_run(SERVICE_VM2, 0);
190 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000191
Andrew Walbran95534922019-06-19 11:32:54 +0100192 /* Ensure the message is intact. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100193 EXPECT_EQ(ffa_msg_send_receiver(run_res), HF_PRIMARY_VM_ID);
194 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100195 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100196 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000197}
198
199/**
200 * Send a message before the secondary VM is configured, but do not register
201 * for notification. Ensure we're not notified.
202 */
203TEST(mailbox, no_primary_to_secondary_notification_on_configure)
204{
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100205 struct ffa_value run_res;
Andrew Walbran27faff32019-10-02 18:20:57 +0100206
Andrew Walbran70bc8622019-10-07 14:15:58 +0100207 set_up_mailbox();
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000208
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100209 EXPECT_FFA_ERROR(ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0, 0),
210 FFA_BUSY);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000211
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100212 run_res = ffa_run(SERVICE_VM1, 0);
213 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
214 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000215
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100216 EXPECT_EQ(ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0, 0).func,
217 FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000218}
219
220/**
221 * Send a message before the secondary VM is configured, and receive a
222 * notification when it configures.
223 */
224TEST(mailbox, secondary_to_primary_notification_on_configure)
225{
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100226 struct ffa_value run_res;
Andrew Walbran27faff32019-10-02 18:20:57 +0100227
Andrew Walbran70bc8622019-10-07 14:15:58 +0100228 set_up_mailbox();
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000229
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100230 EXPECT_FFA_ERROR(ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
231 FFA_MSG_SEND_NOTIFY),
232 FFA_BUSY);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000233
234 /*
235 * Run first VM for it to configure itself. It should result in
236 * notifications having to be issued.
237 */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100238 run_res = ffa_run(SERVICE_VM1, 0);
239 EXPECT_EQ(run_res.func, FFA_RX_RELEASE_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000240
241 /* A single waiter is returned. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000242 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), HF_PRIMARY_VM_ID);
243 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), -1);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000244
Andrew Scullb06d1752019-02-04 10:15:48 +0000245 /* Send should now succeed. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100246 EXPECT_EQ(ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0, 0).func,
247 FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000248}
249
250/**
251 * Causes secondary VM to send two messages to primary VM. The second message
252 * will reach the mailbox while it's not writable. Checks that notifications are
253 * properly delivered when mailbox is cleared.
254 */
255TEST(mailbox, primary_to_secondary)
256{
257 char message[] = "not ready echo";
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100258 struct ffa_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000259 struct mailbox_buffers mb = set_up_mailbox();
260
Fuad Tabba7bd14132019-11-07 14:18:52 +0000261 SERVICE_SELECT(SERVICE_VM1, "echo_with_notification", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000262
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100263 run_res = ffa_run(SERVICE_VM1, 0);
264 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
265 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000266
267 /* Send a message to echo service, and get response back. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100268 memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message, sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100269 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100270 ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100271 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100272 FFA_SUCCESS_32);
273 run_res = ffa_run(SERVICE_VM1, 0);
274 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
275 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100276 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000277
278 /* Let secondary VM continue running so that it will wait again. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100279 run_res = ffa_run(SERVICE_VM1, 0);
280 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
281 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000282
283 /* Without clearing our mailbox, send message again. */
Andrew Scull55baca62019-04-05 14:56:20 +0100284 reverse(message, strnlen_s(message, sizeof(message)));
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100285 memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message, sizeof(message));
Jose Marinhoa1dfeda2019-02-27 16:46:03 +0000286
287 /* Message should be dropped since the mailbox was not cleared. */
Andrew Walbran70bc8622019-10-07 14:15:58 +0100288 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100289 ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100290 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100291 FFA_SUCCESS_32);
292 run_res = ffa_run(SERVICE_VM1, 0);
293 EXPECT_EQ(run_res.func, HF_FFA_RUN_WAIT_FOR_INTERRUPT);
294 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000295
296 /* Clear the mailbox. We expect to be told there are pending waiters. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100297 EXPECT_EQ(ffa_rx_release().func, FFA_RX_RELEASE_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000298
299 /* Retrieve a single waiter. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000300 EXPECT_EQ(hf_mailbox_waiter_get(HF_PRIMARY_VM_ID), SERVICE_VM1);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000301 EXPECT_EQ(hf_mailbox_waiter_get(HF_PRIMARY_VM_ID), -1);
302
303 /*
304 * Inject interrupt into VM and let it run again. We should receive
305 * the echoed message.
306 */
307 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000308 hf_interrupt_inject(SERVICE_VM1, 0, HF_MAILBOX_WRITABLE_INTID),
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000309 1);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100310 run_res = ffa_run(SERVICE_VM1, 0);
311 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
312 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100313 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100314 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000315}
316
317/**
318 * Sends two messages to secondary VM without letting it run, so second message
319 * won't go through. Ensure that a notification is delivered when secondary VM
320 * clears the mailbox.
321 */
322TEST(mailbox, secondary_to_primary_notification)
323{
324 const char message[] = "not ready echo";
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100325 struct ffa_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000326 struct mailbox_buffers mb = set_up_mailbox();
327
Fuad Tabba7bd14132019-11-07 14:18:52 +0000328 SERVICE_SELECT(SERVICE_VM1, "echo_with_notification", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000329
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100330 run_res = ffa_run(SERVICE_VM1, 0);
331 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
332 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000333
334 /* Send a message to echo service twice. The second should fail. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100335 memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message, sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100336 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100337 ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100338 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100339 FFA_SUCCESS_32);
340 EXPECT_FFA_ERROR(ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
341 sizeof(message), FFA_MSG_SEND_NOTIFY),
342 FFA_BUSY);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000343
344 /* Receive a reply for the first message. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100345 run_res = ffa_run(SERVICE_VM1, 0);
346 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
347 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100348 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100349 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000350
351 /* Run VM again so that it clears its mailbox. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100352 run_res = ffa_run(SERVICE_VM1, 0);
353 EXPECT_EQ(run_res.func, FFA_RX_RELEASE_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000354
355 /* Retrieve a single waiter. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000356 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), HF_PRIMARY_VM_ID);
357 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), -1);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000358
Andrew Scullb06d1752019-02-04 10:15:48 +0000359 /* Send should now succeed. */
Andrew Walbran70bc8622019-10-07 14:15:58 +0100360 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100361 ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100362 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100363 FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000364}