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>
This commit is contained in:
Tomasz Bursztyka 2020-12-16 11:10:21 +01:00 committed by Anas Nashif
parent 2b1cbcbddc
commit 1a1bc0d242
4 changed files with 23 additions and 8 deletions

View file

@ -290,7 +290,7 @@ bool arch_pcie_msi_vector_connect(msi_vector_t *vector,
return false; return false;
} }
vtd_remap(vtd, vector); vtd_remap(vtd, vector->arch.irte, vector->arch.vector, flags);
} }
#endif /* CONFIG_INTEL_VTD_ICTL */ #endif /* CONFIG_INTEL_VTD_ICTL */

View file

@ -19,6 +19,7 @@
#include <arch/x86/intel_vtd.h> #include <arch/x86/intel_vtd.h>
#include <drivers/interrupt_controller/intel_vtd.h> #include <drivers/interrupt_controller/intel_vtd.h>
#include <drivers/interrupt_controller/ioapic.h>
#include "intc_intel_vtd.h" #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, 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; struct vtd_ictl_data *data = dev->data;
uint8_t irte_idx = vector->arch.irte;
memset(&data->irte[irte_idx], 0, sizeof(struct vtd_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)) { if (IS_ENABLED(CONFIG_X2APIC)) {
data->irte[irte_idx].l.dst_id = arch_curr_cpu()->id; 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.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; data->irte[irte_idx].l.present = 1;
return 0; return 0;

View file

@ -16,7 +16,9 @@ typedef uint32_t (*vtd_remap_msi_f)(const struct device *dev,
uint8_t n_vector); uint8_t n_vector);
typedef int (*vtd_remap_f)(const struct device *dev, 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 { struct vtd_driver_api {
vtd_alloc_entries_f allocate_entries; 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 * @brief Remap the given vector
* *
* @param dev Pointer to the device structure for the driver instance * @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 * @return 0 on success, a negative errno otherwise
*/ */
static inline int vtd_remap(const struct device *dev, 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 *api =
(const struct vtd_driver_api *)dev->api; (const struct vtd_driver_api *)dev->api;
return api->remap(dev, vector); return api->remap(dev, irte_idx, vector, flags);
} }

View file

@ -27,6 +27,7 @@ extern "C" {
#define IOAPIC_HIGH 0x00000000 #define IOAPIC_HIGH 0x00000000
#define IOAPIC_LOGICAL 0x00000800 #define IOAPIC_LOGICAL 0x00000800
#define IOAPIC_PHYSICAL 0x00000000 #define IOAPIC_PHYSICAL 0x00000000
#define IOAPIC_DELIVERY_MODE_MASK 0x00000700
#define IOAPIC_FIXED 0x00000000 #define IOAPIC_FIXED 0x00000000
#define IOAPIC_LOWEST 0x00000100 #define IOAPIC_LOWEST 0x00000100
#define IOAPIC_SMI 0x00000200 #define IOAPIC_SMI 0x00000200