spl: Always define preloader_console_init
[oweals/u-boot.git] / common / console.c
index f38f71f819bdd1c272fa428eac3d7c9d629b88c4..e398530a138c4c7f8d87ab926c696afa95e5b1f8 100644 (file)
@@ -1,21 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2000
  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <console.h>
 #include <debug_uart.h>
+#include <dm.h>
+#include <env.h>
 #include <stdarg.h>
 #include <iomux.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <os.h>
 #include <serial.h>
 #include <stdio_dev.h>
 #include <exports.h>
-#include <environment.h>
+#include <env_internal.h>
 #include <watchdog.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -41,14 +43,14 @@ static int on_console(const char *name, const char *value, enum env_op op,
        case env_op_create:
        case env_op_overwrite:
 
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
                if (iomux_doenv(console, value))
                        return 1;
 #else
                /* Try assigning specified device */
                if (console_assign(console, value) < 0)
                        return 1;
-#endif /* CONFIG_CONSOLE_MUX */
+#endif
                return 0;
 
        case env_op_delete:
@@ -66,11 +68,11 @@ U_BOOT_ENV_CALLBACK(console, on_console);
 static int on_silent(const char *name, const char *value, enum env_op op,
        int flags)
 {
-#ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_SET
+#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET)
        if (flags & H_INTERACTIVE)
                return 0;
 #endif
-#ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC
+#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC)
        if ((flags & H_INTERACTIVE) == 0)
                return 0;
 #endif
@@ -85,7 +87,7 @@ static int on_silent(const char *name, const char *value, enum env_op op,
 U_BOOT_ENV_CALLBACK(silent, on_silent);
 #endif
 
-#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
 /*
  * if overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -98,7 +100,7 @@ extern int overwrite_console(void);
 #define OVERWRITE_CONSOLE 0
 #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
 
-#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
+#endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
 
 static int console_setfile(int file, struct stdio_dev * dev)
 {
@@ -145,7 +147,30 @@ static int console_setfile(int file, struct stdio_dev * dev)
        return error;
 }
 
-#if defined(CONFIG_CONSOLE_MUX)
+/**
+ * console_dev_is_serial() - Check if a stdio device is a serial device
+ *
+ * @sdev: Device to check
+ * @return true if this device is in the serial uclass (or for pre-driver-model,
+ * whether it is called "serial".
+ */
+static bool console_dev_is_serial(struct stdio_dev *sdev)
+{
+       bool is_serial;
+
+#ifdef CONFIG_DM_SERIAL
+       if (sdev->flags & DEV_FLAGS_DM) {
+               struct udevice *dev = sdev->priv;
+
+               is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL;
+       } else
+#endif
+       is_serial = !strcmp(sdev->name, "serial");
+
+       return is_serial;
+}
+
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 /** Console I/O multiplexing *******************************************/
 
 static struct stdio_dev *tstcdev;
@@ -172,20 +197,21 @@ static int console_tstc(int file)
 {
        int i, ret;
        struct stdio_dev *dev;
+       int prev;
 
-       disable_ctrlc(1);
+       prev = disable_ctrlc(1);
        for (i = 0; i < cd_count[file]; i++) {
                dev = console_devices[file][i];
                if (dev->tstc != NULL) {
                        ret = dev->tstc(dev);
                        if (ret > 0) {
                                tstcdev = dev;
-                               disable_ctrlc(0);
+                               disable_ctrlc(prev);
                                return ret;
                        }
                }
        }
-       disable_ctrlc(0);
+       disable_ctrlc(prev);
 
        return 0;
 }
@@ -202,7 +228,6 @@ static void console_putc(int file, const char c)
        }
 }
 
-#ifdef CONFIG_PRE_CONSOLE_BUFFER
 static void console_puts_noserial(int file, const char *s)
 {
        int i;
@@ -210,11 +235,10 @@ static void console_puts_noserial(int file, const char *s)
 
        for (i = 0; i < cd_count[file]; i++) {
                dev = console_devices[file][i];
-               if (dev->puts != NULL && strcmp(dev->name, "serial") != 0)
+               if (dev->puts != NULL && !console_dev_is_serial(dev))
                        dev->puts(dev, s);
        }
 }
-#endif
 
 static void console_puts(int file, const char *s)
 {
@@ -228,10 +252,12 @@ static void console_puts(int file, const char *s)
        }
 }
 
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
 static inline void console_doenv(int file, struct stdio_dev *dev)
 {
        iomux_doenv(file, dev->name);
 }
+#endif
 #else
 static inline int console_getc(int file)
 {
@@ -248,24 +274,24 @@ static inline void console_putc(int file, const char c)
        stdio_devices[file]->putc(stdio_devices[file], c);
 }
 
-#ifdef CONFIG_PRE_CONSOLE_BUFFER
 static inline void console_puts_noserial(int file, const char *s)
 {
-       if (strcmp(stdio_devices[file]->name, "serial") != 0)
+       if (!console_dev_is_serial(stdio_devices[file]))
                stdio_devices[file]->puts(stdio_devices[file], s);
 }
-#endif
 
 static inline void console_puts(int file, const char *s)
 {
        stdio_devices[file]->puts(stdio_devices[file], s);
 }
 
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
 static inline void console_doenv(int file, struct stdio_dev *dev)
 {
        console_setfile(file, dev);
 }
-#endif /* defined(CONFIG_CONSOLE_MUX) */
+#endif
+#endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
 
 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
 
@@ -290,12 +316,12 @@ int serial_printf(const char *fmt, ...)
 int fgetc(int file)
 {
        if (file < MAX_FILES) {
-#if defined(CONFIG_CONSOLE_MUX)
                /*
                 * Effectively poll for input wherever it may be available.
                 */
                for (;;) {
                        WATCHDOG_RESET();
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
                        /*
                         * Upper layer may have already called tstc() so
                         * check for that first.
@@ -303,6 +329,10 @@ int fgetc(int file)
                        if (tstcdev != NULL)
                                return console_getc(file);
                        console_tstc(file);
+#else
+                       if (console_tstc(file))
+                               return console_getc(file);
+#endif
 #ifdef CONFIG_WATCHDOG
                        /*
                         * If the watchdog must be rate-limited then it should
@@ -311,9 +341,6 @@ int fgetc(int file)
                         udelay(1);
 #endif
                }
-#else
-               return console_getc(file);
-#endif
        }
 
        return -1;
@@ -374,7 +401,7 @@ int getc(void)
        if (gd->console_in.start) {
                int ch;
 
-               ch = membuff_getbyte(&gd->console_in);
+               ch = membuff_getbyte((struct membuff *)&gd->console_in);
                if (ch != -1)
                        return 1;
        }
@@ -399,7 +426,7 @@ int tstc(void)
                return 0;
 #ifdef CONFIG_CONSOLE_RECORD
        if (gd->console_in.start) {
-               if (membuff_peekbyte(&gd->console_in) != -1)
+               if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1)
                        return 1;
        }
 #endif
@@ -415,14 +442,18 @@ int tstc(void)
 #define PRE_CONSOLE_FLUSHPOINT1_SERIAL                 0
 #define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL  1
 
-#ifdef CONFIG_PRE_CONSOLE_BUFFER
+#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
 #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
 
 static void pre_console_putc(const char c)
 {
-       char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
+       char *buffer;
+
+       buffer = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
 
        buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
+
+       unmap_sysmem(buffer);
 }
 
 static void pre_console_puts(const char *s)
@@ -434,14 +465,21 @@ static void pre_console_puts(const char *s)
 static void print_pre_console_buffer(int flushpoint)
 {
        unsigned long in = 0, out = 0;
-       char *buf_in = (char *)CONFIG_PRE_CON_BUF_ADDR;
        char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
+       char *buf_in;
 
+#ifdef CONFIG_SILENT_CONSOLE
+       if (gd->flags & GD_FLG_SILENT)
+               return;
+#endif
+
+       buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
        if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
                in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
 
        while (in < gd->precon_buf_idx)
                buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)];
+       unmap_sysmem(buf_in);
 
        buf_out[out] = 0;
 
@@ -476,13 +514,18 @@ void putc(const char c)
                return;
        }
 #endif
+       if (!gd)
+               return;
 #ifdef CONFIG_CONSOLE_RECORD
-       if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start)
-               membuff_putbyte(&gd->console_out, c);
+       if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
+               membuff_putbyte((struct membuff *)&gd->console_out, c);
 #endif
 #ifdef CONFIG_SILENT_CONSOLE
-       if (gd->flags & GD_FLG_SILENT)
+       if (gd->flags & GD_FLG_SILENT) {
+               if (!(gd->flags & GD_FLG_DEVINIT))
+                       pre_console_putc(c);
                return;
+       }
 #endif
 
 #ifdef CONFIG_DISABLE_CONSOLE
@@ -506,6 +549,7 @@ void putc(const char c)
 void puts(const char *s)
 {
 #ifdef CONFIG_SANDBOX
+       /* sandbox can send characters to stdout before it has a console */
        if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
                os_puts(s);
                return;
@@ -521,13 +565,18 @@ void puts(const char *s)
                return;
        }
 #endif
+       if (!gd)
+               return;
 #ifdef CONFIG_CONSOLE_RECORD
-       if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start)
-               membuff_put(&gd->console_out, s, strlen(s));
+       if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
+               membuff_put((struct membuff *)&gd->console_out, s, strlen(s));
 #endif
 #ifdef CONFIG_SILENT_CONSOLE
-       if (gd->flags & GD_FLG_SILENT)
+       if (gd->flags & GD_FLG_SILENT) {
+               if (!(gd->flags & GD_FLG_DEVINIT))
+                       pre_console_puts(s);
                return;
+       }
 #endif
 
 #ifdef CONFIG_DISABLE_CONSOLE
@@ -553,18 +602,20 @@ int console_record_init(void)
 {
        int ret;
 
-       ret = membuff_new(&gd->console_out, CONFIG_CONSOLE_RECORD_OUT_SIZE);
+       ret = membuff_new((struct membuff *)&gd->console_out,
+                         CONFIG_CONSOLE_RECORD_OUT_SIZE);
        if (ret)
                return ret;
-       ret = membuff_new(&gd->console_in, CONFIG_CONSOLE_RECORD_IN_SIZE);
+       ret = membuff_new((struct membuff *)&gd->console_in,
+                         CONFIG_CONSOLE_RECORD_IN_SIZE);
 
        return ret;
 }
 
 void console_record_reset(void)
 {
-       membuff_purge(&gd->console_out);
-       membuff_purge(&gd->console_in);
+       membuff_purge((struct membuff *)&gd->console_out);
+       membuff_purge((struct membuff *)&gd->console_in);
 }
 
 void console_record_reset_enable(void)
@@ -572,6 +623,18 @@ void console_record_reset_enable(void)
        console_record_reset();
        gd->flags |= GD_FLG_RECORD;
 }
+
+int console_record_readline(char *str, int maxlen)
+{
+       return membuff_readline((struct membuff *)&gd->console_out, str,
+                               maxlen, ' ');
+}
+
+int console_record_avail(void)
+{
+       return membuff_avail((struct membuff *)&gd->console_out);
+}
+
 #endif
 
 /* test if ctrl-c was pressed */
@@ -579,7 +642,6 @@ static int ctrlc_disabled = 0;      /* see disable_ctrl() */
 static int ctrlc_was_pressed = 0;
 int ctrlc(void)
 {
-#ifndef CONFIG_SANDBOX
        if (!ctrlc_disabled && gd->have_console) {
                if (tstc()) {
                        switch (getc()) {
@@ -591,7 +653,6 @@ int ctrlc(void)
                        }
                }
        }
-#endif
 
        return 0;
 }
@@ -689,14 +750,35 @@ int console_assign(int file, const char *devname)
        return -1;
 }
 
-static void console_update_silent(void)
+/* return true if the 'silent' flag is removed */
+static bool console_update_silent(void)
 {
 #ifdef CONFIG_SILENT_CONSOLE
-       if (getenv("silent") != NULL)
+       if (env_get("silent")) {
                gd->flags |= GD_FLG_SILENT;
-       else
+       } else {
+               unsigned long flags = gd->flags;
+
                gd->flags &= ~GD_FLG_SILENT;
+
+               return !!(flags & GD_FLG_SILENT);
+       }
 #endif
+
+       return false;
+}
+
+int console_announce_r(void)
+{
+#if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
+       char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
+
+       display_options_get_banner(false, buf, sizeof(buf));
+
+       console_puts_noserial(stdout, buf);
+#endif
+
+       return 0;
 }
 
 /* Called before relocation - use serial functions */
@@ -736,7 +818,7 @@ void stdio_print_current_devices(void)
        }
 }
 
-#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
 /* Called after the relocation - use desired console functions */
 int console_init_r(void)
 {
@@ -745,9 +827,16 @@ int console_init_r(void)
 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
        int i;
 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
        int iomux_err = 0;
 #endif
+       int flushpoint;
+
+       /* update silent for env loaded from flash (initr_env) */
+       if (console_update_silent())
+               flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
+       else
+               flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
 
        /* set default handlers at first */
        gd->jt->getc  = serial_getc;
@@ -758,15 +847,15 @@ int console_init_r(void)
 
        /* stdin stdout and stderr are in environment */
        /* scan for it */
-       stdinname  = getenv("stdin");
-       stdoutname = getenv("stdout");
-       stderrname = getenv("stderr");
+       stdinname  = env_get("stdin");
+       stdoutname = env_get("stdout");
+       stderrname = env_get("stderr");
 
        if (OVERWRITE_CONSOLE == 0) {   /* if not overwritten by config switch */
                inputdev  = search_device(DEV_FLAGS_INPUT,  stdinname);
                outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
                errdev    = search_device(DEV_FLAGS_OUTPUT, stderrname);
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
                iomux_err = iomux_doenv(stdin, stdinname);
                iomux_err += iomux_doenv(stdout, stdoutname);
                iomux_err += iomux_doenv(stderr, stderrname);
@@ -799,7 +888,7 @@ int console_init_r(void)
                console_doenv(stdin, inputdev);
        }
 
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 done:
 #endif
 
@@ -813,8 +902,8 @@ done:
 
 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
        /* set the environment variables (will overwrite previous env settings) */
-       for (i = 0; i < 3; i++) {
-               setenv(stdio_names[i], stdio_devices[i]->name);
+       for (i = 0; i < MAX_FILES; i++) {
+               env_set(stdio_names[i], stdio_devices[i]->name);
        }
 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
 
@@ -825,11 +914,11 @@ done:
        if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
                return 0;
 #endif
-       print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
+       print_pre_console_buffer(flushpoint);
        return 0;
 }
 
-#else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
+#else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
 
 /* Called after the relocation - use desired console functions */
 int console_init_r(void)
@@ -839,8 +928,13 @@ int console_init_r(void)
        struct list_head *list = stdio_get_list();
        struct list_head *pos;
        struct stdio_dev *dev;
+       int flushpoint;
 
-       console_update_silent();
+       /* update silent for env loaded from flash (initr_env) */
+       if (console_update_silent())
+               flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
+       else
+               flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
 
 #ifdef CONFIG_SPLASH_SCREEN
        /*
@@ -849,7 +943,7 @@ int console_init_r(void)
         * console to serial console in this case or suppress it if
         * "silent" mode was requested.
         */
-       if (getenv("splashimage") != NULL) {
+       if (env_get("splashimage") != NULL) {
                if (!(gd->flags & GD_FLG_SILENT))
                        outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
        }
@@ -873,7 +967,7 @@ int console_init_r(void)
        if (outputdev != NULL) {
                console_setfile(stdout, outputdev);
                console_setfile(stderr, outputdev);
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
                console_devices[stdout][0] = outputdev;
                console_devices[stderr][0] = outputdev;
 #endif
@@ -882,7 +976,7 @@ int console_init_r(void)
        /* Initializes input console */
        if (inputdev != NULL) {
                console_setfile(stdin, inputdev);
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
                console_devices[stdin][0] = inputdev;
 #endif
        }
@@ -892,8 +986,8 @@ int console_init_r(void)
 #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
 
        /* Setting environment variables */
-       for (i = 0; i < 3; i++) {
-               setenv(stdio_names[i], stdio_devices[i]->name);
+       for (i = 0; i < MAX_FILES; i++) {
+               env_set(stdio_names[i], stdio_devices[i]->name);
        }
 
        gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
@@ -903,8 +997,8 @@ int console_init_r(void)
        if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
                return 0;
 #endif
-       print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
+       print_pre_console_buffer(flushpoint);
        return 0;
 }
 
-#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
+#endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */