Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/iommu/intel_utils.c
Show First 20 Lines • Show All 476 Lines • ▼ Show 20 Lines | dmar_flush_write_bufs(struct dmar_unit *unit) | ||||
int error; | int error; | ||||
DMAR_ASSERT_LOCKED(unit); | DMAR_ASSERT_LOCKED(unit); | ||||
/* | /* | ||||
* DMAR_GCMD_WBF is only valid when CAP_RWBF is reported. | * DMAR_GCMD_WBF is only valid when CAP_RWBF is reported. | ||||
*/ | */ | ||||
KASSERT((unit->hw_cap & DMAR_CAP_RWBF) != 0, | KASSERT((unit->hw_cap & DMAR_CAP_RWBF) != 0, | ||||
("dmar%d: no RWBF", unit->unit)); | ("dmar%d: no RWBF", unit->iommu.unit)); | ||||
dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd | DMAR_GCMD_WBF); | dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd | DMAR_GCMD_WBF); | ||||
DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_WBFS) | DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_WBFS) | ||||
!= 0)); | != 0)); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | dmar_barrier_enter(struct dmar_unit *dmar, u_int barrier_id) | ||||
if ((dmar->barrier_flags & f_done) != 0) { | if ((dmar->barrier_flags & f_done) != 0) { | ||||
DMAR_UNLOCK(dmar); | DMAR_UNLOCK(dmar); | ||||
return (false); | return (false); | ||||
} | } | ||||
if ((dmar->barrier_flags & f_inproc) != 0) { | if ((dmar->barrier_flags & f_inproc) != 0) { | ||||
while ((dmar->barrier_flags & f_inproc) != 0) { | while ((dmar->barrier_flags & f_inproc) != 0) { | ||||
dmar->barrier_flags |= f_wakeup; | dmar->barrier_flags |= f_wakeup; | ||||
msleep(&dmar->barrier_flags, &dmar->lock, 0, | msleep(&dmar->barrier_flags, &dmar->iommu.lock, 0, | ||||
"dmarb", 0); | "dmarb", 0); | ||||
} | } | ||||
KASSERT((dmar->barrier_flags & f_done) != 0, | KASSERT((dmar->barrier_flags & f_done) != 0, | ||||
("dmar%d barrier %d missing done", dmar->unit, barrier_id)); | ("dmar%d barrier %d missing done", dmar->iommu.unit, | ||||
barrier_id)); | |||||
DMAR_UNLOCK(dmar); | DMAR_UNLOCK(dmar); | ||||
return (false); | return (false); | ||||
} | } | ||||
dmar->barrier_flags |= f_inproc; | dmar->barrier_flags |= f_inproc; | ||||
DMAR_UNLOCK(dmar); | DMAR_UNLOCK(dmar); | ||||
return (true); | return (true); | ||||
} | } | ||||
void | void | ||||
dmar_barrier_exit(struct dmar_unit *dmar, u_int barrier_id) | dmar_barrier_exit(struct dmar_unit *dmar, u_int barrier_id) | ||||
{ | { | ||||
BARRIER_F; | BARRIER_F; | ||||
DMAR_ASSERT_LOCKED(dmar); | DMAR_ASSERT_LOCKED(dmar); | ||||
KASSERT((dmar->barrier_flags & (f_done | f_inproc)) == f_inproc, | KASSERT((dmar->barrier_flags & (f_done | f_inproc)) == f_inproc, | ||||
("dmar%d barrier %d missed entry", dmar->unit, barrier_id)); | ("dmar%d barrier %d missed entry", dmar->iommu.unit, barrier_id)); | ||||
dmar->barrier_flags |= f_done; | dmar->barrier_flags |= f_done; | ||||
if ((dmar->barrier_flags & f_wakeup) != 0) | if ((dmar->barrier_flags & f_wakeup) != 0) | ||||
wakeup(&dmar->barrier_flags); | wakeup(&dmar->barrier_flags); | ||||
dmar->barrier_flags &= ~(f_inproc | f_wakeup); | dmar->barrier_flags &= ~(f_inproc | f_wakeup); | ||||
DMAR_UNLOCK(dmar); | DMAR_UNLOCK(dmar); | ||||
} | } | ||||
int dmar_batch_coalesce = 100; | int dmar_batch_coalesce = 100; | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |