11556Srgrimes/*	$NetBSD: console.c,v 1.14 2008/04/28 20:23:22 martin Exp $	*/
21556Srgrimes
31556Srgrimes/*-
41556Srgrimes * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
51556Srgrimes * All rights reserved.
61556Srgrimes *
71556Srgrimes * This code is derived from software contributed to The NetBSD Foundation
81556Srgrimes * by UCHIYAMA Yasushi.
91556Srgrimes *
101556Srgrimes * Redistribution and use in source and binary forms, with or without
111556Srgrimes * modification, are permitted provided that the following conditions
121556Srgrimes * are met:
131556Srgrimes * 1. Redistributions of source code must retain the above copyright
141556Srgrimes *    notice, this list of conditions and the following disclaimer.
151556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161556Srgrimes *    notice, this list of conditions and the following disclaimer in the
171556Srgrimes *    documentation and/or other materials provided with the distribution.
181556Srgrimes *
191556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
201556Srgrimes * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211556Srgrimes * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221556Srgrimes * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
231556Srgrimes * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241556Srgrimes * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251556Srgrimes * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261556Srgrimes * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271556Srgrimes * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281556Srgrimes * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291556Srgrimes * POSSIBILITY OF SUCH DAMAGE.
301556Srgrimes */
311556Srgrimes
321556Srgrimes#include <sys/cdefs.h>
331556Srgrimes__KERNEL_RCSID(0, "$NetBSD: console.c,v 1.14 2008/04/28 20:23:22 martin Exp $");
341556Srgrimes
351556Srgrimes#include "opt_kgdb.h"
361556Srgrimes#include "biconsdev.h"
371556Srgrimes#include "hpcfb.h"
3850471Speter#include "scif.h"
391556Srgrimes#include "hd64461uart.h"
401556Srgrimes#include "hd64465uart.h"
411556Srgrimes#include "hd64461video.h"
421556Srgrimes#include "wskbd.h"
431556Srgrimes#include "pfckbd.h"
441556Srgrimes
451556Srgrimes#include <sys/param.h>
461556Srgrimes#include <sys/systm.h>
471556Srgrimes#include <sys/conf.h>
481556Srgrimes#include <dev/cons.h> /* consdev */
491556Srgrimes
501556Srgrimes#include <machine/bootinfo.h>
5176286Skris
521556Srgrimes#include <dev/wscons/wsdisplayvar.h>
531556Srgrimes#include <dev/rasops/rasops.h>
541556Srgrimes#include <dev/hpc/bicons.h>
551556Srgrimes#include <dev/hpc/biconsvar.h>
561556Srgrimes#include <dev/hpc/hpcfbvar.h>
571556Srgrimes#include <sh3/dev/scifvar.h>
581556Srgrimes#include <hpcsh/dev/pfckbdvar.h>
591556Srgrimes#include <hpcsh/dev/hd64461/hd64461uartvar.h>
601556Srgrimes#include <hpcsh/dev/hd64465/hd64465uartvar.h>
611556Srgrimes
621556Srgrimes/* Serial console */
631556Srgrimes#define scifcnpollc	nullcnpollc
641556Srgrimescons_decl(scif);
651556Srgrimes#define	hd64461uartcnputc	comcnputc
661556Srgrimes#define	hd64461uartcngetc	comcngetc
671556Srgrimes#define	hd64461uartcnpollc	comcnpollc
681556Srgrimescons_decl(hd64461uart);
691556Srgrimes#define	hd64465uartcnputc	comcnputc
701556Srgrimes#define	hd64465uartcngetc	comcngetc
711556Srgrimes#define	hd64465uartcnpollc	comcnpollc
721556Srgrimescons_decl(hd64465uart);
731556Srgrimes
741556Srgrimes/* Builtin video console */
751556Srgrimes#if NBICONSDEV > 0
761556Srgrimes#define biconscnpollc	nullcnpollc
771556Srgrimescons_decl(bicons);
781556Srgrimes#endif
791556Srgrimes
801556Srgrimes/* HD64461 video module */
811556Srgrimes#if NHD64461VIDEO > 0
821556Srgrimescons_decl(hd64461video_);
831556Srgrimes#if NWSKBD > 0
841556Srgrimes#include <dev/wscons/wskbdvar.h>
851556Srgrimes#define hd64461video_cngetc	wskbd_cngetc
861556Srgrimes#else  /* NWSKBD == 0 */
871556Srgrimesint
881556Srgrimeshd64461video_cngetc(dev_t dev)
891556Srgrimes{
901556Srgrimes	printf("no input method. reboot me.\n");
911556Srgrimes	for (;;)
921556Srgrimes		continue;
931556Srgrimes	/* NOTREACHED */
941556Srgrimes}
951556Srgrimes#endif /* NWSKBD == 0 */
961556Srgrimes#define hd64461video_cnputc	wsdisplay_cnputc
971556Srgrimes#define	hd64461video_cnpollc	nullcnpollc
981556Srgrimes#endif /* NHD64461VIDEO > 0 */
991556Srgrimes
1001556Srgrimesstruct consdev constab[] = {
1011556Srgrimes#if NBICONSDEV > 0
1021556Srgrimes	cons_init(bicons),
1031556Srgrimes#endif
1041556Srgrimes#if NHD64461VIDEO > 0
1051556Srgrimes	cons_init(hd64461video_),
1061556Srgrimes#endif
1071556Srgrimes#if NSCIF > 0
1081556Srgrimes	cons_init(scif),
1091556Srgrimes#endif
1101556Srgrimes#if NHD64461UART > 0
1111556Srgrimes	cons_init(hd64461uart),
1121556Srgrimes#endif
1131556Srgrimes#if NHD64465UART > 0
1141556Srgrimes	cons_init(hd64465uart),
1151556Srgrimes#endif
1161556Srgrimes	{ NULL }		/* terminator */
1171556Srgrimes};
1181556Srgrimes
1191556Srgrimes#define CN_ENABLE(x)	set_console(x ## cninit, x ## cnprobe)
1201556Srgrimes
1211556Srgrimesstatic int initialized;
1221556Srgrimesstatic int attach_kbd  __attribute__((__unused__)) = 0;
1231556Srgrimesstatic void set_console(void (*)(struct consdev *), void (*)(struct consdev *));
1241556Srgrimesstatic void disable_console(void);
1251556Srgrimesstatic void cn_nonprobe(struct consdev *);
1261556Srgrimes#if NBICONSDEV > 0
1271556Srgrimesstatic void enable_bicons(void);
1281556Srgrimes#endif
1291556Srgrimes
1301556Srgrimesvoid
1311556Srgrimesconsinit(void)
1321556Srgrimes{
1331556Srgrimes	if (initialized)
1341556Srgrimes		return;
1351556Srgrimes
1361556Srgrimes	/* select console */
1371556Srgrimes	disable_console();
1381556Srgrimes
1391556Srgrimes	switch (bootinfo->bi_cnuse) {
1401556Srgrimes	case BI_CNUSE_BUILTIN:
1411556Srgrimes#if NBICONSDEV > 0
1421556Srgrimes		enable_bicons();
1431556Srgrimes#endif
1441556Srgrimes		break;
1451556Srgrimes	case BI_CNUSE_HD64461VIDEO:
1461556Srgrimes#if NHD64461VIDEO > 0
1471556Srgrimes		CN_ENABLE(hd64461video_);
1481556Srgrimes		attach_kbd = 1;
1491556Srgrimes#endif
1501556Srgrimes		break;
1511556Srgrimes	case BI_CNUSE_SCIF:
1521556Srgrimes#if NSCIF > 0
1531556Srgrimes		CN_ENABLE(scif);
1541556Srgrimes#endif
1551556Srgrimes		break;
1561556Srgrimes	case BI_CNUSE_HD64461COM:
1571556Srgrimes#if NHD64461UART > 0
1581556Srgrimes		CN_ENABLE(hd64461uart);
1591556Srgrimes#endif
1601556Srgrimes		break;
1611556Srgrimes	case BI_CNUSE_HD64465COM:
1621556Srgrimes#if NHD64465UART > 0
1631556Srgrimes		CN_ENABLE(hd64465uart);
1641556Srgrimes#endif
1651556Srgrimes		break;
1661556Srgrimes	}
1671556Srgrimes
1681556Srgrimes#if NBICONSDEV > 0
1691556Srgrimes	if (!initialized) { /* use builtin console instead */
1701556Srgrimes		enable_bicons();
1711556Srgrimes	}
1721556Srgrimes#endif
1731556Srgrimes
1741556Srgrimes	if (initialized) {
1751556Srgrimes		cninit();
1761556Srgrimes	}
1771556Srgrimes
1781556Srgrimes#if NPFCKBD > 0
1791556Srgrimes	if (attach_kbd)
1801556Srgrimes		pfckbd_cnattach();
1811556Srgrimes#endif
1821556Srgrimes
1831556Srgrimes#if NHPCFB > 0 && NBICONSDEV > 0
1841556Srgrimes	if (cn_tab->cn_putc == biconscnputc)
1851556Srgrimes		hpcfb_cnattach(0);
1861556Srgrimes#endif
1871556Srgrimes
1881556Srgrimes#ifdef KGDB
1891556Srgrimes#if NSCIF > 0
1901556Srgrimes	scif_kgdb_init();
1911556Srgrimes#endif
1921556Srgrimes#if NHD64461UART > 0
1931556Srgrimes	hd64461uart_kgdb_init();
1941556Srgrimes#endif
1951556Srgrimes#if NHD64465UART > 0
1961556Srgrimes	hd64465uart_kgdb_init();
1971556Srgrimes#endif
1981556Srgrimes#endif /* KGDB */
1991556Srgrimes}
2001556Srgrimes
2011556Srgrimesstatic void
2021556Srgrimesset_console(void (*init_func)(struct consdev *),
2031556Srgrimes    void (*probe_func)(struct consdev *))
2041556Srgrimes{
2051556Srgrimes	struct consdev *cp;
2061556Srgrimes
2071556Srgrimes	for (cp = constab; cp->cn_probe; cp++) {
2081556Srgrimes		if (cp->cn_init == init_func) {
2091556Srgrimes			cp->cn_probe = probe_func;
2101556Srgrimes			initialized = 1;
2111556Srgrimes			break;
2121556Srgrimes		}
2131556Srgrimes	}
2141556Srgrimes}
2151556Srgrimes
2161556Srgrimesstatic void
2171556Srgrimesdisable_console(void)
2181556Srgrimes{
2191556Srgrimes	struct consdev *cp;
2201556Srgrimes
2211556Srgrimes	for (cp = constab; cp->cn_probe; cp++)
2221556Srgrimes		cp->cn_probe = cn_nonprobe;
2231556Srgrimes}
2241556Srgrimes
2251556Srgrimesstatic void
2261556Srgrimescn_nonprobe(struct consdev *cp)
2271556Srgrimes{
22876016Skris
22976016Skris	cp->cn_pri = CN_DEAD;
23076016Skris}
2311556Srgrimes
2321556Srgrimes#if NBICONSDEV > 0
2331556Srgrimesstatic void
2341556Srgrimesenable_bicons(void)
2351556Srgrimes{
2361556Srgrimes
2371556Srgrimes	bootinfo->bi_cnuse = BI_CNUSE_BUILTIN;
2381556Srgrimes	bicons_set_priority(CN_INTERNAL);
2391556Srgrimes	CN_ENABLE(bicons);
2401556Srgrimes	attach_kbd = 1;
2411556Srgrimes}
2421556Srgrimes#endif /* NBICONSDEV > 0 */
2431556Srgrimes