1 /* $NetBSD: consinit.c,v 1.2 2002/09/06 13:18:43 gehenna 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 "opt_ddb.h" 33 #include "opt_kgdb.h" 34 #include "pcons.h" 35 #include "kbd.h" 36 #include "zs.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/conf.h> 41 #include <sys/device.h> 42 #include <sys/file.h> 43 #include <sys/ioctl.h> 44 #include <sys/kernel.h> 45 #include <sys/proc.h> 46 #include <sys/tty.h> 47 #include <sys/time.h> 48 #include <sys/syslog.h> 49 #include <sys/kgdb.h> 50 51 #include <machine/autoconf.h> 52 #include <machine/promlib.h> 53 #include <machine/cpu.h> 54 #include <machine/eeprom.h> 55 #include <machine/psl.h> 56 #include <machine/z8530var.h> 57 58 #include <dev/cons.h> 59 60 #include <sun2/dev/cons.h> 61 62 static void prom_cnprobe __P((struct consdev *)); 63 static void prom_cninit __P((struct consdev *)); 64 int prom_cngetc __P((dev_t)); 65 static void prom_cnputc __P((dev_t, int)); 66 static void prom_cnpollc __P((dev_t, int)); 67 static void prom_cnputc __P((dev_t, int)); 68 69 #ifdef PROM_OBP_V2 70 /* 71 * The following several variables are related to 72 * the configuration process, and are used in initializing 73 * the machine. 74 */ 75 int prom_stdin_node; /* node ID of ROM's console input device */ 76 int prom_stdout_node; /* node ID of ROM's console output device */ 77 char prom_stdin_args[16]; 78 char prom_stdout_args[16]; 79 #endif /* PROM_OBP_V2 */ 80 81 /* 82 * The console is set to this one initially, 83 * which lets us use the PROM until consinit() 84 * is called to select a real console. 85 */ 86 struct consdev consdev_prom = { 87 prom_cnprobe, 88 prom_cninit, 89 prom_cngetc, 90 prom_cnputc, 91 prom_cnpollc, 92 NULL, 93 }; 94 95 /* 96 * The console table pointer is statically initialized 97 * to point to the PROM (output only) table, so that 98 * early calls to printf will work. 99 */ 100 struct consdev *cn_tab = &consdev_prom; 101 102 void 103 prom_cnprobe(cd) 104 struct consdev *cd; 105 { 106 #if NPCONS > 0 107 extern const struct cdevsw pcons_cdevsw; 108 109 cd->cn_dev = makedev(cdevsw_lookup_major(&pcons_cdevsw), 0); 110 cd->cn_pri = CN_INTERNAL; 111 #endif 112 } 113 114 int 115 prom_cngetc(dev) 116 dev_t dev; 117 { 118 int ch; 119 #ifdef DDB 120 static int nplus = 0; 121 #endif 122 123 ch = prom_getchar(); 124 #ifdef DDB 125 if (ch == '+') { 126 if (nplus++ > 3) Debugger(); 127 } else nplus = 0; 128 #endif 129 return ch; 130 } 131 132 static void 133 prom_cninit(cn) 134 struct consdev *cn; 135 { 136 } 137 138 /* 139 * PROM console output putchar. 140 */ 141 static void 142 prom_cnputc(dev, c) 143 dev_t dev; 144 int c; 145 { 146 int s; 147 148 s = splhigh(); 149 prom_putchar(c); 150 splx(s); 151 } 152 153 void 154 prom_cnpollc(dev, on) 155 dev_t dev; 156 int on; 157 { 158 if (on) { 159 /* Entering debugger. */ 160 #if NFB > 0 161 fb_unblank(); 162 #endif 163 } else { 164 /* Resuming kernel. */ 165 } 166 #if NPCONS > 0 167 pcons_cnpollc(dev, on); 168 #endif 169 } 170 171 /*****************************************************************/ 172 173 #ifdef DEBUG 174 #define DBPRINT(x) prom_printf x 175 #else 176 #define DBPRINT(x) 177 #endif 178 179 #ifdef notyet /* PROM_OBP_V2 */ 180 void 181 prom_get_device_args(prop, dev, dev_sz, args, args_sz) 182 const char *prop; 183 char *dev; 184 unsigned int dev_sz; 185 char *args; 186 unsigned int args_sz; 187 { 188 char *cp, buffer[128]; 189 190 getpropstringA(prom_findroot(), (char *)prop, buffer, sizeof buffer); 191 192 /* 193 * Extract device-specific arguments from a PROM device path (if any) 194 */ 195 cp = buffer + strlen(buffer); 196 while (cp >= buffer) { 197 if (*cp == ':') { 198 strncpy(args, cp+1, args_sz); 199 *cp = '\0'; 200 strncpy(dev, buffer, dev_sz); 201 break; 202 } 203 cp--; 204 } 205 } 206 #endif /* PROM_OBP_V2 */ 207 208 /* 209 * This function replaces sys/dev/cninit.c 210 * Determine which device is the console using 211 * the PROM "input source" and "output sink". 212 */ 213 void 214 consinit() 215 { 216 #ifdef notyet /* PROM_OBP_V2 */ 217 char buffer[128]; 218 #endif /* PROM_OBP_V2 */ 219 char *consname = "unknown"; 220 #if KGDB 221 #if NZS > 0 222 extern const struct cdevsw zstty_cdevsw; 223 #endif 224 #endif 225 226 DBPRINT(("consinit()\r\n")); 227 if (cn_tab != &consdev_prom) return; 228 229 switch(prom_version()) { 230 #ifdef PROM_OLDMON 231 case PROM_OLDMON: 232 case PROM_OBP_V0: 233 switch(prom_stdin()) { 234 case PROMDEV_KBD: 235 consname = "keyboard/display"; 236 break; 237 case PROMDEV_TTYA: 238 consname = "ttya"; 239 break; 240 case PROMDEV_TTYB: 241 consname = "ttyb"; 242 break; 243 } 244 break; 245 #endif /* PROM_OLDMON */ 246 247 #ifdef notyet /* PROM_OBP_V2 */ 248 case PROM_OBP_V2: 249 case PROM_OBP_V3: 250 case PROM_OPENFIRM: 251 252 /* Save PROM arguments for device matching */ 253 prom_get_device_args("stdin-path", 254 buffer, 255 sizeof(buffer), 256 prom_stdin_args, 257 sizeof(prom_stdin_args)); 258 prom_get_device_args("stdout-path", 259 buffer, 260 sizeof(buffer), 261 prom_stdout_args, 262 sizeof(prom_stdout_args)); 263 264 /* 265 * Translate the STDIO package instance (`ihandle') -- that 266 * the PROM has already opened for us -- to a device tree 267 * node (i.e. a `phandle'). 268 */ 269 DBPRINT(("stdin instance = %x\r\n", prom_stdin())); 270 if ((prom_stdin_node = prom_instance_to_package(prom_stdin())) == 0) { 271 printf("WARNING: no PROM stdin\n"); 272 } 273 DBPRINT(("stdin package = %x\r\n", prom_stdin_node)); 274 275 DBPRINT(("stdout instance = %x\r\n", prom_stdout())); 276 if ((prom_stdout_node = prom_instance_to_package(prom_stdout())) == 0) { 277 printf("WARNING: no PROM stdout\n"); 278 } 279 DBPRINT(("stdout package = %x\r\n", prom_stdout_node)); 280 DBPRINT(("buffer @ %p\r\n", buffer)); 281 282 if (prom_stdin_node && prom_node_has_property(prom_stdin_node, "keyboard") { 283 #if NKBD == 0 284 printf("cninit: kdb/display not configured\n"); 285 #endif 286 consname = "keyboard/display"; 287 } else if (prom_stdout_node) 288 consname = buffer; 289 #endif /* PROM_OBP_V2 */ 290 } 291 printf("console is %s\n", consname); 292 293 /* Initialize PROM console */ 294 (*cn_tab->cn_probe)(cn_tab); 295 (*cn_tab->cn_init)(cn_tab); 296 297 #ifdef KGDB 298 /* Set up KGDB */ 299 #if NZS > 0 300 if (cdevsw_lookup(kgdb_dev) == &zstty_cdevsw) 301 zs_kgdb_init(); 302 #endif /* NZS > 0 */ 303 #endif /* KGDB */ 304 } 305 306