return 1;
}
-void api_init(void)
+int api_init(void)
{
struct api_signature *sig;
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);
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,
#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 *);
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
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 */
#endif
}
-void noncached_init(void)
+int noncached_init(void)
{
phys_addr_t start, end;
size_t size;
noncached_next = start;
noncached_set_region();
+
+ return 0;
}
phys_addr_t noncached_alloc(size_t size, size_t align)
for(;;);
}
-void trap_init(ulong value) {
+static void trap_init(ulong value) {
unsigned long *vec = (ulong *)value;
int i;
setvbr(value); /* set vector base register to new table */
}
+
+int arch_initr_trap(void)
+{
+ trap_init(CONFIG_SYS_SDRAM_BASE);
+
+ return 0;
+}
flush_cache(ebase + offset, size);
}
-void trap_init(ulong reloc_addr)
+static void trap_init(ulong reloc_addr)
{
unsigned long ebase = gd->irq_sp;
clear_c0_status(ST0_BEV);
execution_hazard_barrier();
}
+
+int arch_initr_trap(void)
+{
+ trap_init(CONFIG_SYS_SDRAM_BASE);
+
+ return 0;
+}
mtmsr(msr);
}
-void cpu_secondary_init_r(void)
+int cpu_secondary_init_r(void)
{
#ifdef CONFIG_QE
#ifdef CONFIG_U_QE
qe_init(qe_base);
qe_reset();
#endif
+
+ return 0;
}
#ifdef CONFIG_BOARD_LATE_INIT
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
--- /dev/null
+// 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;
+}
#include <efi_loader.h>
#include <errno.h>
#include <init.h>
+#include <log.h>
#include <os.h>
#include <cli.h>
#include <sort.h>
*/
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);
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
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
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
KEY_UP,
KEY_DOWN,
KEY_SELECT,
+ KEY_QUIT,
};
static char *bootmenu_getoption(unsigned short int n)
case '\r':
*key = KEY_SELECT;
break;
+ case 0x3: /* ^C */
+ *key = KEY_QUIT;
+ break;
default:
*key = KEY_NONE;
break;
{
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' */
*esc = 2;
*key = KEY_NONE;
} else {
- *esc = 0;
+ /* Alone ESC key was pressed */
+ *key = KEY_QUIT;
+ *esc = (c == '\e') ? 1 : 0;
}
break;
case 2:
/* 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)
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;
}
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);
return 1;
}
bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
- fit_print_contents(fit_hdr);
}
#endif
#include <command.h>
#include <part.h>
#include <part_efi.h>
+#include <part.h>
#include <exports.h>
#include <uuid.h>
#include <linux/ctype.h>
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;
} 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
" 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"
--- /dev/null
+// 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"
+);
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
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"
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
DECLARE_GLOBAL_DATA_PTR;
-#define MAX_DELAY_STOP_STR 32
+#define MAX_DELAY_STOP_STR 64
#ifndef DEBUG_BOOTKEYS
#define DEBUG_BOOTKEYS 0
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;
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
return 0;
}
- presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR);
sha = malloc_cache_aligned(SHA256_SUM_LEN);
size = SHA256_SUM_LEN;
/*
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));
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;
}
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();
}
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;
}
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)
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;
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
reserve_uboot,
reserve_malloc,
reserve_board,
- setup_machine,
reserve_global_data,
reserve_fdt,
reserve_bootstage,
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;
}
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)
}
#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)
{
}
#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
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)) {
}
#endif
-#ifdef CONFIG_XEN
-static int initr_xen(void)
-{
- xen_init();
- return 0;
-}
-#endif
-
#ifdef CONFIG_PVBLOCK
static int initr_pvblock(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)
{
}
#endif
-#ifdef CONFIG_BITBANGMII
-static int initr_bbmii(void)
-{
- bb_miiphy_init();
- return 0;
-}
-#endif
-
#ifdef CONFIG_CMD_NET
static int initr_net(void)
{
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
#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
#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,
initr_mmc,
#endif
#ifdef CONFIG_XEN
- initr_xen,
+ xen_init,
#endif
#ifdef CONFIG_PVBLOCK
initr_pvblock,
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
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
}
#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;
}
}
#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
}
#endif
-#if defined(CONFIG_NEEDS_MANUAL_RELOC)
-DECLARE_GLOBAL_DATA_PTR;
-
void fixup_cmdtable(struct cmd_tbl *cmdtp, int size)
{
int i;
cmdtp++;
}
}
-#endif
int cmd_always_repeatable(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[], int *repeatable)
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:
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;
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
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;
{
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;
}
#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
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;
}
#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]);
#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, ...)
*/
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);
}
}
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);
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);
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)
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);
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++;
}
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);
/** 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;
/* Check for valid device name */
- dev = search_device(flag, devname);
+ dev = console_search_dev(flag, devname);
if (dev)
return console_setfile(file, dev);
/* 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)
{
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) */
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) {
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;
}
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) {
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++) {
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;
}
# 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;
}
{
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)
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) {
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;
/*
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 */
* @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
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;
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;
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;
}
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.
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));
* '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))
/*
* 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
#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)
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",
}
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);
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,
#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 */
(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); */
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,
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);
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;
#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 */
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);
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;"
bootefi
bootmenu
button
+ mbr
pstore
--- /dev/null
+.. 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 |
++---+------------------------------+
}
#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",
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);
*/
#ifndef __UBOOT__
-#include <log.h>
-#include <dm/devres.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
sizeof(bb_miiphy_buses[0]);
#endif
-void bb_miiphy_init(void)
+int bb_miiphy_init(void)
{
int i;
bb_miiphy_buses[i].init(&bb_miiphy_buses[i]);
}
}
+
+ return 0;
}
static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
.of_match = pci_generic_ids,
};
-void pci_init(void)
+int pci_init(void)
{
struct udevice *bus;
uclass_next_device_check(&bus)) {
;
}
+
+ return 0;
}
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
.flags = DM_UC_FLAG_SEQ_ALIAS,
};
-void pci_ep_init(void)
+int pci_ep_init(void)
{
struct udevice *dev;
uclass_next_device_check(&dev)) {
;
}
+
+ return 0;
}
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.
/* 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;
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);
}
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;
}
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);
}
(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) {
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 =
#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 */
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
/* 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();
}
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
synch_clear_bit(port, &s->evtchn_pending[0]);
}
-void xen_init(void)
+int xen_init(void)
{
debug("%s\n", __func__);
init_events();
init_xenbus();
init_gnttab();
+
+ return 0;
}
void xen_fini(void)
$(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; \
#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
* @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)
/**
#define __CONSOLE_H
#include <stdbool.h>
+#include <stdio_dev.h>
#include <linux/errno.h>
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? */
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
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
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);
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
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);
/* 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
int iomux_doenv(const int, const char *);
void iomux_printdevs(const int);
-struct stdio_dev *search_device(int, const char *);
#endif /* _IO_MUX_H */
*/
#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)
#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)
#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 */
* 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 */
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);
#include <blk.h>
#include <ide.h>
#include <uuid.h>
+#include <linker_lists.h>
#include <linux/list.h>
struct block_drvr {
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 */
#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;
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, ...);
#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);
*/
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
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
* 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
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
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
}
{
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;
{"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},
};
/*
* 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
}
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
#include "deflate.h"
#ifdef DEBUG
-# include <ctype.h>
+# include <linux/ctype.h>
#endif
/* ===========================================================================
}
/* ... and the messages are output once we are relocated */
-void post_output_backlog(void)
+int post_output_backlog(void)
{
int j;
}
}
}
+
+ return 0;
}
static void post_bootmode_test_on(unsigned int last_test)
#
# (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
#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>
/* 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;
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));
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;
}
/* 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;
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");
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;
}
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);
}
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
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
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)
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;
}
#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)
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");
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;
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;
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));
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));
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);
--- /dev/null
+// 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);
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)
/* 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];
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)
#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>
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);
+}