1 /* 2 * (C) Copyright 2000 3 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <stdarg.h> 10 #include <iomux.h> 11 #include <malloc.h> 12 #include <os.h> 13 #include <serial.h> 14 #include <stdio_dev.h> 15 #include <exports.h> 16 #include <environment.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 static int on_console(const char *name, const char *value, enum env_op op, 21 int flags) 22 { 23 int console = -1; 24 25 /* Check for console redirection */ 26 if (strcmp(name, "stdin") == 0) 27 console = stdin; 28 else if (strcmp(name, "stdout") == 0) 29 console = stdout; 30 else if (strcmp(name, "stderr") == 0) 31 console = stderr; 32 33 /* if not actually setting a console variable, we don't care */ 34 if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0) 35 return 0; 36 37 switch (op) { 38 case env_op_create: 39 case env_op_overwrite: 40 41 #ifdef CONFIG_CONSOLE_MUX 42 if (iomux_doenv(console, value)) 43 return 1; 44 #else 45 /* Try assigning specified device */ 46 if (console_assign(console, value) < 0) 47 return 1; 48 #endif /* CONFIG_CONSOLE_MUX */ 49 return 0; 50 51 case env_op_delete: 52 if ((flags & H_FORCE) == 0) 53 printf("Can't delete \"%s\"\n", name); 54 return 1; 55 56 default: 57 return 0; 58 } 59 } 60 U_BOOT_ENV_CALLBACK(console, on_console); 61 62 #ifdef CONFIG_SILENT_CONSOLE 63 static int on_silent(const char *name, const char *value, enum env_op op, 64 int flags) 65 { 66 #ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_SET 67 if (flags & H_INTERACTIVE) 68 return 0; 69 #endif 70 #ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC 71 if ((flags & H_INTERACTIVE) == 0) 72 return 0; 73 #endif 74 75 if (value != NULL) 76 gd->flags |= GD_FLG_SILENT; 77 else 78 gd->flags &= ~GD_FLG_SILENT; 79 80 return 0; 81 } 82 U_BOOT_ENV_CALLBACK(silent, on_silent); 83 #endif 84 85 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV 86 /* 87 * if overwrite_console returns 1, the stdin, stderr and stdout 88 * are switched to the serial port, else the settings in the 89 * environment are used 90 */ 91 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE 92 extern int overwrite_console(void); 93 #define OVERWRITE_CONSOLE overwrite_console() 94 #else 95 #define OVERWRITE_CONSOLE 0 96 #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */ 97 98 #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ 99 100 static int console_setfile(int file, struct stdio_dev * dev) 101 { 102 int error = 0; 103 104 if (dev == NULL) 105 return -1; 106 107 switch (file) { 108 case stdin: 109 case stdout: 110 case stderr: 111 /* Start new device */ 112 if (dev->start) { 113 error = dev->start(dev); 114 /* If it's not started dont use it */ 115 if (error < 0) 116 break; 117 } 118 119 /* Assign the new device (leaving the existing one started) */ 120 stdio_devices[file] = dev; 121 122 /* 123 * Update monitor functions 124 * (to use the console stuff by other applications) 125 */ 126 switch (file) { 127 case stdin: 128 gd->jt->getc = getc; 129 gd->jt->tstc = tstc; 130 break; 131 case stdout: 132 gd->jt->putc = putc; 133 gd->jt->puts = puts; 134 gd->jt->printf = printf; 135 break; 136 } 137 break; 138 139 default: /* Invalid file ID */ 140 error = -1; 141 } 142 return error; 143 } 144 145 #if defined(CONFIG_CONSOLE_MUX) 146 /** Console I/O multiplexing *******************************************/ 147 148 static struct stdio_dev *tstcdev; 149 struct stdio_dev **console_devices[MAX_FILES]; 150 int cd_count[MAX_FILES]; 151 152 /* 153 * This depends on tstc() always being called before getc(). 154 * This is guaranteed to be true because this routine is called 155 * only from fgetc() which assures it. 156 * No attempt is made to demultiplex multiple input sources. 157 */ 158 static int console_getc(int file) 159 { 160 unsigned char ret; 161 162 /* This is never called with testcdev == NULL */ 163 ret = tstcdev->getc(tstcdev); 164 tstcdev = NULL; 165 return ret; 166 } 167 168 static int console_tstc(int file) 169 { 170 int i, ret; 171 struct stdio_dev *dev; 172 173 disable_ctrlc(1); 174 for (i = 0; i < cd_count[file]; i++) { 175 dev = console_devices[file][i]; 176 if (dev->tstc != NULL) { 177 ret = dev->tstc(dev); 178 if (ret > 0) { 179 tstcdev = dev; 180 disable_ctrlc(0); 181 return ret; 182 } 183 } 184 } 185 disable_ctrlc(0); 186 187 return 0; 188 } 189 190 static void console_putc(int file, const char c) 191 { 192 int i; 193 struct stdio_dev *dev; 194 195 for (i = 0; i < cd_count[file]; i++) { 196 dev = console_devices[file][i]; 197 if (dev->putc != NULL) 198 dev->putc(dev, c); 199 } 200 } 201 202 #ifdef CONFIG_PRE_CONSOLE_BUFFER 203 static void console_putc_noserial(int file, const char c) 204 { 205 int i; 206 struct stdio_dev *dev; 207 208 for (i = 0; i < cd_count[file]; i++) { 209 dev = console_devices[file][i]; 210 if (dev->putc != NULL && strcmp(dev->name, "serial") != 0) 211 dev->putc(dev, c); 212 } 213 } 214 #endif 215 216 static void console_puts(int file, const char *s) 217 { 218 int i; 219 struct stdio_dev *dev; 220 221 for (i = 0; i < cd_count[file]; i++) { 222 dev = console_devices[file][i]; 223 if (dev->puts != NULL) 224 dev->puts(dev, s); 225 } 226 } 227 228 static inline void console_printdevs(int file) 229 { 230 iomux_printdevs(file); 231 } 232 233 static inline void console_doenv(int file, struct stdio_dev *dev) 234 { 235 iomux_doenv(file, dev->name); 236 } 237 #else 238 static inline int console_getc(int file) 239 { 240 return stdio_devices[file]->getc(stdio_devices[file]); 241 } 242 243 static inline int console_tstc(int file) 244 { 245 return stdio_devices[file]->tstc(stdio_devices[file]); 246 } 247 248 static inline void console_putc(int file, const char c) 249 { 250 stdio_devices[file]->putc(stdio_devices[file], c); 251 } 252 253 #ifdef CONFIG_PRE_CONSOLE_BUFFER 254 static inline void console_putc_noserial(int file, const char c) 255 { 256 if (strcmp(stdio_devices[file]->name, "serial") != 0) 257 stdio_devices[file]->putc(stdio_devices[file], c); 258 } 259 #endif 260 261 static inline void console_puts(int file, const char *s) 262 { 263 stdio_devices[file]->puts(stdio_devices[file], s); 264 } 265 266 static inline void console_printdevs(int file) 267 { 268 printf("%s\n", stdio_devices[file]->name); 269 } 270 271 static inline void console_doenv(int file, struct stdio_dev *dev) 272 { 273 console_setfile(file, dev); 274 } 275 #endif /* defined(CONFIG_CONSOLE_MUX) */ 276 277 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ 278 279 int serial_printf(const char *fmt, ...) 280 { 281 va_list args; 282 uint i; 283 char printbuffer[CONFIG_SYS_PBSIZE]; 284 285 va_start(args, fmt); 286 287 /* For this to work, printbuffer must be larger than 288 * anything we ever want to print. 289 */ 290 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 291 va_end(args); 292 293 serial_puts(printbuffer); 294 return i; 295 } 296 297 int fgetc(int file) 298 { 299 if (file < MAX_FILES) { 300 #if defined(CONFIG_CONSOLE_MUX) 301 /* 302 * Effectively poll for input wherever it may be available. 303 */ 304 for (;;) { 305 /* 306 * Upper layer may have already called tstc() so 307 * check for that first. 308 */ 309 if (tstcdev != NULL) 310 return console_getc(file); 311 console_tstc(file); 312 #ifdef CONFIG_WATCHDOG 313 /* 314 * If the watchdog must be rate-limited then it should 315 * already be handled in board-specific code. 316 */ 317 udelay(1); 318 #endif 319 } 320 #else 321 return console_getc(file); 322 #endif 323 } 324 325 return -1; 326 } 327 328 int ftstc(int file) 329 { 330 if (file < MAX_FILES) 331 return console_tstc(file); 332 333 return -1; 334 } 335 336 void fputc(int file, const char c) 337 { 338 if (file < MAX_FILES) 339 console_putc(file, c); 340 } 341 342 void fputs(int file, const char *s) 343 { 344 if (file < MAX_FILES) 345 console_puts(file, s); 346 } 347 348 int fprintf(int file, const char *fmt, ...) 349 { 350 va_list args; 351 uint i; 352 char printbuffer[CONFIG_SYS_PBSIZE]; 353 354 va_start(args, fmt); 355 356 /* For this to work, printbuffer must be larger than 357 * anything we ever want to print. 358 */ 359 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 360 va_end(args); 361 362 /* Send to desired file */ 363 fputs(file, printbuffer); 364 return i; 365 } 366 367 /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ 368 369 int getc(void) 370 { 371 #ifdef CONFIG_DISABLE_CONSOLE 372 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 373 return 0; 374 #endif 375 376 if (!gd->have_console) 377 return 0; 378 379 if (gd->flags & GD_FLG_DEVINIT) { 380 /* Get from the standard input */ 381 return fgetc(stdin); 382 } 383 384 /* Send directly to the handler */ 385 return serial_getc(); 386 } 387 388 int tstc(void) 389 { 390 #ifdef CONFIG_DISABLE_CONSOLE 391 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 392 return 0; 393 #endif 394 395 if (!gd->have_console) 396 return 0; 397 398 if (gd->flags & GD_FLG_DEVINIT) { 399 /* Test the standard input */ 400 return ftstc(stdin); 401 } 402 403 /* Send directly to the handler */ 404 return serial_tstc(); 405 } 406 407 #define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0 408 #define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1 409 410 #ifdef CONFIG_PRE_CONSOLE_BUFFER 411 #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ) 412 413 static void pre_console_putc(const char c) 414 { 415 char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; 416 417 buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c; 418 } 419 420 static void pre_console_puts(const char *s) 421 { 422 while (*s) 423 pre_console_putc(*s++); 424 } 425 426 static void print_pre_console_buffer(int flushpoint) 427 { 428 unsigned long i = 0; 429 char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; 430 431 if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ) 432 i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ; 433 434 while (i < gd->precon_buf_idx) 435 switch (flushpoint) { 436 case PRE_CONSOLE_FLUSHPOINT1_SERIAL: 437 putc(buffer[CIRC_BUF_IDX(i++)]); 438 break; 439 case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL: 440 console_putc_noserial(stdout, 441 buffer[CIRC_BUF_IDX(i++)]); 442 break; 443 } 444 } 445 #else 446 static inline void pre_console_putc(const char c) {} 447 static inline void pre_console_puts(const char *s) {} 448 static inline void print_pre_console_buffer(int flushpoint) {} 449 #endif 450 451 void putc(const char c) 452 { 453 #ifdef CONFIG_SANDBOX 454 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { 455 os_putc(c); 456 return; 457 } 458 #endif 459 #ifdef CONFIG_SILENT_CONSOLE 460 if (gd->flags & GD_FLG_SILENT) 461 return; 462 #endif 463 464 #ifdef CONFIG_DISABLE_CONSOLE 465 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 466 return; 467 #endif 468 469 if (!gd->have_console) 470 return pre_console_putc(c); 471 472 if (gd->flags & GD_FLG_DEVINIT) { 473 /* Send to the standard output */ 474 fputc(stdout, c); 475 } else { 476 /* Send directly to the handler */ 477 pre_console_putc(c); 478 serial_putc(c); 479 } 480 } 481 482 void puts(const char *s) 483 { 484 #ifdef CONFIG_SANDBOX 485 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { 486 os_puts(s); 487 return; 488 } 489 #endif 490 491 #ifdef CONFIG_SILENT_CONSOLE 492 if (gd->flags & GD_FLG_SILENT) 493 return; 494 #endif 495 496 #ifdef CONFIG_DISABLE_CONSOLE 497 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 498 return; 499 #endif 500 501 if (!gd->have_console) 502 return pre_console_puts(s); 503 504 if (gd->flags & GD_FLG_DEVINIT) { 505 /* Send to the standard output */ 506 fputs(stdout, s); 507 } else { 508 /* Send directly to the handler */ 509 pre_console_puts(s); 510 serial_puts(s); 511 } 512 } 513 514 int printf(const char *fmt, ...) 515 { 516 va_list args; 517 uint i; 518 char printbuffer[CONFIG_SYS_PBSIZE]; 519 520 #if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER) 521 if (!gd->have_console) 522 return 0; 523 #endif 524 525 va_start(args, fmt); 526 527 /* For this to work, printbuffer must be larger than 528 * anything we ever want to print. 529 */ 530 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 531 va_end(args); 532 533 /* Print the string */ 534 puts(printbuffer); 535 return i; 536 } 537 538 int vprintf(const char *fmt, va_list args) 539 { 540 uint i; 541 char printbuffer[CONFIG_SYS_PBSIZE]; 542 543 #if defined(CONFIG_PRE_CONSOLE_BUFFER) && !defined(CONFIG_SANDBOX) 544 if (!gd->have_console) 545 return 0; 546 #endif 547 548 /* For this to work, printbuffer must be larger than 549 * anything we ever want to print. 550 */ 551 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 552 553 /* Print the string */ 554 puts(printbuffer); 555 return i; 556 } 557 558 /* test if ctrl-c was pressed */ 559 static int ctrlc_disabled = 0; /* see disable_ctrl() */ 560 static int ctrlc_was_pressed = 0; 561 int ctrlc(void) 562 { 563 #ifndef CONFIG_SANDBOX 564 if (!ctrlc_disabled && gd->have_console) { 565 if (tstc()) { 566 switch (getc()) { 567 case 0x03: /* ^C - Control C */ 568 ctrlc_was_pressed = 1; 569 return 1; 570 default: 571 break; 572 } 573 } 574 } 575 #endif 576 577 return 0; 578 } 579 /* Reads user's confirmation. 580 Returns 1 if user's input is "y", "Y", "yes" or "YES" 581 */ 582 int confirm_yesno(void) 583 { 584 int i; 585 char str_input[5]; 586 587 /* Flush input */ 588 while (tstc()) 589 getc(); 590 i = 0; 591 while (i < sizeof(str_input)) { 592 str_input[i] = getc(); 593 putc(str_input[i]); 594 if (str_input[i] == '\r') 595 break; 596 i++; 597 } 598 putc('\n'); 599 if (strncmp(str_input, "y\r", 2) == 0 || 600 strncmp(str_input, "Y\r", 2) == 0 || 601 strncmp(str_input, "yes\r", 4) == 0 || 602 strncmp(str_input, "YES\r", 4) == 0) 603 return 1; 604 return 0; 605 } 606 /* pass 1 to disable ctrlc() checking, 0 to enable. 607 * returns previous state 608 */ 609 int disable_ctrlc(int disable) 610 { 611 int prev = ctrlc_disabled; /* save previous state */ 612 613 ctrlc_disabled = disable; 614 return prev; 615 } 616 617 int had_ctrlc (void) 618 { 619 return ctrlc_was_pressed; 620 } 621 622 void clear_ctrlc(void) 623 { 624 ctrlc_was_pressed = 0; 625 } 626 627 #ifdef CONFIG_MODEM_SUPPORT_DEBUG 628 char screen[1024]; 629 char *cursor = screen; 630 int once = 0; 631 inline void dbg(const char *fmt, ...) 632 { 633 va_list args; 634 uint i; 635 char printbuffer[CONFIG_SYS_PBSIZE]; 636 637 if (!once) { 638 memset(screen, 0, sizeof(screen)); 639 once++; 640 } 641 642 va_start(args, fmt); 643 644 /* For this to work, printbuffer must be larger than 645 * anything we ever want to print. 646 */ 647 i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); 648 va_end(args); 649 650 if ((screen + sizeof(screen) - 1 - cursor) 651 < strlen(printbuffer) + 1) { 652 memset(screen, 0, sizeof(screen)); 653 cursor = screen; 654 } 655 sprintf(cursor, printbuffer); 656 cursor += strlen(printbuffer); 657 658 } 659 #else 660 static inline void dbg(const char *fmt, ...) 661 { 662 } 663 #endif 664 665 /** U-Boot INIT FUNCTIONS *************************************************/ 666 667 struct stdio_dev *search_device(int flags, const char *name) 668 { 669 struct stdio_dev *dev; 670 671 dev = stdio_get_by_name(name); 672 673 if (dev && (dev->flags & flags)) 674 return dev; 675 676 return NULL; 677 } 678 679 int console_assign(int file, const char *devname) 680 { 681 int flag; 682 struct stdio_dev *dev; 683 684 /* Check for valid file */ 685 switch (file) { 686 case stdin: 687 flag = DEV_FLAGS_INPUT; 688 break; 689 case stdout: 690 case stderr: 691 flag = DEV_FLAGS_OUTPUT; 692 break; 693 default: 694 return -1; 695 } 696 697 /* Check for valid device name */ 698 699 dev = search_device(flag, devname); 700 701 if (dev) 702 return console_setfile(file, dev); 703 704 return -1; 705 } 706 707 /* Called before relocation - use serial functions */ 708 int console_init_f(void) 709 { 710 gd->have_console = 1; 711 712 #ifdef CONFIG_SILENT_CONSOLE 713 if (getenv("silent") != NULL) 714 gd->flags |= GD_FLG_SILENT; 715 #endif 716 717 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL); 718 719 return 0; 720 } 721 722 void stdio_print_current_devices(void) 723 { 724 /* Print information */ 725 puts("In: "); 726 if (stdio_devices[stdin] == NULL) { 727 puts("No input devices available!\n"); 728 } else { 729 printf ("%s\n", stdio_devices[stdin]->name); 730 } 731 732 puts("Out: "); 733 if (stdio_devices[stdout] == NULL) { 734 puts("No output devices available!\n"); 735 } else { 736 printf ("%s\n", stdio_devices[stdout]->name); 737 } 738 739 puts("Err: "); 740 if (stdio_devices[stderr] == NULL) { 741 puts("No error devices available!\n"); 742 } else { 743 printf ("%s\n", stdio_devices[stderr]->name); 744 } 745 } 746 747 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV 748 /* Called after the relocation - use desired console functions */ 749 int console_init_r(void) 750 { 751 char *stdinname, *stdoutname, *stderrname; 752 struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL; 753 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE 754 int i; 755 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ 756 #ifdef CONFIG_CONSOLE_MUX 757 int iomux_err = 0; 758 #endif 759 760 /* set default handlers at first */ 761 gd->jt->getc = serial_getc; 762 gd->jt->tstc = serial_tstc; 763 gd->jt->putc = serial_putc; 764 gd->jt->puts = serial_puts; 765 gd->jt->printf = serial_printf; 766 767 /* stdin stdout and stderr are in environment */ 768 /* scan for it */ 769 stdinname = getenv("stdin"); 770 stdoutname = getenv("stdout"); 771 stderrname = getenv("stderr"); 772 773 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */ 774 inputdev = search_device(DEV_FLAGS_INPUT, stdinname); 775 outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname); 776 errdev = search_device(DEV_FLAGS_OUTPUT, stderrname); 777 #ifdef CONFIG_CONSOLE_MUX 778 iomux_err = iomux_doenv(stdin, stdinname); 779 iomux_err += iomux_doenv(stdout, stdoutname); 780 iomux_err += iomux_doenv(stderr, stderrname); 781 if (!iomux_err) 782 /* Successful, so skip all the code below. */ 783 goto done; 784 #endif 785 } 786 /* if the devices are overwritten or not found, use default device */ 787 if (inputdev == NULL) { 788 inputdev = search_device(DEV_FLAGS_INPUT, "serial"); 789 } 790 if (outputdev == NULL) { 791 outputdev = search_device(DEV_FLAGS_OUTPUT, "serial"); 792 } 793 if (errdev == NULL) { 794 errdev = search_device(DEV_FLAGS_OUTPUT, "serial"); 795 } 796 /* Initializes output console first */ 797 if (outputdev != NULL) { 798 /* need to set a console if not done above. */ 799 console_doenv(stdout, outputdev); 800 } 801 if (errdev != NULL) { 802 /* need to set a console if not done above. */ 803 console_doenv(stderr, errdev); 804 } 805 if (inputdev != NULL) { 806 /* need to set a console if not done above. */ 807 console_doenv(stdin, inputdev); 808 } 809 810 #ifdef CONFIG_CONSOLE_MUX 811 done: 812 #endif 813 814 #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET 815 stdio_print_current_devices(); 816 #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ 817 818 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE 819 /* set the environment variables (will overwrite previous env settings) */ 820 for (i = 0; i < 3; i++) { 821 setenv(stdio_names[i], stdio_devices[i]->name); 822 } 823 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ 824 825 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 826 827 #if 0 828 /* If nothing usable installed, use only the initial console */ 829 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 830 return 0; 831 #endif 832 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL); 833 return 0; 834 } 835 836 #else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ 837 838 /* Called after the relocation - use desired console functions */ 839 int console_init_r(void) 840 { 841 struct stdio_dev *inputdev = NULL, *outputdev = NULL; 842 int i; 843 struct list_head *list = stdio_get_list(); 844 struct list_head *pos; 845 struct stdio_dev *dev; 846 847 #ifdef CONFIG_SPLASH_SCREEN 848 /* 849 * suppress all output if splash screen is enabled and we have 850 * a bmp to display. We redirect the output from frame buffer 851 * console to serial console in this case or suppress it if 852 * "silent" mode was requested. 853 */ 854 if (getenv("splashimage") != NULL) { 855 if (!(gd->flags & GD_FLG_SILENT)) 856 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 857 } 858 #endif 859 860 /* Scan devices looking for input and output devices */ 861 list_for_each(pos, list) { 862 dev = list_entry(pos, struct stdio_dev, list); 863 864 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { 865 inputdev = dev; 866 } 867 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { 868 outputdev = dev; 869 } 870 if(inputdev && outputdev) 871 break; 872 } 873 874 /* Initializes output console first */ 875 if (outputdev != NULL) { 876 console_setfile(stdout, outputdev); 877 console_setfile(stderr, outputdev); 878 #ifdef CONFIG_CONSOLE_MUX 879 console_devices[stdout][0] = outputdev; 880 console_devices[stderr][0] = outputdev; 881 #endif 882 } 883 884 /* Initializes input console */ 885 if (inputdev != NULL) { 886 console_setfile(stdin, inputdev); 887 #ifdef CONFIG_CONSOLE_MUX 888 console_devices[stdin][0] = inputdev; 889 #endif 890 } 891 892 #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET 893 stdio_print_current_devices(); 894 #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ 895 896 /* Setting environment variables */ 897 for (i = 0; i < 3; i++) { 898 setenv(stdio_names[i], stdio_devices[i]->name); 899 } 900 901 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 902 903 #if 0 904 /* If nothing usable installed, use only the initial console */ 905 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 906 return 0; 907 #endif 908 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL); 909 return 0; 910 } 911 912 #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ 913