[BACK]Return to wscons_machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / hp300

File: [local] / sys / arch / hp300 / hp300 / wscons_machdep.c (download)

Revision 1.1, Tue Mar 4 16:05:38 2008 UTC (16 years, 2 months ago) by nbrk
Branch point for: MAIN

Initial revision

/*	$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 <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/device.h>

#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/hp300spu.h>

#include <dev/cons.h>

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>

#include "wsdisplay.h"
#include "wskbd.h"
#if NWSKBD > 0
#include <dev/wscons/wskbdvar.h>
#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 <hp300/dev/dioreg.h>
#include <hp300/dev/diovar.h>
#include <hp300/dev/diofbreg.h>
#include <hp300/dev/diofbvar.h>
struct diofb diofb_cn;
#endif

#include "sti.h"
#if NSTI > 0
#include <machine/bus.h>
#include <hp300/dev/sgcreg.h>
#include <hp300/dev/sgcvar.h>
#include <dev/ic/stireg.h>
#include <dev/ic/stivar.h>
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
}