/* $OpenBSD: wscons_machdep.c,v 1.8 2006/12/18 18:57:26 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat * * 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 ``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 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. */ /* * Copyright (c) 2002 Michael Shalayeff * 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. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 HIS RELATIVES 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 MIND, 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 #include #include #include #include #include #include #include #include #include #include #include #include "wsdisplay.h" #include "wskbd.h" #if NWSKBD > 0 #include #endif #include "dvbox.h" #include "gbox.h" #include "hyper.h" #include "rbox.h" #include "topcat.h" #include "tvrx.h" #if NDVBOX > 0 || NGBOX > 0 || NHYPER > 0 || NRBOX > 0 || NTOPCAT > 0 || NTVRX > 0 #include #include #include #include struct diofb diofb_cn; #endif #include "sti.h" #if NSTI > 0 #include #include #include #include #include extern int sti_console_scan(int); extern void sticninit(void); #endif extern caddr_t internalhpib; cons_decl(ws); void (*wsfbcninit)(void) = NULL; #if NDVBOX > 0 || NGBOX > 0 || NHYPER > 0 || NRBOX > 0 || NTOPCAT > 0 || NTVRX > 0 int dio_fbidentify(struct diofbreg *); /* * Identify a DIO frame buffer and set up wsfbcninit accordingly. */ int dio_fbidentify(struct diofbreg *fbr) { if (fbr->id == GRFHWID) switch (fbr->fbid) { #if NDVBOX > 0 case GID_DAVINCI: wsfbcninit = dvboxcninit; return (1); #endif #if NGBOX > 0 case GID_GATORBOX: wsfbcninit = gboxcninit; return (1); #endif #if NHYPER > 0 case GID_HYPERION: wsfbcninit = hypercninit; return (1); #endif #if NRBOX > 0 case GID_RENAISSANCE: wsfbcninit = rboxcninit; return (1); #endif #if NTOPCAT > 0 case GID_TOPCAT: case GID_LRCATSEYE: case GID_HRCCATSEYE: case GID_HRMCATSEYE: wsfbcninit = topcatcninit; return (1); #endif #if NTVRX > 0 case GID_TIGER: wsfbcninit = tvrxcninit; return (1); #endif default: break; } return (0); } #endif /* * This routine handles the dirty work of picking the best frame buffer * suitable for the console. * We try to behave as close as possible to the PROM's logic, by preferring * devices for which we have drivers, in that order: * - internal video. * - lowest select code on DIO bus. * - lowest slot on SGC bus. */ void wscnprobe(struct consdev *cp) { int maj, tmpconscode; vsize_t mapsize; vaddr_t va; #if NDVBOX > 0 || NGBOX > 0 || NHYPER > 0 || NRBOX > 0 || NTOPCAT > 0 || NTVRX > 0 paddr_t pa; u_int scode, sctop; struct diofbreg *fbr; #endif for (maj = 0; maj < nchrdev; maj++) { if (cdevsw[maj].d_open == wsdisplayopen) break; } cp->cn_dev = makedev(maj, 0); wsfbcninit = NULL; #if NDVBOX > 0 || NGBOX > 0 || NRBOX > 0 || NTOPCAT > 0 /* * Look for an ``internal'' frame buffer. */ va = IIOV(GRFIADDR); fbr = (struct diofbreg *)va; if (!badaddr((caddr_t)va)) { if (dio_fbidentify(fbr)) { tmpconscode = CONSCODE_INTERNAL; mapsize = 0; goto found; } } #endif #if NDVBOX > 0 || NGBOX > 0 || NHYPER > 0 || NRBOX > 0 || NTOPCAT > 0 || NTVRX > 0 /* * Scan the DIO bus. */ sctop = DIO_SCMAX(machineid); for (scode = 0; scode < sctop; scode++) { /* * Skip over the select code hole and the internal * HP-IB controller. */ if (DIO_INHOLE(scode) || (scode == 7 && internalhpib)) continue; /* Map current PA. */ pa = (paddr_t)dio_scodetopa(scode); va = (vaddr_t)iomap((caddr_t)pa, PAGE_SIZE); if (va == NULL) continue; /* Check to see if hardware exists. */ if (badaddr((caddr_t)va)) { iounmap((caddr_t)va, PAGE_SIZE); continue; } /* Check hardware. */ fbr = (struct diofbreg *)va; if (dio_fbidentify(fbr)) { tmpconscode = scode; mapsize = DIO_SIZE(scode, va); iounmap((caddr_t)va, PAGE_SIZE); va = (vaddr_t)iomap((caddr_t)pa, mapsize); if (va == NULL) continue; goto found; } else iounmap((caddr_t)va, PAGE_SIZE); } #endif #if NSTI > 0 /* * Scan the SGC bus. */ for (scode = 0; scode < SGC_NSLOTS; scode++) { int rv; /* Map current PA. */ pa = (paddr_t)sgc_slottopa(scode); va = (vaddr_t)iomap((caddr_t)pa, PAGE_SIZE); if (va == NULL) continue; /* Check to see if hardware exists. */ rv = badaddr((caddr_t)va); iounmap((caddr_t)va, PAGE_SIZE); if (rv != 0) continue; /* Check hardware. */ if (sti_console_scan(scode) != 0) { wsfbcninit = sticninit; tmpconscode = SGC_SLOT_TO_CONSCODE(scode); mapsize = 0; va = 0; goto found; } } #endif return; found: cp->cn_pri = CN_INTERNAL; #ifdef CONSCODE if (CONSCODE == tmpconscode) cp->cn_pri = CN_FORCED; #endif /* * If our priority is higher than the currently remembered console, * install ourselves, and unmap whichever device might be currently * mapped. */ if (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri) { cn_tab = cp; /* Free last mapping. */ if (convasize) iounmap(conaddr, convasize); conscode = tmpconscode; conaddr = (caddr_t)va; convasize = mapsize; } } void wscninit(struct consdev *cp) { /* * Note that this relies on the fact that DIO frame buffers will cause * cn_tab to switch to wsdisplaycons, so their cninit function will * never get invoked a second time during the second console pass. */ if (wsfbcninit != NULL) (*wsfbcninit)(); } void wscnputc(dev_t dev, int i) { #if NWSDISPLAY > 0 wsdisplay_cnputc(dev, i); #endif } int wscngetc(dev_t dev) { #if NWSKBD > 0 return (wskbd_cngetc(dev)); #else return (0); #endif } void wscnpollc(dev_t dev, int on) { #if NWSKBD > 0 wskbd_cnpollc(dev, on); #endif }