/*
 * Adapted from Hafnium.
 * TODO: Figure out the right way of specifying the license header.
 */

#include "arm64/ffa_utils.h"


static struct mailbox_buffers mb;

#ifndef be16toh
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__

#define be16toh(v) __builtin_bswap16(v)
#define be32toh(v) __builtin_bswap32(v)
#define be64toh(v) __builtin_bswap64(v)

#define htobe16(v) __builtin_bswap16(v)
#define htobe32(v) __builtin_bswap32(v)
#define htobe64(v) __builtin_bswap64(v)

#define le16toh(v) (v)
#define le32toh(v) (v)
#define le64toh(v) (v)

#define htole16(v) (v)
#define htole32(v) (v)
#define htole64(v) (v)

#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__

#define be16toh(v) (v)
#define be32toh(v) (v)
#define be64toh(v) (v)

#define htobe16(v) (v)
#define htobe32(v) (v)
#define htobe64(v) (v)

#define le16toh(v) __builtin_bswap16(v)
#define le32toh(v) __builtin_bswap32(v)
#define le64toh(v) __builtin_bswap64(v)

#define htole16(v) __builtin_bswap16(v)
#define htole32(v) __builtin_bswap32(v)
#define htole64(v) __builtin_bswap64(v)

#else

/*
 * __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ &&
 * __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
 */

#error "Unsupported byte order"

#endif
#endif


/**
 * Reverses the order of the elements in the given array.
 */
static void reverse(char *s, size_t len)
{
	size_t i;

	for (i = 0; i < len / 2; i++) {
		char t = s[i];
		s[i] = s[len - 1 - i];
		s[len - 1 - i] = t;
	}
}

/**
 * Finds the next lexicographic permutation of the given array, if there is one.
 */
static void next_permutation(char *s, size_t len)
{
	size_t i;
	size_t j;

	for (i = len - 2; i < len; i--) {
		const char t = s[i];
		if (t >= s[i + 1]) {
			continue;
		}

		for (j = len - 1; t >= s[j]; j--) {
		}

		s[i] = s[j];
		s[j] = t;
		reverse(s + i + 1, len - i - 1);
		return;
	}
}

static void service_echo(int count)
{
        report_info("%s: %d: VM id %d is running!", __func__, __LINE__, get_vm_id());

	/* Loop, echo messages back to the sender. */
	while (count--) {
		struct ffa_value ret = ffa_msg_wait();
		ffa_vm_id_t target_vm_id = ffa_msg_send_receiver(ret);
		ffa_vm_id_t source_vm_id = ffa_msg_send_sender(ret);
		void *send_buf = mb.send;
		void *recv_buf = mb.recv;

		ASSERT_EQ(ret.func, FFA_MSG_SEND_32);
		memcpy_s(send_buf, FFA_MSG_PAYLOAD_MAX, recv_buf,
			 ffa_msg_send_size(ret));

		EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
		ffa_msg_send(target_vm_id, source_vm_id, ffa_msg_send_size(ret),
			     0);
	}

        report_info("%s: %d: VM id %d is done!", __func__, __LINE__, get_vm_id());
}

static void service_relay(int count)
{
        report_info("%s: %d: VM id %d is running!", __func__, __LINE__, get_vm_id());

	/*
	 * Loop, forward messages to the next VM.
	 *
	 * The first 32-bits of the message are the little-endian 32-bit ID of
	 * the VM to forward the message to. This ID will be dropped from the
	 * message so multiple IDs can be places at the start of the message.
	 */
	while (count--) {
		ffa_vm_id_t *chain;
		ffa_vm_id_t next_vm_id;
		void *next_message;
		uint32_t next_message_size;

		/* Receive the message to relay. */
		struct ffa_value ret = ffa_msg_wait();
		ASSERT_EQ(ret.func, FFA_MSG_SEND_32);

		/* Prepare to relay the message. */
		void *send_buf = mb.send;
		void *recv_buf = mb.recv;
		ASSERT_GE(ffa_msg_send_size(ret), sizeof(ffa_vm_id_t));

		chain = (ffa_vm_id_t *)recv_buf;
		next_vm_id = le16toh(*chain);
		next_message = chain + 1;
		next_message_size =
			ffa_msg_send_size(ret) - sizeof(ffa_vm_id_t);

		/* Send the message to the next stage. */
		memcpy_s(send_buf, FFA_MSG_PAYLOAD_MAX, next_message,
			 next_message_size);

		EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
		ffa_msg_send(get_vm_id(), next_vm_id, next_message_size, 0);
	}

	report_info("%s: %d: VM id %d is done!", __func__, __LINE__, get_vm_id());
}

static void service_clear_empty(void)
{
        report_info("%s: %d: VM id %d is running!", __func__, __LINE__, get_vm_id());
        report_info("%s: %d: VM id %d is done!", __func__, __LINE__, get_vm_id());
}

static void echo(void)
{
	const char message[] = "Echo this back to me!";
	struct ffa_value run_res;

	EXPECT(is_primary_vm());

	run_res = ffa_run(SERVICE_VM1, 0);
	EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
	EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);

	/* Set the message, echo it and check it didn't change. */
	memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message, sizeof(message));
	EXPECT_EQ(
		ffa_msg_send(get_vm_id(), SERVICE_VM1, sizeof(message), 0)
			.func,
		FFA_SUCCESS_32);
	run_res = ffa_run(SERVICE_VM1, 0);
	EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
	EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
	EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
	EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);

	report(true, "%s", __func__);
}

static void repeated_echo(int count)
{
	char message[] = "Echo this back to me!";
	struct ffa_value run_res;

	while (count--) {
		/* Run secondary until it reaches the wait for messages. */
		run_res = ffa_run(SERVICE_VM1, 0);
		EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
		EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);

		/* Set the message, echo it and check it didn't change. */
		next_permutation(message, sizeof(message) - 1);
		memcpy_s(mb.send, FFA_MSG_PAYLOAD_MAX, message,
			 sizeof(message));
		EXPECT_EQ(ffa_msg_send(get_vm_id(), SERVICE_VM1,
				       sizeof(message), 0)
				  .func,
			  FFA_SUCCESS_32);
		run_res = ffa_run(SERVICE_VM1, 0);
		EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
		EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
		EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
		EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
	}

	report(true, "%s", __func__);
}

/**
 * Send a message to relay_a which will forward it to relay_b where it will be
 * sent back here.
 */
static void relay(void)
{
	const char message[] = "Send this round the relay!";
	struct ffa_value run_res;

	run_res = ffa_run(SERVICE_VM1, 0);
	EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
	EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
	run_res = ffa_run(SERVICE_VM2, 0);
	EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
	EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);

	/*
	 * Build the message chain so the message is sent from here to
	 * SERVICE_VM1, then to SERVICE_VM2 and finally back to here.
	 */
	{
		ffa_vm_id_t *chain = (ffa_vm_id_t *)mb.send;
		*chain++ = htole32(SERVICE_VM2);
		*chain++ = htole32(get_vm_id());
		memcpy_s(chain, FFA_MSG_PAYLOAD_MAX - (2 * sizeof(ffa_vm_id_t)),
			 message, sizeof(message));

		EXPECT_EQ(
			ffa_msg_send(
				get_vm_id(), SERVICE_VM1,
				sizeof(message) + (2 * sizeof(ffa_vm_id_t)), 0)
				.func,
			FFA_SUCCESS_32);
	}

	/* Let SERVICE_VM1 forward the message. */
	run_res = ffa_run(SERVICE_VM1, 0);
	EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);
	EXPECT_EQ(ffa_msg_send_receiver(run_res), SERVICE_VM2);
	EXPECT_EQ(ffa_msg_send_size(run_res), 0);

	/* Let SERVICE_VM2 forward the message. */
	run_res = ffa_run(SERVICE_VM2, 0);
	EXPECT_EQ(run_res.func, FFA_MSG_SEND_32);

	/* Ensure the message is intact. */
	EXPECT_EQ(ffa_msg_send_receiver(run_res), get_vm_id());
	EXPECT_EQ(ffa_msg_send_size(run_res), sizeof(message));
	EXPECT_EQ(memcmp(mb.recv, message, sizeof(message)), 0);
	EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);

	report(true, "%s", __func__);
}


/**
 * Clearing an empty mailbox is an error.
 */
static void clear_empty(void)
{
	EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
	EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
	EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
	report(true, "%s", __func__);
}

static void test_echo(void)
{
	if (is_primary_vm()) {
		echo();
	} else {
		service_echo(1);
	}
}

static void test_repeated_echo(void)
{
	int count = 100;

	if (is_primary_vm()) {
		repeated_echo(count);
	} else {
		service_echo(count);
	}
}

static void test_relay(void)
{
	if (is_primary_vm()) {
		relay();
	} else {
		service_relay(1);
	}
}

static void test_clear_empty(void)
{
	if (is_primary_vm()) {
		clear_empty();
	} else {
		service_clear_empty();
	}
}

int main(void)
{
	mb = set_up_mailbox();

	if (0) {
	test_echo();
	test_repeated_echo();
	test_clear_empty();}
	test_relay();

	if (is_primary_vm()) {
		return report_summary();
	} else {
		return 0;
	}
}
