diff --git a/drivers/interrupt_controller/Kconfig.intel_vtd b/drivers/interrupt_controller/Kconfig.intel_vtd index b8465032e29..a60941d85c2 100644 --- a/drivers/interrupt_controller/Kconfig.intel_vtd +++ b/drivers/interrupt_controller/Kconfig.intel_vtd @@ -7,6 +7,7 @@ menuconfig INTEL_VTD_ICTL bool "Intel VT-D interrupt remapping controller" depends on ACPI && X86 && 64BIT select PCIE_MSI_MULTI_VECTOR + select CACHE_MANAGEMENT help Such interrupt remapping hardware is provided through Intel VT-D technology. It's being used, currently, only for MSI/MSI-X diff --git a/drivers/interrupt_controller/intc_intel_vtd.c b/drivers/interrupt_controller/intc_intel_vtd.c index 61303f9178f..352a1c3944a 100644 --- a/drivers/interrupt_controller/intc_intel_vtd.c +++ b/drivers/interrupt_controller/intc_intel_vtd.c @@ -17,6 +17,8 @@ #include +#include + #include #include #include @@ -74,6 +76,17 @@ static void vtd_send_cmd(const struct device *dev, } } +static void vtd_flush_irte_from_cache(const struct device *dev, + uint8_t irte_idx) +{ + struct vtd_ictl_data *data = dev->data; + + if (!data->pwc) { + sys_cache_data_range(&data->irte[irte_idx], + sizeof(struct vtd_irte), K_CACHE_WB); + } +} + static void vtd_qi_init(const struct device *dev) { struct vtd_ictl_data *data = dev->data; @@ -328,6 +341,8 @@ static int vtd_ictl_remap(const struct device *dev, vtd_index_iec_invalidate(dev, irte_idx); + vtd_flush_irte_from_cache(dev, irte_idx); + return 0; } @@ -417,6 +432,11 @@ static int vtd_ictl_init(const struct device *dev) DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + if (vtd_read_reg64(dev, VTD_ECAP_REG) & VTD_ECAP_C) { + printk("Page walk coherency supported\n"); + data->pwc = true; + } + vtd_fault_event_init(dev); vtd_qi_init(dev); diff --git a/drivers/interrupt_controller/intc_intel_vtd.h b/drivers/interrupt_controller/intc_intel_vtd.h index c11baacb6dd..eda4f60de67 100644 --- a/drivers/interrupt_controller/intc_intel_vtd.h +++ b/drivers/interrupt_controller/intc_intel_vtd.h @@ -114,6 +114,7 @@ struct vtd_ictl_data { uint16_t fault_record_num; uint16_t qi_tail; uint8_t fault_vector; + bool pwc; }; struct vtd_ictl_cfg { diff --git a/include/arch/x86/intel_vtd.h b/include/arch/x86/intel_vtd.h index 78ef29097e6..cc1ae0c7800 100644 --- a/include/arch/x86/intel_vtd.h +++ b/include/arch/x86/intel_vtd.h @@ -96,6 +96,9 @@ #define VTD_CAP_FRO(cap) \ (((uint64_t)cap & VTD_CAP_FRO_MASK) >> VTD_CAP_FRO_POS) +/* Extended Capability Register details */ +#define VTD_ECAP_C BIT(0) + /* Global Command Register details */ #define VTD_GCMD_CFI 23 #define VTD_GCMD_SIRTP 24