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