summaryrefslogtreecommitdiffstats
path: root/sys/x86/iommu/intel_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/x86/iommu/intel_utils.c')
-rw-r--r--sys/x86/iommu/intel_utils.c52
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; \
\
OpenPOWER on IntegriCloud