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