/*
 * Copyright (c) 2020 Intel Corporation
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_
#define ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_

#include <drivers/pcie/msi.h>

typedef int (*vtd_alloc_entries_f)(const struct device *dev,
				   uint8_t n_entries);

typedef uint32_t (*vtd_remap_msi_f)(const struct device *dev,
				    msi_vector_t *vector,
				    uint8_t n_vector);

typedef int (*vtd_remap_f)(const struct device *dev,
			   uint8_t irte_idx,
			   uint16_t vector,
			   uint32_t flags,
			   uint16_t src_id);

typedef int (*vtd_set_irte_vector_f)(const struct device *dev,
				     uint8_t irte_idx,
				     uint16_t vector);

typedef int (*vtd_get_irte_by_vector_f)(const struct device *dev,
					uint16_t vector);

typedef uint16_t (*vtd_get_irte_vector_f)(const struct device *dev,
					  uint8_t irte_idx);

typedef int (*vtd_set_irte_irq_f)(const struct device *dev,
				  uint8_t irte_idx,
				  unsigned int irq);

typedef int (*vtd_get_irte_by_irq_f)(const struct device *dev,
				     unsigned int irq);

typedef void (*vtd_set_irte_msi_f)(const struct device *dev,
				   uint8_t irte_idx,
				   bool msi);

typedef bool (*vtd_irte_is_msi_f)(const struct device *dev,
				  uint8_t irte_idx);

struct vtd_driver_api {
	vtd_alloc_entries_f allocate_entries;
	vtd_remap_msi_f remap_msi;
	vtd_remap_f remap;
	vtd_set_irte_vector_f set_irte_vector;
	vtd_get_irte_by_vector_f get_irte_by_vector;
	vtd_get_irte_vector_f get_irte_vector;
	vtd_set_irte_irq_f set_irte_irq;
	vtd_get_irte_by_irq_f get_irte_by_irq;
	vtd_set_irte_msi_f set_irte_msi;
	vtd_irte_is_msi_f irte_is_msi;
};

/**
 * @brief Allocate contiguous IRTEs
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param n_entries How many IRTE to allocate
 *
 * Note: It will try to allocate all, or it will fail.
 *
 * @return The first allocated IRTE index, or -EBUSY on failure
 */
static inline int vtd_allocate_entries(const struct device *dev,
				       uint8_t n_entries)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->allocate_entries(dev, n_entries);
}

/**
 * @brief Generate the MSI Message Address data for the given vector
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param vector A valid allocated MSI vector array
 * @param n_vector the size of the vector array
 *
 * @return The MSI Message Address value
 */
static inline uint32_t vtd_remap_msi(const struct device *dev,
				     msi_vector_t *vector,
				     uint8_t n_vector)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->remap_msi(dev, vector, n_vector);
}

/**
 * @brief Remap the given vector
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param irte_idx A previously allocated irte entry index number
 * @param vector An allocated interrupt vector
 * @param flags interrupt flags
 * @param src_id a valid source ID or USHRT_MAX if none
 *
 * @return 0 on success, a negative errno otherwise
 */
static inline int vtd_remap(const struct device *dev,
			    uint8_t irte_idx,
			    uint16_t vector,
			    uint32_t flags,
			    uint16_t src_id)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->remap(dev, irte_idx, vector, flags, src_id);
}

/**
 * @brief Set the vector on the allocated irte
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param irte_idx A previously allocated irte entry index number
 * @param vector An allocated interrupt vector
 *
 * @return 0, a negative errno otherwise
 */
static inline int vtd_set_irte_vector(const struct device *dev,
				      uint8_t irte_idx,
				      uint16_t vector)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->set_irte_vector(dev, irte_idx, vector);
}

/**
 * @brief Get the irte allocated for the given vector
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param vector An allocated interrupt vector
 *
 * @return 0 or positive value on success, a negative errno otherwise
 */
static inline int vtd_get_irte_by_vector(const struct device *dev,
					 uint16_t vector)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->get_irte_by_vector(dev, vector);
}

/**
 * @brief Get the vector given to the IRTE
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param irte_idx A previously allocated irte entry index number
 *
 * @return the vector set to this IRTE
 */
static inline uint16_t vtd_get_irte_vector(const struct device *dev,
					   uint8_t irte_idx)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->get_irte_vector(dev, irte_idx);
}

/**
 * @brief Set the irq on the allocated irte
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param irte_idx A previously allocated irte entry index number
 * @param irq A valid IRQ number
 *
 * @return 0, a negative errno otherwise
 */
static inline int vtd_set_irte_irq(const struct device *dev,
				   uint8_t irte_idx,
				   unsigned int irq)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->set_irte_irq(dev, irte_idx, irq);
}

/**
 * @brief Get the irte allocated for the given irq
 *
 * @param dev Pointer to the device structure for the driver instance
 * @param irq A valid IRQ number
 *
 * @return 0 or positive value on success, a negative errno otherwise
 */
static inline int vtd_get_irte_by_irq(const struct device *dev,
				      unsigned int irq)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->get_irte_by_irq(dev, irq);
}

static inline void vtd_set_irte_msi(const struct device *dev,
				    uint8_t irte_idx,
				    bool msi)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->set_irte_msi(dev, irte_idx, msi);
}

static inline bool vtd_irte_is_msi(const struct device *dev,
				   uint8_t irte_idx)
{
	const struct vtd_driver_api *api =
		(const struct vtd_driver_api *)dev->api;

	return api->irte_is_msi(dev, irte_idx);
}


#endif /* ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_ */
