drivers/interrupt_controller: VT-D may manipulate the cache
Depending on a VT-D capability, it might be necessary to flush objects from the cache. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
25640f65c9
commit
149cef11ce
4 changed files with 25 additions and 0 deletions
|
@ -7,6 +7,7 @@ menuconfig INTEL_VTD_ICTL
|
||||||
bool "Intel VT-D interrupt remapping controller"
|
bool "Intel VT-D interrupt remapping controller"
|
||||||
depends on ACPI && X86 && 64BIT
|
depends on ACPI && X86 && 64BIT
|
||||||
select PCIE_MSI_MULTI_VECTOR
|
select PCIE_MSI_MULTI_VECTOR
|
||||||
|
select CACHE_MANAGEMENT
|
||||||
help
|
help
|
||||||
Such interrupt remapping hardware is provided through Intel VT-D
|
Such interrupt remapping hardware is provided through Intel VT-D
|
||||||
technology. It's being used, currently, only for MSI/MSI-X
|
technology. It's being used, currently, only for MSI/MSI-X
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#include <zephyr.h>
|
#include <zephyr.h>
|
||||||
|
|
||||||
|
#include <cache.h>
|
||||||
|
|
||||||
#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 <drivers/interrupt_controller/ioapic.h>
|
||||||
|
@ -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)
|
static void vtd_qi_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct vtd_ictl_data *data = dev->data;
|
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_index_iec_invalidate(dev, irte_idx);
|
||||||
|
|
||||||
|
vtd_flush_irte_from_cache(dev, irte_idx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,6 +432,11 @@ static int vtd_ictl_init(const struct device *dev)
|
||||||
|
|
||||||
DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);
|
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_fault_event_init(dev);
|
||||||
|
|
||||||
vtd_qi_init(dev);
|
vtd_qi_init(dev);
|
||||||
|
|
|
@ -114,6 +114,7 @@ struct vtd_ictl_data {
|
||||||
uint16_t fault_record_num;
|
uint16_t fault_record_num;
|
||||||
uint16_t qi_tail;
|
uint16_t qi_tail;
|
||||||
uint8_t fault_vector;
|
uint8_t fault_vector;
|
||||||
|
bool pwc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vtd_ictl_cfg {
|
struct vtd_ictl_cfg {
|
||||||
|
|
|
@ -96,6 +96,9 @@
|
||||||
#define VTD_CAP_FRO(cap) \
|
#define VTD_CAP_FRO(cap) \
|
||||||
(((uint64_t)cap & VTD_CAP_FRO_MASK) >> VTD_CAP_FRO_POS)
|
(((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 */
|
/* Global Command Register details */
|
||||||
#define VTD_GCMD_CFI 23
|
#define VTD_GCMD_CFI 23
|
||||||
#define VTD_GCMD_SIRTP 24
|
#define VTD_GCMD_SIRTP 24
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue