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