From owner-svn-src-all@FreeBSD.ORG Thu Sep 26 22:47:03 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id B1FB670D; Thu, 26 Sep 2013 22:47:03 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 8F4522FDC; Thu, 26 Sep 2013 22:47:03 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r8QMl3LJ022771; Thu, 26 Sep 2013 22:47:03 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r8QMl3wx022767; Thu, 26 Sep 2013 22:47:03 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201309262247.r8QMl3wx022767@svn.freebsd.org> From: Nathan Whitehorn Date: Thu, 26 Sep 2013 22:47:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r255904 - head/sys/powerpc/ofw X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Sep 2013 22:47:03 -0000 Author: nwhitehorn Date: Thu Sep 26 22:47:02 2013 New Revision: 255904 URL: http://svnweb.freebsd.org/changeset/base/255904 Log: Allow Open Firmware syscons to attach to devices without an "address" property such as those found on some real and emulated IBM systems. The approach, which is taken from Linux, is to scan through the PCI bars until we find one large enough to contain the linear framebuffer and which is ideally prefetchable if no "address" property can be found. This makes the graphical console work with the pSeries target in QEMU. Approved by: re (delphij) Modified: head/sys/powerpc/ofw/ofw_machdep.c head/sys/powerpc/ofw/ofw_syscons.c head/sys/powerpc/ofw/ofw_syscons.h Modified: head/sys/powerpc/ofw/ofw_machdep.c ============================================================================== --- head/sys/powerpc/ofw/ofw_machdep.c Thu Sep 26 21:18:46 2013 (r255903) +++ head/sys/powerpc/ofw/ofw_machdep.c Thu Sep 26 22:47:02 2013 (r255904) @@ -680,7 +680,7 @@ OF_decode_addr(phandle_t dev, int regno, bus_size_t size, rsize; uint32_t c, nbridge, naddr, nsize; phandle_t bridge, parent; - u_int spc, rspc; + u_int spc, rspc, prefetch; int pci, pcib, res; /* Sanity checking. */ @@ -707,6 +707,7 @@ OF_decode_addr(phandle_t dev, int regno, if (regno + naddr + nsize > res) return (EINVAL); spc = (pci) ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK : ~0; + prefetch = (pci) ? cell[regno] & OFW_PCI_PHYS_HI_PREFETCHABLE : 0; addr = 0; for (c = 0; c < naddr; c++) addr = ((uint64_t)addr << 32) | cell[regno++]; @@ -763,6 +764,7 @@ OF_decode_addr(phandle_t dev, int regno, } *tag = &bs_le_tag; - return (bus_space_map(*tag, addr, size, 0, handle)); + return (bus_space_map(*tag, addr, size, + prefetch ? BUS_SPACE_MAP_PREFETCHABLE : 0, handle)); } Modified: head/sys/powerpc/ofw/ofw_syscons.c ============================================================================== --- head/sys/powerpc/ofw/ofw_syscons.c Thu Sep 26 21:18:46 2013 (r255903) +++ head/sys/powerpc/ofw/ofw_syscons.c Thu Sep 26 22:47:02 2013 (r255904) @@ -199,13 +199,18 @@ ofwfb_foreground(uint8_t attr) } static u_int -ofwfb_pix32(int attr) +ofwfb_pix32(struct ofwfb_softc *sc, int attr) { u_int retval; - retval = (ofwfb_cmap[attr].blue << 16) | - (ofwfb_cmap[attr].green << 8) | - ofwfb_cmap[attr].red; + if (sc->sc_tag == &bs_le_tag) + retval = (ofwfb_cmap[attr].red << 16) | + (ofwfb_cmap[attr].green << 8) | + ofwfb_cmap[attr].blue; + else + retval = (ofwfb_cmap[attr].blue << 16) | + (ofwfb_cmap[attr].green << 8) | + ofwfb_cmap[attr].red; return (retval); } @@ -221,6 +226,7 @@ ofwfb_configure(int flags) int depth; int disable; int len; + int i; char type[16]; static int done = 0; @@ -265,7 +271,8 @@ ofwfb_configure(int flags) return (0); if (OF_getproplen(node, "height") != sizeof(sc->sc_height) || - OF_getproplen(node, "width") != sizeof(sc->sc_width)) + OF_getproplen(node, "width") != sizeof(sc->sc_width) || + OF_getproplen(node, "linebytes") != sizeof(sc->sc_stride)) return (0); sc->sc_depth = depth; @@ -276,20 +283,6 @@ ofwfb_configure(int flags) OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride)); /* - * 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. - */ - if (OF_getproplen(node, "address") != sizeof(fb_phys)) - return (0); - OF_getprop(node, "address", &fb_phys, sizeof(fb_phys)); - - bus_space_map(&bs_be_tag, fb_phys, sc->sc_height * sc->sc_stride, - BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr); - - /* * Get the PCI addresses of the adapter. The node may be the * child of the PCI device: in that case, try the parent for * the assigned-addresses property. @@ -300,9 +293,53 @@ ofwfb_configure(int flags) len = OF_getprop(OF_parent(node), "assigned-addresses", sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs)); } + if (len == -1) + len = 0; + sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register); - if (len != -1) { - sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register); + /* + * 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. + */ + if (OF_getproplen(node, "address") == sizeof(fb_phys)) { + OF_getprop(node, "address", &fb_phys, sizeof(fb_phys)); + sc->sc_tag = &bs_be_tag; + bus_space_map(sc->sc_tag, fb_phys, sc->sc_height * + sc->sc_stride, BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr); + } else { + /* + * Some IBM systems don't have an address property. Try to + * guess the framebuffer region from the assigned addresses. + * This is ugly, but there doesn't seem to be an alternative. + * Linux does the same thing. + */ + + fb_phys = sc->sc_num_pciaddrs; + for (i = 0; i < sc->sc_num_pciaddrs; i++) { + /* If it is too small, not the framebuffer */ + if (sc->sc_pciaddrs[i].size_lo < + sc->sc_stride*sc->sc_height) + continue; + /* If it is not memory, it isn't either */ + if (!(sc->sc_pciaddrs[i].phys_hi & + OFW_PCI_PHYS_HI_SPACE_MEM32)) + continue; + + /* This could be the framebuffer */ + fb_phys = i; + + /* If it is prefetchable, it certainly is */ + if (sc->sc_pciaddrs[i].phys_hi & + OFW_PCI_PHYS_HI_PREFETCHABLE) + break; + } + if (fb_phys == sc->sc_num_pciaddrs) + return (0); + + OF_decode_addr(node, fb_phys, &sc->sc_tag, &sc->sc_addr); } ofwfb_init(0, &sc->sc_va, 0); @@ -617,13 +654,14 @@ ofwfb_blank_display32(video_adapter_t *a { struct ofwfb_softc *sc; int i; - uint32_t *addr; + uint32_t *addr, blank; sc = (struct ofwfb_softc *)adp; addr = (uint32_t *) sc->sc_addr; + blank = ofwfb_pix32(sc, ofwfb_background(SC_NORM_ATTR)); for (i = 0; i < (sc->sc_stride/4)*sc->sc_height; i++) - *(addr + i) = ofwfb_pix32(ofwfb_background(SC_NORM_ATTR)); + *(addr + i) = blank; return (0); } @@ -821,7 +859,7 @@ ofwfb_putc32(video_adapter_t *adp, vm_of int row; int col; int i, j, k; - uint32_t *addr; + uint32_t *addr, fg, bg; u_char *p; sc = (struct ofwfb_softc *)adp; @@ -831,13 +869,16 @@ ofwfb_putc32(video_adapter_t *adp, vm_of addr = (uint32_t *)sc->sc_addr + (row + sc->sc_ymargin)*(sc->sc_stride/4) + col + sc->sc_xmargin; + + fg = ofwfb_pix32(sc, ofwfb_foreground(a)); + bg = ofwfb_pix32(sc, ofwfb_background(a)); for (i = 0; i < sc->sc_font_height; i++) { for (j = 0, k = 7; j < 8; j++, k--) { if ((p[i] & (1 << k)) == 0) - *(addr + j) = ofwfb_pix32(ofwfb_background(a)); + *(addr + j) = bg; else - *(addr + j) = ofwfb_pix32(ofwfb_foreground(a)); + *(addr + j) = fg; } addr += (sc->sc_stride/4); } @@ -928,8 +969,8 @@ ofwfb_putm32(video_adapter_t *adp, int x + (y + sc->sc_ymargin)*(sc->sc_stride/4) + x + sc->sc_xmargin; - fg = ofwfb_pix32(ofwfb_foreground(SC_NORM_ATTR)); - bg = ofwfb_pix32(ofwfb_background(SC_NORM_ATTR)); + fg = ofwfb_pix32(sc, ofwfb_foreground(SC_NORM_ATTR)); + bg = ofwfb_pix32(sc, ofwfb_background(SC_NORM_ATTR)); for (i = 0; i < size && i+y < sc->sc_height - 2*sc->sc_ymargin; i++) { for (j = 0, k = width; j < 8; j++, k--) { Modified: head/sys/powerpc/ofw/ofw_syscons.h ============================================================================== --- head/sys/powerpc/ofw/ofw_syscons.h Thu Sep 26 21:18:46 2013 (r255903) +++ head/sys/powerpc/ofw/ofw_syscons.h Thu Sep 26 22:47:02 2013 (r255904) @@ -32,6 +32,7 @@ struct ofwfb_softc { video_adapter_t sc_va; struct cdev *sc_si; + bus_space_tag_t sc_tag; phandle_t sc_node; int sc_console;