blob: 1ea363a792459c731c658831aa6f1179a4fbebe9 [file] [log] [blame]
Fuad Tabbabfa42bc2019-08-06 13:45:50 +01001/*
2 * Copyright 2019 The Hafnium Authors.
3 *
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.
Fuad Tabbabfa42bc2019-08-06 13:45:50 +01007 */
8
9#include <stdalign.h>
10#include <stdint.h>
11
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010012#include "hf/ffa.h"
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010013#include "hf/memiter.h"
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010014#include "hf/std.h"
15
16#include "vmapi/hf/call.h"
17#include "vmapi/hf/transport.h"
18
Andrew Walbran1e7c7742019-12-13 17:10:02 +000019#include "test/hftest.h"
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010020#include "test/vmapi/ffa.h"
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010021
22alignas(4096) uint8_t kstack[4096];
23
24static alignas(HF_MAILBOX_SIZE) uint8_t send[HF_MAILBOX_SIZE];
25static alignas(HF_MAILBOX_SIZE) uint8_t recv[HF_MAILBOX_SIZE];
26
27static hf_ipaddr_t send_addr = (hf_ipaddr_t)send;
28static hf_ipaddr_t recv_addr = (hf_ipaddr_t)recv;
29
30static struct hftest_context global_context;
31
32struct hftest_context *hftest_get_context(void)
33{
34 return &global_context;
35}
36
37noreturn void abort(void)
38{
39 HFTEST_LOG("Service contained failures.");
40 /* Cause a fault, as a secondary can't power down the machine. */
41 *((volatile uint8_t *)1) = 1;
42
43 /* This should never be reached, but to make the compiler happy... */
44 for (;;) {
45 }
46}
47
48static void swap(uint64_t *a, uint64_t *b)
49{
50 uint64_t t = *a;
51 *a = *b;
52 *b = t;
53}
54
55noreturn void kmain(size_t memory_size)
56{
57 struct hftest_context *ctx;
58
59 /* Prepare the context. */
60
61 /* Set up the mailbox. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010062 ffa_rxtx_map(send_addr, recv_addr);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010063
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010064 EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010065
66 /* Clean the context. */
67 ctx = hftest_get_context();
68 memset_s(ctx, sizeof(*ctx), 0, sizeof(*ctx));
69 ctx->abort = abort;
Andrew Walbran70bc8622019-10-07 14:15:58 +010070 ctx->send = send;
71 ctx->recv = recv;
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010072 ctx->memory_size = memory_size;
73
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010074 for (;;) {
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010075 struct ffa_value ret;
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010076
77 /* Receive the packet. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010078 ret = ffa_msg_wait();
79 EXPECT_EQ(ret.func, FFA_MSG_SEND_32);
80 EXPECT_LE(ffa_msg_send_size(ret), FFA_MSG_PAYLOAD_MAX);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010081
82 /* Echo the message back to the sender. */
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010083 memcpy_s(send, FFA_MSG_PAYLOAD_MAX, recv,
84 ffa_msg_send_size(ret));
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010085
86 /* Swap the socket's source and destination ports */
Andrew Walbran70bc8622019-10-07 14:15:58 +010087 struct hf_msg_hdr *hdr = (struct hf_msg_hdr *)send;
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010088 swap(&(hdr->src_port), &(hdr->dst_port));
89
90 /* Swap the destination and source ids. */
J-Alvesd6f4e142021-03-05 13:33:59 +000091 ffa_vm_id_t dst_id = ffa_sender(ret);
92 ffa_vm_id_t src_id = ffa_receiver(ret);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010093
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010094 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
95 EXPECT_EQ(
96 ffa_msg_send(src_id, dst_id, ffa_msg_send_size(ret), 0)
97 .func,
98 FFA_SUCCESS_32);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010099 }
100}