summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/drm_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/drm/drm_linux.c')
-rw-r--r--sys/dev/pci/drm/drm_linux.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c
index 8810360c58c..7939c70570a 100644
--- a/sys/dev/pci/drm/drm_linux.c
+++ b/sys/dev/pci/drm/drm_linux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_linux.c,v 1.2 2015/04/06 12:25:10 jsg Exp $ */
+/* $OpenBSD: drm_linux.c,v 1.3 2015/04/08 02:28:13 jsg Exp $ */
/*
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
*
@@ -117,3 +117,65 @@ dmi_check_system(const struct dmi_system_id *sysid)
}
return (num);
}
+
+void *
+kmap(struct vm_page *pg)
+{
+ vaddr_t va;
+
+#if defined (__HAVE_PMAP_DIRECT)
+ va = pmap_map_direct(pg);
+#else
+ va = uvm_km_valloc_wait(phys_map, PAGE_SIZE);
+ pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), PROT_READ | PROT_WRITE);
+ pmap_update(pmap_kernel());
+#endif
+ return (void *)va;
+}
+
+void
+kunmap(void *addr)
+{
+ vaddr_t va = (vaddr_t)addr;
+
+#if defined (__HAVE_PMAP_DIRECT)
+ pmap_unmap_direct(va);
+#else
+ pmap_kremove(va, PAGE_SIZE);
+ pmap_update(pmap_kernel());
+ uvm_km_free_wakeup(phys_map, va, PAGE_SIZE);
+#endif
+}
+
+void *
+vmap(struct vm_page **pages, unsigned int npages, unsigned long flags,
+ pgprot_t prot)
+{
+ vaddr_t va;
+ paddr_t pa;
+ int i;
+
+ va = uvm_km_valloc_wait(phys_map, PAGE_SIZE * npages);
+ if (va == 0)
+ return NULL;
+ for (i = 0; i < npages; i++) {
+ pa = VM_PAGE_TO_PHYS(pages[i]) | prot;
+ pmap_enter(pmap_kernel(), va + (i * PAGE_SIZE), pa,
+ PROT_READ | PROT_WRITE,
+ PROT_READ | PROT_WRITE | PMAP_WIRED);
+ pmap_update(pmap_kernel());
+ }
+
+ return (void *)va;
+}
+
+void
+vunmap(void *addr, size_t size)
+{
+ vaddr_t va = (vaddr_t)addr;
+
+ pmap_remove(pmap_kernel(), va, va + size);
+ pmap_update(pmap_kernel());
+ uvm_km_free(phys_map, va, size);
+}
+