drivers/interrupt_controller: Expanding VT-D public API
Adding a way to pre-install the irg/vector on an irte and a way to get an irte based on irq/vector. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
1a1bc0d242
commit
edef8e6b0d
3 changed files with 229 additions and 1 deletions
|
@ -104,6 +104,82 @@ static int vtd_ictl_remap(const struct device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vtd_ictl_set_irte_vector(const struct device *dev,
|
||||||
|
uint8_t irte_idx,
|
||||||
|
uint16_t vector)
|
||||||
|
{
|
||||||
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
|
||||||
|
data->vectors[irte_idx] = vector;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vtd_ictl_get_irte_by_vector(const struct device *dev,
|
||||||
|
uint16_t vector)
|
||||||
|
{
|
||||||
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
int irte_idx;
|
||||||
|
|
||||||
|
for (irte_idx = 0; irte_idx < IRTE_NUM; irte_idx++) {
|
||||||
|
if (data->vectors[irte_idx] == vector) {
|
||||||
|
return irte_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t vtd_ictl_get_irte_vector(const struct device *dev,
|
||||||
|
uint8_t irte_idx)
|
||||||
|
{
|
||||||
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
|
||||||
|
return data->vectors[irte_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vtd_ictl_set_irte_irq(const struct device *dev,
|
||||||
|
uint8_t irte_idx,
|
||||||
|
unsigned int irq)
|
||||||
|
{
|
||||||
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
|
||||||
|
data->irqs[irte_idx] = irq;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vtd_ictl_get_irte_by_irq(const struct device *dev,
|
||||||
|
unsigned int irq)
|
||||||
|
{
|
||||||
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
int irte_idx;
|
||||||
|
|
||||||
|
for (irte_idx = 0; irte_idx < IRTE_NUM; irte_idx++) {
|
||||||
|
if (data->irqs[irte_idx] == irq) {
|
||||||
|
return irte_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vtd_ictl_set_irte_msi(const struct device *dev,
|
||||||
|
uint8_t irte_idx, bool msi)
|
||||||
|
{
|
||||||
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
|
||||||
|
data->msi[irte_idx] = msi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool vtd_ictl_irte_is_msi(const struct device *dev,
|
||||||
|
uint8_t irte_idx)
|
||||||
|
{
|
||||||
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
|
||||||
|
return data->msi[irte_idx];
|
||||||
|
}
|
||||||
|
|
||||||
static int vtd_ictl_init(const struct device *dev)
|
static int vtd_ictl_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct vtd_ictl_data *data = dev->data;
|
struct vtd_ictl_data *data = dev->data;
|
||||||
|
@ -142,9 +218,19 @@ static const struct vtd_driver_api vtd_api = {
|
||||||
.allocate_entries = vtd_ictl_allocate_entries,
|
.allocate_entries = vtd_ictl_allocate_entries,
|
||||||
.remap_msi = vtd_ictl_remap_msi,
|
.remap_msi = vtd_ictl_remap_msi,
|
||||||
.remap = vtd_ictl_remap,
|
.remap = vtd_ictl_remap,
|
||||||
|
.set_irte_vector = vtd_ictl_set_irte_vector,
|
||||||
|
.get_irte_by_vector = vtd_ictl_get_irte_by_vector,
|
||||||
|
.get_irte_vector = vtd_ictl_get_irte_vector,
|
||||||
|
.set_irte_irq = vtd_ictl_set_irte_irq,
|
||||||
|
.get_irte_by_irq = vtd_ictl_get_irte_by_irq,
|
||||||
|
.set_irte_msi = vtd_ictl_set_irte_msi,
|
||||||
|
.irte_is_msi = vtd_ictl_irte_is_msi
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct vtd_ictl_data vtd_ictl_data_0;
|
static struct vtd_ictl_data vtd_ictl_data_0 = {
|
||||||
|
.irqs = { -EINVAL },
|
||||||
|
.vectors = { -EINVAL },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct vtd_ictl_cfg vtd_ictl_cfg_0 = {
|
static const struct vtd_ictl_cfg vtd_ictl_cfg_0 = {
|
||||||
DEVICE_MMIO_ROM_INIT(DT_DRV_INST(0)),
|
DEVICE_MMIO_ROM_INIT(DT_DRV_INST(0)),
|
||||||
|
|
|
@ -48,6 +48,9 @@ struct vtd_irte {
|
||||||
|
|
||||||
struct vtd_ictl_data {
|
struct vtd_ictl_data {
|
||||||
struct vtd_irte irte[IRTE_NUM];
|
struct vtd_irte irte[IRTE_NUM];
|
||||||
|
int irqs[IRTE_NUM];
|
||||||
|
int vectors[IRTE_NUM];
|
||||||
|
bool msi[IRTE_NUM];
|
||||||
int irte_num_used;
|
int irte_num_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,41 @@ typedef int (*vtd_remap_f)(const struct device *dev,
|
||||||
uint16_t vector,
|
uint16_t vector,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
|
|
||||||
|
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 {
|
struct vtd_driver_api {
|
||||||
vtd_alloc_entries_f allocate_entries;
|
vtd_alloc_entries_f allocate_entries;
|
||||||
vtd_remap_msi_f remap_msi;
|
vtd_remap_msi_f remap_msi;
|
||||||
vtd_remap_f remap;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,5 +116,113 @@ static inline int vtd_remap(const struct device *dev,
|
||||||
return api->remap(dev, irte_idx, vector, flags);
|
return api->remap(dev, irte_idx, vector, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the vector on the allocated irte
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the device structure for the driver instance
|
||||||
|
* @param irte_idx A previoulsy 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 previoulsy 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 previoulsy 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_ */
|
#endif /* ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue