Merge tag 'doc-2021-04-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
authorTom Rini <trini@konsulko.com>
Mon, 18 Jan 2021 13:04:05 +0000 (08:04 -0500)
committerTom Rini <trini@konsulko.com>
Mon, 18 Jan 2021 13:04:05 +0000 (08:04 -0500)
Pull request for documentation tag doc-2021-04-rc1

* document man-page base command
* move README.fdt-overlays to HTML documentation
* add synopsis for pstore command

85 files changed:
api/api.c
api/api_private.h
arch/arm/cpu/armv8/Makefile
arch/arm/include/asm/system.h
arch/arm/lib/cache.c
arch/m68k/lib/traps.c
arch/mips/lib/traps.c
arch/powerpc/cpu/mpc85xx/cpu_init.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/traps.c [new file with mode: 0644]
arch/sandbox/cpu/start.c
cmd/Kconfig
cmd/Makefile
cmd/bootmenu.c
cmd/disk.c
cmd/gpt.c
cmd/mbr.c [new file with mode: 0644]
common/Kconfig
common/Kconfig.boot
common/Makefile
common/autoboot.c
common/board_f.c
common/board_r.c
common/cli_readline.c
common/command.c
common/console.c
common/exports.c
common/iomux.c
common/log.c
common/spl/Kconfig
common/spl/spl_fit.c
common/stdio.c
disk/part_dos.c
disk/part_dos.h
disk/part_efi.c
doc/README.gpt
doc/usage/index.rst
doc/usage/mbr.rst [new file with mode: 0644]
drivers/core/uclass.c
drivers/fastboot/fb_mmc.c
drivers/mtd/mtdcore.c
drivers/net/phy/miiphybb.c
drivers/pci/pci-uclass.c
drivers/pci/pci.c
drivers/pci_endpoint/pci_ep-uclass.c
drivers/power/regulator/Kconfig
drivers/ram/k3-j721e/lpddr4.c
drivers/ram/k3-j721e/lpddr4_private.h
drivers/serial/Kconfig
drivers/serial/serial-uclass.c
drivers/video/Kconfig
drivers/xen/hypervisor.c
dts/Makefile
include/api.h
include/asm-generic/global_data.h
include/console.h
include/dm/uclass.h
include/exports.h
include/init.h
include/iomux.h
include/log.h
include/miiphy.h
include/part.h
include/part_efi.h
include/post.h
include/test/ut.h
include/uuid.h
include/xen.h
lib/Kconfig
lib/aes.c
lib/string.c
lib/uuid.c
lib/zlib/deflate.c
lib/zlib/trees.c
post/post.c
test/Makefile
test/bloblist.c
test/cmd/mem.c
test/lib/Makefile
test/log/Makefile
test/log/log_test.c
test/log/pr_cont_test.c [new file with mode: 0644]
test/py/tests/test_log.py
test/str_ut.c
test/ut.c

index 493b77f..89003c1 100644 (file)
--- a/api/api.c
+++ b/api/api.c
@@ -642,7 +642,7 @@ int syscall(int call, int *retval, ...)
        return 1;
 }
 
-void api_init(void)
+int api_init(void)
 {
        struct api_signature *sig;
 
@@ -679,7 +679,7 @@ void api_init(void)
        sig = malloc(sizeof(struct api_signature));
        if (sig == NULL) {
                printf("API: could not allocate memory for the signature!\n");
-               return;
+               return -ENOMEM;
        }
 
        env_set_hex("api_address", (unsigned long)sig);
@@ -691,6 +691,8 @@ void api_init(void)
        sig->checksum = crc32(0, (unsigned char *)sig,
                              sizeof(struct api_signature));
        debugf("syscall entry: 0x%lX\n", (unsigned long)sig->syscall);
+
+       return 0;
 }
 
 void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size,
index 07fd50a..bb23821 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef _API_PRIVATE_H_
 #define _API_PRIVATE_H_
 
-void   api_init(void);
+int    api_init(void);
 void   platform_set_mr(struct sys_info *, unsigned long, unsigned long, int);
 int    platform_sys_info(struct sys_info *);
 
index f7b4a5e..d85ddde 100644 (file)
@@ -9,14 +9,16 @@ obj-y += cpu.o
 ifndef CONFIG_$(SPL_TPL_)TIMER
 obj-$(CONFIG_SYS_ARCH_TIMER) += generic_timer.o
 endif
+ifndef CONFIG_$(SPL_)SYS_DCACHE_OFF
 obj-y  += cache_v8.o
+obj-y  += cache.o
+endif
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o
 else
 obj-y  += exceptions.o
 obj-y  += exception_level.o
 endif
-obj-y  += cache.o
 obj-y  += tlb.o
 obj-y  += transition.o
 ifndef CONFIG_ARMV8_PSCI
index ce55294..5fe8369 100644 (file)
@@ -628,7 +628,18 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
                                     enum dcache_option option);
 
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
-void noncached_init(void);
+/**
+ * noncached_init() - Initialize non-cached memory region
+ *
+ * Initialize non-cached memory area. This memory region will be typically
+ * located right below the malloc() area and mapped uncached in the MMU.
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int noncached_init(void);
+
 phys_addr_t noncached_alloc(size_t size, size_t align);
 #endif /* CONFIG_SYS_NONCACHED_MEMORY */
 
index ee7d14b..bdde9cd 100644 (file)
@@ -86,7 +86,7 @@ void noncached_set_region(void)
 #endif
 }
 
-void noncached_init(void)
+int noncached_init(void)
 {
        phys_addr_t start, end;
        size_t size;
@@ -103,6 +103,8 @@ void noncached_init(void)
        noncached_next = start;
 
        noncached_set_region();
+
+       return 0;
 }
 
 phys_addr_t noncached_alloc(size_t size, size_t align)
index c49141f..0c2c1a9 100644 (file)
@@ -40,7 +40,7 @@ void exc_handler(struct pt_regs *fp) {
        for(;;);
 }
 
-void trap_init(ulong value) {
+static void trap_init(ulong value) {
        unsigned long *vec = (ulong *)value;
        int i;
 
@@ -59,3 +59,10 @@ void trap_init(ulong value) {
 
        setvbr(value);          /* set vector base register to new table */
 }
+
+int arch_initr_trap(void)
+{
+       trap_init(CONFIG_SYS_SDRAM_BASE);
+
+       return 0;
+}
index df8b63f..540ea48 100644 (file)
@@ -99,7 +99,7 @@ static void set_handler(unsigned long offset, void *addr, unsigned long size)
        flush_cache(ebase + offset, size);
 }
 
-void trap_init(ulong reloc_addr)
+static void trap_init(ulong reloc_addr)
 {
        unsigned long ebase = gd->irq_sp;
 
@@ -131,3 +131,10 @@ void trap_restore(void)
        clear_c0_status(ST0_BEV);
        execution_hazard_barrier();
 }
+
+int arch_initr_trap(void)
+{
+       trap_init(CONFIG_SYS_SDRAM_BASE);
+
+       return 0;
+}
index e0f0f7e..e920e01 100644 (file)
@@ -1028,7 +1028,7 @@ void arch_preboot_os(void)
        mtmsr(msr);
 }
 
-void cpu_secondary_init_r(void)
+int cpu_secondary_init_r(void)
 {
 #ifdef CONFIG_QE
 #ifdef CONFIG_U_QE
@@ -1040,6 +1040,8 @@ void cpu_secondary_init_r(void)
        qe_init(qe_base);
        qe_reset();
 #endif
+
+       return 0;
 }
 
 #ifdef CONFIG_BOARD_LATE_INIT
index f61809a..2782740 100644 (file)
@@ -40,6 +40,7 @@ obj-y += interrupts.o
 obj-$(CONFIG_CMD_KGDB) += kgdb.o
 obj-y  += stack.o
 obj-y  += time.o
+obj-y  += traps.o
 endif # not minimal
 
 ifdef CONFIG_SPL_BUILD
diff --git a/arch/powerpc/lib/traps.c b/arch/powerpc/lib/traps.c
new file mode 100644 (file)
index 0000000..288e377
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <init.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void trap_init(unsigned long reloc_addr);
+
+int arch_initr_trap(void)
+{
+       trap_init(gd->relocaddr);
+
+       return 0;
+}
index 8322ed7..2d18d9d 100644 (file)
@@ -9,6 +9,7 @@
 #include <efi_loader.h>
 #include <errno.h>
 #include <init.h>
+#include <log.h>
 #include <os.h>
 #include <cli.h>
 #include <sort.h>
@@ -486,6 +487,10 @@ int main(int argc, char *argv[])
         */
        gd->reloc_off = (ulong)gd->arch.text_base;
 
+       /* sandbox test: log functions called before log_init in board_init_f */
+       log_info("sandbox: starting...\n");
+       log_debug("debug: %s\n", __func__);
+
        /* Do pre- and post-relocation init */
        board_init_f(0);
 
index da86a94..1b53e5b 100644 (file)
@@ -122,6 +122,7 @@ config CMD_CONSOLE
 
 config CMD_CPU
        bool "cpu"
+       depends on CPU
        help
          Print information about available CPUs. This normally shows the
          number of CPUs, type (e.g. manufacturer, architecture, product or
@@ -1034,6 +1035,14 @@ config CMD_LSBLK
          Print list of available block device drivers, and for each, the list
          of known block devices.
 
+config CMD_MBR
+       bool "MBR (Master Boot Record) command"
+       select DOS_PARTITION
+       select HAVE_BLOCK_DEVICE
+       help
+         Enable the 'mbr' command to ready and write MBR (Master Boot Record)
+         style partition tables.
+
 config CMD_MISC
        bool "misc"
        depends on MISC
index 5b3400a..87aa949 100644 (file)
@@ -178,6 +178,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o
 
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
+obj-$(CONFIG_CMD_MBR) += mbr.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
 obj-$(CONFIG_CMD_AXI) += axi.o
 obj-$(CONFIG_CMD_PVBLOCK) += pvblock.o
index 1ba7b62..409ef9a 100644 (file)
@@ -45,6 +45,7 @@ enum bootmenu_key {
        KEY_UP,
        KEY_DOWN,
        KEY_SELECT,
+       KEY_QUIT,
 };
 
 static char *bootmenu_getoption(unsigned short int n)
@@ -109,6 +110,9 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
                        case '\r':
                                *key = KEY_SELECT;
                                break;
+                       case 0x3: /* ^C */
+                               *key = KEY_QUIT;
+                               break;
                        default:
                                *key = KEY_NONE;
                                break;
@@ -136,13 +140,25 @@ static void bootmenu_loop(struct bootmenu_data *menu,
 {
        int c;
 
-       while (!tstc()) {
-               WATCHDOG_RESET();
-               mdelay(10);
+       if (*esc == 1) {
+               if (tstc()) {
+                       c = getchar();
+               } else {
+                       WATCHDOG_RESET();
+                       mdelay(10);
+                       if (tstc())
+                               c = getchar();
+                       else
+                               c = '\e';
+               }
+       } else {
+               while (!tstc()) {
+                       WATCHDOG_RESET();
+                       mdelay(10);
+               }
+               c = getchar();
        }
 
-       c = getchar();
-
        switch (*esc) {
        case 0:
                /* First char of ANSI escape sequence '\e' */
@@ -157,7 +173,9 @@ static void bootmenu_loop(struct bootmenu_data *menu,
                        *esc = 2;
                        *key = KEY_NONE;
                } else {
-                       *esc = 0;
+               /* Alone ESC key was pressed */
+                       *key = KEY_QUIT;
+                       *esc = (c == '\e') ? 1 : 0;
                }
                break;
        case 2:
@@ -187,6 +205,10 @@ static void bootmenu_loop(struct bootmenu_data *menu,
        /* enter key was pressed */
        if (c == '\r')
                *key = KEY_SELECT;
+
+       /* ^C was pressed */
+       if (c == 0x3)
+               *key = KEY_QUIT;
 }
 
 static char *bootmenu_choice_entry(void *data)
@@ -222,6 +244,12 @@ static char *bootmenu_choice_entry(void *data)
                        for (i = 0; i < menu->active; ++i)
                                iter = iter->next;
                        return iter->key;
+               case KEY_QUIT:
+                       /* Quit by choosing the last entry - U-Boot console */
+                       iter = menu->first;
+                       while (iter->next)
+                               iter = iter->next;
+                       return iter->key;
                default:
                        break;
                }
@@ -389,7 +417,7 @@ static void menu_display_statusline(struct menu *m)
        printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
        puts(ANSI_CLEAR_LINE);
        printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
-       puts("  Press UP/DOWN to move, ENTER to select");
+       puts("  Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit");
        puts(ANSI_CLEAR_LINE_TO_END);
        printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
        puts(ANSI_CLEAR_LINE);
index 8060e75..0bc3808 100644 (file)
@@ -120,7 +120,6 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc,
                        return 1;
                }
                bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
-               fit_print_contents(fit_hdr);
        }
 #endif
 
index df75941..76a95ad 100644 (file)
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -18,6 +18,7 @@
 #include <command.h>
 #include <part.h>
 #include <part_efi.h>
+#include <part.h>
 #include <exports.h>
 #include <uuid.h>
 #include <linux/ctype.h>
@@ -621,6 +622,152 @@ static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part)
        return ret;
 }
 
+/**
+ * gpt_enumerate() - Enumerate partition names into environment variable.
+ *
+ * Enumerate partition names. Partition names are stored in gpt_partition_list
+ * environment variable. Each partition name is delimited by space.
+ *
+ * @desc: block device descriptor
+ *
+ * @Return: '0' on success and -ve error on failure
+ */
+static int gpt_enumerate(struct blk_desc *desc)
+{
+       struct part_driver *first_drv, *part_drv;
+       int str_len = 0, tmp_len;
+       char part_list[2048];
+       int n_drvs;
+       char *ptr;
+
+       part_list[0] = 0;
+       n_drvs = part_driver_get_count();
+       if (!n_drvs) {
+               printf("Failed to get partition driver count\n");
+               return -ENOENT;
+       }
+
+       first_drv = part_driver_get_first();
+       for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) {
+               struct disk_partition pinfo;
+               int ret;
+               int i;
+
+               for (i = 1; i < part_drv->max_entries; i++) {
+                       ret = part_drv->get_info(desc, i, &pinfo);
+                       if (ret) {
+                               /* no more entries in table */
+                               break;
+                       }
+
+                       ptr = &part_list[str_len];
+                       tmp_len = strlen((const char *)pinfo.name);
+                       str_len += tmp_len;
+                       /* +1 for space */
+                       str_len++;
+                       if (str_len > sizeof(part_list)) {
+                               printf("Error insufficient memory\n");
+                               return -ENOMEM;
+                       }
+                       strcpy(ptr, (const char *)pinfo.name);
+                       /* One byte for space(" ") delimiter */
+                       ptr[tmp_len] = ' ';
+               }
+       }
+       if (*part_list)
+               part_list[strlen(part_list) - 1] = 0;
+       debug("setenv gpt_partition_list %s\n", part_list);
+
+       return env_set("gpt_partition_list", part_list);
+}
+
+/**
+ * gpt_setenv_part_variables() - setup partition environmental variables
+ *
+ * Setup the gpt_partition_name, gpt_partition_entry, gpt_partition_addr
+ * and gpt_partition_size environment variables.
+ *
+ * @pinfo: pointer to disk partition
+ * @i: partition entry
+ *
+ * @Return: '0' on success and -ENOENT on failure
+ */
+static int gpt_setenv_part_variables(struct disk_partition *pinfo, int i)
+{
+       int ret;
+
+       ret = env_set_hex("gpt_partition_addr", pinfo->start);
+       if (ret)
+               goto fail;
+
+       ret = env_set_hex("gpt_partition_size", pinfo->size);
+       if (ret)
+               goto fail;
+
+       ret = env_set_ulong("gpt_partition_entry", i);
+       if (ret)
+               goto fail;
+
+       ret = env_set("gpt_partition_name", (const char *)pinfo->name);
+       if (ret)
+               goto fail;
+
+       return 0;
+
+fail:
+       return -ENOENT;
+}
+
+/**
+ * gpt_setenv() - Dynamically setup environment variables.
+ *
+ * Dynamically setup environment variables for name, index, offset and size
+ * for partition in GPT table after running "gpt setenv" for a partition name.
+ *
+ * @desc: block device descriptor
+ * @name: partition name
+ *
+ * @Return: '0' on success and -ve err on failure
+ */
+static int gpt_setenv(struct blk_desc *desc, const char *name)
+{
+       struct part_driver *first_drv, *part_drv;
+       int n_drvs;
+       int ret = -1;
+
+       n_drvs = part_driver_get_count();
+       if (!n_drvs) {
+               printf("Failed to get partition driver count\n");
+               goto fail;
+       }
+
+       first_drv = part_driver_get_first();
+       for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) {
+               struct disk_partition pinfo;
+               int i;
+
+               for (i = 1; i < part_drv->max_entries; i++) {
+                       ret = part_drv->get_info(desc, i, &pinfo);
+                       if (ret) {
+                               /* no more entries in table */
+                               break;
+                       }
+
+                       if (!strcmp(name, (const char *)pinfo.name)) {
+                               /* match found, setup environment variables */
+                               ret = gpt_setenv_part_variables(&pinfo, i);
+                               if (ret)
+                                       goto fail;
+
+                               return 0;
+                       }
+               }
+       }
+
+fail:
+       return ret;
+}
+
 static int do_disk_guid(struct blk_desc *dev_desc, char * const namestr)
 {
        int ret;
@@ -827,6 +974,10 @@ static int do_gpt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
        } else if ((strcmp(argv[1], "verify") == 0)) {
                ret = gpt_verify(blk_dev_desc, argv[4]);
                printf("Verify GPT: ");
+       } else if ((strcmp(argv[1], "setenv") == 0)) {
+               ret = gpt_setenv(blk_dev_desc, argv[4]);
+       } else if ((strcmp(argv[1], "enumerate") == 0)) {
+               ret = gpt_enumerate(blk_dev_desc);
        } else if (strcmp(argv[1], "guid") == 0) {
                ret = do_disk_guid(blk_dev_desc, argv[4]);
 #ifdef CONFIG_CMD_GPT_RENAME
@@ -857,7 +1008,17 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
        " to interface\n"
        " Example usage:\n"
        " gpt write mmc 0 $partitions\n"
+       "    - write the GPT to device\n"
        " gpt verify mmc 0 $partitions\n"
+       "    - verify the GPT on device against $partitions\n"
+       " gpt setenv mmc 0 $name\n"
+       "    - setup environment variables for partition $name:\n"
+       "      gpt_partition_addr, gpt_partition_size,\n"
+       "      gpt_partition_name, gpt_partition_entry\n"
+       " gpt enumerate mmc 0\n"
+       "    - store list of partitions to gpt_partition_list environment variable\n"
+       " read <interface> <dev>\n"
+       "    - read GPT into a data structure for manipulation\n"
        " gpt guid <interface> <dev>\n"
        "    - print disk GUID\n"
        " gpt guid <interface> <dev> <varname>\n"
diff --git a/cmd/mbr.c b/cmd/mbr.c
new file mode 100644 (file)
index 0000000..da2e3a4
--- /dev/null
+++ b/cmd/mbr.c
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * cmd_mbr.c -- MBR (Master Boot Record) handling command
+ *
+ * Copyright (C) 2020 Samsung Electronics
+ * author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * based on the gpt command.
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <command.h>
+#include <malloc.h>
+#include <part.h>
+
+/**
+ * extract_val() - Extract a value from the key=value pair list
+ * @str: pointer to string with key=values pairs
+ * @key: pointer to the key to search for
+ *
+ * The list of parameters is come separated, only a value for
+ * the given key is returend.
+ *
+ * Function allocates memory for the value, remember to free!
+ *
+ * Return: Pointer to allocated string with the value.
+ */
+static char *extract_val(const char *str, const char *key)
+{
+       char *v, *k;
+       char *s, *strcopy;
+       char *new = NULL;
+
+       strcopy = strdup(str);
+       if (strcopy == NULL)
+               return NULL;
+
+       s = strcopy;
+       while (s) {
+               v = strsep(&s, ",");
+               if (!v)
+                       break;
+               k = strsep(&v, "=");
+               if (!k)
+                       break;
+               if  (strcmp(k, key) == 0) {
+                       new = strdup(v);
+                       break;
+               }
+       }
+
+       free(strcopy);
+
+       return new;
+}
+
+/**
+ * found_key() - Search for a key without a value in the parameter list
+ * @str: pointer to string with key
+ * @key: pointer to the key to search for
+ *
+ * The list of parameters is come separated.
+ *
+ * Return: True if key has been found.
+ */
+static bool found_key(const char *str, const char *key)
+{
+       char *k;
+       char *s, *strcopy;
+       bool result = false;
+
+       strcopy = strdup(str);
+       if (!strcopy)
+               return NULL;
+
+       s = strcopy;
+       while (s) {
+               k = strsep(&s, ",");
+               if (!k)
+                       break;
+               if  (strcmp(k, key) == 0) {
+                       result = true;
+                       break;
+               }
+       }
+
+       free(strcopy);
+
+       return result;
+}
+
+static int str_to_partitions(const char *str_part, int blksz,
+       unsigned long *disk_uuid, struct disk_partition **partitions,
+       int *parts_count)
+{
+       char *tok, *str, *s;
+       int i;
+       char *val, *p;
+       int p_count;
+       struct disk_partition *parts;
+       int errno = 0;
+       uint64_t size_ll, start_ll;
+
+       if (str_part == NULL)
+               return -1;
+
+       str = strdup(str_part);
+       if (str == NULL)
+               return -ENOMEM;
+
+       /* extract disk guid */
+       s = str;
+       val = extract_val(str, "uuid_disk");
+       if (val) {
+               val = strsep(&val, ";");
+               p = val;
+               *disk_uuid = ustrtoull(p, &p, 0);
+               free(val);
+               /* Move s to first partition */
+               strsep(&s, ";");
+       }
+       if (s == NULL) {
+               printf("Error: is the partitions string NULL-terminated?\n");
+               return -EINVAL;
+       }
+
+       /* remove the optional semicolon at the end of the string */
+       i = strlen(s) - 1;
+       if (s[i] == ';')
+               s[i] = '\0';
+
+       /* calculate expected number of partitions */
+       p_count = 1;
+       p = s;
+       while (*p) {
+               if (*p++ == ';')
+                       p_count++;
+       }
+
+       /* allocate memory for partitions */
+       parts = calloc(sizeof(struct disk_partition), p_count);
+       if (parts == NULL)
+               return -ENOMEM;
+
+       /* retrieve partitions data from string */
+       for (i = 0; i < p_count; i++) {
+               tok = strsep(&s, ";");
+
+               if (tok == NULL)
+                       break;
+
+               /* size */
+               val = extract_val(tok, "size");
+               if (!val) { /* 'size' is mandatory */
+                       errno = -4;
+                       goto err;
+               }
+               p = val;
+               if ((strcmp(p, "-") == 0)) {
+                       /* auto extend the size */
+                       parts[i].size = 0;
+               } else {
+                       size_ll = ustrtoull(p, &p, 0);
+                       parts[i].size = size_ll / blksz;
+               }
+               free(val);
+
+               /* start address */
+               val = extract_val(tok, "start");
+               if (val) { /* start address is optional */
+                       p = val;
+                       start_ll = ustrtoull(p, &p, 0);
+                       parts[i].start = start_ll / blksz;
+                       free(val);
+               }
+
+               /* system id */
+               val = extract_val(tok, "id");
+               if (!val) { /* '' is mandatory */
+                       errno = -4;
+                       goto err;
+               }
+               p = val;
+               parts[i].sys_ind = ustrtoul(p, &p, 0);
+               free(val);
+
+               /* bootable */
+               if (found_key(tok, "bootable"))
+                       parts[i].bootable = PART_BOOTABLE;
+       }
+
+       *parts_count = p_count;
+       *partitions = parts;
+       free(str);
+
+       return 0;
+err:
+       free(str);
+       free(parts);
+
+       return errno;
+}
+
+static int do_write_mbr(struct blk_desc *dev, const char *str)
+{
+       unsigned long disk_uuid = 0;
+       struct disk_partition *partitions;
+       int blksz = dev->blksz;
+       int count;
+
+       if (str_to_partitions(str, blksz, &disk_uuid, &partitions, &count)) {
+               printf("MBR: failed to setup partitions from \"%s\"\n", str);
+               return -1;
+       }
+
+       if (layout_mbr_partitions(partitions, count, dev->lba)) {
+               printf("MBR: failed to layout partitions on the device\n");
+               free(partitions);
+               return -1;
+       }
+
+       if (write_mbr_partitions(dev, partitions, count, disk_uuid)) {
+               printf("MBR: failed to write partitions to the device\n");
+               free(partitions);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int do_verify_mbr(struct blk_desc *dev, const char *str)
+{
+       unsigned long disk_uuid = 0;
+       struct disk_partition *partitions;
+       int blksz = dev->blksz;
+       int count, i, ret = 1;
+
+       if (str_to_partitions(str, blksz, &disk_uuid, &partitions, &count)) {
+               printf("MBR: failed to setup partitions from \"%s\"\n", str);
+               return -1;
+       }
+
+       for (i = 0; i < count; i++) {
+               struct disk_partition p;
+
+               if (part_get_info(dev, i+1, &p))
+                       goto fail;
+
+               if ((partitions[i].size && p.size < partitions[i].size) ||
+                   (partitions[i].start && p.start < partitions[i].start) ||
+                   (p.sys_ind != partitions[i].sys_ind))
+                       goto fail;
+       }
+       ret = 0;
+fail:
+       free(partitions);
+       return ret;
+}
+
+static int do_mbr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+       const char *parts = NULL;
+       int ret = CMD_RET_SUCCESS;
+       int dev = 0;
+       char *ep;
+       struct blk_desc *blk_dev_desc = NULL;
+
+       if (argc != 4 && argc != 5)
+               return CMD_RET_USAGE;
+
+       dev = (int)simple_strtoul(argv[3], &ep, 10);
+       if (!ep || ep[0] != '\0') {
+               printf("'%s' is not a number\n", argv[3]);
+               return CMD_RET_USAGE;
+       }
+       blk_dev_desc = blk_get_dev(argv[2], dev);
+       if (!blk_dev_desc) {
+               printf("%s: %s dev %d NOT available\n",
+                      __func__, argv[2], dev);
+               return CMD_RET_FAILURE;
+       }
+
+       if ((strcmp(argv[1], "write") == 0)) {
+               parts = (argc == 5) ? argv[4] : env_get("mbr_parts");
+               printf("MBR: write ");
+               ret = do_write_mbr(blk_dev_desc, parts);
+       } else if ((strcmp(argv[1], "verify") == 0)) {
+               printf("MBR: verify ");
+               parts = (argc == 5) ? argv[4] : env_get("mbr_parts");
+               ret = do_verify_mbr(blk_dev_desc, parts);
+       } else {
+               return CMD_RET_USAGE;
+       }
+
+       if (ret) {
+               printf("error!\n");
+               return CMD_RET_FAILURE;
+       }
+
+       printf("success!\n");
+       return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(mbr, CONFIG_SYS_MAXARGS, 1, do_mbr,
+       "MBR (Master Boot Record)",
+       "<command> <interface> <dev> <partitions_list>\n"
+       " - MBR partition table restoration utility\n"
+       " Restore or check partition information on a device connected\n"
+       " to the given block interface\n"
+       " Example usage:\n"
+       " mbr write mmc 0 [\"${mbr_parts}\"]\n"
+       " mbr verify mmc 0 [\"${partitions}\"]\n"
+);
index 2bce8c9..d8982ba 100644 (file)
@@ -17,6 +17,14 @@ config CONSOLE_RECORD
          To enable console recording, call console_record_reset_enable()
          from your code.
 
+config CONSOLE_RECORD_INIT_F
+       bool "Enable console recording during pre-relocation init"
+       depends on CONSOLE_RECORD && SYS_MALLOC_F
+       default y
+       help
+         This option enables console recording during pre-relocation init.
+         CONFIG_SYS_MALLOC_F must be enabled to use this feature.
+
 config CONSOLE_RECORD_OUT_SIZE
        hex "Output buffer size"
        depends on CONSOLE_RECORD
index 58e9854..4525a12 100644 (file)
@@ -819,7 +819,10 @@ config AUTOBOOT_STOP_STR_SHA256
          This option adds the feature to only stop the autobooting,
          and therefore boot into the U-Boot prompt, when the input
          string / password matches a values that is encypted via
-         a SHA256 hash and saved in the environment.
+         a SHA256 hash and saved in the environment variable
+         "bootstopkeysha256". If the value in that variable
+         includes a ":", the portion prior to the ":" will be treated
+         as a salt value.
 
 config AUTOBOOT_USE_MENUKEY
        bool "Allow a specify key to run a menu from the environment"
index bcf352d..daeea67 100644 (file)
@@ -68,7 +68,6 @@ obj-$(CONFIG_DFU_OVER_USB) += dfu.o
 endif
 obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o
 obj-$(CONFIG_TPL_HASH_SUPPORT) += hash.o
-obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
 obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
index e628baf..ddb6246 100644 (file)
@@ -25,7 +25,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define MAX_DELAY_STOP_STR 32
+#define MAX_DELAY_STOP_STR 64
 
 #ifndef DEBUG_BOOTKEYS
 #define DEBUG_BOOTKEYS 0
@@ -80,6 +80,7 @@ static int passwd_abort_sha256(uint64_t etime)
        u8 sha_env[SHA256_SUM_LEN];
        u8 *sha;
        char *presskey;
+       char *c;
        const char *algo_name = "sha256";
        u_int presskey_len = 0;
        int abort = 0;
@@ -89,6 +90,14 @@ static int passwd_abort_sha256(uint64_t etime)
        if (sha_env_str == NULL)
                sha_env_str = AUTOBOOT_STOP_STR_SHA256;
 
+       presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR);
+       c = strstr(sha_env_str, ":");
+       if (c && (c - sha_env_str < MAX_DELAY_STOP_STR)) {
+               /* preload presskey with salt */
+               memcpy(presskey, sha_env_str, c - sha_env_str);
+               presskey_len = c - sha_env_str;
+               sha_env_str = c + 1;
+       }
        /*
         * Generate the binary value from the environment hash value
         * so that we can compare this value with the computed hash
@@ -100,7 +109,6 @@ static int passwd_abort_sha256(uint64_t etime)
                return 0;
        }
 
-       presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR);
        sha = malloc_cache_aligned(SHA256_SUM_LEN);
        size = SHA256_SUM_LEN;
        /*
index 9f441c4..ae3001b 100644 (file)
@@ -503,14 +503,6 @@ static int reserve_board(void)
        return 0;
 }
 
-static int setup_machine(void)
-{
-#ifdef CONFIG_MACH_TYPE
-       gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
-#endif
-       return 0;
-}
-
 static int reserve_global_data(void)
 {
        gd->start_addr_sp = reserve_stack_aligned(sizeof(gd_t));
@@ -522,21 +514,21 @@ static int reserve_global_data(void)
 
 static int reserve_fdt(void)
 {
-#ifndef CONFIG_OF_EMBED
-       /*
-        * If the device tree is sitting immediately above our image then we
-        * must relocate it. If it is embedded in the data section, then it
-        * will be relocated with other data.
-        */
-       if (gd->fdt_blob) {
-               gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32);
+       if (!IS_ENABLED(CONFIG_OF_EMBED)) {
+               /*
+                * If the device tree is sitting immediately above our image
+                * then we must relocate it. If it is embedded in the data
+                * section, then it will be relocated with other data.
+                */
+               if (gd->fdt_blob) {
+                       gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32);
 
-               gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
-               gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
-               debug("Reserving %lu Bytes for FDT at: %08lx\n",
-                     gd->fdt_size, gd->start_addr_sp);
+                       gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
+                       gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
+                       debug("Reserving %lu Bytes for FDT at: %08lx\n",
+                             gd->fdt_size, gd->start_addr_sp);
+               }
        }
-#endif
 
        return 0;
 }
@@ -605,6 +597,10 @@ int setup_bdinfo(void)
                bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;  /* size  of SRAM */
        }
 
+#ifdef CONFIG_MACH_TYPE
+       bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
+#endif
+
        return arch_setup_bdinfo();
 }
 
@@ -620,14 +616,15 @@ static int init_post(void)
 
 static int reloc_fdt(void)
 {
-#ifndef CONFIG_OF_EMBED
-       if (gd->flags & GD_FLG_SKIP_RELOC)
-               return 0;
-       if (gd->new_fdt) {
-               memcpy(gd->new_fdt, gd->fdt_blob, fdt_totalsize(gd->fdt_blob));
-               gd->fdt_blob = gd->new_fdt;
+       if (!IS_ENABLED(CONFIG_OF_EMBED)) {
+               if (gd->flags & GD_FLG_SKIP_RELOC)
+                       return 0;
+               if (gd->new_fdt) {
+                       memcpy(gd->new_fdt, gd->fdt_blob,
+                              fdt_totalsize(gd->fdt_blob));
+                       gd->fdt_blob = gd->new_fdt;
+               }
        }
-#endif
 
        return 0;
 }
@@ -765,15 +762,6 @@ static int initf_bootstage(void)
        return 0;
 }
 
-static int initf_console_record(void)
-{
-#if defined(CONFIG_CONSOLE_RECORD) && CONFIG_VAL(SYS_MALLOC_F_LEN)
-       return console_record_init();
-#else
-       return 0;
-#endif
-}
-
 static int initf_dm(void)
 {
 #if defined(CONFIG_DM) && CONFIG_VAL(SYS_MALLOC_F_LEN)
@@ -784,11 +772,12 @@ static int initf_dm(void)
        bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_F);
        if (ret)
                return ret;
-#endif
-#ifdef CONFIG_TIMER_EARLY
-       ret = dm_timer_init();
-       if (ret)
-               return ret;
+
+       if (IS_ENABLED(CONFIG_TIMER_EARLY)) {
+               ret = dm_timer_init();
+               if (ret)
+                       return ret;
+       }
 #endif
 
        return 0;
@@ -830,7 +819,9 @@ static const init_fnc_t init_sequence_f[] = {
        bloblist_init,
 #endif
        setup_spl_handoff,
-       initf_console_record,
+#if defined(CONFIG_CONSOLE_RECORD_INIT_F)
+       console_record_init,
+#endif
 #if defined(CONFIG_HAVE_FSP)
        arch_fsp_init,
 #endif
@@ -922,7 +913,6 @@ static const init_fnc_t init_sequence_f[] = {
        reserve_uboot,
        reserve_malloc,
        reserve_board,
-       setup_machine,
        reserve_global_data,
        reserve_fdt,
        reserve_bootstage,
index 29dd7d2..9fa4d4b 100644 (file)
@@ -91,21 +91,8 @@ __weak int board_flash_wp_on(void)
        return 0;
 }
 
-__weak void cpu_secondary_init_r(void)
+__weak int cpu_secondary_init_r(void)
 {
-}
-
-static int initr_secondary_cpu(void)
-{
-       /*
-        * after non-volatile devices & environment is setup and cpu code have
-        * another round to deal with any initialization that might require
-        * full access to the environment or loading of some image (firmware)
-        * from a non-volatile device
-        */
-       /* TODO: maybe define this for all archs? */
-       cpu_secondary_init_r();
-
        return 0;
 }
 
@@ -195,20 +182,10 @@ static int initr_reloc_global_data(void)
        return 0;
 }
 
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
-static int initr_trap(void)
+__weak int arch_initr_trap(void)
 {
-       /*
-        * Setup trap handlers
-        */
-#if defined(CONFIG_PPC)
-       trap_init(gd->relocaddr);
-#else
-       trap_init(CONFIG_SYS_SDRAM_BASE);
-#endif
        return 0;
 }
-#endif
 
 #ifdef CONFIG_ADDR_MAP
 static int initr_addr_map(void)
@@ -219,14 +196,6 @@ static int initr_addr_map(void)
 }
 #endif
 
-#ifdef CONFIG_POST
-static int initr_post_backlog(void)
-{
-       post_output_backlog();
-       return 0;
-}
-#endif
-
 #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
 static int initr_unlock_ram_in_cache(void)
 {
@@ -235,25 +204,6 @@ static int initr_unlock_ram_in_cache(void)
 }
 #endif
 
-#ifdef CONFIG_PCI_ENDPOINT
-static int initr_pci_ep(void)
-{
-       pci_ep_init();
-
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_PCI
-static int initr_pci(void)
-{
-       if (IS_ENABLED(CONFIG_PCI_INIT_R))
-               pci_init();
-
-       return 0;
-}
-#endif
-
 static int initr_barrier(void)
 {
 #ifdef CONFIG_PPC
@@ -282,23 +232,6 @@ static int initr_malloc(void)
        return 0;
 }
 
-static int initr_console_record(void)
-{
-#if defined(CONFIG_CONSOLE_RECORD)
-       return console_record_init();
-#else
-       return 0;
-#endif
-}
-
-#ifdef CONFIG_SYS_NONCACHED_MEMORY
-static int initr_noncached(void)
-{
-       noncached_init();
-       return 0;
-}
-#endif
-
 static int initr_of_live(void)
 {
        if (CONFIG_IS_ENABLED(OF_LIVE)) {
@@ -485,14 +418,6 @@ static int initr_mmc(void)
 }
 #endif
 
-#ifdef CONFIG_XEN
-static int initr_xen(void)
-{
-       xen_init();
-       return 0;
-}
-#endif
-
 #ifdef CONFIG_PVBLOCK
 static int initr_pvblock(void)
 {
@@ -555,21 +480,6 @@ static int initr_malloc_bootparams(void)
 }
 #endif
 
-static int initr_jumptable(void)
-{
-       jumptable_init();
-       return 0;
-}
-
-#if defined(CONFIG_API)
-static int initr_api(void)
-{
-       /* Initialize API */
-       api_init();
-       return 0;
-}
-#endif
-
 #ifdef CONFIG_CMD_NET
 static int initr_ethaddr(void)
 {
@@ -614,14 +524,6 @@ static int initr_scsi(void)
 }
 #endif
 
-#ifdef CONFIG_BITBANGMII
-static int initr_bbmii(void)
-{
-       bb_miiphy_init();
-       return 0;
-}
-#endif
-
 #ifdef CONFIG_CMD_NET
 static int initr_net(void)
 {
@@ -713,9 +615,11 @@ static init_fnc_t init_sequence_r[] = {
        initr_malloc,
        log_init,
        initr_bootstage,        /* Needs malloc() but has its own timer */
-       initr_console_record,
+#if defined(CONFIG_CONSOLE_RECORD)
+       console_record_init,
+#endif
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
-       initr_noncached,
+       noncached_init,
 #endif
        initr_of_live,
 #ifdef CONFIG_DM
@@ -755,9 +659,7 @@ static init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
        initr_manual_reloc_cmdtable,
 #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
-       initr_trap,
-#endif
+       arch_initr_trap,
 #ifdef CONFIG_ADDR_MAP
        initr_addr_map,
 #endif
@@ -766,15 +668,15 @@ static init_fnc_t init_sequence_r[] = {
 #endif
        INIT_FUNC_WATCHDOG_RESET
 #ifdef CONFIG_POST
-       initr_post_backlog,
+       post_output_backlog,
 #endif
        INIT_FUNC_WATCHDOG_RESET
-#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
+#if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT)
        /*
         * Do early PCI configuration _before_ the flash gets initialised,
         * because PCU resources are crucial for flash access on some boards.
         */
-       initr_pci,
+       pci_init,
 #endif
 #ifdef CONFIG_ARCH_EARLY_INIT_R
        arch_early_init_r,
@@ -798,7 +700,7 @@ static init_fnc_t init_sequence_r[] = {
        initr_mmc,
 #endif
 #ifdef CONFIG_XEN
-       initr_xen,
+       xen_init,
 #endif
 #ifdef CONFIG_PVBLOCK
        initr_pvblock,
@@ -808,21 +710,21 @@ static init_fnc_t init_sequence_r[] = {
        initr_malloc_bootparams,
 #endif
        INIT_FUNC_WATCHDOG_RESET
-       initr_secondary_cpu,
+       cpu_secondary_init_r,
 #if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
        mac_read_from_eeprom,
 #endif
        INIT_FUNC_WATCHDOG_RESET
-#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
+#if defined(CONFIG_PCI_INIT_R) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
        /*
         * Do pci configuration
         */
-       initr_pci,
+       pci_init,
 #endif
        stdio_add_devices,
-       initr_jumptable,
+       jumptable_init,
 #ifdef CONFIG_API
-       initr_api,
+       api_init,
 #endif
        console_init_r,         /* fully init console as a device */
 #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
@@ -861,10 +763,10 @@ static init_fnc_t init_sequence_r[] = {
        initr_scsi,
 #endif
 #ifdef CONFIG_BITBANGMII
-       initr_bbmii,
+       bb_miiphy_init,
 #endif
 #ifdef CONFIG_PCI_ENDPOINT
-       initr_pci_ep,
+       pci_ep_init,
 #endif
 #ifdef CONFIG_CMD_NET
        INIT_FUNC_WATCHDOG_RESET
index 47b8762..5c158d0 100644 (file)
@@ -493,8 +493,10 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
                }
 #endif
                default:
-                       cread_add_char(ichar, insert, &num, &eol_num, buf,
-                                      *len);
+                       if (ichar >= ' ' && ichar <= '~') {
+                               cread_add_char(ichar, insert, &num, &eol_num,
+                                              buf, *len);
+                       }
                        break;
                }
        }
index 068cb55..3fe6791 100644 (file)
@@ -16,6 +16,8 @@
 #include <log.h>
 #include <linux/ctype.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /*
  * Use puts() instead of printf() to avoid printf buffer overflow
  * for long help messages
@@ -488,9 +490,6 @@ int cmd_get_data_size(char* arg, int default_size)
 }
 #endif
 
-#if defined(CONFIG_NEEDS_MANUAL_RELOC)
-DECLARE_GLOBAL_DATA_PTR;
-
 void fixup_cmdtable(struct cmd_tbl *cmdtp, int size)
 {
        int     i;
@@ -535,7 +534,6 @@ void fixup_cmdtable(struct cmd_tbl *cmdtp, int size)
                cmdtp++;
        }
 }
-#endif
 
 int cmd_always_repeatable(struct cmd_tbl *cmdtp, int flag, int argc,
                          char *const argv[], int *repeatable)
index 3348436..f3cc45c 100644 (file)
@@ -44,14 +44,15 @@ static int on_console(const char *name, const char *value, enum env_op op,
        case env_op_create:
        case env_op_overwrite:
 
-#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
+               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;
+               }
+
                return 0;
 
        case env_op_delete:
@@ -69,14 +70,13 @@ U_BOOT_ENV_CALLBACK(console, on_console);
 static int on_silent(const char *name, const char *value, enum env_op op,
        int flags)
 {
-#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET)
-       if (flags & H_INTERACTIVE)
-               return 0;
-#endif
-#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC)
-       if ((flags & H_INTERACTIVE) == 0)
-               return 0;
-#endif
+       if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET))
+               if (flags & H_INTERACTIVE)
+                       return 0;
+
+       if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC))
+               if ((flags & H_INTERACTIVE) == 0)
+                       return 0;
 
        if (value != NULL)
                gd->flags |= GD_FLG_SILENT;
@@ -88,6 +88,64 @@ static int on_silent(const char *name, const char *value, enum env_op op,
 U_BOOT_ENV_CALLBACK(silent, on_silent);
 #endif
 
+#ifdef CONFIG_CONSOLE_RECORD
+/* helper function: access to gd->console_out and gd->console_in */
+static void console_record_putc(const char c)
+{
+       if (!(gd->flags & GD_FLG_RECORD))
+               return;
+       if  (gd->console_out.start)
+               membuff_putbyte((struct membuff *)&gd->console_out, c);
+}
+
+static void console_record_puts(const char *s)
+{
+       if (!(gd->flags & GD_FLG_RECORD))
+               return;
+       if  (gd->console_out.start)
+               membuff_put((struct membuff *)&gd->console_out, s, strlen(s));
+}
+
+static int console_record_getc(void)
+{
+       if (!(gd->flags & GD_FLG_RECORD))
+               return -1;
+       if (!gd->console_in.start)
+               return -1;
+
+       return membuff_getbyte((struct membuff *)&gd->console_in);
+}
+
+static int console_record_tstc(void)
+{
+       if (!(gd->flags & GD_FLG_RECORD))
+               return 0;
+       if (gd->console_in.start) {
+               if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1)
+                       return 1;
+       }
+       return 0;
+}
+#else
+static void console_record_putc(char c)
+{
+}
+
+static void console_record_puts(const char *s)
+{
+}
+
+static int console_record_getc(void)
+{
+       return -1;
+}
+
+static int console_record_tstc(void)
+{
+       return 0;
+}
+#endif
+
 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
 /*
  * if overwrite_console returns 1, the stdin, stderr and stdout
@@ -114,13 +172,9 @@ static int console_setfile(int file, struct stdio_dev * dev)
        case stdin:
        case stdout:
        case stderr:
-               /* Start new device */
-               if (dev->start) {
-                       error = dev->start(dev);
-                       /* If it's not started dont use it */
-                       if (error < 0)
-                               break;
-               }
+               error = console_start(file, dev);
+               if (error)
+                       break;
 
                /* Assign the new device (leaving the existing one started) */
                stdio_devices[file] = dev;
@@ -159,14 +213,13 @@ static bool console_dev_is_serial(struct stdio_dev *sdev)
 {
        bool is_serial;
 
-#ifdef CONFIG_DM_SERIAL
-       if (sdev->flags & DEV_FLAGS_DM) {
+       if (IS_ENABLED(CONFIG_DM_SERIAL) && (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");
+       } else {
+               is_serial = !strcmp(sdev->name, "serial");
+       }
 
        return is_serial;
 }
@@ -174,10 +227,42 @@ static bool console_dev_is_serial(struct stdio_dev *sdev)
 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
 /** Console I/O multiplexing *******************************************/
 
+/* tstcdev: save the last stdio device with pending characters, with tstc != 0 */
 static struct stdio_dev *tstcdev;
 struct stdio_dev **console_devices[MAX_FILES];
 int cd_count[MAX_FILES];
 
+static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
+{
+       console_devices[file][0] = dev;
+}
+
+/**
+ * console_needs_start_stop() - check if we need to start or stop the STDIO device
+ * @file: STDIO file
+ * @sdev: STDIO device in question
+ *
+ * This function checks if we need to start or stop the stdio device used for
+ * a console. For IOMUX case it simply enforces one time start and one time
+ * stop of the device independently of how many STDIO files are using it. In
+ * other words, we start console once before first STDIO device wants it and
+ * stop after the last is gone.
+ */
+static bool console_needs_start_stop(int file, struct stdio_dev *sdev)
+{
+       int i, j;
+
+       for (i = 0; i < ARRAY_SIZE(cd_count); i++) {
+               if (i == file)
+                       continue;
+
+               for (j = 0; j < cd_count[i]; j++)
+                       if (console_devices[i][j] == sdev)
+                               return false;
+       }
+       return true;
+}
+
 /*
  * This depends on tstc() always being called before getchar().
  * This is guaranteed to be true because this routine is called
@@ -194,6 +279,12 @@ static int console_getc(int file)
        return ret;
 }
 
+/*  Upper layer may have already called tstc(): check the saved result */
+static bool console_has_tstc(void)
+{
+       return !!tstcdev;
+}
+
 static int console_tstc(int file)
 {
        int i, ret;
@@ -276,11 +367,26 @@ static inline void console_doenv(int file, struct stdio_dev *dev)
 }
 #endif
 #else
+
+static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
+{
+}
+
+static inline bool console_needs_start_stop(int file, struct stdio_dev *sdev)
+{
+       return true;
+}
+
 static inline int console_getc(int file)
 {
        return stdio_devices[file]->getc(stdio_devices[file]);
 }
 
+static bool console_has_tstc(void)
+{
+       return false;
+}
+
 static inline int console_tstc(int file)
 {
        return stdio_devices[file]->tstc(stdio_devices[file]);
@@ -310,6 +416,32 @@ static inline void console_doenv(int file, struct stdio_dev *dev)
 #endif
 #endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
 
+int console_start(int file, struct stdio_dev *sdev)
+{
+       int error;
+
+       if (!console_needs_start_stop(file, sdev))
+               return 0;
+
+       /* Start new device */
+       if (sdev->start) {
+               error = sdev->start(sdev);
+               /* If it's not started don't use it */
+               if (error < 0)
+                       return error;
+       }
+       return 0;
+}
+
+void console_stop(int file, struct stdio_dev *sdev)
+{
+       if (!console_needs_start_stop(file, sdev))
+               return;
+
+       if (sdev->stop)
+               sdev->stop(sdev);
+}
+
 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
 
 int serial_printf(const char *fmt, ...)
@@ -338,25 +470,25 @@ int fgetc(int file)
                 */
                for (;;) {
                        WATCHDOG_RESET();
-#if CONFIG_IS_ENABLED(CONSOLE_MUX)
-                       /*
-                        * Upper layer may have already called tstc() so
-                        * check for that first.
-                        */
-                       if (tstcdev != NULL)
-                               return console_getc(file);
-                       console_tstc(file);
-#else
-                       if (console_tstc(file))
-                               return console_getc(file);
-#endif
-#ifdef CONFIG_WATCHDOG
+                       if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
+                               /*
+                                * Upper layer may have already called tstc() so
+                                * check for that first.
+                                */
+                               if (console_has_tstc())
+                                       return console_getc(file);
+                               console_tstc(file);
+                       } else {
+                               if (console_tstc(file))
+                                       return console_getc(file);
+                       }
+
                        /*
                         * If the watchdog must be rate-limited then it should
                         * already be handled in board-specific code.
                         */
-                        udelay(1);
-#endif
+                       if (IS_ENABLED(CONFIG_WATCHDOG))
+                               udelay(1);
                }
        }
 
@@ -406,23 +538,18 @@ int fprintf(int file, const char *fmt, ...)
 
 int getchar(void)
 {
-#ifdef CONFIG_DISABLE_CONSOLE
-       if (gd->flags & GD_FLG_DISABLE_CONSOLE)
+       int ch;
+
+       if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
                return 0;
-#endif
 
        if (!gd->have_console)
                return 0;
 
-#ifdef CONFIG_CONSOLE_RECORD
-       if (gd->console_in.start) {
-               int ch;
+       ch = console_record_getc();
+       if (ch != -1)
+               return ch;
 
-               ch = membuff_getbyte((struct membuff *)&gd->console_in);
-               if (ch != -1)
-                       return 1;
-       }
-#endif
        if (gd->flags & GD_FLG_DEVINIT) {
                /* Get from the standard input */
                return fgetc(stdin);
@@ -434,19 +561,15 @@ int getchar(void)
 
 int tstc(void)
 {
-#ifdef CONFIG_DISABLE_CONSOLE
-       if (gd->flags & GD_FLG_DISABLE_CONSOLE)
+       if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
                return 0;
-#endif
 
        if (!gd->have_console)
                return 0;
-#ifdef CONFIG_CONSOLE_RECORD
-       if (gd->console_in.start) {
-               if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1)
-                       return 1;
-       }
-#endif
+
+       if (console_record_tstc())
+               return 1;
+
        if (gd->flags & GD_FLG_DEVINIT) {
                /* Test the standard input */
                return ftstc(stdin);
@@ -485,10 +608,8 @@ static void print_pre_console_buffer(int flushpoint)
        char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
        char *buf_in;
 
-#ifdef CONFIG_SILENT_CONSOLE
-       if (gd->flags & GD_FLG_SILENT)
+       if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (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)
@@ -517,38 +638,31 @@ static inline void print_pre_console_buffer(int flushpoint) {}
 
 void putc(const char c)
 {
-#ifdef CONFIG_SANDBOX
+       if (!gd)
+               return;
+
+       console_record_putc(c);
+
        /* sandbox can send characters to stdout before it has a console */
-       if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+       if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
                os_putc(c);
                return;
        }
-#endif
-#ifdef CONFIG_DEBUG_UART
+
        /* if we don't have a console yet, use the debug UART */
-       if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+       if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
                printch(c);
                return;
        }
-#endif
-       if (!gd)
-               return;
-#ifdef CONFIG_CONSOLE_RECORD
-       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 (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) {
                if (!(gd->flags & GD_FLG_DEVINIT))
                        pre_console_putc(c);
                return;
        }
-#endif
 
-#ifdef CONFIG_DISABLE_CONSOLE
-       if (gd->flags & GD_FLG_DISABLE_CONSOLE)
+       if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
                return;
-#endif
 
        if (!gd->have_console)
                return pre_console_putc(c);
@@ -565,15 +679,18 @@ void putc(const char c)
 
 void puts(const char *s)
 {
-#ifdef CONFIG_SANDBOX
+       if (!gd)
+               return;
+
+       console_record_puts(s);
+
        /* sandbox can send characters to stdout before it has a console */
-       if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+       if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
                os_puts(s);
                return;
        }
-#endif
-#ifdef CONFIG_DEBUG_UART
-       if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+
+       if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
                while (*s) {
                        int ch = *s++;
 
@@ -581,25 +698,15 @@ void puts(const char *s)
                }
                return;
        }
-#endif
-       if (!gd)
-               return;
-#ifdef CONFIG_CONSOLE_RECORD
-       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 (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) {
                if (!(gd->flags & GD_FLG_DEVINIT))
                        pre_console_puts(s);
                return;
        }
-#endif
 
-#ifdef CONFIG_DISABLE_CONSOLE
-       if (gd->flags & GD_FLG_DISABLE_CONSOLE)
+       if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
                return;
-#endif
 
        if (!gd->have_console)
                return pre_console_puts(s);
@@ -725,7 +832,7 @@ void clear_ctrlc(void)
 
 /** U-Boot INIT FUNCTIONS *************************************************/
 
-struct stdio_dev *search_device(int flags, const char *name)
+struct stdio_dev *console_search_dev(int flags, const char *name)
 {
        struct stdio_dev *dev;
 
@@ -761,7 +868,7 @@ int console_assign(int file, const char *devname)
 
        /* Check for valid device name */
 
-       dev = search_device(flag, devname);
+       dev = console_search_dev(flag, devname);
 
        if (dev)
                return console_setfile(file, dev);
@@ -772,19 +879,19 @@ int console_assign(int file, const char *devname)
 /* return true if the 'silent' flag is removed */
 static bool console_update_silent(void)
 {
-#ifdef CONFIG_SILENT_CONSOLE
-       if (env_get("silent")) {
-               gd->flags |= GD_FLG_SILENT;
-       } else {
-               unsigned long flags = gd->flags;
+       unsigned long flags = gd->flags;
 
-               gd->flags &= ~GD_FLG_SILENT;
+       if (!IS_ENABLED(CONFIG_SILENT_CONSOLE))
+               return false;
 
-               return !!(flags & GD_FLG_SILENT);
+       if (env_get("silent")) {
+               gd->flags |= GD_FLG_SILENT;
+               return false;
        }
-#endif
 
-       return false;
+       gd->flags &= ~GD_FLG_SILENT;
+
+       return !!(flags & GD_FLG_SILENT);
 }
 
 int console_announce_r(void)
@@ -843,12 +950,8 @@ int console_init_r(void)
 {
        char *stdinname, *stdoutname, *stderrname;
        struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
-#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
        int i;
-#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
-#if CONFIG_IS_ENABLED(CONSOLE_MUX)
        int iomux_err = 0;
-#endif
        int flushpoint;
 
        /* update silent for env loaded from flash (initr_env) */
@@ -871,27 +974,27 @@ int console_init_r(void)
        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);
-#if CONFIG_IS_ENABLED(CONSOLE_MUX)
-               iomux_err = iomux_doenv(stdin, stdinname);
-               iomux_err += iomux_doenv(stdout, stdoutname);
-               iomux_err += iomux_doenv(stderr, stderrname);
-               if (!iomux_err)
-                       /* Successful, so skip all the code below. */
-                       goto done;
-#endif
+               inputdev  = console_search_dev(DEV_FLAGS_INPUT,  stdinname);
+               outputdev = console_search_dev(DEV_FLAGS_OUTPUT, stdoutname);
+               errdev    = console_search_dev(DEV_FLAGS_OUTPUT, stderrname);
+               if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
+                       iomux_err = iomux_doenv(stdin, stdinname);
+                       iomux_err += iomux_doenv(stdout, stdoutname);
+                       iomux_err += iomux_doenv(stderr, stderrname);
+                       if (!iomux_err)
+                               /* Successful, so skip all the code below. */
+                               goto done;
+               }
        }
        /* if the devices are overwritten or not found, use default device */
        if (inputdev == NULL) {
-               inputdev  = search_device(DEV_FLAGS_INPUT,  "serial");
+               inputdev  = console_search_dev(DEV_FLAGS_INPUT,  "serial");
        }
        if (outputdev == NULL) {
-               outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
+               outputdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial");
        }
        if (errdev == NULL) {
-               errdev    = search_device(DEV_FLAGS_OUTPUT, "serial");
+               errdev    = console_search_dev(DEV_FLAGS_OUTPUT, "serial");
        }
        /* Initializes output console first */
        if (outputdev != NULL) {
@@ -907,33 +1010,25 @@ int console_init_r(void)
                console_doenv(stdin, inputdev);
        }
 
-#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 done:
-#endif
 
-#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
-       stdio_print_current_devices();
-#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
+       if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
+               stdio_print_current_devices();
+
 #ifdef CONFIG_VIDCONSOLE_AS_LCD
        if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_NAME))
                printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n",
                       CONFIG_VIDCONSOLE_AS_NAME);
 #endif
 
-#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
-       /* set the environment variables (will overwrite previous env settings) */
-       for (i = 0; i < MAX_FILES; i++) {
-               env_set(stdio_names[i], stdio_devices[i]->name);
+       if (IS_ENABLED(CONFIG_SYS_CONSOLE_ENV_OVERWRITE)) {
+               /* set the environment variables (will overwrite previous env settings) */
+               for (i = 0; i < MAX_FILES; i++)
+                       env_set(stdio_names[i], stdio_devices[i]->name);
        }
-#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
 
        gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
 
-#if 0
-       /* If nothing usable installed, use only the initial console */
-       if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
-               return 0;
-#endif
        print_pre_console_buffer(flushpoint);
        return 0;
 }
@@ -956,18 +1051,16 @@ int console_init_r(void)
        else
                flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
 
-#ifdef CONFIG_SPLASH_SCREEN
        /*
         * suppress all output if splash screen is enabled and we have
         * a bmp to display. We redirect the output from frame buffer
         * console to serial console in this case or suppress it if
         * "silent" mode was requested.
         */
-       if (env_get("splashimage") != NULL) {
+       if (IS_ENABLED(CONFIG_SPLASH_SCREEN) && env_get("splashimage")) {
                if (!(gd->flags & GD_FLG_SILENT))
-                       outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
+                       outputdev = console_search_dev (DEV_FLAGS_OUTPUT, "serial");
        }
-#endif
 
        /* Scan devices looking for input and output devices */
        list_for_each(pos, list) {
@@ -987,23 +1080,18 @@ int console_init_r(void)
        if (outputdev != NULL) {
                console_setfile(stdout, outputdev);
                console_setfile(stderr, outputdev);
-#if CONFIG_IS_ENABLED(CONSOLE_MUX)
-               console_devices[stdout][0] = outputdev;
-               console_devices[stderr][0] = outputdev;
-#endif
+               console_devices_set(stdout, outputdev);
+               console_devices_set(stderr, outputdev);
        }
 
        /* Initializes input console */
        if (inputdev != NULL) {
                console_setfile(stdin, inputdev);
-#if CONFIG_IS_ENABLED(CONSOLE_MUX)
-               console_devices[stdin][0] = inputdev;
-#endif
+               console_devices_set(stdin, inputdev);
        }
 
-#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
-       stdio_print_current_devices();
-#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
+       if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
+               stdio_print_current_devices();
 
        /* Setting environment variables */
        for (i = 0; i < MAX_FILES; i++) {
@@ -1012,11 +1100,6 @@ int console_init_r(void)
 
        gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
 
-#if 0
-       /* If nothing usable installed, use only the initial console */
-       if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
-               return 0;
-#endif
        print_pre_console_buffer(flushpoint);
        return 0;
 }
index 6253b55..4578f07 100644 (file)
@@ -25,8 +25,10 @@ unsigned long get_version(void)
 # define miiphy_set_current_dev                dummy
 #endif
 
-void jumptable_init(void)
+int jumptable_init(void)
 {
        gd->jt = malloc(sizeof(struct jt_funcs));
 #include <_exports.h>
+
+       return 0;
 }
index 7cfd9f2..15bf533 100644 (file)
@@ -27,8 +27,8 @@ int iomux_doenv(const int console, const char *arg)
 {
        char *console_args, *temp, **start;
        int i, j, k, io_flag, cs_idx, repeat;
+       struct stdio_dev **cons_set, **old_set;
        struct stdio_dev *dev;
-       struct stdio_dev **cons_set;
 
        console_args = strdup(arg);
        if (console_args == NULL)
@@ -45,15 +45,14 @@ int iomux_doenv(const int console, const char *arg)
        i = 0;
        temp = console_args;
        for (;;) {
-               temp = strchr(temp, ',');
-               if (temp != NULL) {
-                       i++;
-                       temp++;
-                       continue;
-               }
                /* There's always one entry more than the number of commas. */
                i++;
-               break;
+
+               temp = strchr(temp, ',');
+               if (temp == NULL)
+                       break;
+
+               temp++;
        }
        start = (char **)malloc(i * sizeof(char *));
        if (start == NULL) {
@@ -95,10 +94,10 @@ int iomux_doenv(const int console, const char *arg)
        for (j = 0; j < i; j++) {
                /*
                 * Check whether the device exists and is valid.
-                * console_assign() also calls search_device(),
+                * console_assign() also calls console_search_dev(),
                 * but I need the pointer to the device.
                 */
-               dev = search_device(io_flag, start[j]);
+               dev = console_search_dev(io_flag, start[j]);
                if (dev == NULL)
                        continue;
                /*
@@ -127,21 +126,25 @@ int iomux_doenv(const int console, const char *arg)
        if (cs_idx == 0) {
                free(cons_set);
                return 1;
-       } else {
-               /* Works even if console_devices[console] is NULL. */
-               console_devices[console] =
-                       (struct stdio_dev **)realloc(console_devices[console],
-                       cs_idx * sizeof(struct stdio_dev *));
-               if (console_devices[console] == NULL) {
-                       free(cons_set);
-                       return 1;
-               }
-               memcpy(console_devices[console], cons_set, cs_idx *
-                       sizeof(struct stdio_dev *));
+       }
+
+       old_set = console_devices[console];
+       repeat = cd_count[console];
 
-               cd_count[console] = cs_idx;
+       console_devices[console] = cons_set;
+       cd_count[console] = cs_idx;
+
+       /* Stop dropped consoles */
+       for (i = 0; i < repeat; i++) {
+               for (j = 0; j < cs_idx; j++) {
+                       if (old_set[i] == cons_set[j])
+                               break;
+               }
+               if (j == cs_idx)
+                       console_stop(console, old_set[i]);
        }
-       free(cons_set);
+
+       free(old_set);
        return 0;
 }
 #endif /* CONSOLE_MUX */
index ce39918..767f0fe 100644 (file)
@@ -198,9 +198,10 @@ static bool log_passes_filters(struct log_device *ldev, struct log_rec *rec)
  * @rec:       log record to dispatch
  * Return:     0 msg sent, 1 msg not sent while already dispatching another msg
  */
-static int log_dispatch(struct log_rec *rec)
+static int log_dispatch(struct log_rec *rec, const char *fmt, va_list args)
 {
        struct log_device *ldev;
+       char buf[CONFIG_SYS_CBSIZE];
 
        /*
         * When a log driver writes messages (e.g. via the network stack) this
@@ -214,8 +215,13 @@ static int log_dispatch(struct log_rec *rec)
        gd->processing_msg = true;
        list_for_each_entry(ldev, &gd->log_head, sibling_node) {
                if ((ldev->flags & LOGDF_ENABLE) &&
-                   log_passes_filters(ldev, rec))
+                   log_passes_filters(ldev, rec)) {
+                       if (!rec->msg) {
+                               vsnprintf(buf, sizeof(buf), fmt, args);
+                               rec->msg = buf;
+                       }
                        ldev->drv->emit(ldev, rec);
+               }
        }
        gd->processing_msg = false;
        return 0;
@@ -224,10 +230,12 @@ static int log_dispatch(struct log_rec *rec)
 int _log(enum log_category_t cat, enum log_level_t level, const char *file,
         int line, const char *func, const char *fmt, ...)
 {
-       char buf[CONFIG_SYS_CBSIZE];
        struct log_rec rec;
        va_list args;
 
+       if (!gd)
+               return -ENOSYS;
+
        /* Check for message continuation */
        if (cat == LOGC_CONT)
                cat = gd->logc_prev;
@@ -240,19 +248,29 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file,
        rec.file = file;
        rec.line = line;
        rec.func = func;
-       va_start(args, fmt);
-       vsnprintf(buf, sizeof(buf), fmt, args);
-       va_end(args);
-       rec.msg = buf;
-       if (!gd || !(gd->flags & GD_FLG_LOG_READY)) {
-               if (gd)
-                       gd->log_drop_count++;
+       rec.msg = NULL;
+
+       if (!(gd->flags & GD_FLG_LOG_READY)) {
+               gd->log_drop_count++;
+
+               /* display dropped traces with console puts and DEBUG_UART */
+               if (rec.level <= CONFIG_LOG_DEFAULT_LEVEL || rec.force_debug) {
+                       char buf[CONFIG_SYS_CBSIZE];
+
+                       va_start(args, fmt);
+                       vsnprintf(buf, sizeof(buf), fmt, args);
+                       puts(buf);
+                       va_end(args);
+               }
+
                return -ENOSYS;
        }
-       if (!log_dispatch(&rec)) {
+       va_start(args, fmt);
+       if (!log_dispatch(&rec, fmt, args)) {
                gd->logc_prev = cat;
                gd->logl_prev = level;
        }
+       va_end(args);
 
        return 0;
 }
index 6b01867..7561335 100644 (file)
@@ -126,7 +126,7 @@ endmenu
 
 config HANDOFF
        bool "Pass hand-off information from SPL to U-Boot proper"
-       depends on BLOBLIST
+       depends on SPL && BLOBLIST
        help
          It is useful to be able to pass information from SPL to U-Boot
          proper to preserve state that is known in SPL and is needed in U-Boot.
index 795e292..a6ad094 100644 (file)
@@ -684,8 +684,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
 
                ret = spl_load_fit_image(info, sector, fit, base_offset, node,
                                         &image_info);
-               if (ret < 0)
-                       continue;
+               if (ret < 0) {
+                       printf("%s: can't load image loadables index %d (ret = %d)\n",
+                              __func__, index, ret);
+                       return ret;
+               }
 
                if (!spl_fit_image_get_os(fit, node, &os_type))
                        debug("Loadable is %s\n", genimg_get_os_name(os_type));
index a15f308..abf9b1e 100644 (file)
@@ -181,7 +181,7 @@ struct stdio_dev *stdio_get_by_name(const char *name)
                 * 'stdout', which may include a list of devices separate by
                 * commas. Obviously this is not going to work, so we ignore
                 * that case. The call path in that case is
-                * console_init_r() -> search_device() -> stdio_get_by_name()
+                * console_init_r() -> console_search_dev() -> stdio_get_by_name()
                 */
                if (!strncmp(name, "vidconsole", 10) && !strchr(name, ',') &&
                    !stdio_probe_device(name, UCLASS_VIDEO, &sdev))
@@ -332,7 +332,7 @@ int stdio_add_devices(void)
                /*
                 * If the console setting is not in environment variables then
                 * console_init_r() will not be calling iomux_doenv() (which
-                * calls search_device()). So we will not dynamically add
+                * calls console_search_dev()). So we will not dynamically add
                 * devices by calling stdio_probe_device().
                 *
                 * So just probe all video devices now so that whichever one is
index 04f5310..f431925 100644 (file)
@@ -18,6 +18,8 @@
 #include <command.h>
 #include <ide.h>
 #include <memalign.h>
+#include <asm/unaligned.h>
+#include <linux/compiler.h>
 #include "part_dos.h"
 #include <part.h>
 
  * to use large numbers of partitions */
 #define MAX_EXT_PARTS 256
 
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned int le32_to_int(unsigned char *le32)
-{
-    return ((le32[3] << 24) +
-           (le32[2] << 16) +
-           (le32[1] << 8) +
-            le32[0]
-          );
-}
-
 static inline int is_extended(int part_type)
 {
-    return (part_type == 0x5 ||
-           part_type == 0xf ||
-           part_type == 0x85);
+    return (part_type == DOS_PART_TYPE_EXTENDED ||
+           part_type == DOS_PART_TYPE_EXTENDED_LBA ||
+           part_type == DOS_PART_TYPE_EXTENDED_LINUX);
 }
 
 static int get_bootable(dos_partition_t *p)
@@ -61,8 +52,8 @@ static int get_bootable(dos_partition_t *p)
 static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
                           int part_num, unsigned int disksig)
 {
-       lbaint_t lba_start = ext_part_sector + le32_to_int (p->start4);
-       lbaint_t lba_size  = le32_to_int (p->size4);
+       lbaint_t lba_start = ext_part_sector + get_unaligned_le32(p->start4);
+       lbaint_t lba_size  = get_unaligned_le32(p->size4);
 
        printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength
                "u\t%08x-%02x\t%02x%s%s\n",
@@ -171,7 +162,7 @@ static void print_partition_extended(struct blk_desc *dev_desc,
        }
 
        if (!ext_part_sector)
-               disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]);
+               disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
 
        /* Print all primary/logical partitions */
        pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
@@ -198,7 +189,7 @@ static void print_partition_extended(struct blk_desc *dev_desc,
        for (i = 0; i < 4; i++, pt++) {
                if (is_extended (pt->sys_ind)) {
                        lbaint_t lba_start
-                               = le32_to_int (pt->start4) + relative;
+                               = get_unaligned_le32 (pt->start4) + relative;
 
                        print_partition_extended(dev_desc, lba_start,
                                ext_part_sector == 0  ? lba_start : relative,
@@ -244,7 +235,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
 
 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
        if (!ext_part_sector)
-               disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]);
+               disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
 #endif
 
        /* Print all primary/logical partitions */
@@ -260,8 +251,8 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
                    (ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
                        info->blksz = DOS_PART_DEFAULT_SECTOR;
                        info->start = (lbaint_t)(ext_part_sector +
-                                       le32_to_int(pt->start4));
-                       info->size  = (lbaint_t)le32_to_int(pt->size4);
+                                       get_unaligned_le32(pt->start4));
+                       info->size  = (lbaint_t)get_unaligned_le32(pt->size4);
                        part_set_generic_name(dev_desc, part_num,
                                              (char *)info->name);
                        /* sprintf(info->type, "%d, pt->sys_ind); */
@@ -286,7 +277,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
        for (i = 0; i < 4; i++, pt++) {
                if (is_extended (pt->sys_ind)) {
                        lbaint_t lba_start
-                               = le32_to_int (pt->start4) + relative;
+                               = get_unaligned_le32 (pt->start4) + relative;
 
                        return part_get_info_extended(dev_desc, lba_start,
                                 ext_part_sector == 0 ? lba_start : relative,
@@ -312,13 +303,13 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
        return -1;
 }
 
-void part_print_dos(struct blk_desc *dev_desc)
+static void __maybe_unused part_print_dos(struct blk_desc *dev_desc)
 {
        printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n");
        print_partition_extended(dev_desc, 0, 0, 1, 0);
 }
 
-int part_get_info_dos(struct blk_desc *dev_desc, int part,
+static int __maybe_unused part_get_info_dos(struct blk_desc *dev_desc, int part,
                      struct disk_partition *info)
 {
        return part_get_info_extended(dev_desc, 0, 0, 1, part, info, 0);
@@ -329,7 +320,174 @@ int is_valid_dos_buf(void *buf)
        return test_block_type(buf) == DOS_MBR ? 0 : -1;
 }
 
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf)
+#if CONFIG_IS_ENABLED(CMD_MBR)
+static void lba_to_chs(lbaint_t lba, unsigned char *rc, unsigned char *rh,
+                      unsigned char *rs)
+{
+       unsigned int c, h, s;
+       /* use fixed CHS geometry */
+       unsigned int sectpertrack = 63;
+       unsigned int heads = 255;
+
+       c = (lba + 1) / sectpertrack / heads;
+       h = (lba + 1) / sectpertrack - c * heads;
+       s = (lba + 1) - (c * heads + h) * sectpertrack;
+
+       if (c > 1023) {
+               c = 1023;
+               h = 254;
+               s = 63;
+       }
+
+       *rc = c & 0xff;
+       *rh = h;
+       *rs = s + ((c & 0x300) >> 2);
+}
+
+static void mbr_fill_pt_entry(dos_partition_t *pt, lbaint_t start,
+               lbaint_t relative, lbaint_t size, uchar sys_ind, bool bootable)
+{
+       pt->boot_ind = bootable ? 0x80 : 0x00;
+       pt->sys_ind = sys_ind;
+       lba_to_chs(start, &pt->cyl, &pt->head, &pt->sector);
+       lba_to_chs(start + size - 1, &pt->end_cyl, &pt->end_head, &pt->end_sector);
+       put_unaligned_le32(relative, &pt->start4);
+       put_unaligned_le32(size, &pt->size4);
+}
+
+int write_mbr_partitions(struct blk_desc *dev,
+               struct disk_partition *p, int count, unsigned int disksig)
+{
+       ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev->blksz);
+       lbaint_t ext_part_start = 0, ext_part_size = 0, ext_part_sect = 0;
+       dos_partition_t *pt;
+       int i;
+
+       memset(buffer, 0, dev->blksz);
+       buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+       buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+       put_unaligned_le32(disksig, &buffer[DOS_PART_DISKSIG_OFFSET]);
+       pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+       /* create all primary partitions */
+       for (i = 0; i < 4 && i < count; i++, pt++) {
+               mbr_fill_pt_entry(pt, p[i].start, p[i].start, p[i].size,
+                                 p[i].sys_ind, p[i].bootable);
+               if (is_extended(p[i].sys_ind)) {
+                       ext_part_start = p[i].start;
+                       ext_part_size = p[i].size;
+                       ext_part_sect = p[i].start;
+               }
+       }
+
+       if (i < count && !ext_part_start) {
+               printf("%s: extended partition is needed for more than 4 partitions\n",
+                       __func__);
+               return -1;
+       }
+
+       /* write MBR */
+       if (blk_dwrite(dev, 0, 1, buffer) != 1) {
+               printf("%s: failed writing 'MBR' (1 blks at 0x0)\n",
+                      __func__);
+               return -1;
+       }
+
+       /* create extended volumes */
+       for (; i < count; i++) {
+               lbaint_t next_ebr = 0;
+
+               memset(buffer, 0, dev->blksz);
+               buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+               buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+               pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+               mbr_fill_pt_entry(pt, p[i].start, p[i].start - ext_part_sect,
+                                 p[i].size, p[i].sys_ind, p[i].bootable);
+
+               if (i + 1 < count) {
+                       pt++;
+                       next_ebr = p[i].start + p[i].size;
+                       mbr_fill_pt_entry(pt, next_ebr,
+                                         next_ebr - ext_part_start,
+                                         p[i+1].start + p[i+1].size - next_ebr,
+                                         DOS_PART_TYPE_EXTENDED, 0);
+               }
+
+               /* write EBR */
+               if (blk_dwrite(dev, ext_part_sect, 1, buffer) != 1) {
+                       printf("%s: failed writing 'EBR' (1 blks at 0x%lx)\n",
+                              __func__, ext_part_sect);
+                       return -1;
+               }
+               ext_part_sect = next_ebr;
+       }
+
+       return 0;
+}
+
+int layout_mbr_partitions(struct disk_partition *p, int count,
+                         lbaint_t total_sectors)
+{
+       struct disk_partition *ext = NULL;
+       int i, j;
+       lbaint_t ext_vol_start;
+
+       /* calculate primary partitions start and size if needed */
+       if (!p[0].start)
+               p[0].start = DOS_PART_DEFAULT_GAP;
+       for (i = 0; i < 4 && i < count; i++) {
+               if (!p[i].start)
+                       p[i].start = p[i - 1].start + p[i - 1].size;
+               if (!p[i].size) {
+                       lbaint_t end = total_sectors;
+                       lbaint_t allocated = 0;
+
+                       for (j = i + 1; j < 4 && j < count; j++) {
+                               if (p[j].start) {
+                                       end = p[j].start;
+                                       break;
+                               }
+                               allocated += p[j].size;
+                       }
+                       p[i].size = end - allocated - p[i].start;
+               }
+               if (p[i].sys_ind == 0x05)
+                       ext = &p[i];
+       }
+
+       if (i >= 4 && !ext) {
+               printf("%s: extended partition is needed for more than 4 partitions\n",
+                       __func__);
+               return -1;
+       }
+
+       /* calculate extended volumes start and size if needed */
+       ext_vol_start = ext->start;
+       for (i = 4; i < count; i++) {
+               if (!p[i].start)
+                       p[i].start = ext_vol_start + DOS_PART_DEFAULT_GAP;
+               if (!p[i].size) {
+                       lbaint_t end = ext->start + ext->size;
+                       lbaint_t allocated = 0;
+
+                       for (j = i + 1; j < count; j++) {
+                               if (p[j].start) {
+                                       end = p[j].start - DOS_PART_DEFAULT_GAP;
+                                       break;
+                               }
+                               allocated += p[j].size + DOS_PART_DEFAULT_GAP;
+                       }
+                       p[i].size = end - allocated - p[i].start;
+               }
+               ext_vol_start = p[i].start + p[i].size;
+       }
+
+       return 0;
+}
+#endif
+
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf)
 {
        if (is_valid_dos_buf(buf))
                return -1;
index 434b021..5055822 100644 (file)
 #define DOS_PBR_MEDIA_TYPE_OFFSET      0x15
 #define DOS_MBR        0
 #define DOS_PBR        1
+#define DOS_PART_TYPE_EXTENDED         0x05
+#define DOS_PART_TYPE_EXTENDED_LBA     0x0F
+#define DOS_PART_TYPE_EXTENDED_LINUX   0x85
+
+#define DOS_PART_DEFAULT_GAP           2048
 
 typedef struct dos_partition {
        unsigned char boot_ind;         /* 0x80 - active                        */
index 60b1c1d..2f92266 100644 (file)
@@ -247,10 +247,11 @@ void part_print_efi(struct blk_desc *dev_desc)
                uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
                uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
                printf("\ttype:\t%s\n", uuid);
-#ifdef CONFIG_PARTITION_TYPE_GUID
-               if (!uuid_guid_get_str(uuid_bin, uuid))
-                       printf("\ttype:\t%s\n", uuid);
-#endif
+               if (CONFIG_IS_ENABLED(PARTITION_TYPE_GUID)) {
+                       const char *type = uuid_guid_get_str(uuid_bin);
+                       if (type)
+                               printf("\ttype:\t%s\n", type);
+               }
                uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
                uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
                printf("\tguid:\t%s\n", uuid);
index facd7af..ac975f6 100644 (file)
@@ -251,22 +251,24 @@ can specify a other partition type guid:
        type=0FC63DAF-8483-4772-8E79-3D69D8477DE4;"
 
 Some strings can be also used at the place of known GUID :
-       "system" = PARTITION_SYSTEM_GUID
-                  (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
-       "mbr"    = LEGACY_MBR_PARTITION_GUID
-                  (024DEE41-33E7-11D3-9D69-0008C781F39F)
-       "msft"   = PARTITION_MSFT_RESERVED_GUID
-                  (E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
-       "data"   = PARTITION_BASIC_DATA_GUID
-                   (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
-       "linux"  = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID
-                  (0FC63DAF-8483-4772-8E79-3D69D8477DE4)
-       "raid"   = PARTITION_LINUX_RAID_GUID
-                  (A19D880F-05FC-4D3B-A006-743F0F84911E)
-       "swap"   = PARTITION_LINUX_SWAP_GUID
-                  (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
-       "lvm"    = PARTITION_LINUX_LVM_GUID
-                  (E6D6D379-F507-44C2-A23C-238F2A3DF928)
+       "system"          = PARTITION_SYSTEM_GUID
+                           (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
+       "mbr"             = LEGACY_MBR_PARTITION_GUID
+                           (024DEE41-33E7-11D3-9D69-0008C781F39F)
+       "msft"            = PARTITION_MSFT_RESERVED_GUID
+                           (E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
+       "data"            = PARTITION_BASIC_DATA_GUID
+                            (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
+       "linux"           = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID
+                           (0FC63DAF-8483-4772-8E79-3D69D8477DE4)
+       "raid"            = PARTITION_LINUX_RAID_GUID
+                           (A19D880F-05FC-4D3B-A006-743F0F84911E)
+       "swap"            = PARTITION_LINUX_SWAP_GUID
+                           (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
+       "lvm"             = PARTITION_LINUX_LVM_GUID
+                           (E6D6D379-F507-44C2-A23C-238F2A3DF928)
+       "u-boot-env"      = PARTITION_U_BOOT_ENVIRONMENT
+                           (3DE21764-95BD-54BD-A5C3-4ABE786F38A8)
 
     "uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
        name=kernel,size=60MiB,uuid=...,type=linux;"
index ada0df0..6def250 100644 (file)
@@ -17,4 +17,5 @@ Shell commands
    bootefi
    bootmenu
    button
+   mbr
    pstore
diff --git a/doc/usage/mbr.rst b/doc/usage/mbr.rst
new file mode 100644 (file)
index 0000000..bddf2f6
--- /dev/null
@@ -0,0 +1,94 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+mbr command
+===========
+
+Synopsis
+--------
+
+::
+
+    mbr verify [interface] [device no] [partition list]
+    mbr write [interface] [device no] [partition list]
+
+Description
+-----------
+
+The mbr command lets users create or verify the MBR (Master Boot Record)
+partition layout based on the provided text description. The partition
+layout is alternatively read from the 'mbr_parts' environment variable.
+This can be used in scripts to help system image flashing tools to ensure
+proper partition layout.
+
+The syntax of the text description of the partition list is similar to
+the one used by the 'gpt' command.
+
+Supported partition parameters are:
+
+* name (currently ignored)
+* start (partition start offset in bytes)
+* size (in bytes or '-' to expand it to the whole free area)
+* bootable (boolean flag)
+* id (MBR partition type)
+
+If one wants to create more than 4 partitions, an 'Extended' primary
+partition (with 0x05 ID) has to be explicitly provided as a one of the
+first 4 entries.
+
+Here is an example how to create a 6 partitions (3 on the 'extended
+volume'), some of the predefined sizes:
+
+::
+
+    => setenv mbr_parts 'name=boot,start=4M,size=128M,bootable,id=0x0e;
+        name=rootfs,size=3072M,id=0x83;
+        name=system-data,size=512M,id=0x83;
+        name=[ext],size=-,id=0x05;
+        name=user,size=-,id=0x83;
+        name=modules,size=100M,id=0x83;
+        name=ramdisk,size=8M,id=0x83'
+    => mbr write mmc 0
+
+To check if the layout on the MMC #0 storage device matches the provided
+text description one has to issue following command (assuming that
+mbr_parts environment variable is set):
+
+::
+
+    => mbr verify mmc 0
+
+The verify sub-command is especially useful in the system update scripts:
+
+::
+
+    => if mbr verify mmc 0; then
+         echo MBR layout needs to be updated
+         ...
+       fi
+
+The 'mbr write' command returns 0 on success write or 1 on failure.
+
+The 'mbr verify' returns 0 if the layout matches the one on the storage
+device or 1 if not.
+
+Configuration
+-------------
+
+To use the mbr command you must specify CONFIG_CMD_MBR=y.
+
+Return value
+------------
+
+The variable *$?* takes the following values
+
++---+------------------------------+
+| 0 | mbr write was succesful      |
++---+------------------------------+
+| 1 | mbr write failed             |
++---+------------------------------+
+| 0 | mbr verify was succesful     |
++---+------------------------------+
+| 1 | mbr verify was not succesful |
++---+------------------------------+
+|-1 | invalid arguments            |
++---+------------------------------+
index cdb975d..f38122d 100644 (file)
@@ -757,6 +757,25 @@ int uclass_pre_remove_device(struct udevice *dev)
 }
 #endif
 
+int uclass_probe_all(enum uclass_id id)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = uclass_first_device(id, &dev);
+       if (ret || !dev)
+               return ret;
+
+       /* Scanning uclass to probe all devices */
+       while (dev) {
+               ret = uclass_next_device(&dev);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 UCLASS_DRIVER(nop) = {
        .id             = UCLASS_NOP,
        .name           = "nop",
index ae8e8e5..4e26cef 100644 (file)
@@ -508,7 +508,7 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
                        fastboot_fail("invalid MBR partition", response);
                        return;
                }
-               if (write_mbr_partition(dev_desc, download_buffer)) {
+               if (write_mbr_sector(dev_desc, download_buffer)) {
                        printf("%s: writing MBR partition failed\n", __func__);
                        fastboot_fail("writing MBR partition failed",
                                      response);
index 1a4dec3..0d1f94c 100644 (file)
@@ -9,8 +9,6 @@
  */
 
 #ifndef __UBOOT__
-#include <log.h>
-#include <dm/devres.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
index ba97a54..59a32c4 100644 (file)
@@ -105,7 +105,7 @@ int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
                          sizeof(bb_miiphy_buses[0]);
 #endif
 
-void bb_miiphy_init(void)
+int bb_miiphy_init(void)
 {
        int i;
 
@@ -124,6 +124,8 @@ void bb_miiphy_init(void)
                        bb_miiphy_buses[i].init(&bb_miiphy_buses[i]);
                }
        }
+
+       return 0;
 }
 
 static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
index 4cdd06b..ba65f47 100644 (file)
@@ -1842,7 +1842,7 @@ U_BOOT_DRIVER(pci_generic_drv) = {
        .of_match       = pci_generic_ids,
 };
 
-void pci_init(void)
+int pci_init(void)
 {
        struct udevice *bus;
 
@@ -1855,4 +1855,6 @@ void pci_init(void)
             uclass_next_device_check(&bus)) {
                ;
        }
+
+       return 0;
 }
index 664e837..a7453e5 100644 (file)
@@ -454,16 +454,18 @@ int pci_hose_scan(struct pci_controller *hose)
        return pci_hose_scan_bus(hose, hose->current_busno);
 }
 
-void pci_init(void)
+int pci_init(void)
 {
        hose_head = NULL;
 
        /* allow env to disable pci init/enum */
        if (env_get("pcidisable") != NULL)
-               return;
+               return 0;
 
        /* now call board specific pci_init()... */
        pci_init_board();
+
+       return 0;
 }
 
 /* Returns the address of the requested capability structure within the
index 38a5f08..aa89701 100644 (file)
@@ -210,7 +210,7 @@ UCLASS_DRIVER(pci_ep) = {
        .flags          = DM_UC_FLAG_SEQ_ALIAS,
 };
 
-void pci_ep_init(void)
+int pci_ep_init(void)
 {
        struct udevice *dev;
 
@@ -219,4 +219,6 @@ void pci_ep_init(void)
             uclass_next_device_check(&dev)) {
                ;
        }
+
+       return 0;
 }
index d431102..fbbea18 100644 (file)
@@ -18,7 +18,7 @@ config DM_REGULATOR
 
 config SPL_DM_REGULATOR
        bool "Enable regulators for SPL"
-       depends on DM_REGULATOR
+       depends on DM_REGULATOR && SPL_POWER_SUPPORT
        ---help---
        Regulators are seldom needed in SPL. Even if they are accessed, some
        code space can be saved by accessing the PMIC registers directly.
index fc80fb1..68043d7 100644 (file)
@@ -719,7 +719,7 @@ uint32_t lpddr4_checkctlinterrupt(const lpddr4_privatedata * pd,
 
                /* MISRA compliance (Shifting operation) check */
                if (fieldshift < WORD_SHIFT) {
-                       if (((ctlirqstatus >> fieldshift) & BIT_MASK) > 0U) {
+                       if ((ctlirqstatus >> fieldshift) & LPDDR4_BIT_MASK) {
                                *irqstatus = true;
                        } else {
                                *irqstatus = false;
@@ -746,11 +746,11 @@ uint32_t lpddr4_ackctlinterrupt(const lpddr4_privatedata * pd,
                if (localinterrupt > WORD_SHIFT) {
                        localinterrupt =
                            (localinterrupt - (uint32_t) WORD_SHIFT);
-                       regval = ((uint32_t) BIT_MASK << localinterrupt);
+                       regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
                        CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG),
                                      regval);
                } else {
-                       regval = ((uint32_t) BIT_MASK << localinterrupt);
+                       regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
                        CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG),
                                      regval);
                }
@@ -823,7 +823,7 @@ uint32_t lpddr4_checkphyindepinterrupt(const lpddr4_privatedata * pd,
                phyindepirqstatus =
                    CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG));
                *irqstatus =
-                   (((phyindepirqstatus >> (uint32_t) intr) & BIT_MASK) > 0U);
+                   !!((phyindepirqstatus >> (uint32_t)intr) & LPDDR4_BIT_MASK);
        }
        return result;
 }
@@ -841,7 +841,7 @@ uint32_t lpddr4_ackphyindepinterrupt(const lpddr4_privatedata * pd,
                lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
 
                /* Write 1 to the requested bit to ACk the interrupt */
-               regval = ((uint32_t) BIT_MASK << ui32shiftinterrupt);
+               regval = (uint32_t)LPDDR4_BIT_MASK << ui32shiftinterrupt;
                CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval);
        }
 
@@ -894,7 +894,7 @@ static void lpddr4_checkwrlvlerror(lpddr4_ctlregs * ctlregbase,
            (volatile uint32_t
             *)(&(ctlregbase->LPDDR4__PHY_WRLVL_ERROR_OBS_0__REG));
        /* PHY_WRLVL_ERROR_OBS_X[1:0] should be zero */
-       errbitmask = (BIT_MASK << 1) | (BIT_MASK);
+       errbitmask = (LPDDR4_BIT_MASK << 1) | LPDDR4_BIT_MASK;
        for (snum = 0U; snum < DSLICE_NUM; snum++) {
                regval = CPS_REG_READ(regaddress);
                if ((regval & errbitmask) != 0U) {
@@ -1054,7 +1054,7 @@ static void lpddr4_seterrors(lpddr4_ctlregs * ctlregbase,
                             lpddr4_debuginfo * debuginfo, bool * errfoundptr)
 {
 
-       uint32_t errbitmask = (BIT_MASK << 0x1U) | (BIT_MASK);
+       uint32_t errbitmask = (LPDDR4_BIT_MASK << 0x1U) | LPDDR4_BIT_MASK;
        /* Check PLL observation registers for PLL lock errors */
 
        debuginfo->pllerror =
index 42c9234..3d5017e 100644 (file)
@@ -14,9 +14,9 @@
 #define VERSION_0  (0x54d5da40U)
 #define VERSION_1  (0xc1865a1U)
 
-#define BIT_MASK    (0x1U)
-#define BYTE_MASK   (0xffU)
-#define NIBBLE_MASK (0xfU)
+#define LPDDR4_BIT_MASK        (0x1U)
+#define BYTE_MASK      (0xffU)
+#define NIBBLE_MASK    (0xfU)
 
 #define WORD_SHIFT (32U)
 #define WORD_MASK (0xffffffffU)
 #define IO_CALIB_DONE ((uint32_t)0x1U << 23U)
 #define IO_CALIB_FIELD ((uint32_t)NIBBLE_MASK << 28U)
 #define IO_CALIB_STATE ((uint32_t)0xBU << 28U)
-#define RX_CAL_DONE ((uint32_t)BIT_MASK << 4U)
-#define CA_TRAIN_RL (((uint32_t)BIT_MASK << 5U) | ((uint32_t)BIT_MASK << 4U))
+#define RX_CAL_DONE ((uint32_t)LPDDR4_BIT_MASK << 4U)
+#define CA_TRAIN_RL (((uint32_t)LPDDR4_BIT_MASK << 5U) | \
+                    ((uint32_t)LPDDR4_BIT_MASK << 4U))
 #define WR_LVL_STATE (((uint32_t)NIBBLE_MASK) << 13U)
-#define GATE_LVL_ERROR_FIELDS (((uint32_t)BIT_MASK << 7U) | ((uint32_t)BIT_MASK << 6U))
-#define READ_LVL_ERROR_FIELDS ((((uint32_t)NIBBLE_MASK) << 28U) | (((uint32_t)BYTE_MASK) << 16U))
-#define DQ_LVL_STATUS (((uint32_t)BIT_MASK << 26U) | (((uint32_t)BYTE_MASK) << 18U))
+#define GATE_LVL_ERROR_FIELDS (((uint32_t)LPDDR4_BIT_MASK << 7U) | \
+                              ((uint32_t)LPDDR4_BIT_MASK << 6U))
+#define READ_LVL_ERROR_FIELDS ((((uint32_t)NIBBLE_MASK) << 28U) | \
+                              (((uint32_t)BYTE_MASK) << 16U))
+#define DQ_LVL_STATUS (((uint32_t)LPDDR4_BIT_MASK << 26U) | \
+                      (((uint32_t)BYTE_MASK) << 18U))
 
 #endif  /* LPDDR4_PRIV_H */
index b4805a2..1294943 100644 (file)
@@ -134,6 +134,22 @@ config SERIAL_SEARCH_ALL
 
          If unsure, say N.
 
+config SERIAL_PROBE_ALL
+       bool "Probe all available serial devices"
+       depends on DM_SERIAL
+       default n
+       help
+         The serial subsystem only probes for a single serial device,
+         but does not probe for other remaining serial devices.
+         With this option set, we make probing and searching for
+         all available devices optional.
+         Normally, U-Boot talks to one serial port at a time, but SBSA
+         compliant UART devices like PL011 require initialization
+         by firmware and to let the kernel use serial port for sending
+         and receiving the characters.
+
+         If unsure, say N.
+
 config SPL_DM_SERIAL
        bool "Enable Driver Model for serial drivers in SPL"
        depends on DM_SERIAL && SPL_DM
index 58a6541..ead0193 100644 (file)
@@ -172,6 +172,15 @@ int serial_init(void)
 /* Called after relocation */
 int serial_initialize(void)
 {
+       /* Scanning uclass to probe devices */
+       if (IS_ENABLED(CONFIG_SERIAL_PROBE_ALL)) {
+               int ret;
+
+               ret  = uclass_probe_all(UCLASS_SERIAL);
+               if (ret)
+                       return ret;
+       }
+
        return serial_init();
 }
 
index d39d9b2..d782eb8 100644 (file)
@@ -199,7 +199,7 @@ config PANEL
 
 config SIMPLE_PANEL
        bool "Enable simple panel support"
-       depends on PANEL
+       depends on PANEL && BACKLIGHT
        default y
        help
          This turns on a simple panel driver that enables a compatible
index 178c206..2560894 100644 (file)
@@ -232,7 +232,7 @@ void clear_evtchn(uint32_t port)
        synch_clear_bit(port, &s->evtchn_pending[0]);
 }
 
-void xen_init(void)
+int xen_init(void)
 {
        debug("%s\n", __func__);
 
@@ -240,6 +240,8 @@ void xen_init(void)
        init_events();
        init_xenbus();
        init_gnttab();
+
+       return 0;
 }
 
 void xen_fini(void)
index 94967cf..cb31113 100644 (file)
@@ -33,7 +33,7 @@ targets += dt.dtb
 $(DTB): arch-dtbs
        $(Q)test -e $@ || (                                             \
        echo >&2;                                                       \
-       echo >&2 "Device Tree Source is not correctly specified.";      \
+       echo >&2 "Device Tree Source ($@) is not correctly specified."; \
        echo >&2 "Please define 'CONFIG_DEFAULT_DEVICE_TREE'";          \
        echo >&2 "or build with 'DEVICE_TREE=<device_tree>' argument";  \
        echo >&2;                                                       \
index 84d81dc..83412a7 100644 (file)
@@ -7,6 +7,14 @@
 #ifndef __API_H
 #define __API_H
 
-void api_init(void);
+/**
+ * api_init() - Initialize API for external applications
+ *
+ * Initialize API for external (standalone) applications running on top of
+ * U-Boot. It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int api_init(void);
 
 #endif
index efa09a1..19f7039 100644 (file)
@@ -412,12 +412,12 @@ struct global_data {
         * @new_bloblist: relocated blob list information
         */
        struct bloblist_hdr *new_bloblist;
-# ifdef CONFIG_SPL
+#endif
+#if CONFIG_IS_ENABLED(HANDOFF)
        /**
         * @spl_handoff: SPL hand-off information
         */
        struct spl_handoff *spl_handoff;
-# endif
 #endif
 #if defined(CONFIG_TRANSLATION_OFFSET)
        /**
index 432f892..7e628c0 100644 (file)
@@ -8,6 +8,7 @@
 #define __CONSOLE_H
 
 #include <stdbool.h>
+#include <stdio_dev.h>
 #include <linux/errno.h>
 
 extern char console_buffer[];
@@ -15,6 +16,8 @@ extern char console_buffer[];
 /* common/console.c */
 int console_init_f(void);      /* Before relocation; uses the serial  stuff */
 int console_init_r(void);      /* After  relocation; uses the console stuff */
+int console_start(int file, struct stdio_dev *sdev);   /* Start a console device */
+void console_stop(int file, struct stdio_dev *sdev);   /* Stop a console device */
 int console_assign(int file, const char *devname);     /* Assign the console */
 int ctrlc(void);
 int had_ctrlc(void);   /* have we had a Control-C since last clear? */
@@ -22,6 +25,18 @@ void clear_ctrlc(void);      /* clear the Control-C condition */
 int disable_ctrlc(int);        /* 1 to disable, 0 to enable Control-C detect */
 int confirm_yesno(void);        /*  1 if input is "y", "Y", "yes" or "YES" */
 
+/**
+ * console_search_dev() - search for stdio device with given flags and name
+ * @flags: device flags as per input/output/system
+ * @name: device name
+ *
+ * Iterates over registered STDIO devices and match them with given @flags
+ * and @name.
+ *
+ * @return pointer to the &struct stdio_dev if found, or NULL otherwise
+ */
+struct stdio_dev *console_search_dev(int flags, const char *name);
+
 #ifdef CONFIG_CONSOLE_RECORD
 /**
  * console_record_init() - set up the console recording buffers
index b5f066d..d956837 100644 (file)
@@ -377,6 +377,17 @@ int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
                                struct udevice **devp);
 
 /**
+ * uclass_probe_all() - Probe all devices based on an uclass ID
+ *
+ * This function probes all devices associated with a uclass by
+ * looking for its ID.
+ *
+ * @id: uclass ID to look up
+ * @return 0 if OK, other -ve on error
+ */
+int uclass_probe_all(enum uclass_id id);
+
+/**
  * uclass_id_foreach_dev() - Helper function to iteration through devices
  *
  * This creates a for() loop which works through the available devices in
index b300554..faf0f59 100644 (file)
 struct cmd_tbl;
 struct spi_slave;
 
-/* Set up the jump table for use by the API */
-void jumptable_init(void);
+/**
+ * jumptable_init() - Set up the jump table for use by the API
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int jumptable_init(void);
 
 /* These are declarations of exported functions available in C code */
 unsigned long get_version(void);
index 0f48ccb..980be27 100644 (file)
@@ -164,6 +164,41 @@ int arch_setup_bdinfo(void);
 int setup_bdinfo(void);
 
 /**
+ * cpu_secondary_init_r() - CPU-specific secondary initialization
+ *
+ * After non-volatile devices, environment and cpu code are setup, have
+ * another round to deal with any initialization that might require
+ * full access to the environment or loading of some image (firmware)
+ * from a non-volatile device.
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int cpu_secondary_init_r(void);
+
+/**
+ * pci_ep_init() - Initialize pci endpoint devices
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int pci_ep_init(void);
+
+/**
+ * pci_init() - Enumerate pci devices
+ *
+ * It is called during the generic post-relocation init sequence to enumerate
+ * pci buses. This is needed, for instance, in the case of DM PCI-based
+ * Ethernet devices, which will not be detected without having the enumeration
+ * performed earlier.
+ *
+ * Return: 0 if OK
+ */
+int pci_init(void);
+
+/**
  * init_cache_f_r() - Turn on the cache in preparation for relocation
  *
  * Return: 0 if OK, -ve on error
@@ -234,8 +269,6 @@ int mac_read_from_eeprom(void);
 int set_cpu_clk_info(void);
 int update_flash_size(int flash_size);
 int arch_early_init_r(void);
-void pci_init(void);
-void pci_ep_init(void);
 int misc_init_r(void);
 #if defined(CONFIG_VID)
 int init_func_vid(void);
@@ -267,7 +300,15 @@ int board_early_init_r(void);
 /* TODO(sjg@chromium.org): Drop this when DM_PCI migration is completed */
 void pci_init_board(void);
 
-void trap_init(unsigned long reloc_addr);
+/**
+ * arch_initr_trap() - Init traps
+ *
+ * Arch specific routine for initializing traps. It is called during the
+ * generic board init sequence, after relocation.
+ *
+ * Return: 0 if OK
+ */
+int arch_initr_trap(void);
 
 /**
  * main_loop() - Enter the main loop of U-Boot
index e6e1097..da7ff69 100644 (file)
@@ -26,6 +26,5 @@ extern int cd_count[MAX_FILES];
 
 int iomux_doenv(const int, const char *);
 void iomux_printdevs(const int);
-struct stdio_dev *search_device(int, const char *);
 
 #endif /* _IO_MUX_H */
index 6bce560..2d27f9f 100644 (file)
@@ -156,6 +156,9 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level,
  */
 #if CONFIG_IS_ENABLED(LOG)
 #define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL)
+#define log_emer(_fmt...)      log(LOG_CATEGORY, LOGL_EMERG, ##_fmt)
+#define log_alert(_fmt...)     log(LOG_CATEGORY, LOGL_ALERT, ##_fmt)
+#define log_crit(_fmt...)      log(LOG_CATEGORY, LOGL_CRIT, ##_fmt)
 #define log_err(_fmt...)       log(LOG_CATEGORY, LOGL_ERR, ##_fmt)
 #define log_warning(_fmt...)   log(LOG_CATEGORY, LOGL_WARNING, ##_fmt)
 #define log_notice(_fmt...)    log(LOG_CATEGORY, LOGL_NOTICE, ##_fmt)
@@ -163,12 +166,17 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level,
 #define log_debug(_fmt...)     log(LOG_CATEGORY, LOGL_DEBUG, ##_fmt)
 #define log_content(_fmt...)   log(LOG_CATEGORY, LOGL_DEBUG_CONTENT, ##_fmt)
 #define log_io(_fmt...)                log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt)
+#define log_cont(_fmt...)      log(LOGC_CONT, LOGL_CONT, ##_fmt)
 #else
 #define _LOG_MAX_LEVEL LOGL_INFO
+#define log_emerg(_fmt, ...)   printf(_fmt, ##__VA_ARGS__)
+#define log_alert(_fmt, ...)   printf(_fmt, ##__VA_ARGS__)
+#define log_crit(_fmt, ...)    printf(_fmt, ##__VA_ARGS__)
 #define log_err(_fmt, ...)     printf(_fmt, ##__VA_ARGS__)
 #define log_warning(_fmt, ...) printf(_fmt, ##__VA_ARGS__)
 #define log_notice(_fmt, ...)  printf(_fmt, ##__VA_ARGS__)
 #define log_info(_fmt, ...)    printf(_fmt, ##__VA_ARGS__)
+#define log_cont(_fmt, ...)    printf(_fmt, ##__VA_ARGS__)
 #define log_debug(_fmt, ...)   debug(_fmt, ##__VA_ARGS__)
 #define log_content(_fmt...)   log_nop(LOG_CATEGORY, \
                                        LOGL_DEBUG_CONTENT, ##_fmt)
@@ -217,10 +225,9 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level,
 #if !_DEBUG && CONFIG_IS_ENABLED(LOG)
 
 #define debug_cond(cond, fmt, args...)                 \
-       do {                                            \
-               if (1)                                  \
-                       log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
-       } while (0)
+({                                                     \
+       log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args);     \
+})
 
 #else /* _DEBUG */
 
@@ -229,11 +236,11 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level,
  * computed by a preprocessor in the best case, allowing for the best
  * optimization.
  */
-#define debug_cond(cond, fmt, args...)                 \
-       do {                                            \
-               if (cond)                               \
-                       printf(pr_fmt(fmt), ##args);    \
-       } while (0)
+#define debug_cond(cond, fmt, args...)         \
+({                                             \
+       if (cond)                               \
+               printf(pr_fmt(fmt), ##args);    \
+})
 
 #endif /* _DEBUG */
 
index 61c136b..8b77bac 100644 (file)
@@ -81,7 +81,15 @@ struct bb_miiphy_bus {
 extern struct bb_miiphy_bus bb_miiphy_buses[];
 extern int bb_miiphy_buses_num;
 
-void bb_miiphy_init(void);
+/**
+ * bb_miiphy_init() - Initialize bit-banged MII bus driver
+ *
+ * It is called during the generic post-relocation init sequence.
+ *
+ * Return: 0 if OK
+ */
+int bb_miiphy_init(void);
+
 int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg);
 int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
                    u16 value);
index 55be724..815515a 100644 (file)
@@ -9,6 +9,7 @@
 #include <blk.h>
 #include <ide.h>
 #include <uuid.h>
+#include <linker_lists.h>
 #include <linux/list.h>
 
 struct block_drvr {
@@ -465,16 +466,49 @@ int get_disk_guid(struct blk_desc *dev_desc, char *guid);
 int is_valid_dos_buf(void *buf);
 
 /**
- * write_mbr_partition() - write DOS MBR
+ * write_mbr_sector() - write DOS MBR
  *
  * @param dev_desc - block device descriptor
  * @param buf - buffer which contains the MBR
  *
  * @return - '0' on success, otherwise error
  */
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf);
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf);
+
+int write_mbr_partitions(struct blk_desc *dev,
+               struct disk_partition *p, int count, unsigned int disksig);
+int layout_mbr_partitions(struct disk_partition *p, int count,
+                         lbaint_t total_sectors);
 
 #endif
 
+#ifdef CONFIG_PARTITIONS
+/**
+ * part_driver_get_count() - get partition driver count
+ *
+ * @return - number of partition drivers
+ */
+static inline int part_driver_get_count(void)
+{
+       return ll_entry_count(struct part_driver, part_driver);
+}
+
+/**
+ * part_driver_get_first() - get first partition driver
+ *
+ * @return - pointer to first partition driver on success, otherwise NULL
+ */
+static inline struct part_driver *part_driver_get_first(void)
+{
+       return ll_entry_start(struct part_driver, part_driver);
+}
+
+#else
+static inline int part_driver_get_count(void)
+{ return 0; }
+
+static inline struct part_driver *part_driver_get_first(void)
+{ return NULL; }
+#endif /* CONFIG_PARTITIONS */
 
 #endif /* _PART_H */
index 1929e44..c68529b 100644 (file)
@@ -56,6 +56,9 @@
 #define PARTITION_LINUX_LVM_GUID \
        EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
                0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
+#define PARTITION_U_BOOT_ENVIRONMENT \
+       EFI_GUID( 0x3de21764, 0x95bd, 0x54bd, \
+               0xa5, 0xc3, 0x4a, 0xbe, 0x78, 0x6f, 0x38, 0xa8)
 
 /* linux/include/efi.h */
 typedef u16 efi_char16_t;
index eb218ac..5695e2b 100644 (file)
@@ -107,7 +107,6 @@ int post_init_f (void);
 void post_bootmode_init (void);
 int post_bootmode_get (unsigned int * last_test);
 void post_bootmode_clear (void);
-void post_output_backlog ( void );
 int post_run (char *name, int flags);
 int post_info (char *name);
 int post_log (char *format, ...);
@@ -116,6 +115,16 @@ void post_reloc (void);
 #endif
 unsigned long post_time_ms (unsigned long base);
 
+/**
+ * post_output_backlog() - Print POST results
+ *
+ * Print POST results during the generic board init sequence, after
+ * relocation.
+ *
+ * Return: 0 if OK
+ */
+int post_output_backlog(void);
+
 extern struct post_test post_list[];
 extern unsigned int post_list_size;
 extern int post_hotkeys_pressed(void);
index 3f2ee75..17400c7 100644 (file)
@@ -338,4 +338,22 @@ ulong ut_check_free(void);
  */
 long ut_check_delta(ulong last);
 
+/**
+ * ut_silence_console() - Silence the console if requested by the user
+ *
+ * This stops test output from appear on the console. It is the default on
+ * sandbox, unless the -v flag is given. For other boards, this does nothing.
+ *
+ * @uts: Test state (in case in future we want to keep state here)
+ */
+void ut_silence_console(struct unit_test_state *uts);
+
+/**
+ * ut_unsilence_console() - Unsilence the console after a test
+ *
+ * This restarts console output again and turns off console recording. This
+ * happens on all boards, including sandbox.
+ */
+void ut_unsilence_console(struct unit_test_state *uts);
+
 #endif
index 73c5a89..0c653cb 100644 (file)
@@ -39,10 +39,8 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
                    int str_format);
 void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str,
                     int str_format);
-#ifdef CONFIG_PARTITION_TYPE_GUID
 int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin);
-int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str);
-#endif
+const char *uuid_guid_get_str(const unsigned char *guid_bin);
 void gen_rand_uuid(unsigned char *uuid_bin);
 void gen_rand_uuid_str(char *uuid_str, int str_format);
 #endif
index a952a2c..8681321 100644 (file)
@@ -11,7 +11,7 @@
  * Map Xen memory pages, initialize event handler and xenbus,
  * setup the grant table.
  */
-void xen_init(void);
+int xen_init(void);
 
 /**
  * xen_fini() - Board cleanup before Linux kernel start
index a704568..88c43a3 100644 (file)
@@ -695,8 +695,8 @@ config LIB_DATE
 config LIB_ELF
        bool
        help
-         Supoort basic elf loading/validating functions.
-         This supports fir 32 bit and 64 bit versions.
+         Support basic elf loading/validating functions.
+         This supports for 32 bit and 64 bit versions.
 
 endmenu
 
index c998aec..05ec235 100644 (file)
--- a/lib/aes.c
+++ b/lib/aes.c
@@ -619,7 +619,7 @@ void aes_decrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out)
 static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
 {
 #ifdef DEBUG
-       printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
+       printf("%s [%d] @0x%p", name, num_bytes, data);
        print_buffer(0, data, 1, num_bytes, 16);
 #endif
 }
index ae7835f..73b9841 100644 (file)
@@ -567,7 +567,19 @@ void * memmove(void * dest,const void *src,size_t count)
 {
        char *tmp, *s;
 
-       if (dest <= src) {
+       if (dest <= src || (src + count) <= dest) {
+       /*
+        * Use the fast memcpy implementation (ARCH optimized or lib/string.c) when it is possible:
+        * - when dest is before src (assuming that memcpy is doing forward-copying)
+        * - when destination don't overlap the source buffer (src + count <= dest)
+        *
+        * WARNING: the first optimisation cause an issue, when __HAVE_ARCH_MEMCPY is defined,
+        *          __HAVE_ARCH_MEMMOVE is not defined and if the memcpy ARCH-specific
+        *          implementation is not doing a forward-copying.
+        *
+        * No issue today because memcpy is doing a forward-copying in lib/string.c and for ARM32
+        * architecture; no other arches use __HAVE_ARCH_MEMCPY without __HAVE_ARCH_MEMMOVE.
+        */
                memcpy(dest, src, count);
        } else {
                tmp = (char *) dest + count;
index e62d5ca..54a93aa 100644 (file)
@@ -96,7 +96,8 @@ static const struct {
        {"linux",       PARTITION_LINUX_FILE_SYSTEM_DATA_GUID},
        {"raid",        PARTITION_LINUX_RAID_GUID},
        {"swap",        PARTITION_LINUX_SWAP_GUID},
-       {"lvm",         PARTITION_LINUX_LVM_GUID}
+       {"lvm",         PARTITION_LINUX_LVM_GUID},
+       {"u-boot-env",  PARTITION_U_BOOT_ENVIRONMENT},
 };
 
 /*
@@ -122,20 +123,19 @@ int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin)
  * uuid_guid_get_str() - this function get string for GUID.
  *
  * @param guid_bin - pointer to string with partition type guid [16B]
- * @param guid_str - pointer to allocated partition type string [7B]
+ *
+ * Returns NULL if the type GUID is not known.
  */
-int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str)
+const char *uuid_guid_get_str(const unsigned char *guid_bin)
 {
        int i;
 
-       *guid_str = 0;
        for (i = 0; i < ARRAY_SIZE(list_guid); i++) {
                if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) {
-                       strcpy(guid_str, list_guid[i].string);
-                       return 0;
+                       return list_guid[i].string;
                }
        }
-       return -ENODEV;
+       return NULL;
 }
 #endif
 
index 1fe58d5..6347335 100644 (file)
@@ -1284,7 +1284,7 @@ local void check_match(s, start, match, length)
     }
     if (z_verbose > 1) {
         fprintf(stderr,"\\[%d,%d]", start-match, length);
-        do { putc(s->window[start++], stderr); } while (--length != 0);
+       do { putc(s->window[start++]); } while (--length != 0);
     }
 }
 #else
index 3e09517..700c62f 100644 (file)
@@ -38,7 +38,7 @@
 #include "deflate.h"
 
 #ifdef DEBUG
-#  include <ctype.h>
+#  include <linux/ctype.h>
 #endif
 
 /* ===========================================================================
index 0f1fe8d..7d6a647 100644 (file)
@@ -128,7 +128,7 @@ static void post_log_mark_succ(unsigned long testid)
 }
 
 /* ... and the messages are output once we are relocated */
-void post_output_backlog(void)
+int post_output_backlog(void)
 {
        int j;
 
@@ -143,6 +143,8 @@ void post_output_backlog(void)
                        }
                }
        }
+
+       return 0;
 }
 
 static void post_bootmode_test_on(unsigned int last_test)
index d4323f9..3c7bc8b 100644 (file)
@@ -2,7 +2,7 @@
 #
 # (C) Copyright 2012 The Chromium Authors
 
-ifneq ($(CONFIG_SANDBOX),)
+ifneq ($(CONFIG_$(SPL_)BLOBLIST),)
 obj-$(CONFIG_$(SPL_)CMDLINE) += bloblist.o
 endif
 obj-$(CONFIG_$(SPL_)CMDLINE) += bootm.o
index 0bb9e2d..900299d 100644 (file)
@@ -7,7 +7,6 @@
 #include <bloblist.h>
 #include <log.h>
 #include <mapmem.h>
-#include <asm/state.h>
 #include <test/suites.h>
 #include <test/test.h>
 #include <test/ut.h>
@@ -240,7 +239,6 @@ BLOBLIST_TEST(bloblist_test_checksum, 0);
 /* Test the 'bloblist info' command */
 static int bloblist_test_cmd_info(struct unit_test_state *uts)
 {
-       struct sandbox_state *state = state_get_current();
        struct bloblist_hdr *hdr;
        char *data, *data2;
 
@@ -250,8 +248,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts)
        data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
 
        console_record_reset_enable();
-       if (!state->show_test_output)
-               gd->flags |= GD_FLG_SILENT;
+       ut_silence_console(uts);
        console_record_reset();
        run_command("bloblist info", 0);
        ut_assert_nextline("base:     %lx", (ulong)map_to_sysmem(hdr));
@@ -259,7 +256,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts)
        ut_assert_nextline("alloced:  70     112 Bytes");
        ut_assert_nextline("free:     390    912 Bytes");
        ut_assert_console_end();
-       gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+       ut_unsilence_console(uts);
 
        return 0;
 }
@@ -268,7 +265,6 @@ BLOBLIST_TEST(bloblist_test_cmd_info, 0);
 /* Test the 'bloblist list' command */
 static int bloblist_test_cmd_list(struct unit_test_state *uts)
 {
-       struct sandbox_state *state = state_get_current();
        struct bloblist_hdr *hdr;
        char *data, *data2;
 
@@ -278,8 +274,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts)
        data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
 
        console_record_reset_enable();
-       if (!state->show_test_output)
-               gd->flags |= GD_FLG_SILENT;
+       ut_silence_console(uts);
        console_record_reset();
        run_command("bloblist list", 0);
        ut_assert_nextline("Address       Size  Tag Name");
@@ -288,7 +283,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts)
        ut_assert_nextline("%08lx  %8x    2 SPL hand-off",
                           (ulong)map_to_sysmem(data2), TEST_SIZE2);
        ut_assert_console_end();
-       gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+       ut_unsilence_console(uts);
 
        return 0;
 }
index fa6770e..fbaa8a4 100644 (file)
@@ -15,6 +15,6 @@ int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
        struct unit_test *tests = ll_entry_start(struct unit_test, mem_test);
        const int n_ents = ll_entry_count(struct unit_test, mem_test);
 
-       return cmd_ut_category("cmd_mem", "cmd_mem_", tests, n_ents, argc,
+       return cmd_ut_category("cmd_mem", "mem_test_", tests, n_ents, argc,
                               argv);
 }
index 98a9abf..97c11e3 100644 (file)
@@ -7,7 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o
 obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
 obj-y += hexdump.o
 obj-y += lmb.o
-obj-y += test_print.o
+obj-$(CONFIG_CONSOLE_RECORD) += test_print.o
 obj-$(CONFIG_SSCANF) += sscanf.o
 obj-y += string.o
 obj-$(CONFIG_ERRNO_STR) += test_errno_str.o
index 88bc573..afdafa5 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_CMD_LOG) += log_filter.o
 ifdef CONFIG_UT_LOG
 
 obj-y += test-main.o
+obj-y += pr_cont_test.o
 
 ifdef CONFIG_SANDBOX
 obj-$(CONFIG_LOG_SYSLOG) += syslog_test.o
index ea4fc6b..82234a6 100644 (file)
 DECLARE_GLOBAL_DATA_PTR;
 
 /* emit some sample log records in different ways, for testing */
-static int do_log_run(int cat, const char *file)
+static int do_log_run(struct unit_test_state *uts, int cat, const char *file)
 {
        int i;
+       int ret, expected_ret;
+
+       if (gd->flags & GD_FLG_LOG_READY)
+               expected_ret = 0;
+       else
+               expected_ret = -ENOSYS;
 
        gd->log_fmt = LOGF_TEST;
        debug("debug\n");
        for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
                log(cat, i, "log %d\n", i);
-               _log(log_uc_cat(cat), i, file, 100 + i, "func", "_log %d\n",
-                    i);
+               ret = _log(log_uc_cat(cat), i, file, 100 + i,
+                          "func", "_log %d\n", i);
+               ut_asserteq(ret, expected_ret);
+       }
+       /* test with LOGL_COUNT flag */
+       for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
+               ret = _log(log_uc_cat(cat), i | LOGL_FORCE_DEBUG, file, 100 + i,
+                          "func", "_log force %d\n", i);
+               ut_asserteq(ret, expected_ret);
        }
 
        gd->log_fmt = log_get_default_format();
        return 0;
 }
 
-#define log_run_cat(cat) do_log_run(cat, "file")
-#define log_run_file(file) do_log_run(UCLASS_SPI, file)
-#define log_run() do_log_run(UCLASS_SPI, "file")
+#define log_run_cat(cat) do_log_run(uts, cat, "file")
+#define log_run_file(file) do_log_run(uts, UCLASS_SPI, file)
+#define log_run() do_log_run(uts, UCLASS_SPI, "file")
 
 #define EXPECT_LOG BIT(0)
 #define EXPECT_DIRECT BIT(1)
 #define EXPECT_EXTRA BIT(2)
+#define EXPECT_FORCE BIT(3)
+#define EXPECT_DEBUG BIT(4)
 
 static int do_check_log_entries(struct unit_test_state *uts, int flags, int min,
                                int max)
@@ -49,11 +64,22 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min,
                        ut_assert_nextline("do_log_run() log %d", i);
                if (flags & EXPECT_DIRECT)
                        ut_assert_nextline("func() _log %d", i);
+               if (flags & EXPECT_DEBUG) {
+                       ut_assert_nextline("log %d", i);
+                       ut_assert_nextline("_log %d", i);
+               }
        }
        if (flags & EXPECT_EXTRA)
                for (; i <= LOGL_MAX ; i++)
                        ut_assert_nextline("func() _log %d", i);
 
+       for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
+               if (flags & EXPECT_FORCE)
+                       ut_assert_nextline("func() _log force %d", i);
+               if (flags & EXPECT_DEBUG)
+                       ut_assert_nextline("_log force %d", i);
+       }
+
        ut_assert_console_end();
        return 0;
 }
@@ -66,10 +92,10 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min,
 
 #define check_log_entries_flags(flags) \
        check_log_entries_flags_levels(flags, LOGL_FIRST, _LOG_MAX_LEVEL)
-#define check_log_entries() check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT)
+#define check_log_entries() check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE)
 #define check_log_entries_extra() \
-       check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT | EXPECT_EXTRA)
-#define check_log_entries_none() check_log_entries_flags(0)
+       check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE)
+#define check_log_entries_none() check_log_entries_flags(EXPECT_FORCE)
 
 /* Check a category filter using the first category */
 int log_test_cat_allow(struct unit_test_state *uts)
@@ -126,7 +152,7 @@ int log_test_file(struct unit_test_state *uts)
 
        ut_assertok(console_record_reset_enable());
        log_run_file("file");
-       check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA);
+       check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE);
 
        ut_assertok(console_record_reset_enable());
        log_run_file("file2");
@@ -147,7 +173,7 @@ int log_test_file_second(struct unit_test_state *uts)
 
        ut_assertok(console_record_reset_enable());
        log_run_file("file2");
-       check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA);
+       check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE);
 
        ut_assertok(log_remove_filter("console", filt));
        return 0;
@@ -182,8 +208,8 @@ int log_test_level(struct unit_test_state *uts)
 
        ut_assertok(console_record_reset_enable());
        log_run();
-       check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT, LOGL_FIRST,
-                                      LOGL_WARNING);
+       check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE,
+                                      LOGL_FIRST, LOGL_WARNING);
 
        ut_assertok(log_remove_filter("console", filt));
        return 0;
@@ -351,7 +377,7 @@ int log_test_level_deny(struct unit_test_state *uts)
 
        ut_assertok(console_record_reset_enable());
        log_run();
-       check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT,
+       check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE,
                                       LOGL_WARNING + 1, _LOG_MAX_LEVEL);
 
        ut_assertok(log_remove_filter("console", filt1));
@@ -374,7 +400,7 @@ int log_test_min(struct unit_test_state *uts)
 
        ut_assertok(console_record_reset_enable());
        log_run();
-       check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT,
+       check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE,
                                       LOGL_WARNING, LOGL_INFO - 1);
 
        ut_assertok(log_remove_filter("console", filt1));
@@ -382,3 +408,23 @@ int log_test_min(struct unit_test_state *uts)
        return 0;
 }
 LOG_TEST_FLAGS(log_test_min, UT_TESTF_CONSOLE_REC);
+
+/* Check dropped traces */
+int log_test_dropped(struct unit_test_state *uts)
+{
+       /* force LOG not ready */
+       gd->flags &= ~(GD_FLG_LOG_READY);
+       gd->log_drop_count = 0;
+
+       ut_assertok(console_record_reset_enable());
+       log_run();
+
+       ut_asserteq(gd->log_drop_count, 3 * (LOGL_COUNT - LOGL_FIRST - 1));
+       check_log_entries_flags_levels(EXPECT_DEBUG, LOGL_FIRST, CONFIG_LOG_DEFAULT_LEVEL);
+
+       gd->flags |= GD_FLG_LOG_READY;
+       gd->log_drop_count = 0;
+
+       return 0;
+}
+LOG_TEST_FLAGS(log_test_dropped, UT_TESTF_CONSOLE_REC);
diff --git a/test/log/pr_cont_test.c b/test/log/pr_cont_test.c
new file mode 100644 (file)
index 0000000..236eff4
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Test continuation of log messages using pr_cont().
+ */
+
+#include <common.h>
+#include <console.h>
+#include <test/log.h>
+#include <test/test.h>
+#include <test/suites.h>
+#include <test/ut.h>
+#include <linux/printk.h>
+
+#define BUFFSIZE 64
+
+#undef CONFIG_LOGLEVEL
+#define CONFIG_LOGLEVEL 4
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int log_test_pr_cont(struct unit_test_state *uts)
+{
+       int log_fmt;
+       int log_level;
+
+       log_fmt = gd->log_fmt;
+       log_level = gd->default_log_level;
+
+       /* Write two messages, the second continuing the first */
+       gd->log_fmt = BIT(LOGF_MSG);
+       gd->default_log_level = LOGL_INFO;
+       console_record_reset_enable();
+       pr_err("ea%d ", 1);
+       pr_cont("cc%d\n", 2);
+       gd->default_log_level = log_level;
+       gd->log_fmt = log_fmt;
+       gd->flags &= ~GD_FLG_RECORD;
+       ut_assertok(ut_check_console_line(uts, "ea1 cc2"));
+       ut_assertok(ut_check_console_end(uts));
+
+       return 0;
+}
+LOG_TEST(log_test_pr_cont);
index 387b392..f889120 100644 (file)
@@ -36,3 +36,14 @@ def test_log_format(u_boot_console):
         run_with_format('FLfm', 'file.c:123-func() msg')
         run_with_format('lm', 'NOTICE. msg')
         run_with_format('m', 'msg')
+
+@pytest.mark.buildconfigspec('debug_uart')
+@pytest.mark.boardspec('sandbox')
+def test_log_dropped(u_boot_console):
+    """Test dropped 'log' message when debug_uart is activated"""
+
+    cons = u_boot_console
+    cons.restart_uboot()
+    output = cons.get_spawn_output().replace('\r', '')
+    assert 'sandbox: starting...' in output
+    assert (not 'debug: main' in output)
index ef1205d..cd50455 100644 (file)
@@ -19,7 +19,7 @@ static const char str3[] = "0xbI'm sorry you're alive.";
 /* Declare a new str test */
 #define STR_TEST(_name, _flags)                UNIT_TEST(_name, _flags, str_test)
 
-static int str_test_upper(struct unit_test_state *uts)
+static int str_upper(struct unit_test_state *uts)
 {
        char out[TEST_STR_SIZE];
 
@@ -55,7 +55,7 @@ static int str_test_upper(struct unit_test_state *uts)
 
        return 0;
 }
-STR_TEST(str_test_upper, 0);
+STR_TEST(str_upper, 0);
 
 static int run_strtoul(struct unit_test_state *uts, const char *str, int base,
                       ulong expect_val, int expect_endp_offset, bool upper)
index 95bdd66..44ed1ba 100644 (file)
--- a/test/ut.c
+++ b/test/ut.c
@@ -8,6 +8,9 @@
 #include <common.h>
 #include <console.h>
 #include <malloc.h>
+#ifdef CONFIG_SANDBOX
+#include <asm/state.h>
+#endif
 #include <test/test.h>
 #include <test/ut.h>
 
@@ -114,3 +117,18 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes)
 
        return upto == total_bytes ? 0 : 1;
 }
+
+void ut_silence_console(struct unit_test_state *uts)
+{
+#ifdef CONFIG_SANDBOX
+       struct sandbox_state *state = state_get_current();
+
+       if (!state->show_test_output)
+               gd->flags |= GD_FLG_SILENT;
+#endif
+}
+
+void ut_unsilence_console(struct unit_test_state *uts)
+{
+       gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+}