1 /*
2  * Copyright 2018 The Hafnium Authors.
3  *
4  * 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.
7  */
8 
9 #include "hf/std.h"
10 
11 #include "vmapi/hf/call.h"
12 
13 #include "test/hftest.h"
14 
TEST_SERVICE(relay)15 TEST_SERVICE(relay)
16 {
17 	/*
18 	 * Loop, forward messages to the next VM.
19 	 *
20 	 * The first 32-bits of the message are the little-endian 32-bit ID of
21 	 * the VM to forward the message to. This ID will be dropped from the
22 	 * message so multiple IDs can be places at the start of the message.
23 	 */
24 	for (;;) {
25 		ffa_vm_id_t *chain;
26 		ffa_vm_id_t next_vm_id;
27 		void *next_message;
28 		uint32_t next_message_size;
29 
30 		/* Receive the message to relay. */
31 		struct ffa_value ret = ffa_msg_wait();
32 		ASSERT_EQ(ret.func, FFA_MSG_SEND_32);
33 
34 		/* Prepare to relay the message. */
35 		void *recv_buf = SERVICE_RECV_BUFFER();
36 		void *send_buf = SERVICE_SEND_BUFFER();
37 		ASSERT_GE(ffa_msg_send_size(ret), sizeof(ffa_vm_id_t));
38 
39 		chain = (ffa_vm_id_t *)recv_buf;
40 		next_vm_id = le16toh(*chain);
41 		next_message = chain + 1;
42 		next_message_size =
43 			ffa_msg_send_size(ret) - sizeof(ffa_vm_id_t);
44 
45 		/* Send the message to the next stage. */
46 		memcpy_s(send_buf, FFA_MSG_PAYLOAD_MAX, next_message,
47 			 next_message_size);
48 
49 		EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
50 		ffa_msg_send(hf_vm_get_id(), next_vm_id, next_message_size, 0);
51 	}
52 }
53