blob: d9597a63a386a2ef2d82f5da43be951f0ed2fbb5 [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 *
Andrew Walbrane959ec12020-06-17 15:01:09 +01004 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
Andrew Scull2e7a76d2019-01-24 11:47:26 +00007 */
8
9#include <stdint.h>
10
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010011#include "hf/ffa.h"
Andrew Scull8d9e1212019-04-05 13:52:55 +010012#include "hf/std.h"
Jose Marinhoa1dfeda2019-02-27 16:46:03 +000013
Andrew Scull2e7a76d2019-01-24 11:47:26 +000014#include "vmapi/hf/call.h"
15
Andrew Scull2e7a76d2019-01-24 11:47:26 +000016#include "primary_with_secondary.h"
Andrew Walbran1e7c7742019-12-13 17:10:02 +000017#include "test/hftest.h"
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010018#include "test/vmapi/ffa.h"
Andrew Scull2e7a76d2019-01-24 11:47:26 +000019
20/**
Andrew Scull2e7a76d2019-01-24 11:47:26 +000021 * Causes secondary VM to send two messages to primary VM. The second message
22 * will reach the mailbox while it's not writable. Checks that notifications are
23 * properly delivered when mailbox is cleared.
24 */
25TEST(mailbox, primary_to_secondary)
26{
27 char message[] = "not ready echo";
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010028 struct ffa_value run_res;
Andrew Scull2e7a76d2019-01-24 11:47:26 +000029 struct mailbox_buffers mb = set_up_mailbox();
30
Fuad Tabba7bd14132019-11-07 14:18:52 +000031 SERVICE_SELECT(SERVICE_VM1, "echo_with_notification", mb.send);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000032
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010033 run_res = ffa_run(SERVICE_VM1, 0);
34 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
35 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000036
37 /* Send a message to echo service, and get response back. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010038 memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message, sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +010039 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010040 ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +010041 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010042 FFA_SUCCESS_32);
43 run_res = ffa_run(SERVICE_VM1, 0);
44 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
45 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +010046 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000047
48 /* Let secondary VM continue running so that it will wait again. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010049 run_res = ffa_run(SERVICE_VM1, 0);
50 EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
51 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000052
53 /* Without clearing our mailbox, send message again. */
Andrew Scull55baca62019-04-05 14:56:20 +010054 reverse(message, strnlen_s(message, sizeof(message)));
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010055 memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message, sizeof(message));
Jose Marinhoa1dfeda2019-02-27 16:46:03 +000056
57 /* Message should be dropped since the mailbox was not cleared. */
Andrew Walbran70bc8622019-10-07 14:15:58 +010058 EXPECT_EQ(
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010059 ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, sizeof(message), 0)
Andrew Walbran70bc8622019-10-07 14:15:58 +010060 .func,
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010061 FFA_SUCCESS_32);
62 run_res = ffa_run(SERVICE_VM1, 0);
63 EXPECT_EQ(run_res.func, HF_FFA_RUN_WAIT_FOR_INTERRUPT);
64 EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000065
66 /* Clear the mailbox. We expect to be told there are pending waiters. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010067 EXPECT_EQ(ffa_rx_release().func, FFA_RX_RELEASE_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000068
69 /* Retrieve a single waiter. */
Fuad Tabba7bd14132019-11-07 14:18:52 +000070 EXPECT_EQ(hf_mailbox_waiter_get(HF_PRIMARY_VM_ID), SERVICE_VM1);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000071 EXPECT_EQ(hf_mailbox_waiter_get(HF_PRIMARY_VM_ID), -1);
72
73 /*
74 * Inject interrupt into VM and let it run again. We should receive
75 * the echoed message.
76 */
77 EXPECT_EQ(
Fuad Tabba7bd14132019-11-07 14:18:52 +000078 hf_interrupt_inject(SERVICE_VM1, 0, HF_MAILBOX_WRITABLE_INTID),
Andrew Scull2e7a76d2019-01-24 11:47:26 +000079 1);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010080 run_res = ffa_run(SERVICE_VM1, 0);
81 EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
82 EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
Andrew Walbran70bc8622019-10-07 14:15:58 +010083 EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010084 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
Andrew Scull2e7a76d2019-01-24 11:47:26 +000085}