NetBSD/sys/arch/pmax/dev/findcons.c

494 lines
9.8 KiB
C

/* $NetBSD: findcons.c,v 1.20 1999/11/19 02:16:06 simonb Exp $ */
/*
* Copyright (c) 1998 Jonathan Stone
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jonathan Stone for
* the NetBSD Project.
* 4. 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 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 <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: findcons.c,v 1.20 1999/11/19 02:16:06 simonb Exp $$");
#include <sys/param.h>
#include <sys/systm.h>
#include <dev/cons.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <pmax/pmax/pmaxtype.h>
#include <pmax/pmax/machdep.h>
/*
* Default consdev, for errors or warnings before
* consinit runs: use the PROM.
*/
struct consdev cd;
#ifndef integrate
#define integrate static inline
#endif
/*
* Kernel configuration dependencies.
*/
#include "px.h"
#include "pm.h"
#include "cfb.h"
#include "mfb.h"
#include "xcfb.h"
#include "sfb.h"
#include "dc.h"
#include "dtop.h"
#include "scc.h"
#include "tc.h"
#include "rasterconsole.h"
#include <dev/tc/tcvar.h> /* find TC fraembuffer device. */
#include <machine/tc_machdep.h>
#include <pmax/pmax/asic.h> /* scc serial console addresses */
#include <pmax/pmax/kn01.h>
#include <pmax/pmax/kn03.h>
#include <pmax/pmax/kmin.h>
#include <pmax/pmax/maxine.h>
#include <machine/pmioctl.h>
#include <machine/fbio.h> /* framebuffer decls used below */
#include <machine/fbvar.h>
#include <pmax/dev/fbreg.h>
#include <pmax/dev/lk201var.h>
#include <pmax/dev/rconsvar.h>
/* pmax serial interface */
#if NDC > 0
#include <machine/dc7085cons.h>
#include <pmax/dev/dc_cons.h>
#include <pmax/dev/dc_ds_cons.h>
#endif
/* MAXINE desktop bus keyboard */
#if NDTOP > 0
#include <pmax/dev/dtopvar.h>
#endif
/* ioasic serial console */
#if NSCC > 0
#include <pmax/tc/sccvar.h>
#endif
/* ds3100 baseboard framebuffer */
#if NPM > 0
#include <pmax/dev/pmvar.h>
#endif
/* maxine baseboard framebuffer */
#if NXCFB > 0
#include <pmax/dev/xcfbvar.h>
#endif
#define NWS (NXCFB + NPM + NMFB + NSFB + NCFB + NPX)
/*
* XXX Major device numbers for possible console devices.
*/
#define DCDEV 16
#define SCCDEV 17
/*
* forward declarations
*/
/*
* device scan functions.
* This would use the autoconfigatin hiearchy, except we need
* to pick a console early in boot before autoconfig or
* malloc are up.
*/
integrate int dc_ds_kbd __P((int prom_slot));
integrate int scc_kbd __P((int prom_slot));
integrate int dtop_kbd __P((int prom_slot));
integrate int pm_screen __P((int prom_slot));
integrate int xcfb_screen __P((int prom_slot));
#if NRASTERCONSOLE > 0
extern int tcfb_cnattach __P((int prom_slot));
#endif
integrate int dc_ds_serial __P((int prom_slot));
integrate int scc_serial __P((int prom_slot));
int find_kbd __P((int prom_slot));
int find_screen __P((int prom_slot));
int find_serial __P((int prom_slot));
void consinit __P((void));
extern struct consdev promcd;
/*
* Keyboard physically present and driver configured on 3100?
*/
int
dc_ds_kbd(kbd_slot)
int kbd_slot;
{
#if NDC > 0 && NWS > 0
if (systype == DS_PMAX) {
cd.cn_getc = LKgetc;
lk_divert(dcGetc, makedev(DCDEV, DCKBD_PORT));
return 1;
}
else if (systype == DS_3MAX && kbd_slot == 7) {
cd.cn_dev = makedev(DCDEV, DCKBD_PORT);
cd.cn_getc = LKgetc;
lk_divert(dcGetc, makedev(DCDEV, DCKBD_PORT));
return 1;
}
#endif
return 0;
}
/*
* Keyboard configured and physically presnt on 3min, 3maxplus?
*/
int
scc_kbd(kbd_slot)
int kbd_slot;
{
#if NSCC > 0 && NWS > 0
if (kbd_slot == 3) {
cd.cn_dev = makedev(SCCDEV, SCCKBD_PORT);
lk_divert(sccGetc, makedev(SCCDEV, SCCKBD_PORT));
cd.cn_getc = LKgetc;
return 1;
}
#endif /* NSCC */
return 0;
}
/*
* Keyboard physically present and driver configured on MAXINE?
*/
int
dtop_kbd(kbd_slot)
int kbd_slot;
{
if (systype != DS_MAXINE)
return 0;
#if NDTOP > 0
if (kbd_slot == 3) {
cd.cn_getc = dtopKBDGetc;
return 1;
}
#endif
return 0;
}
/*
* Select appropriate keyboard.
*/
int
find_kbd(kbd)
int kbd;
{
switch(systype) {
case DS_PMAX:
case DS_3MAX:
return (dc_ds_kbd(kbd));
break;
case DS_3MIN:
case DS_3MAXPLUS:
/* keyboard on scc? */
return (scc_kbd(kbd));
break;
case DS_MAXINE:
return (dtop_kbd(kbd));
default:
break;
}
/* No keyboard found. */
return (0);
}
/*
* Test if screens configured.
*/
int
pm_screen(crtslot)
int crtslot;
{
#if NPM > 0
struct fbinfo *fi;
caddr_t base;
base = (caddr_t)MIPS_PHYS_TO_KSEG1(KN01_SYS_PCC);
if (fballoc(base, &fi))
return (0);
if (pminit(fi, base, 0, 1)) {
cd.cn_pri = CN_INTERNAL;
return (1);
}
#endif
return (0);
}
/*
* Look for MAXINE baseboard video.
* If selected as console, take it.
*/
int
xcfb_screen(crtslot)
int crtslot;
{
#if NXCFB > 0
struct fbinfo *fi;
caddr_t base;
#endif
if (systype != DS_MAXINE)
return 0;
#if NXCFB > 0
base = (caddr_t)MIPS_PHYS_TO_KSEG1(XINE_PHYS_CFB_START);
if (fballoc(base, &fi))
return (0);
if (crtslot == 3 && xcfbinit(fi, base, 0, 1)) {
cd.cn_pri = CN_INTERNAL;
return(1);
} else
#endif
return (0);
}
/*
* Look for screen.
*/
int
find_screen(crtslot)
int crtslot;
{
switch(systype) {
case DS_PMAX:
if (pm_screen(crtslot))
return (1);
/* no other options on 3100s. */
break;
case DS_MAXINE:
if (crtslot == 3 && xcfb_screen(crtslot))
return (1);
/*FALLTHROUGH*/
case DS_3MAX:
case DS_3MIN:
case DS_3MAXPLUS:
#if NRASTERCONSOLE > 0
/* TC option video?*/
if (tcfb_cnattach(crtslot))
return(1);
#endif
break;
default:
break;
}
/* no screen found. */
return (0);
}
int
dc_ds_serial(comslot)
int comslot;
{
#if NDC > 0
if (comslot == 4)
cd.cn_dev = makedev(DCDEV, DCCOMM_PORT);
else
if (comslot == 0) {
cd.cn_dev = makedev(DCDEV, 0);
} else
cd.cn_dev = makedev(DCDEV, DCPRINTER_PORT);
return dc_ds_consinit(cd.cn_dev);
#endif
return 0;
}
int
scc_serial(comslot)
int comslot;
{
#if NSCC > 0
int dev;
void * sccaddr;
/*
* On the 3min and 3maxplus, the default serial-console
* port is on the chip at the higher address.
* On the MAXINE, there is only serial port, which
* configures at the lower address.
*/
switch (systype) {
case DS_MAXINE:
dev = SCCCOMM2_PORT;
sccaddr = (void*)(TC_KV(XINE_SYS_ASIC) + IOASIC_SLOT_4_START);
break;
case DS_3MIN:
dev = SCCCOMM3_PORT;
sccaddr = (void*)(TC_KV(KMIN_SYS_ASIC) + IOASIC_SLOT_6_START);
break;
case DS_3MAXPLUS:
dev = SCCCOMM3_PORT;
sccaddr = (void*)(TC_KV(KN03_SYS_ASIC) + IOASIC_SLOT_6_START);
break;
default:
return (0);
}
cd.cn_dev = makedev(SCCDEV, dev);
scc_consinit(cd.cn_dev, sccaddr);
return 1;
#endif /* NSCC */
return 0;
}
/*
* find a serial console.
*/
int
find_serial(comslot)
int comslot;
{
switch(systype) {
case DS_PMAX:
case DS_3MAX:
return (dc_ds_serial(comslot));
break;
case DS_MIPSMATE:
/* console fixed on line 0 */
return (dc_ds_serial(0));
break;
case DS_MAXINE: /* XXX only one serial port */
case DS_3MIN:
case DS_3MAXPLUS:
return (scc_serial(comslot));
break;
default:
break;
}
return (0);
}
/*
* Pick a console.
* Use the same devices as PROM says, if we have a driver.
* if wedont' have a driver for the device the PROM chose,
* pick the highest-priority device according to the Owners Guide rules.
* If no match, stick with the PROM and hope for the best.
*/
void
consinit()
{
int prom_using_screen = 0; /* boolean */
int kbd = 0; /* prom kbd locator */
int crt = 0; /* prom framebuffer locator */
/* Use copy of PROM console until we find something better. */
cd = promcd;
cn_tab = &cd;
/* get PROM's idea of what the console is. */
prom_findcons(&kbd, &crt, &prom_using_screen);
/* if the prom is using a screen, try that. */
if (prom_using_screen) {
if (find_kbd(kbd) && find_screen(crt)) {
#if NRASTERCONSOLE > 0
cd.cn_pri = CN_NORMAL;
rcons_indev(&cd);
return;
#endif /* NRASTERCONSOLE > 0 */
}
/* PROM is using fb console, but we have no driver for it. */
printf("No supported console device in slot %d. ", crt);
printf("Trying serial console.\n");
DELAY(500000);
} else {
/*
* If we found a keyboard and framebuffer, wire it up
* as an rcons device even if it's not the OS console.
*/
}
/* Otherwise, try a serial port as console. */
if (find_serial(kbd)) {
cd.cn_pri = CN_REMOTE;
return;
}
/*
* Nothing worked. Revert to using PROM.
* Maybe some device will usurp the console during
* autoconfiguration.
*/
cd = promcd;
printf("No driver for console device, using prom for console I/O.\n");
DELAY(500000);
return;
}