mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-18 06:58:54 +00:00
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
This commit is contained in:
commit
14ea1b3635
45 changed files with 1237 additions and 424 deletions
|
@ -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,
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
19
arch/powerpc/lib/traps.c
Normal file
19
arch/powerpc/lib/traps.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
314
cmd/mbr.c
Normal file
314
cmd/mbr.c
Normal file
|
@ -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"
|
||||
);
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
134
common/board_r.c
134
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
|
||||
|
|
403
common/console.c
403
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
|
||||
unsigned long flags = gd->flags;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_SILENT_CONSOLE))
|
||||
return false;
|
||||
|
||||
if (env_get("silent")) {
|
||||
gd->flags |= GD_FLG_SILENT;
|
||||
} else {
|
||||
unsigned long flags = gd->flags;
|
||||
|
||||
gd->flags &= ~GD_FLG_SILENT;
|
||||
|
||||
return !!(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++) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 *));
|
||||
|
||||
cd_count[console] = cs_idx;
|
||||
}
|
||||
free(cons_set);
|
||||
|
||||
old_set = console_devices[console];
|
||||
repeat = cd_count[console];
|
||||
|
||||
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(old_set);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONSOLE_MUX */
|
||||
|
|
40
common/log.c
40
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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
208
disk/part_dos.c
208
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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -14,4 +14,5 @@ Shell commands
|
|||
bootefi
|
||||
bootmenu
|
||||
button
|
||||
mbr
|
||||
pstore
|
||||
|
|
94
doc/usage/mbr.rst
Normal file
94
doc/usage/mbr.rst
Normal file
|
@ -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 |
|
||||
+---+------------------------------+
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -163,6 +163,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
|
||||
*
|
||||
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue