/* $NetBSD: findcons.c,v 1.12 1999/05/11 05:15:54 nisimura 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 /* RCS ID & Copyright macro defns */ __KERNEL_RCSID(0, "$NetBSD: findcons.c,v 1.12 1999/05/11 05:15:54 nisimura Exp $$"); #include #include #include #include #include #include /* * 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_ds.h" #include "dc_ioasic.h" #include "dtop.h" #include "scc.h" #include "asc.h" #include "tc.h" #include "rasterconsole.h" #include /* find TC fraembuffer device. */ #include #include /* scc serial console addresses */ #include #include #include #include #include /* framebuffer decls used below */ #include #include #include #include /* pmax serial interface */ #if (NDC_DS > 0) || (NDC_IOASIC > 0) #include #include #include #include #endif /* MAXINE desktop bus keyboard */ #if NDTOP > 0 #include #endif /* ioasic serial console */ #if NSCC > 0 #include #endif /* ds3100 baseboard framebuffer */ #if NPM > 0 #include #endif /* maxine baseboard framebuffer */ #if NXCFB > 0 #include #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 dc_ioasic_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)); integrate int tc_screen __P((int prom_slot)); integrate int dc_ds_serial __P((int prom_slot)); integrate int dc_ioasic_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 void prom_findcons __P((int *, int *, int *)); extern struct consdev promcd; /* * Keyboard physically present and driver configured on 3100? */ int dc_ds_kbd(kbd_slot) int kbd_slot; { #if NDC_DS > 0 && NWS > 0 if (systype == DS_PMAX) { cd.cn_getc = LKgetc; lk_divert(dcGetc, makedev(DCDEV, DCKBD_PORT)); return 1; } #endif return 0; } /* * Keyboard supported and present on 5000/200? */ int dc_ioasic_kbd(kbd_slot) int kbd_slot; { #if NDC_IOASIC > 0 && NWS > 0 if (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: return (dc_ds_kbd(kbd)); break; case DS_3MAX: return (dc_ioasic_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 if (pminit(0, 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 (systype != DS_MAXINE) return 0; #if NXCFB > 0 if (crtslot == 3 && xcfbinit(NULL, NULL, 0, 0)) { cd.cn_pri = CN_INTERNAL; return(1); } else #endif return (0); } int tc_screen(crtslot) int crtslot; { #if NTC > 0 if (tc_findconsole(crtslot)) { return (1); } #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 (xcfb_screen(crtslot)) return (1); /*FALLTHROUGH*/ case DS_3MAX: case DS_3MIN: case DS_3MAXPLUS: /* TC option video?*/ if (tc_screen(crtslot)) return(1); break; default: break; } /* no screen found. */ return (0); } int dc_ds_serial(comslot) int comslot; { #if NDC_DS 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 dc_ioasic_serial(comslot) int comslot; { #if NDC_IOASIC cd.cn_dev = makedev(DCDEV, DCPRINTER_PORT); return dc_ioasic_consinit(cd.cn_dev); #else return 0; #endif } 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: return (dc_ds_serial(comslot)); break; case DS_MIPSMATE: /* console fixed on line 0 */ return (dc_ds_serial(0)); break; case DS_3MAX: return (dc_ioasic_serial(comslot)); 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; }