1 /* $NetBSD: consinit.c,v 1.3 2003/07/15 03:36:11 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 Matthew Fredette 5 * Copyright (c) 1999 Eduardo E. Horvath 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.3 2003/07/15 03:36:11 lukem Exp $"); 34 35 #include "opt_ddb.h" 36 #include "opt_kgdb.h" 37 #include "pcons.h" 38 #include "kbd.h" 39 #include "zs.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/conf.h> 44 #include <sys/device.h> 45 #include <sys/file.h> 46 #include <sys/ioctl.h> 47 #include <sys/kernel.h> 48 #include <sys/proc.h> 49 #include <sys/tty.h> 50 #include <sys/time.h> 51 #include <sys/syslog.h> 52 #include <sys/kgdb.h> 53 54 #include <machine/autoconf.h> 55 #include <machine/promlib.h> 56 #include <machine/cpu.h> 57 #include <machine/eeprom.h> 58 #include <machine/psl.h> 59 #include <machine/z8530var.h> 60 61 #include <dev/cons.h> 62 63 #include <sun2/dev/cons.h> 64 65 static void prom_cnprobe __P((struct consdev *)); 66 static void prom_cninit __P((struct consdev *)); 67 int prom_cngetc __P((dev_t)); 68 static void prom_cnputc __P((dev_t, int)); 69 static void prom_cnpollc __P((dev_t, int)); 70 static void prom_cnputc __P((dev_t, int)); 71 72 #ifdef PROM_OBP_V2 73 /* 74 * The following several variables are related to 75 * the configuration process, and are used in initializing 76 * the machine. 77 */ 78 int prom_stdin_node; /* node ID of ROM's console input device */ 79 int prom_stdout_node; /* node ID of ROM's console output device */ 80 char prom_stdin_args[16]; 81 char prom_stdout_args[16]; 82 #endif /* PROM_OBP_V2 */ 83 84 /* 85 * The console is set to this one initially, 86 * which lets us use the PROM until consinit() 87 * is called to select a real console. 88 */ 89 struct consdev consdev_prom = { 90 prom_cnprobe, 91 prom_cninit, 92 prom_cngetc, 93 prom_cnputc, 94 prom_cnpollc, 95 NULL, 96 }; 97 98 /* 99 * The console table pointer is statically initialized 100 * to point to the PROM (output only) table, so that 101 * early calls to printf will work. 102 */ 103 struct consdev *cn_tab = &consdev_prom; 104 105 void 106 prom_cnprobe(cd) 107 struct consdev *cd; 108 { 109 #if NPCONS > 0 110 extern const struct cdevsw pcons_cdevsw; 111 112 cd->cn_dev = makedev(cdevsw_lookup_major(&pcons_cdevsw), 0); 113 cd->cn_pri = CN_INTERNAL; 114 #endif 115 } 116 117 int 118 prom_cngetc(dev) 119 dev_t dev; 120 { 121 int ch; 122 #ifdef DDB 123 static int nplus = 0; 124 #endif 125 126 ch = prom_getchar(); 127 #ifdef DDB 128 if (ch == '+') { 129 if (nplus++ > 3) Debugger(); 130 } else nplus = 0; 131 #endif 132 return ch; 133 } 134 135 static void 136 prom_cninit(cn) 137 struct consdev *cn; 138 { 139 } 140 141 /* 142 * PROM console output putchar. 143 */ 144 static void 145 prom_cnputc(dev, c) 146 dev_t dev; 147 int c; 148 { 149 int s; 150 151 s = splhigh(); 152 prom_putchar(c); 153 splx(s); 154 } 155 156 void 157 prom_cnpollc(dev, on) 158 dev_t dev; 159 int on; 160 { 161 if (on) { 162 /* Entering debugger. */ 163 #if NFB > 0 164 fb_unblank(); 165 #endif 166 } else { 167 /* Resuming kernel. */ 168 } 169 #if NPCONS > 0 170 pcons_cnpollc(dev, on); 171 #endif 172 } 173 174 /*****************************************************************/ 175 176 #ifdef DEBUG 177 #define DBPRINT(x) prom_printf x 178 #else 179 #define DBPRINT(x) 180 #endif 181 182 #ifdef notyet /* PROM_OBP_V2 */ 183 void 184 prom_get_device_args(prop, dev, dev_sz, args, args_sz) 185 const char *prop; 186 char *dev; 187 unsigned int dev_sz; 188 char *args; 189 unsigned int args_sz; 190 { 191 char *cp, buffer[128]; 192 193 getpropstringA(prom_findroot(), (char *)prop, buffer, sizeof buffer); 194 195 /* 196 * Extract device-specific arguments from a PROM device path (if any) 197 */ 198 cp = buffer + strlen(buffer); 199 while (cp >= buffer) { 200 if (*cp == ':') { 201 strncpy(args, cp+1, args_sz); 202 *cp = '\0'; 203 strncpy(dev, buffer, dev_sz); 204 break; 205 } 206 cp--; 207 } 208 } 209 #endif /* PROM_OBP_V2 */ 210 211 /* 212 * This function replaces sys/dev/cninit.c 213 * Determine which device is the console using 214 * the PROM "input source" and "output sink". 215 */ 216 void 217 consinit() 218 { 219 #ifdef notyet /* PROM_OBP_V2 */ 220 char buffer[128]; 221 #endif /* PROM_OBP_V2 */ 222 char *consname = "unknown"; 223 #if KGDB 224 #if NZS > 0 225 extern const struct cdevsw zstty_cdevsw; 226 #endif 227 #endif 228 229 DBPRINT(("consinit()\r\n")); 230 if (cn_tab != &consdev_prom) return; 231 232 switch(prom_version()) { 233 #ifdef PROM_OLDMON 234 case PROM_OLDMON: 235 case PROM_OBP_V0: 236 switch(prom_stdin()) { 237 case PROMDEV_KBD: 238 consname = "keyboard/display"; 239 break; 240 case PROMDEV_TTYA: 241 consname = "ttya"; 242 break; 243 case PROMDEV_TTYB: 244 consname = "ttyb"; 245 break; 246 } 247 break; 248 #endif /* PROM_OLDMON */ 249 250 #ifdef notyet /* PROM_OBP_V2 */ 251 case PROM_OBP_V2: 252 case PROM_OBP_V3: 253 case PROM_OPENFIRM: 254 255 /* Save PROM arguments for device matching */ 256 prom_get_device_args("stdin-path", 257 buffer, 258 sizeof(buffer), 259 prom_stdin_args, 260 sizeof(prom_stdin_args)); 261 prom_get_device_args("stdout-path", 262 buffer, 263 sizeof(buffer), 264 prom_stdout_args, 265 sizeof(prom_stdout_args)); 266 267 /* 268 * Translate the STDIO package instance (`ihandle') -- that 269 * the PROM has already opened for us -- to a device tree 270 * node (i.e. a `phandle'). 271 */ 272 DBPRINT(("stdin instance = %x\r\n", prom_stdin())); 273 if ((prom_stdin_node = prom_instance_to_package(prom_stdin())) == 0) { 274 printf("WARNING: no PROM stdin\n"); 275 } 276 DBPRINT(("stdin package = %x\r\n", prom_stdin_node)); 277 278 DBPRINT(("stdout instance = %x\r\n", prom_stdout())); 279 if ((prom_stdout_node = prom_instance_to_package(prom_stdout())) == 0) { 280 printf("WARNING: no PROM stdout\n"); 281 } 282 DBPRINT(("stdout package = %x\r\n", prom_stdout_node)); 283 DBPRINT(("buffer @ %p\r\n", buffer)); 284 285 if (prom_stdin_node && prom_node_has_property(prom_stdin_node, "keyboard") { 286 #if NKBD == 0 287 printf("cninit: kdb/display not configured\n"); 288 #endif 289 consname = "keyboard/display"; 290 } else if (prom_stdout_node) 291 consname = buffer; 292 #endif /* PROM_OBP_V2 */ 293 } 294 printf("console is %s\n", consname); 295 296 /* Initialize PROM console */ 297 (*cn_tab->cn_probe)(cn_tab); 298 (*cn_tab->cn_init)(cn_tab); 299 300 #ifdef KGDB 301 /* Set up KGDB */ 302 #if NZS > 0 303 if (cdevsw_lookup(kgdb_dev) == &zstty_cdevsw) 304 zs_kgdb_init(); 305 #endif /* NZS > 0 */ 306 #endif /* KGDB */ 307 } 308 309