diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c index cf503d4a201..f08be52eb0e 100644 --- a/arch/x86/core/pcie.c +++ b/arch/x86/core/pcie.c @@ -187,7 +187,7 @@ uint32_t pcie_msi_map(unsigned int irq, ARG_UNUSED(irq); #if defined(CONFIG_INTEL_VTD_ICTL) - return vtd_remap_msi(vtd, vector); + return vtd_remap_msi(vtd, vector, n_vector); #else return 0xFEE00000U; /* standard delivery to BSP local APIC */ #endif diff --git a/drivers/interrupt_controller/intc_intel_vtd.c b/drivers/interrupt_controller/intc_intel_vtd.c index 7e307d01830..898c7323c11 100644 --- a/drivers/interrupt_controller/intc_intel_vtd.c +++ b/drivers/interrupt_controller/intc_intel_vtd.c @@ -68,9 +68,12 @@ static int vtd_ictl_allocate_entries(const struct device *dev, } static uint32_t vtd_ictl_remap_msi(const struct device *dev, - msi_vector_t *vector) + msi_vector_t *vector, + uint8_t n_vector) { - return VTD_MSI_MAP(vector->arch.irte); + uint32_t shv = (n_vector > 1) ? VTD_INT_SHV : 0; + + return VTD_MSI_MAP(vector->arch.irte, shv); } static int vtd_ictl_remap(const struct device *dev, diff --git a/drivers/interrupt_controller/intc_intel_vtd.h b/drivers/interrupt_controller/intc_intel_vtd.h index 912ec1e6150..353d8283f0c 100644 --- a/drivers/interrupt_controller/intc_intel_vtd.h +++ b/drivers/interrupt_controller/intc_intel_vtd.h @@ -12,8 +12,8 @@ /* We don't care about int_idx[15], since the size is fixed to 256, * it's always 0 */ -#define VTD_MSI_MAP(int_idx) \ - ((0x0FEE << 20) | (int_idx << 5) | VTD_INT_SHV | VTD_INT_FORMAT) +#define VTD_MSI_MAP(int_idx, shv) \ + ((0x0FEE00000U) | (int_idx << 5) | shv | VTD_INT_FORMAT) /* Interrupt Remapping Table Entry (IRTE) for Remapped Interrupts */ struct vtd_irte { diff --git a/include/drivers/interrupt_controller/intel_vtd.h b/include/drivers/interrupt_controller/intel_vtd.h index 08c3e4a4ab8..7eadef04c6e 100644 --- a/include/drivers/interrupt_controller/intel_vtd.h +++ b/include/drivers/interrupt_controller/intel_vtd.h @@ -12,7 +12,8 @@ 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); + msi_vector_t *vector, + uint8_t n_vector); typedef int (*vtd_remap_f)(const struct device *dev, msi_vector_t *vector); @@ -46,17 +47,19 @@ static inline int vtd_allocate_entries(const struct device *dev, * @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 + * @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) + 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); + return api->remap_msi(dev, vector, n_vector); } /**