Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci fix mmaped offset.



details:   https://anonhg.NetBSD.org/src/rev/0c5bb0660eb9
branches:  trunk
changeset: 777980:0c5bb0660eb9
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Sun Mar 11 15:58:56 2012 +0000

description:
fix mmaped offset.
X works on Yeeloong Notebook now.

diffstat:

 sys/dev/pci/lynxfb.c    |  54 +++++++++++++++++++++++++++++++++++++++---------
 sys/dev/pci/lynxfbreg.h |   6 ++++-
 2 files changed, 48 insertions(+), 12 deletions(-)

diffs (148 lines):

diff -r 34236051c683 -r 0c5bb0660eb9 sys/dev/pci/lynxfb.c
--- a/sys/dev/pci/lynxfb.c      Sun Mar 11 13:57:30 2012 +0000
+++ b/sys/dev/pci/lynxfb.c      Sun Mar 11 15:58:56 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lynxfb.c,v 1.2 2012/03/11 13:57:30 nonaka Exp $        */
+/*     $NetBSD: lynxfb.c,v 1.3 2012/03/11 15:58:56 nonaka Exp $        */
 /*     $OpenBSD: smfb.c,v 1.13 2011/07/21 20:36:12 miod Exp $  */
 
 /*
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lynxfb.c,v 1.2 2012/03/11 13:57:30 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lynxfb.c,v 1.3 2012/03/11 15:58:56 nonaka Exp $");
 
 #include "opt_wsemul.h"
 
@@ -34,6 +34,7 @@
 #include <sys/systm.h>
 #include <sys/device.h>
 #include <sys/endian.h>
+#include <sys/kauth.h>
 
 #include <sys/bus.h>
 
@@ -117,6 +118,8 @@
 
        struct lynxfb           *sc_fb;
        struct lynxfb           sc_fb_store;
+       bus_addr_t              sc_fbaddr;
+       bus_size_t              sc_fbsize;
 
        struct vcons_data       sc_vd;
        struct wsscreen_list    sc_screenlist;
@@ -168,6 +171,8 @@
        bus_space_tag_t memt;
        bus_space_handle_t memh;
        struct lynxfb fb;
+       bus_addr_t fbaddr;
+       bus_size_t fbsize;
 } lynxfb_console;
 
 int lynxfb_default_width = LYNXFB_DEFAULT_WIDTH;
@@ -229,6 +234,8 @@
 
        lynxfb_console.is_console = true;
        lynxfb_console.tag = tag;
+       lynxfb_console.fbaddr = base;
+       lynxfb_console.fbsize = size;
        (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
        wsdisplay_preattach(&fb->wsd, ri, 0, 0, defattr);
 
@@ -264,7 +271,6 @@
        struct lynxfb *fb;
        struct rasops_info *ri;
        prop_dictionary_t dict;
-       bus_size_t size;
        long defattr;
        bool is_console;
 
@@ -280,9 +286,13 @@
        sc->sc_fb = fb;
        fb->sc = sc;
 
-       if (!is_console) {
+       if (is_console) {
+               sc->sc_fbaddr = lynxfb_console.fbaddr;
+               sc->sc_fbsize = lynxfb_console.fbsize;
+       } else {
                if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM,
-                   BUS_SPACE_MAP_LINEAR, &fb->memt, &fb->memh, NULL, &size)) {
+                   BUS_SPACE_MAP_LINEAR, &fb->memt, &fb->memh, &sc->sc_fbaddr,
+                   &sc->sc_fbsize)) {
                        aprint_error_dev(self, "can't map frame buffer\n");
                        return;
                }
@@ -305,7 +315,7 @@
 
                if (lynxfb_setup(fb)) {
                        aprint_error_dev(self, "can't setup frame buffer\n");
-                       bus_space_unmap(fb->memt, fb->memh, size);
+                       bus_space_unmap(fb->memt, fb->memh, sc->sc_fbsize);
                        return;
                }
        }
@@ -458,14 +468,36 @@
        struct lynxfb_softc *sc = vd->cookie;
        struct rasops_info *ri = &sc->sc_fb->vcs.scr_ri;
 
-       if ((offset & PAGE_MASK) != 0)
-               return (-1);
+       /* 'regular' framebuffer mmap()ing */
+       if (offset < ri->ri_stride * ri->ri_height) {
+               return bus_space_mmap(sc->sc_memt, sc->sc_fbaddr + offset, 0,
+                   prot, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE);
+       }
 
-       if (offset < 0 || offset >= ri->ri_stride * ri->ri_height)
+       /*
+        * restrict all other mappings to processes with superuser privileges
+        * or the kernel itself
+        */
+       if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER,
+           NULL) != 0) {
+               aprint_normal_dev(sc->sc_dev, "mmap() rejected.\n");
                return (-1);
+       }
 
-       return bus_space_mmap(sc->sc_memt, offset, 0, prot,
-           BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE);
+       /* framebuffer mmap()ing */
+       if (offset >= sc->sc_fbaddr &&
+           offset < sc->sc_fbaddr + ri->ri_stride * ri->ri_height) {
+               return bus_space_mmap(sc->sc_memt, offset, 0, prot,
+                   BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE);
+       }
+
+       /* register mmap()ing */
+       if (offset >= sc->sc_fbaddr + SM7XX_REG_BASE &&
+           offset < sc->sc_fbaddr + SM7XX_REG_BASE + SM7XX_REG_SIZE) {
+               return bus_space_mmap(sc->sc_memt, offset, 0, prot, 0);
+       }
+
+       return (-1);
 }
 
 static void
diff -r 34236051c683 -r 0c5bb0660eb9 sys/dev/pci/lynxfbreg.h
--- a/sys/dev/pci/lynxfbreg.h   Sun Mar 11 13:57:30 2012 +0000
+++ b/sys/dev/pci/lynxfbreg.h   Sun Mar 11 15:58:56 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lynxfbreg.h,v 1.1 2012/03/02 13:20:57 nonaka Exp $     */
+/*     $NetBSD: lynxfbreg.h,v 1.2 2012/03/11 15:58:56 nonaka Exp $     */
 /*     $OpenBSD: smfbreg.h,v 1.5 2010/08/27 12:48:54 miod Exp $        */
 
 /*
@@ -60,6 +60,10 @@
 #define        DE_CTRL_ROP_SHIFT                       0
 #define        DE_CTRL_ROP_SRC                         0x0c
 
+
+#define        SM7XX_REG_BASE                  0x00400000
+#define        SM7XX_REG_SIZE                  0x00400000
+
 /*
  * VPR (Video Parameter Registers)
  */



Home | Main Index | Thread Index | Old Index