svn commit: r230428 - in user/ed/newcons/sys: conf dev/vt/hw/ofwfb
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sat Jan 21 17:59:51 UTC 2012
Author: nwhitehorn
Date: Sat Jan 21 17:59:50 2012
New Revision: 230428
URL: http://svn.freebsd.org/changeset/base/230428
Log:
Add a vt(4) framebuffer for Open Firmware linear framebuffer devices (i.e.
all graphics on PowerPC Apple systems). This will also work on some sparc64
graphics hardware with a small amount of modification.
Added:
user/ed/newcons/sys/dev/vt/hw/ofwfb/
user/ed/newcons/sys/dev/vt/hw/ofwfb/ofwfb.c
Modified:
user/ed/newcons/sys/conf/files.powerpc
Modified: user/ed/newcons/sys/conf/files.powerpc
==============================================================================
--- user/ed/newcons/sys/conf/files.powerpc Sat Jan 21 17:50:14 2012 (r230427)
+++ user/ed/newcons/sys/conf/files.powerpc Sat Jan 21 17:59:50 2012 (r230428)
@@ -30,7 +30,7 @@ dev/hwpmc/hwpmc_powerpc.c optional hwpmc
dev/iicbus/ad7417.c optional ad7417 powermac
dev/iicbus/ds1775.c optional ds1775 powermac
dev/iicbus/max6690.c optional max6690 powermac
-dev/kbd/kbd.c optional sc
+dev/kbd/kbd.c optional sc | vt
dev/ofw/openfirm.c optional aim | fdt
dev/ofw/openfirmio.c optional aim | fdt
dev/ofw/ofw_bus_if.m optional aim | fdt
@@ -56,6 +56,7 @@ dev/syscons/scvtb.c optional sc
dev/tsec/if_tsec.c optional tsec
dev/tsec/if_tsec_fdt.c optional tsec fdt
dev/uart/uart_cpu_powerpc.c optional uart aim
+dev/vt/hw/ofwfb/ofwfb.c optional vt aim
kern/kern_clocksource.c standard
kern/syscalls.c optional ktr
libkern/ashldi3.c optional powerpc
Added: user/ed/newcons/sys/dev/vt/hw/ofwfb/ofwfb.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/ed/newcons/sys/dev/vt/hw/ofwfb/ofwfb.c Sat Jan 21 17:59:50 2012 (r230428)
@@ -0,0 +1,238 @@
+/*-
+ * Copyright (c) 2011 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD: user/ed/newcons/sys/dev/vt/hw/ofwfb/ofwfb.c 219888 2011-03-22 21:31:31Z ed $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <dev/vt/vt.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
+
+struct ofwfb_softc {
+ phandle_t sc_node;
+
+ intptr_t sc_addr;
+ int sc_depth;
+ int sc_stride;
+};
+
+static vd_init_t ofwfb_init;
+static vd_blank_t ofwfb_blank;
+static vd_bitblt_t ofwfb_bitblt;
+
+static const struct vt_driver vt_ofwfb_driver = {
+ .vd_init = ofwfb_init,
+ .vd_blank = ofwfb_blank,
+ .vd_bitblt = ofwfb_bitblt,
+};
+
+static struct ofwfb_softc ofwfb_conssoftc;
+VT_CONSDEV_DECLARE(vt_ofwfb_driver, 1600, 1200, &ofwfb_conssoftc);
+
+static const uint32_t colormap[] = {
+ 0x00000000, /* Black */
+ 0x00ff0000, /* Red */
+ 0x0000ff00, /* Green */
+ 0x00c0c000, /* Brown */
+ 0x000000ff, /* Blue */
+ 0x00c000c0, /* Magenta */
+ 0x0000c0c0, /* Cyan */
+ 0x00c0c0c0, /* Light grey */
+ 0x00808080, /* Dark grey */
+ 0x00ff8080, /* Light red */
+ 0x0080ff80, /* Light green */
+ 0x00ffff80, /* Yellow */
+ 0x008080ff, /* Light blue */
+ 0x00ff80ff, /* Light magenta */
+ 0x0080ffff, /* Light cyan */
+ 0x00ffffff, /* White */
+};
+
+static void
+ofwfb_blank(struct vt_device *vd, term_color_t color)
+{
+ struct ofwfb_softc *sc = vd->vd_softc;
+ u_int ofs;
+ uint32_t c;
+
+ switch (sc->sc_depth) {
+ case 8:
+ for (ofs = 0; ofs < sc->sc_stride*vd->vd_height; ofs++)
+ *(uint8_t *)(sc->sc_addr + ofs) = color;
+ break;
+ case 32:
+ c = colormap[color];
+ for (ofs = 0; ofs < sc->sc_stride*vd->vd_height; ofs++)
+ memcpy((void *)(sc->sc_addr + 4*ofs), &c, 4);
+ break;
+ default:
+ /* panic? */
+ break;
+ }
+}
+
+static void
+ofwfb_bitblt(struct vt_device *vd, const uint8_t *src,
+ vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height,
+ term_color_t fg, term_color_t bg)
+{
+ struct ofwfb_softc *sc = vd->vd_softc;
+ u_long line;
+ uint32_t fgc, bgc;
+ int c;
+ uint8_t b = 0;
+
+ fgc = colormap[fg];
+ bgc = colormap[bg];
+
+ line = (sc->sc_stride * top) + left * sc->sc_depth/8;
+ for (; height > 0; height--) {
+ line += sc->sc_stride;
+ for (c = 0; c < width; c++) {
+ if (c % 8 == 0)
+ b = *src++;
+ else
+ b <<= 1;
+ switch(sc->sc_depth) {
+ case 8:
+ *(uint8_t *)(sc->sc_addr + line + c) =
+ b & 0x80 ? fg : bg;
+ break;
+ case 32:
+ memcpy((void *)(sc->sc_addr + line + c*4),
+ b & 0x80 ? &fgc : &bgc, 4);
+ break;
+ default:
+ /* panic? */
+ break;
+ }
+ }
+ }
+}
+
+static void
+ofwfb_initialize(struct vt_device *vd)
+{
+ struct ofwfb_softc *sc = vd->vd_softc;
+ char name[64];
+ ihandle_t ih;
+ cell_t depth = 8;
+ int i, retval;
+
+ /* Open display device, thereby initializing it */
+ memset(name, 0, sizeof(name));
+ OF_package_to_path(sc->sc_node, name, sizeof(name));
+ ih = OF_open(name);
+
+ OF_getprop(sc->sc_node, "depth", &depth, sizeof(depth));
+ sc->sc_depth = depth;
+
+ if (sc->sc_depth == 8) {
+ /*
+ * Install the ISO6429 colormap - older OFW systems
+ * don't do this by default
+ */
+ for (i = 0; i < 16; i++) {
+ OF_call_method("color!", ih, 4, 1,
+ (colormap[i] >> 16) & 0xff,
+ (colormap[i] >> 8) & 0xff,
+ (colormap[i] >> 0) & 0xff,
+ i,
+ &retval);
+ }
+ }
+
+ /* Clear the screen. */
+ ofwfb_blank(vd, TC_BLACK);
+}
+
+static int
+ofwfb_init(struct vt_device *vd)
+{
+ struct ofwfb_softc *sc = vd->vd_softc;
+ char type[64];
+ phandle_t chosen;
+ ihandle_t stdout;
+ phandle_t node;
+ cell_t depth, height, width;
+ uint32_t fb_phys;
+
+ chosen = OF_finddevice("/chosen");
+ OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
+ node = OF_instance_to_package(stdout);
+ if (node == -1) {
+ /*
+ * The "/chosen/stdout" does not exist try
+ * using "screen" directly.
+ */
+ node = OF_finddevice("screen");
+ }
+ OF_getprop(node, "device_type", type, sizeof(type));
+ if (strcmp(type, "display") != 0)
+ return (CN_DEAD);
+
+ /* Keep track of the OF node */
+ sc->sc_node = node;
+
+ /* Only support 8 and 32-bit framebuffers */
+ OF_getprop(node, "depth", &depth, sizeof(depth));
+ sc->sc_depth = depth;
+
+ OF_getprop(node, "height", &height, sizeof(height));
+ OF_getprop(node, "width", &width, sizeof(width));
+ OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride));
+
+ vd->vd_height = height;
+ vd->vd_width = width;
+
+ /*
+ * Grab the physical address of the framebuffer, and then map it
+ * into our memory space. If the MMU is not yet up, it will be
+ * remapped for us when relocation turns on.
+ *
+ * XXX We assume #address-cells is 1 at this point.
+ */
+ OF_getprop(node, "address", &fb_phys, sizeof(fb_phys));
+
+ bus_space_map(&bs_be_tag, fb_phys, height * sc->sc_stride,
+ BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr);
+
+ ofwfb_initialize(vd);
+
+ return (CN_INTERNAL);
+}
+
More information about the svn-src-user
mailing list