Lines Matching full:unit

64  * unit->fault_log, and schedules a task.
72 * For the same reason, each translation unit task is executed in its
80 dmar_fault_next(struct dmar_unit *unit, int faultp) in dmar_fault_next() argument
84 if (faultp == unit->fault_log_size) in dmar_fault_next()
90 dmar_fault_intr_clear(struct dmar_unit *unit, uint32_t fsts) in dmar_fault_intr_clear() argument
96 printf("DMAR%d: Invalidation timed out\n", unit->iommu.unit); in dmar_fault_intr_clear()
101 unit->iommu.unit); in dmar_fault_intr_clear()
106 unit->iommu.unit); in dmar_fault_intr_clear()
110 printf("DMAR%d: Advanced pending fault\n", unit->iommu.unit); in dmar_fault_intr_clear()
114 printf("DMAR%d: Advanced fault overflow\n", unit->iommu.unit); in dmar_fault_intr_clear()
118 dmar_write4(unit, DMAR_FSTS_REG, clear); in dmar_fault_intr_clear()
124 struct dmar_unit *unit; in dmar_fault_intr() local
130 unit = IOMMU2DMAR((struct iommu_unit *)arg); in dmar_fault_intr()
132 fsts = dmar_read4(unit, DMAR_FSTS_REG); in dmar_fault_intr()
133 dmar_fault_intr_clear(unit, fsts); in dmar_fault_intr()
140 frir = (DMAR_CAP_FRO(unit->hw_cap) + fri) * 16; in dmar_fault_intr()
141 fault_rec[1] = dmar_read8(unit, frir + 8); in dmar_fault_intr()
144 fault_rec[0] = dmar_read8(unit, frir); in dmar_fault_intr()
145 dmar_write4(unit, frir + 12, DMAR_FRCD2_F32); in dmar_fault_intr()
146 DMAR_FAULT_LOCK(unit); in dmar_fault_intr()
147 faultp = unit->fault_log_head; in dmar_fault_intr()
148 if (dmar_fault_next(unit, faultp) == unit->fault_log_tail) { in dmar_fault_intr()
151 unit->fault_log[faultp] = fault_rec[0]; in dmar_fault_intr()
152 unit->fault_log[faultp + 1] = fault_rec[1]; in dmar_fault_intr()
153 unit->fault_log_head = dmar_fault_next(unit, faultp); in dmar_fault_intr()
156 DMAR_FAULT_UNLOCK(unit); in dmar_fault_intr()
158 if (fri >= DMAR_CAP_NFR(unit->hw_cap)) in dmar_fault_intr()
176 printf("DMAR%d: Fault Overflow\n", unit->iommu.unit); in dmar_fault_intr()
177 dmar_write4(unit, DMAR_FSTS_REG, DMAR_FSTS_PFO); in dmar_fault_intr()
181 taskqueue_enqueue(unit->fault_taskqueue, in dmar_fault_intr()
182 &unit->fault_task); in dmar_fault_intr()
190 struct dmar_unit *unit; in dmar_fault_task() local
195 unit = arg; in dmar_fault_task()
196 DMAR_FAULT_LOCK(unit); in dmar_fault_task()
198 faultp = unit->fault_log_tail; in dmar_fault_task()
199 if (faultp == unit->fault_log_head) in dmar_fault_task()
202 fault_rec[0] = unit->fault_log[faultp]; in dmar_fault_task()
203 fault_rec[1] = unit->fault_log[faultp + 1]; in dmar_fault_task()
204 unit->fault_log_tail = dmar_fault_next(unit, faultp); in dmar_fault_task()
205 DMAR_FAULT_UNLOCK(unit); in dmar_fault_task()
208 printf("DMAR%d: ", unit->iommu.unit); in dmar_fault_task()
209 DMAR_LOCK(unit); in dmar_fault_task()
210 ctx = dmar_find_ctx_locked(unit, sid); in dmar_fault_task()
231 DMAR_UNLOCK(unit); in dmar_fault_task()
238 DMAR_FAULT_LOCK(unit); in dmar_fault_task()
240 DMAR_FAULT_UNLOCK(unit); in dmar_fault_task()
244 dmar_clear_faults(struct dmar_unit *unit) in dmar_clear_faults() argument
249 for (i = 0; i < DMAR_CAP_NFR(unit->hw_cap); i++) { in dmar_clear_faults()
250 frir = (DMAR_CAP_FRO(unit->hw_cap) + i) * 16; in dmar_clear_faults()
251 frec = dmar_read4(unit, frir + 12); in dmar_clear_faults()
254 dmar_write4(unit, frir + 12, DMAR_FRCD2_F32); in dmar_clear_faults()
256 fsts = dmar_read4(unit, DMAR_FSTS_REG); in dmar_clear_faults()
257 dmar_write4(unit, DMAR_FSTS_REG, fsts); in dmar_clear_faults()
261 dmar_init_fault_log(struct dmar_unit *unit) in dmar_init_fault_log() argument
264 mtx_init(&unit->fault_lock, "dmarflt", NULL, MTX_SPIN); in dmar_init_fault_log()
265 unit->fault_log_size = 256; /* 128 fault log entries */ in dmar_init_fault_log()
266 TUNABLE_INT_FETCH("hw.dmar.fault_log_size", &unit->fault_log_size); in dmar_init_fault_log()
267 if (unit->fault_log_size % 2 != 0) in dmar_init_fault_log()
269 unit->fault_log = malloc(sizeof(uint64_t) * unit->fault_log_size, in dmar_init_fault_log()
272 TASK_INIT(&unit->fault_task, 0, dmar_fault_task, unit); in dmar_init_fault_log()
273 unit->fault_taskqueue = taskqueue_create_fast("dmarff", M_WAITOK, in dmar_init_fault_log()
274 taskqueue_thread_enqueue, &unit->fault_taskqueue); in dmar_init_fault_log()
275 taskqueue_start_threads(&unit->fault_taskqueue, 1, PI_AV, in dmar_init_fault_log()
276 "dmar%d fault taskq", unit->iommu.unit); in dmar_init_fault_log()
278 DMAR_LOCK(unit); in dmar_init_fault_log()
279 dmar_disable_fault_intr(&unit->iommu); in dmar_init_fault_log()
280 dmar_clear_faults(unit); in dmar_init_fault_log()
281 dmar_enable_fault_intr(&unit->iommu); in dmar_init_fault_log()
282 DMAR_UNLOCK(unit); in dmar_init_fault_log()
288 dmar_fini_fault_log(struct dmar_unit *unit) in dmar_fini_fault_log() argument
291 if (unit->fault_taskqueue == NULL) in dmar_fini_fault_log()
294 DMAR_LOCK(unit); in dmar_fini_fault_log()
295 dmar_disable_fault_intr(&unit->iommu); in dmar_fini_fault_log()
296 DMAR_UNLOCK(unit); in dmar_fini_fault_log()
298 taskqueue_drain(unit->fault_taskqueue, &unit->fault_task); in dmar_fini_fault_log()
299 taskqueue_free(unit->fault_taskqueue); in dmar_fini_fault_log()
300 unit->fault_taskqueue = NULL; in dmar_fini_fault_log()
301 mtx_destroy(&unit->fault_lock); in dmar_fini_fault_log()
303 free(unit->fault_log, M_DEVBUF); in dmar_fini_fault_log()
304 unit->fault_log = NULL; in dmar_fini_fault_log()
305 unit->fault_log_head = unit->fault_log_tail = 0; in dmar_fini_fault_log()
311 struct dmar_unit *unit; in dmar_enable_fault_intr() local
314 unit = IOMMU2DMAR(iommu); in dmar_enable_fault_intr()
315 DMAR_ASSERT_LOCKED(unit); in dmar_enable_fault_intr()
316 fectl = dmar_read4(unit, DMAR_FECTL_REG); in dmar_enable_fault_intr()
318 dmar_write4(unit, DMAR_FECTL_REG, fectl); in dmar_enable_fault_intr()
324 struct dmar_unit *unit; in dmar_disable_fault_intr() local
327 unit = IOMMU2DMAR(iommu); in dmar_disable_fault_intr()
328 DMAR_ASSERT_LOCKED(unit); in dmar_disable_fault_intr()
329 fectl = dmar_read4(unit, DMAR_FECTL_REG); in dmar_disable_fault_intr()
330 dmar_write4(unit, DMAR_FECTL_REG, fectl | DMAR_FECTL_IM); in dmar_disable_fault_intr()