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