drivers/interrupt_controller: Make VT-D remap generic and handle flags
This will not only be used by MSI remapping but by all relevant
interrupts.
Fix also IRTE settings:
- handle x2apic for destination id
- destination mode is always logical (as for IOAPIC)
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c
index f08be52..290e6a4 100644
--- a/arch/x86/core/pcie.c
+++ b/arch/x86/core/pcie.c
@@ -290,7 +290,7 @@
return false;
}
- vtd_remap(vtd, vector);
+ vtd_remap(vtd, vector->arch.irte, vector->arch.vector, flags);
}
#endif /* CONFIG_INTEL_VTD_ICTL */
diff --git a/drivers/interrupt_controller/intc_intel_vtd.c b/drivers/interrupt_controller/intc_intel_vtd.c
index 87dc0f7..4012f5d 100644
--- a/drivers/interrupt_controller/intc_intel_vtd.c
+++ b/drivers/interrupt_controller/intc_intel_vtd.c
@@ -19,6 +19,7 @@
#include <arch/x86/intel_vtd.h>
#include <drivers/interrupt_controller/intel_vtd.h>
+#include <drivers/interrupt_controller/ioapic.h>
#include "intc_intel_vtd.h"
@@ -76,14 +77,15 @@
}
static int vtd_ictl_remap(const struct device *dev,
- msi_vector_t *vector)
+ uint8_t irte_idx,
+ uint16_t vector,
+ uint32_t flags)
{
struct vtd_ictl_data *data = dev->data;
- uint8_t irte_idx = vector->arch.irte;
memset(&data->irte[irte_idx], 0, sizeof(struct vtd_irte));
- data->irte[irte_idx].l.vector = vector->arch.vector;
+ data->irte[irte_idx].l.vector = vector;
if (IS_ENABLED(CONFIG_X2APIC)) {
data->irte[irte_idx].l.dst_id = arch_curr_cpu()->id;
@@ -91,6 +93,12 @@
data->irte[irte_idx].l.dst_id = arch_curr_cpu()->id << 8;
}
+ data->irte[irte_idx].l.trigger_mode =
+ (flags & IOAPIC_TRIGGER_MASK) >> 15;
+ data->irte[irte_idx].l.delivery_mode =
+ (flags & IOAPIC_DELIVERY_MODE_MASK) >> 8;
+ data->irte[irte_idx].l.dst_mode = 1;
+ data->irte[irte_idx].l.redirection_hint = 1;
data->irte[irte_idx].l.present = 1;
return 0;
diff --git a/include/drivers/interrupt_controller/intel_vtd.h b/include/drivers/interrupt_controller/intel_vtd.h
index 7eadef0..a2d043e 100644
--- a/include/drivers/interrupt_controller/intel_vtd.h
+++ b/include/drivers/interrupt_controller/intel_vtd.h
@@ -16,7 +16,9 @@
uint8_t n_vector);
typedef int (*vtd_remap_f)(const struct device *dev,
- msi_vector_t *vector);
+ uint8_t irte_idx,
+ uint16_t vector,
+ uint32_t flags);
struct vtd_driver_api {
vtd_alloc_entries_f allocate_entries;
@@ -66,17 +68,21 @@
* @brief Remap the given vector
*
* @param dev Pointer to the device structure for the driver instance
- * @param vector A valid allocated MSI vector
+ * @param irte_idx A previoulsy allocated irte entry index number
+ * @param vector An allocated interrupt vector
+ * @param flags interrupt flags
*
* @return 0 on success, a negative errno otherwise
*/
static inline int vtd_remap(const struct device *dev,
- msi_vector_t *vector)
+ uint8_t irte_idx,
+ uint16_t vector,
+ uint32_t flags)
{
const struct vtd_driver_api *api =
(const struct vtd_driver_api *)dev->api;
- return api->remap(dev, vector);
+ return api->remap(dev, irte_idx, vector, flags);
}
diff --git a/include/drivers/interrupt_controller/ioapic.h b/include/drivers/interrupt_controller/ioapic.h
index 43dda03..154934e 100644
--- a/include/drivers/interrupt_controller/ioapic.h
+++ b/include/drivers/interrupt_controller/ioapic.h
@@ -27,6 +27,7 @@
#define IOAPIC_HIGH 0x00000000
#define IOAPIC_LOGICAL 0x00000800
#define IOAPIC_PHYSICAL 0x00000000
+#define IOAPIC_DELIVERY_MODE_MASK 0x00000700
#define IOAPIC_FIXED 0x00000000
#define IOAPIC_LOWEST 0x00000100
#define IOAPIC_SMI 0x00000200