/*
 * Copyright 2018 The Hafnium Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hf/mm.h"
#include "hf/std.h"

#include "vmapi/hf/call.h"

#include "hftest.h"
#include "primary_with_secondary.h"

alignas(PAGE_SIZE) static uint8_t page[PAGE_SIZE];

TEST_SERVICE(memory_increment)
{
	/* Loop, writing message to the shared memory. */
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), 0);
		uint8_t *ptr;
		size_t i;

		/* Check the memory was cleared. */
		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		ptr = *(uint8_t **)recv_buf->payload;
		spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr),
				  recv_buf->source_vm_id, hf_vm_get_id());

		for (int i = 0; i < PAGE_SIZE; ++i) {
			ASSERT_EQ(ptr[i], 0);
		}

		/* Allow the memory to be populated. */
		EXPECT_EQ(spci_yield(), SPCI_SUCCESS);

		/* Increment each byte of memory. */
		for (i = 0; i < PAGE_SIZE; ++i) {
			++ptr[i];
		}

		/* Signal completion and reset. */
		hf_mailbox_clear();
		spci_msg_send(0);
	}
}

TEST_SERVICE(memory_lend_relinquish_spci)
{
	/* Loop, giving memory back to the sender. */
	for (;;) {
		spci_msg_wait();
		uint8_t *ptr;

		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)(spci_get_lend_descriptor(
							      recv_buf)
							      ->payload);

		ptr = (uint8_t *)memory_region->constituents[0].address;
		/* Relevant information read, mailbox can be cleared. */
		hf_mailbox_clear();

		/* Check that one has access to the shared region. */
		for (int i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}

		hf_mailbox_clear();
		/* Give the memory back and notify the sender. */
		spci_memory_relinquish(
			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
			memory_region->constituents, memory_region->count, 0);
		spci_msg_send(0);

		/*
		 * Try and access the memory which will cause a fault unless the
		 * memory has been shared back again.
		 */
		ptr[0] = 123;
	}
}

TEST_SERVICE(memory_return)
{
	/* Loop, giving memory back to the sender. */
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), 0);
		uint8_t *ptr;

		/* Check the memory was cleared. */
		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		ptr = *(uint8_t **)recv_buf->payload;
		spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr),
				  recv_buf->source_vm_id, hf_vm_get_id());

		for (int i = 0; i < PAGE_SIZE; ++i) {
			ASSERT_EQ(ptr[i], 0);
		}

		/* Give the memory back and notify the sender. */
		ASSERT_EQ(hf_share_memory(recv_buf->source_vm_id,
					  (hf_ipaddr_t)ptr, PAGE_SIZE,
					  HF_MEMORY_GIVE),
			  0);
		hf_mailbox_clear();
		spci_msg_send(0);

		/*
		 * Try and access the memory which will cause a fault unless the
		 * memory has been shared back again.
		 */
		ptr[0] = 123;
	}
}

TEST_SERVICE(give_memory_and_fault)
{
	uint8_t *ptr = page;

	/* Give memory to the primary. */
	ASSERT_EQ(hf_share_memory(HF_PRIMARY_VM_ID, (hf_ipaddr_t)&page,
				  PAGE_SIZE, HF_MEMORY_GIVE),
		  0);

	/*
	 * TODO: the address of the memory will be part of the proper API. That
	 *       API is still to be agreed on so the address is passed
	 *       explicitly to test the mechanism.
	 */
	memcpy_s(SERVICE_SEND_BUFFER()->payload, SPCI_MSG_PAYLOAD_MAX, &ptr,
		 sizeof(ptr));
	spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr), HF_PRIMARY_VM_ID,
			  hf_vm_get_id());
	EXPECT_EQ(spci_msg_send(0), 0);

	/* Try using the memory that isn't valid unless it's been returned. */
	page[16] = 123;
}

TEST_SERVICE(lend_memory_and_fault)
{
	uint8_t *ptr = page;

	/* Lend memory to the primary. */
	ASSERT_EQ(hf_share_memory(HF_PRIMARY_VM_ID, (hf_ipaddr_t)&page,
				  PAGE_SIZE, HF_MEMORY_LEND),
		  0);

	/*
	 * TODO: the address of the memory will be part of the proper API. That
	 *       API is still to be agreed on so the address is passed
	 *       explicitly to test the mechanism.
	 */
	memcpy_s(SERVICE_SEND_BUFFER()->payload, SPCI_MSG_PAYLOAD_MAX, &ptr,
		 sizeof(ptr));
	spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr), HF_PRIMARY_VM_ID,
			  hf_vm_get_id());
	EXPECT_EQ(spci_msg_send(0), 0);

	/* Try using the memory that isn't valid unless it's been returned. */
	page[633] = 180;
}

TEST_SERVICE(spci_memory_return)
{
	/* Loop, giving memory back to the sender. */
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), 0);
		uint8_t *ptr;

		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			spci_get_donated_memory_region(recv_buf);
		hf_mailbox_clear();

		ptr = (uint8_t *)memory_region->constituents[0].address;

		/* Check that one has access to the shared region. */
		for (int i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}

		/* Give the memory back and notify the sender. */
		spci_memory_donate(
			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
			memory_region->constituents, memory_region->count, 0);
		spci_msg_send(0);

		/*
		 * Try and access the memory which will cause a fault unless the
		 * memory has been shared back again.
		 */
		ptr[0] = 123;
	}
}

TEST_SERVICE(spci_donate_check_upper_bound)
{
	EXPECT_EQ(spci_msg_wait(), 0);
	uint8_t *ptr;

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_memory_region *memory_region =
		spci_get_donated_memory_region(recv_buf);
	hf_mailbox_clear();

	ptr = (uint8_t *)memory_region->constituents[0].address;

	/* Check that one cannot access out of bounds after donated region. */
	ptr[PAGE_SIZE]++;
}

TEST_SERVICE(spci_donate_check_lower_bound)
{
	EXPECT_EQ(spci_msg_wait(), 0);
	uint8_t *ptr;

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_memory_region *memory_region =
		spci_get_donated_memory_region(recv_buf);
	hf_mailbox_clear();

	ptr = (uint8_t *)memory_region->constituents[0].address;

	/* Check that one cannot access out of bounds before donated region. */
	ptr[-1]++;
}

/**
 * SPCI: Attempt to donate memory and then modify.
 */
TEST_SERVICE(spci_donate_secondary_and_fault)
{
	EXPECT_EQ(spci_msg_wait(), 0);
	uint8_t *ptr;

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		spci_get_donated_memory_region(recv_buf);
	hf_mailbox_clear();

	ptr = (uint8_t *)memory_region->constituents[0].address;

	/* Donate memory to next VM. */
	spci_memory_donate(send_buf, SERVICE_VM1, recv_buf->target_vm_id,
			   memory_region->constituents, memory_region->count,
			   0);
	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);

	/* Ensure that we are unable to modify memory any more. */
	ptr[0] = 'c';
	EXPECT_EQ(ptr[0], 'c');
	spci_yield();
}

/**
 * SPCI: Attempt to donate memory twice from VM.
 */
TEST_SERVICE(spci_donate_twice)
{
	EXPECT_EQ(spci_msg_wait(), 0);

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		spci_get_donated_memory_region(recv_buf);
	struct spci_memory_region_constituent constituent =
		memory_region->constituents[0];
	hf_mailbox_clear();

	/* Yield to allow attempt to re donate from primary. */
	spci_yield();

	/* Give the memory back and notify the sender. */
	spci_memory_donate(send_buf, HF_PRIMARY_VM_ID, SERVICE_VM0,
			   &constituent, memory_region->count, 0);
	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);

	/* Attempt to donate the memory to another VM. */
	spci_memory_donate(send_buf, SERVICE_VM1, recv_buf->target_vm_id,
			   &constituent, memory_region->count, 0);
	EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);

	spci_yield();
}

/**
 * SPCI: Continually receive memory, check if we have access
 * and ensure it is not changed by a third party.
 */
TEST_SERVICE(spci_memory_receive)
{
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), 0);
		uint8_t *ptr;

		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_memory_region *memory_region =
			spci_get_donated_memory_region(recv_buf);
		hf_mailbox_clear();

		ptr = (uint8_t *)memory_region->constituents[0].address;
		ptr[0] = 'd';
		spci_yield();

		/* Ensure memory has not changed. */
		EXPECT_EQ(ptr[0], 'd');
		spci_yield();
	}
}

/**
 * SPCI: Receive memory and attempt to donate from primary VM.
 */
TEST_SERVICE(spci_donate_invalid_source)
{
	EXPECT_EQ(spci_msg_wait(), 0);

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		spci_get_donated_memory_region(recv_buf);
	hf_mailbox_clear();

	/* Give the memory back and notify the sender. */
	spci_memory_donate(send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
			   memory_region->constituents, memory_region->count,
			   0);
	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);

	/* Fail to donate the memory from the primary to VM1. */
	spci_memory_donate(send_buf, SERVICE_VM1, HF_PRIMARY_VM_ID,
			   memory_region->constituents, memory_region->count,
			   0);
	EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
	spci_yield();
}

TEST_SERVICE(spci_memory_lend_relinquish)
{
	/* Loop, giving memory back to the sender. */
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
		uint8_t *ptr;

		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)(spci_get_lend_descriptor(
							      recv_buf)
							      ->payload);

		ptr = (uint8_t *)memory_region->constituents[0].address;
		/* Relevant information read, mailbox can be cleared. */
		hf_mailbox_clear();

		/* Check that one has access to the shared region. */
		for (int i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}

		hf_mailbox_clear();
		/* Give the memory back and notify the sender. */
		spci_memory_relinquish(
			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
			memory_region->constituents, memory_region->count, 0);
		spci_msg_send(0);

		/*
		 * Try and access the memory which will cause a fault unless the
		 * memory has been shared back again.
		 */
		ptr[0] = 123;
	}
}

/**
 * SPCI: Ensure that we can't relinquish donated memory.
 */
TEST_SERVICE(spci_memory_donate_relinquish)
{
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
		uint8_t *ptr;

		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			spci_get_donated_memory_region(recv_buf);
		hf_mailbox_clear();

		ptr = (uint8_t *)memory_region->constituents[0].address;

		/* Check that one has access to the shared region. */
		for (int i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}
		/* Give the memory back and notify the sender. */
		spci_memory_relinquish(
			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
			memory_region->constituents, memory_region->count, 0);
		EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);

		/* Ensure we still have access to the memory. */
		ptr[0] = 123;

		spci_yield();
	}
}

/**
 * SPCI: Receive memory and attempt to donate from primary VM.
 */
TEST_SERVICE(spci_lend_invalid_source)
{
	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
						      ->payload);
	hf_mailbox_clear();

	/* Attempt to relinquish from primary VM. */
	spci_memory_relinquish(send_buf, recv_buf->target_vm_id,
			       HF_PRIMARY_VM_ID, memory_region->constituents,
			       memory_region->count, 0);
	EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);

	/* Give the memory back and notify the sender. */
	spci_memory_relinquish(
		send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
		memory_region->constituents, memory_region->count, 0);
	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);

	/* Ensure we cannot lend from the primary to another secondary. */
	spci_memory_lend(send_buf, SERVICE_VM1, HF_PRIMARY_VM_ID,
			 memory_region->constituents, memory_region->count, 0,
			 SPCI_LEND_RW_X, SPCI_LEND_NORMAL_MEM,
			 SPCI_LEND_CACHE_WRITE_BACK, SPCI_LEND_OUTER_SHAREABLE);
	EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
	spci_yield();
}

/**
 * SPCI: Attempt to execute an instruction from the lent memory.
 */
TEST_SERVICE(spci_memory_lend_relinquish_X)
{
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
		uint64_t *ptr;

		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)(spci_get_lend_descriptor(
							      recv_buf)
							      ->payload);
		hf_mailbox_clear();

		ptr = (uint64_t *)memory_region->constituents[0].address;
		/*
		 * Verify that the instruction in memory is the encoded RET
		 * instruction.
		 */
		EXPECT_EQ(*ptr, 0xD65F03C0);
		/* Try to execute instruction from the shared memory region. */
		__asm__ volatile("blr %0" ::"r"(ptr));

		/* Release the memory again. */
		spci_memory_relinquish(
			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
			memory_region->constituents, memory_region->count, 0);
		EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
	}
}

/**
 * SPCI: Attempt to read and write to a shared page.
 */
TEST_SERVICE(spci_memory_lend_relinquish_RW)
{
	for (;;) {
		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
		uint8_t *ptr;

		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)(spci_get_lend_descriptor(
							      recv_buf)
							      ->payload);
		hf_mailbox_clear();

		ptr = (uint8_t *)memory_region->constituents[0].address;

		/* Check that we have read access. */
		for (int i = 0; i < PAGE_SIZE; ++i) {
			EXPECT_EQ(ptr[i], 'b');
		}

		/* Return control to primary, to verify shared access. */
		spci_yield();

		/* Attempt to modify the memory. */
		for (int i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}

		spci_memory_relinquish(
			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
			memory_region->constituents, memory_region->count, 0);
		EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
	}
}

/**
 * SPCI: Attempt to modify below the lower bound for the lent memory.
 */
TEST_SERVICE(spci_lend_check_lower_bound)
{
	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
	uint8_t *ptr;

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
						      ->payload);
	hf_mailbox_clear();

	ptr = (uint8_t *)memory_region->constituents[0].address;

	/* Check that one cannot access before donated region. */
	ptr[-1]++;
}

/**
 * SPCI: Attempt to modify above the upper bound for the lent memory.
 */
TEST_SERVICE(spci_lend_check_upper_bound)
{
	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
	uint8_t *ptr;

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
						      ->payload);
	hf_mailbox_clear();

	ptr = (uint8_t *)memory_region->constituents[0].address;

	/* Check that one cannot access after donated region. */
	ptr[PAGE_SIZE]++;
}

TEST_SERVICE(spci_memory_lend_twice)
{
	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
	uint8_t *ptr;

	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
						      ->payload);
	hf_mailbox_clear();

	ptr = (uint8_t *)memory_region->constituents[0].address;

	/* Check that we have read access. */
	for (int i = 0; i < PAGE_SIZE; ++i) {
		EXPECT_EQ(ptr[i], 'b');
	}

	/* Return control to primary. */
	spci_yield();

	/* Attempt to modify the memory. */
	for (int i = 0; i < PAGE_SIZE; ++i) {
		ptr[i]++;
	}

	for (int i = 1; i < PAGE_SIZE * 2; i++) {
		memory_region->constituents[0].address = (uint64_t)ptr + i;

		/* Fail to lend the memory back to the primary. */
		spci_memory_lend(
			send_buf, SERVICE_VM1, HF_PRIMARY_VM_ID,
			memory_region->constituents, memory_region->count, 0,
			SPCI_LEND_RW_X, SPCI_LEND_NORMAL_MEM,
			SPCI_LEND_CACHE_WRITE_BACK, SPCI_LEND_OUTER_SHAREABLE);
		EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
	}

	spci_memory_relinquish(
		send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
		memory_region->constituents, memory_region->count, 0);
	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
}
