1 /* 2 * (C) Copyright 2000 3 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <stdarg.h> 26 #include <malloc.h> 27 #include <console.h> 28 #include <exports.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 #ifdef CONFIG_AMIGAONEG3SE 33 int console_changed = 0; 34 #endif 35 36 #ifdef CFG_CONSOLE_IS_IN_ENV 37 /* 38 * if overwrite_console returns 1, the stdin, stderr and stdout 39 * are switched to the serial port, else the settings in the 40 * environment are used 41 */ 42 #ifdef CFG_CONSOLE_OVERWRITE_ROUTINE 43 extern int overwrite_console (void); 44 #define OVERWRITE_CONSOLE overwrite_console () 45 #else 46 #define OVERWRITE_CONSOLE 0 47 #endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */ 48 49 #endif /* CFG_CONSOLE_IS_IN_ENV */ 50 51 static int console_setfile (int file, device_t * dev) 52 { 53 int error = 0; 54 55 if (dev == NULL) 56 return -1; 57 58 switch (file) { 59 case stdin: 60 case stdout: 61 case stderr: 62 /* Start new device */ 63 if (dev->start) { 64 error = dev->start (); 65 /* If it's not started dont use it */ 66 if (error < 0) 67 break; 68 } 69 70 /* Assign the new device (leaving the existing one started) */ 71 stdio_devices[file] = dev; 72 73 /* 74 * Update monitor functions 75 * (to use the console stuff by other applications) 76 */ 77 switch (file) { 78 case stdin: 79 gd->jt[XF_getc] = dev->getc; 80 gd->jt[XF_tstc] = dev->tstc; 81 break; 82 case stdout: 83 gd->jt[XF_putc] = dev->putc; 84 gd->jt[XF_puts] = dev->puts; 85 gd->jt[XF_printf] = printf; 86 break; 87 } 88 break; 89 90 default: /* Invalid file ID */ 91 error = -1; 92 } 93 return error; 94 } 95 96 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ 97 98 void serial_printf (const char *fmt, ...) 99 { 100 va_list args; 101 uint i; 102 char printbuffer[CFG_PBSIZE]; 103 104 va_start (args, fmt); 105 106 /* For this to work, printbuffer must be larger than 107 * anything we ever want to print. 108 */ 109 i = vsprintf (printbuffer, fmt, args); 110 va_end (args); 111 112 serial_puts (printbuffer); 113 } 114 115 int fgetc (int file) 116 { 117 if (file < MAX_FILES) 118 return stdio_devices[file]->getc (); 119 120 return -1; 121 } 122 123 int ftstc (int file) 124 { 125 if (file < MAX_FILES) 126 return stdio_devices[file]->tstc (); 127 128 return -1; 129 } 130 131 void fputc (int file, const char c) 132 { 133 if (file < MAX_FILES) 134 stdio_devices[file]->putc (c); 135 } 136 137 void fputs (int file, const char *s) 138 { 139 if (file < MAX_FILES) 140 stdio_devices[file]->puts (s); 141 } 142 143 void fprintf (int file, const char *fmt, ...) 144 { 145 va_list args; 146 uint i; 147 char printbuffer[CFG_PBSIZE]; 148 149 va_start (args, fmt); 150 151 /* For this to work, printbuffer must be larger than 152 * anything we ever want to print. 153 */ 154 i = vsprintf (printbuffer, fmt, args); 155 va_end (args); 156 157 /* Send to desired file */ 158 fputs (file, printbuffer); 159 } 160 161 /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ 162 163 int getc (void) 164 { 165 if (gd->flags & GD_FLG_DEVINIT) { 166 /* Get from the standard input */ 167 return fgetc (stdin); 168 } 169 170 /* Send directly to the handler */ 171 return serial_getc (); 172 } 173 174 int tstc (void) 175 { 176 if (gd->flags & GD_FLG_DEVINIT) { 177 /* Test the standard input */ 178 return ftstc (stdin); 179 } 180 181 /* Send directly to the handler */ 182 return serial_tstc (); 183 } 184 185 void putc (const char c) 186 { 187 #ifdef CONFIG_SILENT_CONSOLE 188 if (gd->flags & GD_FLG_SILENT) 189 return; 190 #endif 191 192 if (gd->flags & GD_FLG_DEVINIT) { 193 /* Send to the standard output */ 194 fputc (stdout, c); 195 } else { 196 /* Send directly to the handler */ 197 serial_putc (c); 198 } 199 } 200 201 void puts (const char *s) 202 { 203 #ifdef CONFIG_SILENT_CONSOLE 204 if (gd->flags & GD_FLG_SILENT) 205 return; 206 #endif 207 208 if (gd->flags & GD_FLG_DEVINIT) { 209 /* Send to the standard output */ 210 fputs (stdout, s); 211 } else { 212 /* Send directly to the handler */ 213 serial_puts (s); 214 } 215 } 216 217 void printf (const char *fmt, ...) 218 { 219 va_list args; 220 uint i; 221 char printbuffer[CFG_PBSIZE]; 222 223 va_start (args, fmt); 224 225 /* For this to work, printbuffer must be larger than 226 * anything we ever want to print. 227 */ 228 i = vsprintf (printbuffer, fmt, args); 229 va_end (args); 230 231 /* Print the string */ 232 puts (printbuffer); 233 } 234 235 void vprintf (const char *fmt, va_list args) 236 { 237 uint i; 238 char printbuffer[CFG_PBSIZE]; 239 240 /* For this to work, printbuffer must be larger than 241 * anything we ever want to print. 242 */ 243 i = vsprintf (printbuffer, fmt, args); 244 245 /* Print the string */ 246 puts (printbuffer); 247 } 248 249 /* test if ctrl-c was pressed */ 250 static int ctrlc_disabled = 0; /* see disable_ctrl() */ 251 static int ctrlc_was_pressed = 0; 252 int ctrlc (void) 253 { 254 if (!ctrlc_disabled && gd->have_console) { 255 if (tstc ()) { 256 switch (getc ()) { 257 case 0x03: /* ^C - Control C */ 258 ctrlc_was_pressed = 1; 259 return 1; 260 default: 261 break; 262 } 263 } 264 } 265 return 0; 266 } 267 268 /* pass 1 to disable ctrlc() checking, 0 to enable. 269 * returns previous state 270 */ 271 int disable_ctrlc (int disable) 272 { 273 int prev = ctrlc_disabled; /* save previous state */ 274 275 ctrlc_disabled = disable; 276 return prev; 277 } 278 279 int had_ctrlc (void) 280 { 281 return ctrlc_was_pressed; 282 } 283 284 void clear_ctrlc (void) 285 { 286 ctrlc_was_pressed = 0; 287 } 288 289 #ifdef CONFIG_MODEM_SUPPORT_DEBUG 290 char screen[1024]; 291 char *cursor = screen; 292 int once = 0; 293 inline void dbg(const char *fmt, ...) 294 { 295 va_list args; 296 uint i; 297 char printbuffer[CFG_PBSIZE]; 298 299 if (!once) { 300 memset(screen, 0, sizeof(screen)); 301 once++; 302 } 303 304 va_start(args, fmt); 305 306 /* For this to work, printbuffer must be larger than 307 * anything we ever want to print. 308 */ 309 i = vsprintf(printbuffer, fmt, args); 310 va_end(args); 311 312 if ((screen + sizeof(screen) - 1 - cursor) < strlen(printbuffer)+1) { 313 memset(screen, 0, sizeof(screen)); 314 cursor = screen; 315 } 316 sprintf(cursor, printbuffer); 317 cursor += strlen(printbuffer); 318 319 } 320 #else 321 inline void dbg(const char *fmt, ...) 322 { 323 } 324 #endif 325 326 /** U-Boot INIT FUNCTIONS *************************************************/ 327 328 device_t *search_device (int flags, char *name) 329 { 330 device_t *dev; 331 332 dev = device_get_by_name(name); 333 334 if(dev && (dev->flags & flags)) 335 return dev; 336 337 return NULL; 338 } 339 340 int console_assign (int file, char *devname) 341 { 342 int flag; 343 device_t *dev; 344 345 /* Check for valid file */ 346 switch (file) { 347 case stdin: 348 flag = DEV_FLAGS_INPUT; 349 break; 350 case stdout: 351 case stderr: 352 flag = DEV_FLAGS_OUTPUT; 353 break; 354 default: 355 return -1; 356 } 357 358 /* Check for valid device name */ 359 360 dev = search_device(flag, devname); 361 362 if(dev) 363 return console_setfile (file, dev); 364 365 return -1; 366 } 367 368 /* Called before relocation - use serial functions */ 369 int console_init_f (void) 370 { 371 gd->have_console = 1; 372 373 #ifdef CONFIG_SILENT_CONSOLE 374 if (getenv("silent") != NULL) 375 gd->flags |= GD_FLG_SILENT; 376 #endif 377 378 return (0); 379 } 380 381 #ifdef CFG_CONSOLE_IS_IN_ENV 382 /* Called after the relocation - use desired console functions */ 383 int console_init_r (void) 384 { 385 char *stdinname, *stdoutname, *stderrname; 386 device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL; 387 #ifdef CFG_CONSOLE_ENV_OVERWRITE 388 int i; 389 #endif /* CFG_CONSOLE_ENV_OVERWRITE */ 390 391 /* set default handlers at first */ 392 gd->jt[XF_getc] = serial_getc; 393 gd->jt[XF_tstc] = serial_tstc; 394 gd->jt[XF_putc] = serial_putc; 395 gd->jt[XF_puts] = serial_puts; 396 gd->jt[XF_printf] = serial_printf; 397 398 /* stdin stdout and stderr are in environment */ 399 /* scan for it */ 400 stdinname = getenv ("stdin"); 401 stdoutname = getenv ("stdout"); 402 stderrname = getenv ("stderr"); 403 404 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */ 405 inputdev = search_device (DEV_FLAGS_INPUT, stdinname); 406 outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname); 407 errdev = search_device (DEV_FLAGS_OUTPUT, stderrname); 408 } 409 /* if the devices are overwritten or not found, use default device */ 410 if (inputdev == NULL) { 411 inputdev = search_device (DEV_FLAGS_INPUT, "serial"); 412 } 413 if (outputdev == NULL) { 414 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 415 } 416 if (errdev == NULL) { 417 errdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 418 } 419 /* Initializes output console first */ 420 if (outputdev != NULL) { 421 console_setfile (stdout, outputdev); 422 } 423 if (errdev != NULL) { 424 console_setfile (stderr, errdev); 425 } 426 if (inputdev != NULL) { 427 console_setfile (stdin, inputdev); 428 } 429 430 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 431 432 #ifndef CFG_CONSOLE_INFO_QUIET 433 /* Print information */ 434 puts ("In: "); 435 if (stdio_devices[stdin] == NULL) { 436 puts ("No input devices available!\n"); 437 } else { 438 printf ("%s\n", stdio_devices[stdin]->name); 439 } 440 441 puts ("Out: "); 442 if (stdio_devices[stdout] == NULL) { 443 puts ("No output devices available!\n"); 444 } else { 445 printf ("%s\n", stdio_devices[stdout]->name); 446 } 447 448 puts ("Err: "); 449 if (stdio_devices[stderr] == NULL) { 450 puts ("No error devices available!\n"); 451 } else { 452 printf ("%s\n", stdio_devices[stderr]->name); 453 } 454 #endif /* CFG_CONSOLE_INFO_QUIET */ 455 456 #ifdef CFG_CONSOLE_ENV_OVERWRITE 457 /* set the environment variables (will overwrite previous env settings) */ 458 for (i = 0; i < 3; i++) { 459 setenv (stdio_names[i], stdio_devices[i]->name); 460 } 461 #endif /* CFG_CONSOLE_ENV_OVERWRITE */ 462 463 #if 0 464 /* If nothing usable installed, use only the initial console */ 465 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 466 return (0); 467 #endif 468 return (0); 469 } 470 471 #else /* CFG_CONSOLE_IS_IN_ENV */ 472 473 /* Called after the relocation - use desired console functions */ 474 int console_init_r (void) 475 { 476 device_t *inputdev = NULL, *outputdev = NULL; 477 int i; 478 struct list_head *list = device_get_list(); 479 struct list_head *pos; 480 device_t *dev; 481 482 #ifdef CONFIG_SPLASH_SCREEN 483 /* suppress all output if splash screen is enabled and we have 484 a bmp to display */ 485 if (getenv("splashimage") != NULL) 486 gd->flags |= GD_FLG_SILENT; 487 #endif 488 489 /* Scan devices looking for input and output devices */ 490 list_for_each(pos, list) { 491 dev = list_entry(pos, device_t, list); 492 493 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { 494 inputdev = dev; 495 } 496 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { 497 outputdev = dev; 498 } 499 if(inputdev && outputdev) 500 break; 501 } 502 503 /* Initializes output console first */ 504 if (outputdev != NULL) { 505 console_setfile (stdout, outputdev); 506 console_setfile (stderr, outputdev); 507 } 508 509 /* Initializes input console */ 510 if (inputdev != NULL) { 511 console_setfile (stdin, inputdev); 512 } 513 514 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 515 516 #ifndef CFG_CONSOLE_INFO_QUIET 517 /* Print information */ 518 puts ("In: "); 519 if (stdio_devices[stdin] == NULL) { 520 puts ("No input devices available!\n"); 521 } else { 522 printf ("%s\n", stdio_devices[stdin]->name); 523 } 524 525 puts ("Out: "); 526 if (stdio_devices[stdout] == NULL) { 527 puts ("No output devices available!\n"); 528 } else { 529 printf ("%s\n", stdio_devices[stdout]->name); 530 } 531 532 puts ("Err: "); 533 if (stdio_devices[stderr] == NULL) { 534 puts ("No error devices available!\n"); 535 } else { 536 printf ("%s\n", stdio_devices[stderr]->name); 537 } 538 #endif /* CFG_CONSOLE_INFO_QUIET */ 539 540 /* Setting environment variables */ 541 for (i = 0; i < 3; i++) { 542 setenv (stdio_names[i], stdio_devices[i]->name); 543 } 544 545 #if 0 546 /* If nothing usable installed, use only the initial console */ 547 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 548 return (0); 549 #endif 550 551 return (0); 552 } 553 554 #endif /* CFG_CONSOLE_IS_IN_ENV */ 555