Module Name: src Committed By: nonaka Date: Sun Mar 11 15:58:56 UTC 2012
Modified Files: src/sys/dev/pci: lynxfb.c lynxfbreg.h Log Message: fix mmaped offset. X works on Yeeloong Notebook now. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/lynxfb.c cvs rdiff -u -r1.1 -r1.2 src/sys/dev/pci/lynxfbreg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/lynxfb.c diff -u src/sys/dev/pci/lynxfb.c:1.2 src/sys/dev/pci/lynxfb.c:1.3 --- src/sys/dev/pci/lynxfb.c:1.2 Sun Mar 11 13:57:30 2012 +++ src/sys/dev/pci/lynxfb.c Sun Mar 11 15:58:56 2012 @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: lynxfb.c,v 1 #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_softc { 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 @@ static struct { 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_cnattach(bus_space_tag_t memt, bu 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 @@ lynxfb_attach(device_t parent, device_t struct lynxfb *fb; struct rasops_info *ri; prop_dictionary_t dict; - bus_size_t size; long defattr; bool is_console; @@ -280,9 +286,13 @@ lynxfb_attach(device_t parent, device_t 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 @@ lynxfb_attach(device_t parent, device_t 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 @@ lynxfb_mmap(void *v, void *vs, off_t off 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); + } + + /* 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 bus_space_mmap(sc->sc_memt, offset, 0, prot, - BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE); + return (-1); } static void Index: src/sys/dev/pci/lynxfbreg.h diff -u src/sys/dev/pci/lynxfbreg.h:1.1 src/sys/dev/pci/lynxfbreg.h:1.2 --- src/sys/dev/pci/lynxfbreg.h:1.1 Fri Mar 2 13:20:57 2012 +++ src/sys/dev/pci/lynxfbreg.h Sun Mar 11 15:58:56 2012 @@ -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) */