Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/iommu/busdma_dmar.c
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/memdesc.h> | #include <sys/memdesc.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <sys/tree.h> | #include <sys/tree.h> | ||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/vmem.h> | |||||
#include <dev/pci/pcireg.h> | #include <dev/pci/pcireg.h> | ||||
#include <dev/pci/pcivar.h> | #include <dev/pci/pcivar.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_extern.h> | #include <vm/vm_extern.h> | ||||
#include <vm/vm_kern.h> | #include <vm/vm_kern.h> | ||||
#include <vm/vm_object.h> | #include <vm/vm_object.h> | ||||
#include <vm/vm_page.h> | #include <vm/vm_page.h> | ||||
#include <vm/vm_map.h> | #include <vm/vm_map.h> | ||||
Show All 29 Lines | |||||
* Given original device, find the requester ID that will be seen by | * Given original device, find the requester ID that will be seen by | ||||
* the DMAR unit and used for page table lookup. PCI bridges may take | * the DMAR unit and used for page table lookup. PCI bridges may take | ||||
* ownership of transactions from downstream devices, so it may not be | * ownership of transactions from downstream devices, so it may not be | ||||
* the same as the BSF of the target device. In those cases, all | * the same as the BSF of the target device. In those cases, all | ||||
* devices downstream of the bridge must share a single mapping | * devices downstream of the bridge must share a single mapping | ||||
* domain, and must collectively be assigned to use either DMAR or | * domain, and must collectively be assigned to use either DMAR or | ||||
* bounce mapping. | * bounce mapping. | ||||
*/ | */ | ||||
static device_t | device_t | ||||
dmar_get_requester(device_t dev, uint16_t *rid) | dmar_get_requester(device_t dev, uint16_t *rid) | ||||
{ | { | ||||
devclass_t pci_class; | devclass_t pci_class; | ||||
device_t l, pci, pcib, pcip, pcibp, requester; | device_t l, pci, pcib, pcip, pcibp, requester; | ||||
int cap_offset; | int cap_offset; | ||||
uint16_t pcie_flags; | uint16_t pcie_flags; | ||||
bool bridge_is_pcie; | bool bridge_is_pcie; | ||||
▲ Show 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | dmar_get_dma_tag(device_t dev, device_t child) | ||||
struct dmar_unit *dmar; | struct dmar_unit *dmar; | ||||
struct dmar_ctx *ctx; | struct dmar_ctx *ctx; | ||||
bus_dma_tag_t res; | bus_dma_tag_t res; | ||||
dmar = dmar_find(child); | dmar = dmar_find(child); | ||||
/* Not in scope of any DMAR ? */ | /* Not in scope of any DMAR ? */ | ||||
if (dmar == NULL) | if (dmar == NULL) | ||||
return (NULL); | return (NULL); | ||||
if (!dmar->dma_enabled) | |||||
return (NULL); | |||||
dmar_quirks_pre_use(dmar); | dmar_quirks_pre_use(dmar); | ||||
dmar_instantiate_rmrr_ctxs(dmar); | dmar_instantiate_rmrr_ctxs(dmar); | ||||
ctx = dmar_instantiate_ctx(dmar, child, false); | ctx = dmar_instantiate_ctx(dmar, child, false); | ||||
res = ctx == NULL ? NULL : (bus_dma_tag_t)&ctx->ctx_tag; | res = ctx == NULL ? NULL : (bus_dma_tag_t)&ctx->ctx_tag; | ||||
return (res); | return (res); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 581 Lines • ▼ Show 20 Lines | dmar_bus_schedule_dmamap(struct dmar_unit *unit, struct bus_dmamap_dmar *map) | ||||
DMAR_UNLOCK(unit); | DMAR_UNLOCK(unit); | ||||
taskqueue_enqueue(unit->delayed_taskqueue, &unit->dmamap_load_task); | taskqueue_enqueue(unit->delayed_taskqueue, &unit->dmamap_load_task); | ||||
} | } | ||||
int | int | ||||
dmar_init_busdma(struct dmar_unit *unit) | dmar_init_busdma(struct dmar_unit *unit) | ||||
{ | { | ||||
unit->dma_enabled = 1; | |||||
TUNABLE_INT_FETCH("hw.dmar.dma", &unit->dma_enabled); | |||||
TAILQ_INIT(&unit->delayed_maps); | TAILQ_INIT(&unit->delayed_maps); | ||||
TASK_INIT(&unit->dmamap_load_task, 0, dmar_bus_task_dmamap, unit); | TASK_INIT(&unit->dmamap_load_task, 0, dmar_bus_task_dmamap, unit); | ||||
unit->delayed_taskqueue = taskqueue_create("dmar", M_WAITOK, | unit->delayed_taskqueue = taskqueue_create("dmar", M_WAITOK, | ||||
taskqueue_thread_enqueue, &unit->delayed_taskqueue); | taskqueue_thread_enqueue, &unit->delayed_taskqueue); | ||||
taskqueue_start_threads(&unit->delayed_taskqueue, 1, PI_DISK, | taskqueue_start_threads(&unit->delayed_taskqueue, 1, PI_DISK, | ||||
"dmar%d busdma taskq", unit->unit); | "dmar%d busdma taskq", unit->unit); | ||||
return (0); | return (0); | ||||
} | } | ||||
Show All 12 Lines |