1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * isa-specific console configuration routines 31 */ 32 33 #include <sys/types.h> 34 #include <sys/param.h> 35 #include <sys/cmn_err.h> 36 #include <sys/systm.h> 37 #include <sys/conf.h> 38 #include <sys/debug.h> 39 #include <sys/ddi.h> 40 #include <sys/sunddi.h> 41 #include <sys/sunndi.h> 42 #include <sys/esunddi.h> 43 #include <sys/ddi_impldefs.h> 44 #include <sys/promif.h> 45 #include <sys/modctl.h> 46 #include <sys/termios.h> 47 #if defined(__xpv) 48 #include <sys/hypervisor.h> 49 #include <sys/boot_console.h> 50 #endif 51 52 /* The names of currently supported graphics drivers on x86 */ 53 static char * 54 gfxdrv_name[] = { 55 "vgatext", 56 "i915", 57 "nvidia" 58 }; 59 60 int 61 plat_use_polled_debug() { 62 return (0); 63 } 64 65 int 66 plat_support_serial_kbd_and_ms() { 67 return (0); 68 } 69 70 #define A_CNT(arr) (sizeof (arr) / sizeof (arr[0])) 71 72 #define CONS_INVALID -1 73 #define CONS_SCREEN 0 74 #define CONS_TTYA 1 75 #define CONS_TTYB 2 76 #define CONS_USBSER 3 77 #define CONS_HYPERVISOR 4 78 79 static int 80 console_type() 81 { 82 static int boot_console = CONS_INVALID; 83 84 char *cons; 85 dev_info_t *root; 86 87 if (boot_console != CONS_INVALID) 88 return (boot_console); 89 90 #if defined(__xpv) 91 if (!DOMAIN_IS_INITDOMAIN(xen_info) || bcons_hypervisor_redirect()) { 92 boot_console = CONS_HYPERVISOR; 93 return (boot_console); 94 } 95 #endif /* __xpv */ 96 97 /* 98 * console is defined by "console" property, with 99 * fallback on the old "input-device" property. 100 */ 101 boot_console = CONS_SCREEN; /* default is screen/kb */ 102 root = ddi_root_node(); 103 if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, root, 104 DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) || 105 (ddi_prop_lookup_string(DDI_DEV_T_ANY, root, 106 DDI_PROP_DONTPASS, "input-device", &cons) == DDI_SUCCESS)) { 107 if (strcmp(cons, "ttya") == 0) { 108 boot_console = CONS_TTYA; 109 } else if (strcmp(cons, "ttyb") == 0) { 110 boot_console = CONS_TTYB; 111 } else if (strcmp(cons, "usb-serial") == 0) { 112 (void) i_ddi_attach_hw_nodes("ehci"); 113 (void) i_ddi_attach_hw_nodes("uhci"); 114 (void) i_ddi_attach_hw_nodes("ohci"); 115 /* 116 * USB device enumerate asynchronously. 117 * Wait 2 seconds for USB serial devices to attach. 118 */ 119 delay(drv_usectohz(2000000)); 120 boot_console = CONS_USBSER; 121 #if defined(__xpv) 122 } else if (strcmp(cons, "hypervisor") == 0) { 123 boot_console = CONS_HYPERVISOR; 124 #endif /* __xpv */ 125 } 126 ddi_prop_free(cons); 127 } 128 return (boot_console); 129 } 130 131 int 132 plat_stdin_is_keyboard(void) 133 { 134 return (console_type() == CONS_SCREEN); 135 } 136 137 int 138 plat_stdout_is_framebuffer(void) 139 { 140 return (console_type() == CONS_SCREEN); 141 } 142 143 /* 144 * Return generic path to keyboard device from the alias. 145 */ 146 char * 147 plat_kbdpath(void) 148 { 149 /* 150 * Hardcode to isa keyboard path 151 * XXX make it settable via bootprop? 152 */ 153 return ("/isa/i8042@1,60/keyboard@0"); 154 } 155 156 /* 157 * Return generic path to display device from the alias. 158 */ 159 char * 160 plat_fbpath(void) 161 { 162 static char *fbpath = NULL; 163 static char fbpath_buf[MAXPATHLEN]; 164 major_t major; 165 dev_info_t *dip, *dip_pseudo = NULL; 166 int i; 167 168 /* lookup the dip for the pseudo device */ 169 (void) resolve_pathname("/pseudo", &dip_pseudo, NULL, NULL); 170 171 for (i = 0; i < A_CNT(gfxdrv_name); i++) { 172 /* 173 * look for first instance of each driver 174 */ 175 if ((major = ddi_name_to_major(gfxdrv_name[i])) == (major_t)-1) 176 continue; 177 178 if ((dip = devnamesp[major].dn_head) == NULL) 179 continue; 180 181 /* 182 * We're looking for a real hardware device here so skip 183 * any pseudo devices. When could a framebuffer hardware 184 * driver also have a pseudo node? Well, some framebuffer 185 * hardware drivers (nvidia) also create pseudo nodes for 186 * administration purposes, and these nodes will exist 187 * regardless of if the actual associated hardware 188 * is present or not. 189 */ 190 if (ddi_get_parent(dip) == dip_pseudo) 191 continue; 192 193 if (i_ddi_attach_node_hierarchy(dip) == DDI_SUCCESS) { 194 (void) ddi_pathname(dip, fbpath_buf); 195 fbpath = fbpath_buf; 196 } 197 198 if (fbpath) 199 break; 200 } 201 202 if (dip_pseudo != NULL) 203 ddi_release_devi(dip_pseudo); 204 205 /* No screen found */ 206 return (fbpath); 207 } 208 209 char * 210 plat_mousepath(void) 211 { 212 /* 213 * Hardcode to isa mouse path 214 * XXX make it settable via bootprop? 215 */ 216 return ("/isa/i8042@1,60/mouse@1"); 217 } 218 219 /* return path of first usb serial device */ 220 static char * 221 plat_usbser_path(void) 222 { 223 extern dev_info_t *usbser_first_device(void); 224 225 dev_info_t *us_dip; 226 static char *us_path = NULL; 227 228 if (us_path) 229 return (us_path); 230 231 us_dip = usbser_first_device(); 232 if (us_dip == NULL) 233 return (NULL); 234 235 us_path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 236 (void) ddi_pathname(us_dip, us_path); 237 ndi_rele_devi(us_dip); /* held from usbser_first_device */ 238 return (us_path); 239 } 240 241 /* 242 * Lacking support for com2 and com3, if that matters. 243 * Another possible enhancement could be to use properties 244 * for the port mapping rather than simply hard-code them. 245 */ 246 char * 247 plat_stdinpath(void) 248 { 249 switch (console_type()) { 250 #if defined(__xpv) 251 case CONS_HYPERVISOR: 252 return ("/xpvd/xencons@0"); 253 #endif /* __xpv */ 254 case CONS_TTYA: 255 return ("/isa/asy@1,3f8:a"); 256 case CONS_TTYB: 257 return ("/isa/asy@1,2f8:b"); 258 case CONS_USBSER: 259 return (plat_usbser_path()); 260 case CONS_SCREEN: 261 default: 262 break; 263 }; 264 return (plat_kbdpath()); 265 } 266 267 char * 268 plat_stdoutpath(void) 269 { 270 switch (console_type()) { 271 #if defined(__xpv) 272 case CONS_HYPERVISOR: 273 return ("/xpvd/xencons@0"); 274 #endif /* __xpv */ 275 case CONS_TTYA: 276 return ("/isa/asy@1,3f8:a"); 277 case CONS_TTYB: 278 return ("/isa/asy@1,2f8:b"); 279 case CONS_USBSER: 280 return (plat_usbser_path()); 281 case CONS_SCREEN: 282 default: 283 break; 284 }; 285 return (plat_fbpath()); 286 } 287 288 /* 289 * If VIS_PIXEL mode will be implemented on x86, these following 290 * functions should be re-considered. Now these functions are 291 * unused on x86. 292 */ 293 void 294 plat_tem_get_inverses(int *inverse, int *inverse_screen) 295 { 296 *inverse = 0; 297 *inverse_screen = 0; 298 } 299 300 void 301 plat_tem_get_prom_font_size(int *charheight, int *windowtop) 302 { 303 *charheight = 0; 304 *windowtop = 0; 305 } 306 307 /*ARGSUSED*/ 308 void 309 plat_tem_get_prom_size(size_t *height, size_t *width) 310 { 311 panic("unimplemented at line %d of %s", __LINE__, __FILE__); 312 } 313 314 void 315 plat_tem_hide_prom_cursor(void) 316 { 317 panic("unimplemented at line %d of %s", __LINE__, __FILE__); 318 } 319 320 /*ARGSUSED*/ 321 void 322 plat_tem_get_prom_pos(uint32_t *row, uint32_t *col) 323 { 324 panic("unimplemented at line %d of %s", __LINE__, __FILE__); 325 } 326