/*
 * 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.
 */

#pragma once

#include "hf/abi.h"
#include "hf/spci.h"
#include "hf/types.h"

/**
 * This function must be implemented to trigger the architecture-specific
 * mechanism to call to the hypervisor.
 */
int64_t hf_call(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3);
struct spci_value spci_call(struct spci_value args);

/**
 * Returns the VM's own ID.
 */
static inline struct spci_value spci_id_get(void)
{
	return spci_call((struct spci_value){.func = SPCI_ID_GET_32});
}

/**
 * Returns the VM's own ID.
 */
static inline spci_vm_id_t hf_vm_get_id(void)
{
	return spci_id_get().arg2;
}

/**
 * Returns the number of secondary VMs.
 */
static inline spci_vm_count_t hf_vm_get_count(void)
{
	return hf_call(HF_VM_GET_COUNT, 0, 0, 0);
}

/**
 * Returns the number of vCPUs configured in the given secondary VM.
 */
static inline spci_vcpu_count_t hf_vcpu_get_count(spci_vm_id_t vm_id)
{
	return hf_call(HF_VCPU_GET_COUNT, vm_id, 0, 0);
}

/**
 * Runs the given vCPU of the given VM.
 */
static inline struct spci_value spci_run(spci_vm_id_t vm_id,
					 spci_vcpu_index_t vcpu_idx)
{
	return spci_call((struct spci_value){.func = SPCI_RUN_32,
					     spci_vm_vcpu(vm_id, vcpu_idx)});
}

/**
 * Hints that the vCPU is willing to yield its current use of the physical CPU.
 * This call always returns SPCI_SUCCESS.
 */
static inline struct spci_value spci_yield(void)
{
	return spci_call((struct spci_value){.func = SPCI_YIELD_32});
}

/**
 * Configures the pages to send/receive data through. The pages must not be
 * shared.
 *
 * Returns:
 *  - SPCI_ERROR SPCI_INVALID_PARAMETERS if the given addresses are not properly
 *    aligned or are the same.
 *  - SPCI_ERROR SPCI_NO_MEMORY if the hypervisor was unable to map the buffers
 *    due to insuffient page table memory.
 *  - SPCI_ERROR SPCI_DENIED if the pages are already mapped or are not owned by
 *    the caller.
 *  - SPCI_SUCCESS on success if no further action is needed.
 *  - SPCI_RX_RELEASE if it was called by the primary VM and the primary VM now
 *    needs to wake up or kick waiters.
 */
static inline struct spci_value spci_rxtx_map(hf_ipaddr_t send,
					      hf_ipaddr_t recv)
{
	return spci_call(
		(struct spci_value){.func = SPCI_RXTX_MAP_64,
				    .arg1 = send,
				    .arg2 = recv,
				    .arg3 = HF_MAILBOX_SIZE / SPCI_PAGE_SIZE});
}

/**
 * Copies data from the sender's send buffer to the recipient's receive buffer.
 *
 * If the recipient's receive buffer is busy, it can optionally register the
 * caller to be notified when the recipient's receive buffer becomes available.
 *
 * Attributes may include:
 *  - SPCI_MSG_SEND_NOTIFY, to notify the caller when it should try again.
 *  - SPCI_MSG_SEND_LEGACY_MEMORY_*, to send a legacy architected memory sharing
 *    message.
 *
 * Returns SPCI_SUCCESS if the message is sent, or an error code otherwise:
 *  - INVALID_PARAMETERS: one or more of the parameters do not conform.
 *  - BUSY: the message could not be delivered either because the mailbox
 *    was full or the target VM is not yet set up.
 */
static inline struct spci_value spci_msg_send(spci_vm_id_t sender_vm_id,
					      spci_vm_id_t target_vm_id,
					      uint32_t size,
					      uint32_t attributes)
{
	return spci_call((struct spci_value){
		.func = SPCI_MSG_SEND_32,
		.arg1 = ((uint64_t)sender_vm_id << 16) | target_vm_id,
		.arg3 = size,
		.arg4 = attributes});
}

static inline struct spci_value spci_mem_donate(uint32_t fragment_length,
						uint32_t length,
						spci_cookie_t cookie)
{
	return spci_call((struct spci_value){.func = SPCI_MEM_DONATE_32,
					     .arg3 = fragment_length,
					     .arg4 = length,
					     .arg5 = cookie});
}

static inline struct spci_value spci_mem_lend(uint32_t fragment_length,
					      uint32_t length,
					      spci_cookie_t cookie)
{
	return spci_call((struct spci_value){.func = SPCI_MEM_LEND_32,
					     .arg3 = fragment_length,
					     .arg4 = length,
					     .arg5 = cookie});
}

static inline struct spci_value spci_mem_share(uint32_t fragment_length,
					       uint32_t length,
					       spci_cookie_t cookie)
{
	return spci_call((struct spci_value){.func = SPCI_MEM_SHARE_32,
					     .arg3 = fragment_length,
					     .arg4 = length,
					     .arg5 = cookie});
}

static inline struct spci_value spci_mem_retrieve_req(uint32_t fragment_length,
						      uint32_t length,
						      spci_cookie_t cookie)
{
	return spci_call((struct spci_value){.func = SPCI_MEM_RETRIEVE_REQ_32,
					     .arg3 = fragment_length,
					     .arg4 = length,
					     .arg5 = cookie});
}

static inline struct spci_value spci_mem_relinquish(void)
{
	return spci_call((struct spci_value){.func = SPCI_MEM_RELINQUISH_32});
}

static inline struct spci_value spci_mem_reclaim(uint32_t handle,
						 uint32_t flags)
{
	return spci_call((struct spci_value){
		.func = SPCI_MEM_RECLAIM_32, .arg1 = handle, .arg2 = flags});
}

/**
 * Called by secondary VMs to receive a message. This will block until a message
 * is received.
 *
 * The mailbox must be cleared before a new message can be received.
 *
 * If no message is immediately available and there are no enabled and pending
 * interrupts (irrespective of whether interrupts are enabled globally), then
 * this will block until a message is available or an enabled interrupt becomes
 * pending. This matches the behaviour of the WFI instruction on AArch64, except
 * that a message becoming available is also treated like a wake-up event.
 *
 * Returns:
 *  - SPCI_MSG_SEND if a message is successfully received.
 *  - SPCI_ERROR SPCI_NOT_SUPPORTED if called from the primary VM.
 *  - SPCI_ERROR SPCI_INTERRUPTED if an interrupt happened during the call.
 */
static inline struct spci_value spci_msg_wait(void)
{
	return spci_call((struct spci_value){.func = SPCI_MSG_WAIT_32});
}

/**
 * Called by secondary VMs to receive a message. The call will return whether or
 * not a message is available.
 *
 * The mailbox must be cleared before a new message can be received.
 *
 * Returns:
 *  - SPCI_MSG_SEND if a message is successfully received.
 *  - SPCI_ERROR SPCI_NOT_SUPPORTED if called from the primary VM.
 *  - SPCI_ERROR SPCI_INTERRUPTED if an interrupt happened during the call.
 *  - SPCI_ERROR SPCI_RETRY if there was no pending message.
 */
static inline struct spci_value spci_msg_poll(void)
{
	return spci_call((struct spci_value){.func = SPCI_MSG_POLL_32});
}

/**
 * Releases the caller's mailbox so that a new message can be received. The
 * caller must have copied out all data they wish to preserve as new messages
 * will overwrite the old and will arrive asynchronously.
 *
 * Returns:
 *  - SPCI_ERROR SPCI_DENIED on failure, if the mailbox hasn't been read.
 *  - SPCI_SUCCESS on success if no further action is needed.
 *  - SPCI_RX_RELEASE if it was called by the primary VM and the primary VM now
 *    needs to wake up or kick waiters. Waiters should be retrieved by calling
 *    hf_mailbox_waiter_get.
 */
static inline struct spci_value spci_rx_release(void)
{
	return spci_call((struct spci_value){.func = SPCI_RX_RELEASE_32});
}

/**
 * Retrieves the next VM whose mailbox became writable. For a VM to be notified
 * by this function, the caller must have called api_mailbox_send before with
 * the notify argument set to true, and this call must have failed because the
 * mailbox was not available.
 *
 * It should be called repeatedly to retrieve a list of VMs.
 *
 * Returns -1 if no VM became writable, or the id of the VM whose mailbox
 * became writable.
 */
static inline int64_t hf_mailbox_writable_get(void)
{
	return hf_call(HF_MAILBOX_WRITABLE_GET, 0, 0, 0);
}

/**
 * Retrieves the next VM waiting to be notified that the mailbox of the
 * specified VM became writable. Only primary VMs are allowed to call this.
 *
 * Returns -1 on failure or if there are no waiters; the VM id of the next
 * waiter otherwise.
 */
static inline int64_t hf_mailbox_waiter_get(spci_vm_id_t vm_id)
{
	return hf_call(HF_MAILBOX_WAITER_GET, vm_id, 0, 0);
}

/**
 * Enables or disables a given interrupt ID.
 *
 * Returns 0 on success, or -1 if the intid is invalid.
 */
static inline int64_t hf_interrupt_enable(uint32_t intid, bool enable)
{
	return hf_call(HF_INTERRUPT_ENABLE, intid, enable, 0);
}

/**
 * Gets the ID of the pending interrupt (if any) and acknowledge it.
 *
 * Returns HF_INVALID_INTID if there are no pending interrupts.
 */
static inline uint32_t hf_interrupt_get(void)
{
	return hf_call(HF_INTERRUPT_GET, 0, 0, 0);
}

/**
 * Injects a virtual interrupt of the given ID into the given target vCPU.
 * This doesn't cause the vCPU to actually be run immediately; it will be taken
 * when the vCPU is next run, which is up to the scheduler.
 *
 * Returns:
 *  - -1 on failure because the target VM or vCPU doesn't exist, the interrupt
 *    ID is invalid, or the current VM is not allowed to inject interrupts to
 *    the target VM.
 *  - 0 on success if no further action is needed.
 *  - 1 if it was called by the primary VM and the primary VM now needs to wake
 *    up or kick the target vCPU.
 */
static inline int64_t hf_interrupt_inject(spci_vm_id_t target_vm_id,
					  spci_vcpu_index_t target_vcpu_idx,
					  uint32_t intid)
{
	return hf_call(HF_INTERRUPT_INJECT, target_vm_id, target_vcpu_idx,
		       intid);
}

/**
 * Sends a character to the debug log for the VM.
 *
 * Returns 0 on success, or -1 if it failed for some reason.
 */
static inline int64_t hf_debug_log(char c)
{
	return hf_call(HF_DEBUG_LOG, c, 0, 0);
}

/** Obtains the Hafnium's version of the implemented SPCI specification. */
static inline struct spci_value spci_version(void)
{
	return spci_call((struct spci_value){.func = SPCI_VERSION_32});
}

/**
 * Discovery function returning information about the implementation of optional
 * SPCI interfaces.
 *
 * Returns:
 *  - SPCI_SUCCESS in .func if the optional interface with function_id is
 * implemented.
 *  - SPCI_ERROR in .func if the optional interface with function_id is not
 * implemented.
 */
static inline struct spci_value spci_features(uint32_t function_id)
{
	return spci_call((struct spci_value){.func = SPCI_FEATURES_32,
					     .arg1 = function_id});
}
