diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c index f08be52eb0e..290e6a4a8d2 100644 --- a/arch/x86/core/pcie.c +++ b/arch/x86/core/pcie.c @@ -290,7 +290,7 @@ bool arch_pcie_msi_vector_connect(msi_vector_t *vector, 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 87dc0f743f6..4012f5def2b 100644 --- a/drivers/interrupt_controller/intc_intel_vtd.c +++ b/drivers/interrupt_controller/intc_intel_vtd.c @@ -19,6 +19,7 @@ #include #include +#include #include "intc_intel_vtd.h" @@ -76,14 +77,15 @@ static uint32_t vtd_ictl_remap_msi(const struct device *dev, } 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 @@ static int vtd_ictl_remap(const struct device *dev, 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 7eadef04c6e..a2d043e8c02 100644 --- a/include/drivers/interrupt_controller/intel_vtd.h +++ b/include/drivers/interrupt_controller/intel_vtd.h @@ -16,7 +16,9 @@ typedef uint32_t (*vtd_remap_msi_f)(const struct device *dev, 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 @@ static inline uint32_t vtd_remap_msi(const struct device *dev, * @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 43dda038631..154934e63c1 100644 --- a/include/drivers/interrupt_controller/ioapic.h +++ b/include/drivers/interrupt_controller/ioapic.h @@ -27,6 +27,7 @@ extern "C" { #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