/*
 * Copyright 2019 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/dlog.h"

#include "vmapi/hf/call.h"

#include "../msr.h"
#include "sysregs.h"
#include "test/hftest.h"

/**
 * Tracks the number of times the exception handler has been invoked.
 */
static int exception_handler_exception_count = 0;

/**
 * Sends the number of exceptions handled to the Primary VM.
 */
void exception_handler_send_exception_count(void)
{
	void *send_buf = SERVICE_SEND_BUFFER();

	dlog("Sending exception_count %d to primary VM\n",
	     exception_handler_exception_count);
	memcpy_s(send_buf, FFA_MSG_PAYLOAD_MAX,
		 (const void *)&exception_handler_exception_count,
		 sizeof(exception_handler_exception_count));
	EXPECT_EQ(ffa_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID,
			       sizeof(exception_handler_exception_count), 0)
			  .func,
		  FFA_SUCCESS_32);
}

/**
 * Receives the number of exceptions handled.
 */
int exception_handler_receive_exception_count(
	const struct ffa_value *send_res,
	const struct ffa_memory_region *recv_buf)
{
	int exception_count = *((const int *)recv_buf);

	EXPECT_EQ(send_res->func, FFA_MSG_SEND_32);
	EXPECT_EQ(ffa_msg_send_size(*send_res), sizeof(exception_count));
	EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
	return exception_count;
}

/**
 * EL1 exception handler to use in unit test VMs.
 * Skips the instruction that triggered the exception.
 */
bool exception_handler_skip_instruction(void)
{
	dlog("%s function is triggered!\n", __func__);
	++exception_handler_exception_count;

	/* Skip instruction that triggered the exception. */
	uint64_t next_pc = read_msr(elr_el1);
	next_pc += 4UL;
	write_msr(elr_el1, next_pc);

	/* Indicate that elr_el1 should not be restored. */
	return true;
}

/**
 * EL1 exception handler to use in unit test VMs.
 * Yields control back to the hypervisor and sends the number of exceptions.
 */
static bool exception_handler_yield(void)
{
	dlog("%s function is triggered!\n", __func__);
	++exception_handler_exception_count;

	exception_handler_send_exception_count();

	/* Indicate that elr_el1 should not be restored. */
	return true;
}

/**
 * EL1 exception handler to use in unit test VMs.
 * Yields control back to the hypervisor and sends the number of exceptions.
 * Asserts that the Exception Class is Unknown.
 */
bool exception_handler_yield_unknown(void)
{
	uintreg_t esr_el1 = read_msr(ESR_EL1);
	EXPECT_EQ(GET_ESR_EC(esr_el1), EC_UNKNOWN);
	return exception_handler_yield();
}

/**
 * EL1 exception handler to use in unit test VMs.
 * Yields control back to the hypervisor and sends the number of exceptions.
 * Asserts that the Exception Class is Data Abort (same EL).
 */
bool exception_handler_yield_data_abort(void)
{
	uintreg_t esr_el1 = read_msr(ESR_EL1);
	EXPECT_EQ(GET_ESR_EC(esr_el1), EC_DATA_ABORT_SAME_EL);
	return exception_handler_yield();
}

/**
 * EL1 exception handler to use in unit test VMs.
 * Yields control back to the hypervisor and sends the number of exceptions.
 * Asserts that the Exception Class is Instruction Abort (same EL).
 */
bool exception_handler_yield_instruction_abort(void)
{
	uintreg_t esr_el1 = read_msr(ESR_EL1);
	EXPECT_EQ(GET_ESR_EC(esr_el1), EC_INSTRUCTION_ABORT_SAME_EL);
	return exception_handler_yield();
}

/**
 * Returns the number of times the instruction handler was invoked.
 */
int exception_handler_get_num(void)
{
	return exception_handler_exception_count;
}

/**
 * Resets the number of exceptions counter;
 */
void exception_handler_reset(void)
{
	exception_handler_exception_count = 0;
}
