blob: 460d1f18807f3445cee593ad1856a78641f7dbc5 [file] [log] [blame]
Fuad Tabbabfa42bc2019-08-06 13:45:50 +01001/*
2 * Copyright 2019 The Hafnium Authors.
3 *
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 <stdalign.h>
18#include <stdint.h>
19
20#include "hf/memiter.h"
21#include "hf/spci.h"
22#include "hf/std.h"
23
24#include "vmapi/hf/call.h"
25#include "vmapi/hf/transport.h"
26
27#include "hftest.h"
28
29alignas(4096) uint8_t kstack[4096];
30
31static alignas(HF_MAILBOX_SIZE) uint8_t send[HF_MAILBOX_SIZE];
32static alignas(HF_MAILBOX_SIZE) uint8_t recv[HF_MAILBOX_SIZE];
33
34static hf_ipaddr_t send_addr = (hf_ipaddr_t)send;
35static hf_ipaddr_t recv_addr = (hf_ipaddr_t)recv;
36
37static struct hftest_context global_context;
38
39struct hftest_context *hftest_get_context(void)
40{
41 return &global_context;
42}
43
44noreturn void abort(void)
45{
46 HFTEST_LOG("Service contained failures.");
47 /* Cause a fault, as a secondary can't power down the machine. */
48 *((volatile uint8_t *)1) = 1;
49
50 /* This should never be reached, but to make the compiler happy... */
51 for (;;) {
52 }
53}
54
55static void swap(uint64_t *a, uint64_t *b)
56{
57 uint64_t t = *a;
58 *a = *b;
59 *b = t;
60}
61
62noreturn void kmain(size_t memory_size)
63{
64 struct hftest_context *ctx;
65
66 /* Prepare the context. */
67
68 /* Set up the mailbox. */
69 hf_vm_configure(send_addr, recv_addr);
70
71 hf_mailbox_clear();
72
73 /* Clean the context. */
74 ctx = hftest_get_context();
75 memset_s(ctx, sizeof(*ctx), 0, sizeof(*ctx));
76 ctx->abort = abort;
Andrew Walbran70bc8622019-10-07 14:15:58 +010077 ctx->send = send;
78 ctx->recv = recv;
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010079 ctx->memory_size = memory_size;
80
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010081 for (;;) {
Andrew Walbrand4d2fa12019-10-01 16:47:25 +010082 struct spci_value ret;
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010083
84 /* Receive the packet. */
Andrew Walbrand4d2fa12019-10-01 16:47:25 +010085 ret = spci_msg_wait();
Andrew Walbranf1bd6322019-10-03 16:45:11 +010086 EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
Andrew Walbrand4d2fa12019-10-01 16:47:25 +010087 EXPECT_LE(spci_msg_send_size(ret), SPCI_MSG_PAYLOAD_MAX);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010088
89 /* Echo the message back to the sender. */
Andrew Walbran70bc8622019-10-07 14:15:58 +010090 memcpy_s(send, SPCI_MSG_PAYLOAD_MAX, recv,
91 spci_msg_send_size(ret));
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010092
93 /* Swap the socket's source and destination ports */
Andrew Walbran70bc8622019-10-07 14:15:58 +010094 struct hf_msg_hdr *hdr = (struct hf_msg_hdr *)send;
Fuad Tabbabfa42bc2019-08-06 13:45:50 +010095 swap(&(hdr->src_port), &(hdr->dst_port));
96
97 /* Swap the destination and source ids. */
Andrew Walbrand4d2fa12019-10-01 16:47:25 +010098 spci_vm_id_t dst_id = spci_msg_send_sender(ret);
99 spci_vm_id_t src_id = spci_msg_send_receiver(ret);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +0100100
Fuad Tabbabfa42bc2019-08-06 13:45:50 +0100101 hf_mailbox_clear();
Andrew Walbran70bc8622019-10-07 14:15:58 +0100102 EXPECT_EQ(spci_msg_send(src_id, dst_id, spci_msg_send_size(ret),
103 0)
104 .func,
105 SPCI_SUCCESS_32);
Fuad Tabbabfa42bc2019-08-06 13:45:50 +0100106 }
107}