blob: 0a880f799451b8de4fff21b7bc24044d0e67d0be [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
Jose Marinhoa1dfeda2019-02-27 16:46:03 +000019#include "hf/spci.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
24#include "hftest.h"
25#include "primary_with_secondary.h"
Andrew Walbran53d9d042019-03-28 11:35:49 +000026#include "util.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
66/**
Andrew Scullaa7db8e2019-02-01 14:12:19 +000067 * Clearing an empty mailbox is a noop.
68 */
69TEST(mailbox, clear_empty)
70{
Andrew Walbran8a0f5ca2019-11-05 13:12:23 +000071 EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
72 EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
73 EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
Andrew Scullaa7db8e2019-02-01 14:12:19 +000074}
75
76/**
Andrew Scull2e7a76d2019-01-24 11:47:26 +000077 * Send and receive the same message from the echo VM.
78 */
79TEST(mailbox, echo)
80{
81 const char message[] = "Echo this back to me!";
Andrew Walbran27faff32019-10-02 18:20:57 +010082 struct spci_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +000083 struct mailbox_buffers mb = set_up_mailbox();
84
Fuad Tabba7bd14132019-11-07 14:18:52 +000085 SERVICE_SELECT(SERVICE_VM1, "echo", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000086
Fuad Tabba7bd14132019-11-07 14:18:52 +000087 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +010088 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
89 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000090
91 /* Set the message, echo it and check it didn't change. */
Andrew Walbran70bc8622019-10-07 14:15:58 +010092 memcpy_s(mb.send, SPCI_MSG_PAYLOAD_MAX, message, sizeof(message));
93 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +000094 spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +010095 .func,
96 SPCI_SUCCESS_32);
Fuad Tabba7bd14132019-11-07 14:18:52 +000097 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +010098 EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
99 EXPECT_EQ(spci_msg_send_size(run_res), sizeof(message));
100 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbran8a0f5ca2019-11-05 13:12:23 +0000101 EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000102}
103
104/**
105 * Repeatedly send a message and receive it back from the echo VM.
106 */
107TEST(mailbox, repeated_echo)
108{
109 char message[] = "Echo this back to me!";
Andrew Walbran27faff32019-10-02 18:20:57 +0100110 struct spci_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000111 uint8_t i;
112 struct mailbox_buffers mb = set_up_mailbox();
113
Fuad Tabba7bd14132019-11-07 14:18:52 +0000114 SERVICE_SELECT(SERVICE_VM1, "echo", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000115
116 for (i = 0; i < 100; i++) {
117 /* Run secondary until it reaches the wait for messages. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000118 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100119 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
120 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000121
122 /* Set the message, echo it and check it didn't change. */
123 next_permutation(message, sizeof(message) - 1);
Andrew Walbran70bc8622019-10-07 14:15:58 +0100124 memcpy_s(mb.send, SPCI_MSG_PAYLOAD_MAX, message,
Andrew Sculla1aa2ba2019-04-05 11:49:02 +0100125 sizeof(message));
Fuad Tabba7bd14132019-11-07 14:18:52 +0000126 EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
Andrew Walbran70bc8622019-10-07 14:15:58 +0100127 sizeof(message), 0)
128 .func,
129 SPCI_SUCCESS_32);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000130 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100131 EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
132 EXPECT_EQ(spci_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100133 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbran8a0f5ca2019-11-05 13:12:23 +0000134 EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000135 }
136}
137
138/**
139 * Send a message to relay_a which will forward it to relay_b where it will be
140 * sent back here.
141 */
142TEST(mailbox, relay)
143{
144 const char message[] = "Send this round the relay!";
Andrew Walbran27faff32019-10-02 18:20:57 +0100145 struct spci_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000146 struct mailbox_buffers mb = set_up_mailbox();
147
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000148 SERVICE_SELECT(SERVICE_VM1, "relay", mb.send);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000149 SERVICE_SELECT(SERVICE_VM2, "relay", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000150
Fuad Tabba7bd14132019-11-07 14:18:52 +0000151 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100152 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
153 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000154 run_res = spci_run(SERVICE_VM2, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100155 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
156 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000157
158 /*
159 * Build the message chain so the message is sent from here to
Fuad Tabba7bd14132019-11-07 14:18:52 +0000160 * SERVICE_VM1, then to SERVICE_VM2 and finally back to here.
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000161 */
162 {
Andrew Walbran70bc8622019-10-07 14:15:58 +0100163 spci_vm_id_t *chain = (spci_vm_id_t *)mb.send;
Fuad Tabba7bd14132019-11-07 14:18:52 +0000164 *chain++ = htole32(SERVICE_VM2);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000165 *chain++ = htole32(HF_PRIMARY_VM_ID);
Andrew Walbran95534922019-06-19 11:32:54 +0100166 memcpy_s(chain,
167 SPCI_MSG_PAYLOAD_MAX - (2 * sizeof(spci_vm_id_t)),
Andrew Sculla1aa2ba2019-04-05 11:49:02 +0100168 message, sizeof(message));
Jose Marinhoa1dfeda2019-02-27 16:46:03 +0000169
Andrew Walbran70bc8622019-10-07 14:15:58 +0100170 EXPECT_EQ(
171 spci_msg_send(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000172 HF_PRIMARY_VM_ID, SERVICE_VM1,
Andrew Walbran70bc8622019-10-07 14:15:58 +0100173 sizeof(message) + (2 * sizeof(spci_vm_id_t)), 0)
174 .func,
175 SPCI_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000176 }
177
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000178 /* Let SERVICE_VM1 forward the message. */
Andrew Walbran27faff32019-10-02 18:20:57 +0100179 run_res = spci_run(SERVICE_VM1, 0);
180 EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000181 EXPECT_EQ(spci_msg_send_receiver(run_res), SERVICE_VM2);
182 EXPECT_EQ(spci_msg_send_size(run_res), 0);
183
184 /* Let SERVICE_VM2 forward the message. */
185 run_res = spci_run(SERVICE_VM2, 0);
186 EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000187
Andrew Walbran95534922019-06-19 11:32:54 +0100188 /* Ensure the message is intact. */
Andrew Walbran27faff32019-10-02 18:20:57 +0100189 EXPECT_EQ(spci_msg_send_receiver(run_res), HF_PRIMARY_VM_ID);
190 EXPECT_EQ(spci_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100191 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbran8a0f5ca2019-11-05 13:12:23 +0000192 EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000193}
194
195/**
196 * Send a message before the secondary VM is configured, but do not register
197 * for notification. Ensure we're not notified.
198 */
199TEST(mailbox, no_primary_to_secondary_notification_on_configure)
200{
Andrew Walbran27faff32019-10-02 18:20:57 +0100201 struct spci_value run_res;
202
Andrew Walbran70bc8622019-10-07 14:15:58 +0100203 set_up_mailbox();
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000204
Fuad Tabba7bd14132019-11-07 14:18:52 +0000205 EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0, 0),
Andrew Walbran70bc8622019-10-07 14:15:58 +0100206 SPCI_BUSY);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000207
Fuad Tabba7bd14132019-11-07 14:18:52 +0000208 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100209 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
210 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000211
Fuad Tabba7bd14132019-11-07 14:18:52 +0000212 EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0, 0).func,
Andrew Walbran70bc8622019-10-07 14:15:58 +0100213 SPCI_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000214}
215
216/**
217 * Send a message before the secondary VM is configured, and receive a
218 * notification when it configures.
219 */
220TEST(mailbox, secondary_to_primary_notification_on_configure)
221{
Andrew Walbran27faff32019-10-02 18:20:57 +0100222 struct spci_value run_res;
223
Andrew Walbran70bc8622019-10-07 14:15:58 +0100224 set_up_mailbox();
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000225
Fuad Tabba7bd14132019-11-07 14:18:52 +0000226 EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
Andrew Walbran70bc8622019-10-07 14:15:58 +0100227 SPCI_MSG_SEND_NOTIFY),
228 SPCI_BUSY);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000229
230 /*
231 * Run first VM for it to configure itself. It should result in
232 * notifications having to be issued.
233 */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000234 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100235 EXPECT_EQ(run_res.func, SPCI_RX_RELEASE_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000236
237 /* A single waiter is returned. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000238 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), HF_PRIMARY_VM_ID);
239 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), -1);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000240
Andrew Scullb06d1752019-02-04 10:15:48 +0000241 /* Send should now succeed. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000242 EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, 0, 0).func,
Andrew Walbran70bc8622019-10-07 14:15:58 +0100243 SPCI_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000244}
245
246/**
247 * Causes secondary VM to send two messages to primary VM. The second message
248 * will reach the mailbox while it's not writable. Checks that notifications are
249 * properly delivered when mailbox is cleared.
250 */
251TEST(mailbox, primary_to_secondary)
252{
253 char message[] = "not ready echo";
Andrew Walbran27faff32019-10-02 18:20:57 +0100254 struct spci_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000255 struct mailbox_buffers mb = set_up_mailbox();
256
Fuad Tabba7bd14132019-11-07 14:18:52 +0000257 SERVICE_SELECT(SERVICE_VM1, "echo_with_notification", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000258
Fuad Tabba7bd14132019-11-07 14:18:52 +0000259 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100260 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
261 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000262
263 /* Send a message to echo service, and get response back. */
Andrew Walbran70bc8622019-10-07 14:15:58 +0100264 memcpy_s(mb.send, SPCI_MSG_PAYLOAD_MAX, message, sizeof(message));
265 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000266 spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100267 .func,
268 SPCI_SUCCESS_32);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000269 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100270 EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
271 EXPECT_EQ(spci_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100272 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000273
274 /* Let secondary VM continue running so that it will wait again. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000275 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100276 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
277 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000278
279 /* Without clearing our mailbox, send message again. */
Andrew Scull55baca62019-04-05 14:56:20 +0100280 reverse(message, strnlen_s(message, sizeof(message)));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100281 memcpy_s(mb.send, SPCI_MSG_PAYLOAD_MAX, message, sizeof(message));
Jose Marinhoa1dfeda2019-02-27 16:46:03 +0000282
283 /* Message should be dropped since the mailbox was not cleared. */
Andrew Walbran70bc8622019-10-07 14:15:58 +0100284 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000285 spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100286 .func,
287 SPCI_SUCCESS_32);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000288 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100289 EXPECT_EQ(run_res.func, HF_SPCI_RUN_WAIT_FOR_INTERRUPT);
290 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000291
292 /* Clear the mailbox. We expect to be told there are pending waiters. */
Andrew Walbran8a0f5ca2019-11-05 13:12:23 +0000293 EXPECT_EQ(spci_rx_release().func, SPCI_RX_RELEASE_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000294
295 /* Retrieve a single waiter. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000296 EXPECT_EQ(hf_mailbox_waiter_get(HF_PRIMARY_VM_ID), SERVICE_VM1);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000297 EXPECT_EQ(hf_mailbox_waiter_get(HF_PRIMARY_VM_ID), -1);
298
299 /*
300 * Inject interrupt into VM and let it run again. We should receive
301 * the echoed message.
302 */
303 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000304 hf_interrupt_inject(SERVICE_VM1, 0, HF_MAILBOX_WRITABLE_INTID),
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000305 1);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000306 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100307 EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
308 EXPECT_EQ(spci_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100309 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000310}
311
312/**
313 * Sends two messages to secondary VM without letting it run, so second message
314 * won't go through. Ensure that a notification is delivered when secondary VM
315 * clears the mailbox.
316 */
317TEST(mailbox, secondary_to_primary_notification)
318{
319 const char message[] = "not ready echo";
Andrew Walbran27faff32019-10-02 18:20:57 +0100320 struct spci_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000321 struct mailbox_buffers mb = set_up_mailbox();
322
Fuad Tabba7bd14132019-11-07 14:18:52 +0000323 SERVICE_SELECT(SERVICE_VM1, "echo_with_notification", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000324
Fuad Tabba7bd14132019-11-07 14:18:52 +0000325 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100326 EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
327 EXPECT_EQ(run_res.arg2, SPCI_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000328
329 /* Send a message to echo service twice. The second should fail. */
Andrew Walbran70bc8622019-10-07 14:15:58 +0100330 memcpy_s(mb.send, SPCI_MSG_PAYLOAD_MAX, message, sizeof(message));
331 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000332 spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100333 .func,
334 SPCI_SUCCESS_32);
Fuad Tabba7bd14132019-11-07 14:18:52 +0000335 EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
Andrew Walbran9b19b752019-10-10 13:49:25 +0100336 sizeof(message), SPCI_MSG_SEND_NOTIFY),
337 SPCI_BUSY);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000338
339 /* Receive a reply for the first message. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000340 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100341 EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
342 EXPECT_EQ(spci_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +0100343 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000344
345 /* Run VM again so that it clears its mailbox. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000346 run_res = spci_run(SERVICE_VM1, 0);
Andrew Walbran27faff32019-10-02 18:20:57 +0100347 EXPECT_EQ(run_res.func, SPCI_RX_RELEASE_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000348
349 /* Retrieve a single waiter. */
Fuad Tabba7bd14132019-11-07 14:18:52 +0000350 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), HF_PRIMARY_VM_ID);
351 EXPECT_EQ(hf_mailbox_waiter_get(SERVICE_VM1), -1);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000352
Andrew Scullb06d1752019-02-04 10:15:48 +0000353 /* Send should now succeed. */
Andrew Walbran70bc8622019-10-07 14:15:58 +0100354 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +0000355 spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +0100356 .func,
357 SPCI_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +0000358}