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