Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/riastradh-drm2]: src/sys Implement Linux alloc_page/__free_page and kmap...
details: https://anonhg.NetBSD.org/src/rev/d7d33e4f1b6b
branches: riastradh-drm2
changeset: 788379:d7d33e4f1b6b
user: riastradh <riastradh%NetBSD.org@localhost>
date: Wed Jul 24 03:31:12 2013 +0000
description:
Implement Linux alloc_page/__free_page and kmap_atomic/kunmap_atomic.
diffstat:
sys/external/bsd/drm2/drm/drm_module.c | 15 +++-
sys/external/bsd/drm2/include/linux/gfp.h | 6 +-
sys/external/bsd/drm2/include/linux/highmem.h | 20 ++++-
sys/external/bsd/drm2/linux/linux_gfp.c | 76 +++++++++++++++++
sys/external/bsd/drm2/linux/linux_kmap.c | 112 ++++++++++++++++++++++++++
sys/modules/drm2/Makefile | 4 +-
6 files changed, 226 insertions(+), 7 deletions(-)
diffs (truncated from 328 to 300 lines):
diff -r 35e16cbad60d -r d7d33e4f1b6b sys/external/bsd/drm2/drm/drm_module.c
--- a/sys/external/bsd/drm2/drm/drm_module.c Wed Jul 24 03:30:42 2013 +0000
+++ b/sys/external/bsd/drm2/drm/drm_module.c Wed Jul 24 03:31:12 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_module.c,v 1.1.2.3 2013/07/24 03:14:31 riastradh Exp $ */
+/* $NetBSD: drm_module.c,v 1.1.2.4 2013/07/24 03:31:12 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,13 +30,15 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_module.c,v 1.1.2.3 2013/07/24 03:14:31 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_module.c,v 1.1.2.4 2013/07/24 03:31:12 riastradh Exp $");
#include <sys/types.h>
#include <sys/device.h>
#include <sys/module.h>
#include <sys/systm.h>
+#include <linux/highmem.h>
+
/*
* XXX I2C stuff should be moved to a separate drm2edid module.
*
@@ -63,12 +65,19 @@
switch (cmd) {
case MODULE_CMD_INIT:
+ error = linux_kmap_init();
+ if (error) {
+ aprint_error("drm: unable to initialize linux kmap:"
+ " %d", error);
+ return error;
+ }
#ifdef _MODULE
error = config_init_component(cfdriver_ioconf_drm,
cfattach_ioconf_drm, cfdata_ioconf_drm);
if (error) {
aprint_error("drm: unable to init component: %d\n",
error);
+ linux_kmap_fini();
return error;
}
error = devsw_attach("drm", NULL, &bmajor,
@@ -78,6 +87,7 @@
error);
(void)config_fini_component(cfdriver_ioconf_drm,
cfattach_ioconf_drm, cfdata_ioconf_drm);
+ linux_kmap_fini();
return error;
}
#endif
@@ -94,6 +104,7 @@
/* XXX Now what? Reattach the devsw? */
return error;
#endif
+ linux_kmap_fini();
return 0;
default:
diff -r 35e16cbad60d -r d7d33e4f1b6b sys/external/bsd/drm2/include/linux/gfp.h
--- a/sys/external/bsd/drm2/include/linux/gfp.h Wed Jul 24 03:30:42 2013 +0000
+++ b/sys/external/bsd/drm2/include/linux/gfp.h Wed Jul 24 03:31:12 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gfp.h,v 1.1.2.1 2013/07/24 03:30:42 riastradh Exp $ */
+/* $NetBSD: gfp.h,v 1.1.2.2 2013/07/24 03:31:12 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -61,8 +61,8 @@
#define __GFP_ZERO __BIT(12)
/* XXX Make the nm output a little more greppable... */
-#define alloc_page linux_gfp_alloc_page
-#define __free_page linux_gfp___free_page
+#define alloc_page linux_alloc_page
+#define __free_page linux___free_page
struct page;
struct page * alloc_page(gfp_t);
diff -r 35e16cbad60d -r d7d33e4f1b6b sys/external/bsd/drm2/include/linux/highmem.h
--- a/sys/external/bsd/drm2/include/linux/highmem.h Wed Jul 24 03:30:42 2013 +0000
+++ b/sys/external/bsd/drm2/include/linux/highmem.h Wed Jul 24 03:31:12 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: highmem.h,v 1.1.2.1 2013/07/24 00:33:12 riastradh Exp $ */
+/* $NetBSD: highmem.h,v 1.1.2.2 2013/07/24 03:31:12 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -32,4 +32,22 @@
#ifndef _LINUX_HIGHMEM_H_
#define _LINUX_HIGHMEM_H_
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <linux/kernel.h>
+#include <linux/mm_types.h>
+
+/* XXX Make the nm output a little more greppable... */
+#define kmap_atomic linux_kmap_atomic
+#define kunmap_atomic linux_kunmap_atomic
+
+int linux_kmap_init(void);
+void linux_kmap_fini(void);
+
+void * kmap_atomic(struct page *);
+void kunmap_atomic(void *);
+
#endif /* _LINUX_HIGHMEM_H_ */
diff -r 35e16cbad60d -r d7d33e4f1b6b sys/external/bsd/drm2/linux/linux_gfp.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/drm2/linux/linux_gfp.c Wed Jul 24 03:31:12 2013 +0000
@@ -0,0 +1,76 @@
+/* $NetBSD: linux_gfp.c,v 1.1.2.1 2013/07/24 03:31:12 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: linux_gfp.c,v 1.1.2.1 2013/07/24 03:31:12 riastradh Exp $");
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/mm_types.h>
+
+struct page *
+alloc_page(gfp_t gfp)
+{
+ paddr_t low = 0;
+ paddr_t high = ~(paddr_t)0;
+ struct pglist pglist;
+ struct vm_page *vm_page;
+ int error;
+
+ if (ISSET(gfp, __GFP_DMA32))
+ high = 0xffffffff;
+
+ error = uvm_pglistalloc(PAGE_SIZE, low, high, PAGE_SIZE, PAGE_SIZE,
+ &pglist, 1, ISSET(gfp, __GFP_WAIT));
+ if (error)
+ return NULL;
+
+ vm_page = TAILQ_FIRST(&pglist);
+ TAILQ_REMOVE(&pglist, vm_page, pageq.queue); /* paranoia */
+ KASSERT(TAILQ_EMPTY(&pglist));
+
+ return container_of(vm_page, struct page, p_vmp);
+}
+
+void
+__free_page(struct page *page)
+{
+ struct pglist pglist = TAILQ_HEAD_INITIALIZER(pglist);
+
+ TAILQ_INSERT_TAIL(&pglist, &page->p_vmp, pageq.queue);
+
+ uvm_pglistfree(&pglist);
+}
diff -r 35e16cbad60d -r d7d33e4f1b6b sys/external/bsd/drm2/linux/linux_kmap.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/drm2/linux/linux_kmap.c Wed Jul 24 03:31:12 2013 +0000
@@ -0,0 +1,112 @@
+/* $NetBSD: linux_kmap.c,v 1.1.2.1 2013/07/24 03:31:12 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: linux_kmap.c,v 1.1.2.1 2013/07/24 03:31:12 riastradh Exp $");
+
+#include <sys/types.h>
+#include <sys/mutex.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <linux/highmem.h>
+
+/*
+ * XXX Kludgerific implementation of Linux kmap_atomic, which is
+ * required not to fail. To accomodate this, we reserve one page of
+ * kva at boot (or load) and limit the system to at most kmap_atomic in
+ * use at a time.
+ */
+
+static kmutex_t linux_kmap_atomic_lock;
+static vaddr_t linux_kmap_atomic_vaddr;
+
+int
+linux_kmap_init(void)
+{
+
+ /* IPL_VM is needed to block pmap_kenter_pa. */
+ mutex_init(&linux_kmap_atomic_lock, MUTEX_DEFAULT, IPL_VM);
+
+ linux_kmap_atomic_vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+ (UVM_KMF_VAONLY | UVM_KMF_WAITVA));
+
+ KASSERT(linux_kmap_atomic_vaddr != 0);
+ KASSERT(!pmap_extract(pmap_kernel(), linux_kmap_atomic_vaddr, NULL));
+
+ return 0;
+}
+
+void
+linux_kmap_fini(void)
+{
+
+ KASSERT(linux_kmap_atomic_vaddr != 0);
+ KASSERT(!pmap_extract(pmap_kernel(), linux_kmap_atomic_vaddr, NULL));
+
+ uvm_km_free(kernel_map, linux_kmap_atomic_vaddr, PAGE_SIZE,
+ (UVM_KMF_VAONLY | UVM_KMF_WAITVA));
+
+ mutex_destroy(&linux_kmap_atomic_lock);
+}
+
+void *
+kmap_atomic(struct page *page)
+{
+
+ mutex_spin_enter(&linux_kmap_atomic_lock);
+
+ KASSERT(linux_kmap_atomic_vaddr != 0);
+ KASSERT(!pmap_extract(pmap_kernel(), linux_kmap_atomic_vaddr, NULL));
+
+ const vaddr_t vaddr = linux_kmap_atomic_vaddr;
+ const paddr_t paddr = uvm_vm_page_to_phys(&page->p_vmp);
+ const int prot = (VM_PROT_READ | VM_PROT_WRITE);
+ const int flags = 0;
+ pmap_kenter_pa(vaddr, paddr, prot, flags);
+ pmap_update(pmap_kernel());
+
+ return (void *)vaddr;
+}
+
+void
+kunmap_atomic(void *addr)
+{
Home |
Main Index |
Thread Index |
Old Index