From owner-svn-src-user@FreeBSD.ORG Sat Jan 21 17:59:50 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EA938106566C; Sat, 21 Jan 2012 17:59:50 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D41798FC0A; Sat, 21 Jan 2012 17:59:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q0LHxo9J002998; Sat, 21 Jan 2012 17:59:50 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q0LHxocs002995; Sat, 21 Jan 2012 17:59:50 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201201211759.q0LHxocs002995@svn.freebsd.org> From: Nathan Whitehorn Date: Sat, 21 Jan 2012 17:59:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r230428 - in user/ed/newcons/sys: conf dev/vt/hw/ofwfb X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Jan 2012 17:59:51 -0000 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 +__FBSDID("$FreeBSD: user/ed/newcons/sys/dev/vt/hw/ofwfb/ofwfb.c 219888 2011-03-22 21:31:31Z ed $"); + +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +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); +} +