Module Name:    src
Committed By:   jmcneill
Date:           Tue Feb  8 10:52:57 UTC 2011

Modified Files:
        src/sys/arch/x86/x86: genfb_machdep.c x86_autoconf.c
        src/sys/dev/wsfb: genfb.c genfbvar.h

Log Message:
add a 'setmode' callback to genfb and use it to setup write-combining
MTRRs on x86 whenever switching to WSDISPLAYIO_MODE_EMUL


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/x86/x86/genfb_machdep.c
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/x86/x86/x86_autoconf.c
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/wsfb/genfb.c
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/wsfb/genfbvar.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/arch/x86/x86/genfb_machdep.c
diff -u src/sys/arch/x86/x86/genfb_machdep.c:1.4 src/sys/arch/x86/x86/genfb_machdep.c:1.5
--- src/sys/arch/x86/x86/genfb_machdep.c:1.4	Wed Apr 28 19:17:04 2010
+++ src/sys/arch/x86/x86/genfb_machdep.c	Tue Feb  8 10:52:56 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: genfb_machdep.c,v 1.4 2010/04/28 19:17:04 dyoung Exp $ */
+/* $NetBSD: genfb_machdep.c,v 1.5 2011/02/08 10:52:56 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca>
@@ -31,16 +31,20 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfb_machdep.c,v 1.4 2010/04/28 19:17:04 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfb_machdep.c,v 1.5 2011/02/08 10:52:56 jmcneill Exp $");
+
+#include "opt_mtrr.h"
 
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/device.h>
 #include <sys/ioctl.h>
 #include <sys/kernel.h>
+#include <sys/lwp.h>
 
 #include <machine/bus.h>
 #include <machine/bootinfo.h>
+#include <machine/mtrr.h>
 
 #include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wsdisplayvar.h>
@@ -70,6 +74,40 @@
 	NULL
 };
 
+void
+x86_genfb_mtrr_init(uint64_t physaddr, uint32_t size)
+{
+#ifdef MTRR
+	struct mtrr mtrr;
+	int error, n;
+
+	if (mtrr_funcs == NULL) {
+		aprint_debug("%s: no mtrr funcs\n", __func__);
+		return;
+	}
+
+	mtrr.base = physaddr;
+	mtrr.len = size;
+	mtrr.type = MTRR_TYPE_WC;
+	mtrr.flags = MTRR_VALID;
+	mtrr.owner = 0;
+
+	aprint_debug("%s: 0x%llx-0x%llx\n", __func__,
+	    mtrr.base, mtrr.base + mtrr.len - 1);
+
+	n = 1;
+	KERNEL_LOCK(1, NULL);
+	error = mtrr_set(&mtrr, &n, curlwp->l_proc, MTRR_GETSET_KERNEL);
+	if (n != 0)
+		mtrr_commit();
+	KERNEL_UNLOCK_ONE(NULL);
+
+	aprint_debug("%s: mtrr_set returned %d\n", __func__, error);
+#else
+	aprint_debug("%s: kernel lacks MTRR option\n", __func__);
+#endif
+}
+
 int
 x86_genfb_cnattach(void)
 {

Index: src/sys/arch/x86/x86/x86_autoconf.c
diff -u src/sys/arch/x86/x86/x86_autoconf.c:1.53 src/sys/arch/x86/x86/x86_autoconf.c:1.54
--- src/sys/arch/x86/x86/x86_autoconf.c:1.53	Mon Jan 10 21:26:38 2011
+++ src/sys/arch/x86/x86/x86_autoconf.c	Tue Feb  8 10:52:56 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_autoconf.c,v 1.53 2011/01/10 21:26:38 jakllsch Exp $	*/
+/*	$NetBSD: x86_autoconf.c,v 1.54 2011/02/08 10:52:56 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.53 2011/01/10 21:26:38 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.54 2011/02/08 10:52:56 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -72,6 +72,7 @@
 #include <dev/pci/pcivar.h>
 #endif
 #include <dev/wsfb/genfbvar.h>
+#include <arch/x86/include/genfb_machdep.h>
 #if NPCI > 0
 #include <dev/pci/genfb_pcivar.h>
 #endif
@@ -80,6 +81,7 @@
 #if NPCI > 0
 static struct genfb_colormap_callback gfb_cb;
 static struct genfb_pmf_callback pmf_cb;
+static struct genfb_mode_callback mode_cb;
 #endif
 #ifdef VGA_POST
 static struct vga_post *vga_posth = NULL;
@@ -99,6 +101,15 @@
 }
 
 static bool
+x86_genfb_setmode(struct genfb_softc *sc, int newmode)
+{
+	if (newmode == WSDISPLAYIO_MODE_EMUL)
+		x86_genfb_mtrr_init(sc->sc_fboffset,
+		    sc->sc_height * sc->sc_stride);
+	return true;
+}
+
+static bool
 x86_genfb_suspend(device_t dev, const pmf_qual_t *qual)
 {
 	return true;
@@ -675,6 +686,12 @@
 					prop_dictionary_set_uint64(dict,
 					    "cmap_callback", (uint64_t)&gfb_cb);
 				}
+				if (fbinfo->physaddr != 0) {
+					mode_cb.gmc_setmode = x86_genfb_setmode;
+					prop_dictionary_set_uint64(dict,
+					    "mode_callback",
+					    (uint64_t)&mode_cb);
+				}
 			}
 			prop_dictionary_set_bool(dict, "is_console", true);
 			prop_dictionary_set_bool(dict, "clear-screen", false);

Index: src/sys/dev/wsfb/genfb.c
diff -u src/sys/dev/wsfb/genfb.c:1.33 src/sys/dev/wsfb/genfb.c:1.34
--- src/sys/dev/wsfb/genfb.c:1.33	Sun Feb  6 23:25:17 2011
+++ src/sys/dev/wsfb/genfb.c	Tue Feb  8 10:52:56 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: genfb.c,v 1.33 2011/02/06 23:25:17 jmcneill Exp $ */
+/*	$NetBSD: genfb.c,v 1.34 2011/02/08 10:52:56 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2007 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.33 2011/02/06 23:25:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.34 2011/02/08 10:52:56 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -102,7 +102,7 @@
 genfb_init(struct genfb_softc *sc)
 {
 	prop_dictionary_t dict;
-	uint64_t cmap_cb, pmf_cb, bl_cb;
+	uint64_t cmap_cb, pmf_cb, mode_cb, bl_cb;
 	uint32_t fboffset;
 	bool console;
 
@@ -159,6 +159,13 @@
 			sc->sc_pmfcb = (void *)(vaddr_t)pmf_cb;
 	}
 
+	/* optional mode callback */
+	sc->sc_modecb = NULL;
+	if (prop_dictionary_get_uint64(dict, "mode_callback", &mode_cb)) {
+		if (mode_cb != 0)
+			sc->sc_modecb = (void *)(vaddr_t)mode_cb;
+	}
+
 	/* optional backlight control callback */
 	sc->sc_backlight = NULL;
 	if (prop_dictionary_get_uint64(dict, "backlight_callback", &bl_cb)) {
@@ -228,6 +235,8 @@
 	sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
 	memcpy(&sc->sc_ops, ops, sizeof(struct genfb_ops));
 	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+	if (sc->sc_modecb->gmc_setmode)
+		sc->sc_modecb->gmc_setmode(sc, sc->sc_mode);
 
 #ifdef GENFB_SHADOWFB
 	sc->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
@@ -377,6 +386,9 @@
 
 			if (new_mode != sc->sc_mode) {
 				sc->sc_mode = new_mode;
+				if (sc->sc_modecb->gmc_setmode)
+					sc->sc_modecb->gmc_setmode(sc,
+					    sc->sc_mode);
 				if (new_mode == WSDISPLAYIO_MODE_EMUL) {
 					genfb_restore_palette(sc);
 					vcons_redraw_screen(ms);

Index: src/sys/dev/wsfb/genfbvar.h
diff -u src/sys/dev/wsfb/genfbvar.h:1.17 src/sys/dev/wsfb/genfbvar.h:1.18
--- src/sys/dev/wsfb/genfbvar.h:1.17	Thu Oct  7 07:53:53 2010
+++ src/sys/dev/wsfb/genfbvar.h	Tue Feb  8 10:52:56 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: genfbvar.h,v 1.17 2010/10/07 07:53:53 macallan Exp $ */
+/*	$NetBSD: genfbvar.h,v 1.18 2011/02/08 10:52:56 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2007 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfbvar.h,v 1.17 2010/10/07 07:53:53 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfbvar.h,v 1.18 2011/02/08 10:52:56 jmcneill Exp $");
 
 #ifndef GENFBVAR_H
 #define GENFBVAR_H
@@ -51,10 +51,10 @@
 #ifdef SPLASHSCREEN
 #define GENFB_DISABLE_TEXT
 #include <dev/splash/splash.h>
-/* XXX */
-extern const char _splash_header_data_cmap[64+32][3];
 #endif
 
+struct genfb_softc;
+
 struct genfb_ops {
 	int (*genfb_ioctl)(void *, void *, u_long, void *, int, struct lwp *);
 	paddr_t	(*genfb_mmap)(void *, void *, off_t, int);
@@ -77,6 +77,10 @@
 	bool (*gpc_resume)(device_t, const pmf_qual_t *);
 };
 
+struct genfb_mode_callback {
+	bool (*gmc_setmode)(struct genfb_softc *, int);
+};
+
 struct genfb_softc {
 	device_t sc_dev;
 	struct vcons_data vd;
@@ -88,6 +92,7 @@
 	struct genfb_colormap_callback *sc_cmcb;
 	struct genfb_pmf_callback *sc_pmfcb;
 	struct genfb_parameter_callback *sc_backlight;
+	struct genfb_mode_callback *sc_modecb;
 	int sc_backlight_level, sc_backlight_on;
 	void *sc_fbaddr;	/* kva */
 #ifdef GENFB_SHADOWFB
@@ -103,9 +108,6 @@
 	bool sc_want_clear;
 #ifdef SPLASHSCREEN
 	struct splash_info sc_splash;
-#ifdef SPLASHSCREEN_PROGRESS
-	struct splash_progress sc_progress;
-#endif
 #endif
 };
 

Reply via email to