diff options
Diffstat (limited to 'sys/x86/iommu/intel_utils.c')
-rw-r--r-- | sys/x86/iommu/intel_utils.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/sys/x86/iommu/intel_utils.c b/sys/x86/iommu/intel_utils.c index 8dc2f35..f696f9d 100644 --- a/sys/x86/iommu/intel_utils.c +++ b/sys/x86/iommu/intel_utils.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/taskqueue.h> #include <sys/tree.h> +#include <sys/vmem.h> #include <dev/pci/pcivar.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -57,6 +58,8 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_pageout.h> #include <machine/bus.h> #include <machine/cpu.h> +#include <machine/intr_machdep.h> +#include <x86/include/apicvar.h> #include <x86/include/busdma_impl.h> #include <x86/iommu/intel_reg.h> #include <x86/iommu/busdma_dmar.h> @@ -521,6 +524,55 @@ dmar_disable_translation(struct dmar_unit *unit) return (0); } +int +dmar_load_irt_ptr(struct dmar_unit *unit) +{ + uint64_t irta, s; + + DMAR_ASSERT_LOCKED(unit); + irta = unit->irt_phys; + if (DMAR_X2APIC(unit)) + irta |= DMAR_IRTA_EIME; + s = fls(unit->irte_cnt) - 2; + KASSERT(unit->irte_cnt >= 2 && s <= DMAR_IRTA_S_MASK && + powerof2(unit->irte_cnt), + ("IRTA_REG_S overflow %x", unit->irte_cnt)); + irta |= s; + dmar_write8(unit, DMAR_IRTA_REG, irta); + dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd | DMAR_GCMD_SIRTP); + /* XXXKIB should have a timeout */ + while ((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_IRTPS) == 0) + cpu_spinwait(); + return (0); +} + +int +dmar_enable_ir(struct dmar_unit *unit) +{ + + DMAR_ASSERT_LOCKED(unit); + unit->hw_gcmd |= DMAR_GCMD_IRE; + unit->hw_gcmd &= ~DMAR_GCMD_CFI; + dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd); + /* XXXKIB should have a timeout */ + while ((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_IRES) == 0) + cpu_spinwait(); + return (0); +} + +int +dmar_disable_ir(struct dmar_unit *unit) +{ + + DMAR_ASSERT_LOCKED(unit); + unit->hw_gcmd &= ~DMAR_GCMD_IRE; + dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd); + /* XXXKIB should have a timeout */ + while ((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_IRES) != 0) + cpu_spinwait(); + return (0); +} + #define BARRIER_F \ u_int f_done, f_inproc, f_wakeup; \ \ |