diff --git a/drivers/interrupt_controller/intc_intel_vtd.c b/drivers/interrupt_controller/intc_intel_vtd.c index 77c036f6112..2631ae3f58a 100644 --- a/drivers/interrupt_controller/intc_intel_vtd.c +++ b/drivers/interrupt_controller/intc_intel_vtd.c @@ -171,6 +171,16 @@ static int vtd_qi_send(const struct device *dev, return 0; } +static int vtd_global_cc_invalidate(const struct device *dev) +{ + union qi_icc_descriptor iec_desc = { 0 }; + + iec_desc.icc.type = QI_TYPE_ICC; + iec_desc.icc.granularity = 1; /* Global Invalidation requested */ + + return vtd_qi_send(dev, &iec_desc.desc); +} + static int vtd_global_iec_invalidate(const struct device *dev) { union qi_iec_descriptor iec_desc = { 0 }; @@ -462,6 +472,12 @@ static int vtd_ictl_init(const struct device *dev) vtd_qi_init(dev); + if (vtd_global_cc_invalidate(dev) != 0) { + printk("Could not perform ICC invalidation\n"); + ret = -EIO; + goto out; + } + if (IS_ENABLED(CONFIG_X2APIC)) { eime = VTD_IRTA_EIME; } diff --git a/drivers/interrupt_controller/intc_intel_vtd.h b/drivers/interrupt_controller/intc_intel_vtd.h index ad7aeed5f22..94c04bfa9ea 100644 --- a/drivers/interrupt_controller/intc_intel_vtd.h +++ b/drivers/interrupt_controller/intc_intel_vtd.h @@ -57,6 +57,25 @@ struct qi_descriptor { uint64_t high; }; +#define QI_TYPE_ICC 0x1UL + +union qi_icc_descriptor { + struct qi_descriptor desc; + + struct icc_bits { + uint64_t type : 4; + uint64_t granularity : 2; + uint64_t _reserved_0 : 3; + uint64_t zero : 3; + uint64_t _reserved_1 : 4; + uint64_t domain_id : 16; + uint64_t source_id : 16; + uint64_t function_mask : 2; + uint64_t _reserved_2 : 14; + uint64_t reserved; + } icc __packed; +}; + #define QI_TYPE_IEC 0x4UL union qi_iec_descriptor {