aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-01-16 11:14:21 -0500
committerTom Rini <trini@konsulko.com>2021-01-16 11:14:21 -0500
commit14ea1b3635b4af8d9e283e3671f7ee872d50b859 (patch)
treeb8d1c05256b6f160a598656e797071081bd1f61e
parentb0db69b4e1e1bf1109bd9d4a5185cbd4058f4a8b (diff)
parent750c543ca74a80da4b67882deb967c80fe790c3f (diff)
downloadu-boot-14ea1b3635b4af8d9e283e3671f7ee872d50b859.zip
u-boot-14ea1b3635b4af8d9e283e3671f7ee872d50b859.tar.gz
u-boot-14ea1b3635b4af8d9e283e3671f7ee872d50b859.tar.bz2
Merge branch '2021-01-15-assorted-improvements'
- Add MBR partition layout writing supporting, clean up code. - A large number of assorted console/iomux cleanups - A large number of board_r related cleanups. - Log enhancements
-rw-r--r--api/api.c6
-rw-r--r--api/api_private.h2
-rw-r--r--arch/arm/include/asm/system.h13
-rw-r--r--arch/arm/lib/cache.c4
-rw-r--r--arch/m68k/lib/traps.c9
-rw-r--r--arch/mips/lib/traps.c9
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu_init.c4
-rw-r--r--arch/powerpc/lib/Makefile1
-rw-r--r--arch/powerpc/lib/traps.c19
-rw-r--r--arch/sandbox/cpu/start.c5
-rw-r--r--cmd/Kconfig8
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/mbr.c314
-rw-r--r--common/Kconfig8
-rw-r--r--common/board_f.c78
-rw-r--r--common/board_r.c134
-rw-r--r--common/console.c403
-rw-r--r--common/exports.c4
-rw-r--r--common/iomux.c49
-rw-r--r--common/log.c40
-rw-r--r--common/spl/Kconfig2
-rw-r--r--common/stdio.c4
-rw-r--r--disk/part_dos.c208
-rw-r--r--disk/part_dos.h5
-rw-r--r--doc/usage/index.rst1
-rw-r--r--doc/usage/mbr.rst94
-rw-r--r--drivers/fastboot/fb_mmc.c2
-rw-r--r--drivers/net/phy/miiphybb.c4
-rw-r--r--drivers/pci/pci-uclass.c4
-rw-r--r--drivers/pci/pci.c6
-rw-r--r--drivers/pci_endpoint/pci_ep-uclass.c4
-rw-r--r--drivers/xen/hypervisor.c4
-rw-r--r--include/api.h10
-rw-r--r--include/asm-generic/global_data.h4
-rw-r--r--include/console.h15
-rw-r--r--include/exports.h10
-rw-r--r--include/init.h47
-rw-r--r--include/iomux.h1
-rw-r--r--include/miiphy.h10
-rw-r--r--include/part.h9
-rw-r--r--include/post.h11
-rw-r--r--include/xen.h2
-rw-r--r--post/post.c4
-rw-r--r--test/log/log_test.c76
-rw-r--r--test/py/tests/test_log.py11
45 files changed, 1236 insertions, 423 deletions
diff --git a/api/api.c b/api/api.c
index 493b77f..89003c1 100644
--- 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,
diff --git a/api/api_private.h b/api/api_private.h
index 07fd50a..bb23821 100644
--- a/api/api_private.h
+++ b/api/api_private.h
@@ -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 *);
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index ce55294..5fe8369 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -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 */
diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
index ee7d14b..bdde9cd 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/lib/cache.c
@@ -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)
diff --git a/arch/m68k/lib/traps.c b/arch/m68k/lib/traps.c
index c49141f..0c2c1a9 100644
--- a/arch/m68k/lib/traps.c
+++ b/arch/m68k/lib/traps.c
@@ -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;
+}
diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c
index df8b63f..540ea48 100644
--- a/arch/mips/lib/traps.c
+++ b/arch/mips/lib/traps.c
@@ -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;
+}
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index e0f0f7e..e920e01 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -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
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index f61809a..2782740 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -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
index 0000000..288e377
--- /dev/null
+++ b/arch/powerpc/lib/traps.c
@@ -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;
+}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 8322ed7a..2d18d9d 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -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);
diff --git a/cmd/Kconfig b/cmd/Kconfig
index da86a94..0107c0f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1034,6 +1034,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
diff --git a/cmd/Makefile b/cmd/Makefile
index 5b3400a..87aa949 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -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
diff --git a/cmd/mbr.c b/cmd/mbr.c
new file mode 100644
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"
+);
diff --git a/common/Kconfig b/common/Kconfig
index 2bce8c9..d8982ba 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -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
diff --git a/common/board_f.c b/common/board_f.c
index 9f441c4..ae3001b 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -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,
diff --git a/common/board_r.c b/common/board_r.c
index 29dd7d2..9fa4d4b 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -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
diff --git a/common/console.c b/common/console.c
index 3348436..b15f732 100644
--- a/common/console.c
+++ b/common/console.c
@@ -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,25 +1010,22 @@ 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 */
@@ -956,18 +1056,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 +1085,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++) {
diff --git a/common/exports.c b/common/exports.c
index 6253b55..4578f07 100644
--- a/common/exports.c
+++ b/common/exports.c
@@ -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;
}
diff --git a/common/iomux.c b/common/iomux.c
index 7cfd9f2..15bf533 100644
--- a/common/iomux.c
+++ b/common/iomux.c
@@ -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 */
diff --git a/common/log.c b/common/log.c
index ce39918..767f0fe 100644
--- a/common/log.c
+++ b/common/log.c
@@ -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;
}
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 6b01867..7561335 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -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.
diff --git a/common/stdio.c b/common/stdio.c
index a15f308..abf9b1e 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -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
diff --git a/disk/part_dos.c b/disk/part_dos.c
index 04f5310..f431925 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -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>
@@ -29,22 +31,11 @@
* 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;
diff --git a/disk/part_dos.h b/disk/part_dos.h
index 434b021..5055822 100644
--- a/disk/part_dos.h
+++ b/disk/part_dos.h
@@ -15,6 +15,11 @@
#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 */
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index fbb2c04..5869fba 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -14,4 +14,5 @@ Shell commands
bootefi
bootmenu
button
+ mbr
pstore
diff --git a/doc/usage/mbr.rst b/doc/usage/mbr.rst
new file mode 100644
index 0000000..bddf2f6
--- /dev/null
+++ b/doc/usage/mbr.rst
@@ -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 |
++---+------------------------------+
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index ae8e8e5..4e26cef 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -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);
diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c
index ba97a54..59a32c4 100644
--- a/drivers/net/phy/miiphybb.c
+++ b/drivers/net/phy/miiphybb.c
@@ -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)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 4cdd06b..ba65f47 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -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;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 664e837..a7453e5 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -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
diff --git a/drivers/pci_endpoint/pci_ep-uclass.c b/drivers/pci_endpoint/pci_ep-uclass.c
index 38a5f08..aa89701 100644
--- a/drivers/pci_endpoint/pci_ep-uclass.c
+++ b/drivers/pci_endpoint/pci_ep-uclass.c
@@ -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;
}
diff --git a/drivers/xen/hypervisor.c b/drivers/xen/hypervisor.c
index 178c206..2560894 100644
--- a/drivers/xen/hypervisor.c
+++ b/drivers/xen/hypervisor.c
@@ -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)
diff --git a/include/api.h b/include/api.h
index 84d81dc..83412a7 100644
--- a/include/api.h
+++ b/include/api.h
@@ -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
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index efa09a1..19f7039 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -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)
/**
diff --git a/include/console.h b/include/console.h
index 432f892..7e628c0 100644
--- a/include/console.h
+++ b/include/console.h
@@ -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
diff --git a/include/exports.h b/include/exports.h
index b300554..faf0f59 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -15,8 +15,14 @@
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);
diff --git a/include/init.h b/include/init.h
index 0f48ccb..980be27 100644
--- a/include/init.h
+++ b/include/init.h
@@ -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
diff --git a/include/iomux.h b/include/iomux.h
index e6e1097..da7ff69 100644
--- a/include/iomux.h
+++ b/include/iomux.h
@@ -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 */
diff --git a/include/miiphy.h b/include/miiphy.h
index 61c136b..8b77bac 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -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);
diff --git a/include/part.h b/include/part.h
index 55be724..fac3636 100644
--- a/include/part.h
+++ b/include/part.h
@@ -465,14 +465,19 @@ 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
diff --git a/include/post.h b/include/post.h
index eb218ac..5695e2b 100644
--- a/include/post.h
+++ b/include/post.h
@@ -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);
diff --git a/include/xen.h b/include/xen.h
index a952a2c..8681321 100644
--- a/include/xen.h
+++ b/include/xen.h
@@ -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
diff --git a/post/post.c b/post/post.c
index 0f1fe8d..7d6a647 100644
--- a/post/post.c
+++ b/post/post.c
@@ -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)
diff --git a/test/log/log_test.c b/test/log/log_test.c
index ea4fc6b..82234a6 100644
--- a/test/log/log_test.c
+++ b/test/log/log_test.c
@@ -15,29 +15,44 @@
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/py/tests/test_log.py b/test/py/tests/test_log.py
index 387b392..f889120 100644
--- a/test/py/tests/test_log.py
+++ b/test/py/tests/test_log.py
@@ -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)