提交 6731c5a5 编写于 作者: T Tom Rini

Merge branch '2020-10-14-assorted-changes'

- Add support for Linux "pstore" dumps.
- Button command fixup.
- gd cleanup and documentation.
- Assorted other cleanups.
...@@ -938,6 +938,7 @@ config ARCH_QEMU ...@@ -938,6 +938,7 @@ config ARCH_QEMU
select OF_CONTROL select OF_CONTROL
select PL01X_SERIAL select PL01X_SERIAL
imply CMD_DM imply CMD_DM
imply DM_RNG
imply DM_RTC imply DM_RTC
imply RTC_PL031 imply RTC_PL031
......
...@@ -18,14 +18,14 @@ ...@@ -18,14 +18,14 @@
buttons { buttons {
compatible = "gpio-keys"; compatible = "gpio-keys";
summer { btn1 {
gpios = <&gpio_a 3 0>; gpios = <&gpio_a 3 0>;
label = "summer"; label = "button1";
}; };
christmas { btn2 {
gpios = <&gpio_a 4 0>; gpios = <&gpio_a 4 0>;
label = "christmas"; label = "button2";
}; };
}; };
......
...@@ -55,14 +55,14 @@ ...@@ -55,14 +55,14 @@
buttons { buttons {
compatible = "gpio-keys"; compatible = "gpio-keys";
summer { btn1 {
gpios = <&gpio_a 3 0>; gpios = <&gpio_a 3 0>;
label = "summer"; label = "button1";
}; };
christmas { btn2 {
gpios = <&gpio_a 4 0>; gpios = <&gpio_a 4 0>;
label = "christmas"; label = "button2";
}; };
}; };
......
...@@ -1751,6 +1751,77 @@ config CMD_QFW ...@@ -1751,6 +1751,77 @@ config CMD_QFW
feature is to allow easy loading of files passed to qemu-system feature is to allow easy loading of files passed to qemu-system
via -kernel / -initrd via -kernel / -initrd
config CMD_PSTORE
bool "pstore"
help
This provides access to Linux PStore with Rammoops backend. The main
feature is to allow to display or save PStore records.
See doc/pstore.rst for more information.
if CMD_PSTORE
config CMD_PSTORE_MEM_ADDR
hex "Memory Address"
depends on CMD_PSTORE
help
Base addr used for PStore ramoops memory, should be identical to
ramoops.mem_address parameter used by kernel
config CMD_PSTORE_MEM_SIZE
hex "Memory size"
depends on CMD_PSTORE
default "0x10000"
help
Size of PStore ramoops memory, should be identical to ramoops.mem_size
parameter used by kernel, a power of 2 and larger than the sum of the
record sizes
config CMD_PSTORE_RECORD_SIZE
hex "Dump record size"
depends on CMD_PSTORE
default "0x1000"
help
Size of each dump done on oops/panic, should be identical to
ramoops.record_size parameter used by kernel and a power of 2
Must be non-zero
config CMD_PSTORE_CONSOLE_SIZE
hex "Kernel console log size"
depends on CMD_PSTORE
default "0x1000"
help
Size of kernel console log, should be identical to
ramoops.console_size parameter used by kernel and a power of 2
Must be non-zero
config CMD_PSTORE_FTRACE_SIZE
hex "FTrace log size"
depends on CMD_PSTORE
default "0x1000"
help
Size of ftrace log, should be identical to ramoops.ftrace_size
parameter used by kernel and a power of 2
config CMD_PSTORE_PMSG_SIZE
hex "User space message log size"
depends on CMD_PSTORE
default "0x1000"
help
Size of user space message log, should be identical to
ramoops.pmsg_size parameter used by kernel and a power of 2
config CMD_PSTORE_ECC_SIZE
int "ECC size"
depends on CMD_PSTORE
default "0"
help
if non-zero, the option enables ECC support and specifies ECC buffer
size in bytes (1 is a special value, means 16 bytes ECC), should be
identical to ramoops.ramoops_ecc parameter used by kernel
endif
source "cmd/mvebu/Kconfig" source "cmd/mvebu/Kconfig"
config CMD_TERMINAL config CMD_TERMINAL
......
...@@ -116,6 +116,7 @@ obj-$(CONFIG_CMD_PCI) += pci.o ...@@ -116,6 +116,7 @@ obj-$(CONFIG_CMD_PCI) += pci.o
endif endif
obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PINMUX) += pinmux.o
obj-$(CONFIG_CMD_PMC) += pmc.o obj-$(CONFIG_CMD_PMC) += pmc.o
obj-$(CONFIG_CMD_PSTORE) += pstore.o
obj-$(CONFIG_CMD_PXE) += pxe.o pxe_utils.o obj-$(CONFIG_CMD_PXE) += pxe.o pxe_utils.o
obj-$(CONFIG_CMD_WOL) += wol.o obj-$(CONFIG_CMD_WOL) += wol.o
obj-$(CONFIG_CMD_QFW) += qfw.o obj-$(CONFIG_CMD_QFW) += qfw.o
......
...@@ -75,11 +75,11 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ...@@ -75,11 +75,11 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
ret = show_button_state(dev); ret = show_button_state(dev);
return 0; return !ret;
} }
U_BOOT_CMD( U_BOOT_CMD(
button, 4, 1, do_button, button, 2, 1, do_button,
"manage buttons", "manage buttons",
"<button_label> \tGet button state\n" "<button_label> \tGet button state\n"
"button list\t\tShow a list of buttons" "button list\t\tShow a list of buttons"
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright © 2019 Collabora Ltd
*/
#include <config.h>
#include <command.h>
#include <fs.h>
#include <log.h>
#include <mapmem.h>
#include <memalign.h>
#include <part.h>
struct persistent_ram_buffer {
u32 sig;
u32 start;
u32 size;
u8 data[0];
};
#define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */
#define RAMOOPS_KERNMSG_HDR "===="
#define PSTORE_TYPE_DMESG 0
#define PSTORE_TYPE_CONSOLE 2
#define PSTORE_TYPE_FTRACE 3
#define PSTORE_TYPE_PMSG 7
#define PSTORE_TYPE_ALL 255
static phys_addr_t pstore_addr = CONFIG_CMD_PSTORE_MEM_ADDR;
static phys_size_t pstore_length = CONFIG_CMD_PSTORE_MEM_SIZE;
static unsigned int pstore_record_size = CONFIG_CMD_PSTORE_RECORD_SIZE;
static unsigned int pstore_console_size = CONFIG_CMD_PSTORE_CONSOLE_SIZE;
static unsigned int pstore_ftrace_size = CONFIG_CMD_PSTORE_FTRACE_SIZE;
static unsigned int pstore_pmsg_size = CONFIG_CMD_PSTORE_PMSG_SIZE;
static unsigned int pstore_ecc_size = CONFIG_CMD_PSTORE_ECC_SIZE;
static unsigned int buffer_size;
/**
* pstore_read_kmsg_hdr() - Check kernel header and get compression flag if
* available.
* @buffer: Kernel messages buffer.
* @compressed: Returns TRUE if kernel buffer is compressed, else FALSE.
*
* Check if buffer starts with a kernel header of the form:
* ====<secs>.<nsecs>[-<compression>]\n
* If <compression> is equal to 'C' then the buffer is compressed, else iter
* should be 'D'.
*
* Return: Length of kernel header.
*/
static int pstore_read_kmsg_hdr(char *buffer, bool *compressed)
{
char *ptr = buffer;
*compressed = false;
if (strncmp(RAMOOPS_KERNMSG_HDR, ptr, strlen(RAMOOPS_KERNMSG_HDR)) != 0)
return 0;
ptr += strlen(RAMOOPS_KERNMSG_HDR);
ptr = strchr(ptr, '\n');
if (!ptr)
return 0;
if (ptr[-2] == '-' && ptr[-1] == 'C')
*compressed = true;
return ptr - buffer + 1;
}
/**
* pstore_get_buffer() - Get unwrapped record buffer
* @sig: Signature to check
* @buffer: Buffer containing wrapped record
* @size: wrapped record size
* @dest: Buffer used to store unwrapped record
*
* The record starts with <signature><start><size> header.
* The signature is 'DBGC' for all records except for Ftrace's record(s) wich
* use LINUX_VERSION_CODE ^ 'DBGC'.
* Use 0 for @sig to prevent checking signature.
* Start and size are 4 bytes long.
*
* Return: record's length
*/
static u32 pstore_get_buffer(u32 sig, phys_addr_t buffer, u32 size, char *dest)
{
struct persistent_ram_buffer *prb =
(struct persistent_ram_buffer *)map_sysmem(buffer, size);
u32 dest_size;
if (sig == 0 || prb->sig == sig) {
if (prb->size == 0) {
log_debug("found existing empty buffer\n");
return 0;
}
if (prb->size > size) {
log_debug("found existing invalid buffer, size %u, start %u\n",
prb->size, prb->start);
return 0;
}
} else {
log_debug("no valid data in buffer (sig = 0x%08x)\n", prb->sig);
return 0;
}
log_debug("found existing buffer, size %u, start %u\n",
prb->size, prb->start);
memcpy(dest, &prb->data[prb->start], prb->size - prb->start);
memcpy(dest + prb->size - prb->start, &prb->data[0], prb->start);
dest_size = prb->size;
unmap_sysmem(prb);
return dest_size;
}
/**
* pstore_init_buffer_size() - Init buffer size to largest record size
*
* Records, console, FTrace and user logs can use different buffer sizes.
* This function allows to retrieve the biggest one.
*/
static void pstore_init_buffer_size(void)
{
if (pstore_record_size > buffer_size)
buffer_size = pstore_record_size;
if (pstore_console_size > buffer_size)
buffer_size = pstore_console_size;
if (pstore_ftrace_size > buffer_size)
buffer_size = pstore_ftrace_size;
if (pstore_pmsg_size > buffer_size)
buffer_size = pstore_pmsg_size;
}
/**
* pstore_set() - Initialize PStore settings from command line arguments
* @cmdtp: Command data struct pointer
* @flag: Command flag
* @argc: Command-line argument count
* @argv: Array of command-line arguments
*
* Set pstore reserved memory info, starting at 'addr' for 'len' bytes.
* Default length for records is 4K.
* Mandatory arguments:
* - addr: ramoops starting address
* - len: ramoops total length
* Optional arguments:
* - record-size: size of one panic or oops record ('dump' type)
* - console-size: size of the kernel logs record
* - ftrace-size: size of the ftrace record(s), this can be a single record or
* divided in parts based on number of CPUs
* - pmsg-size: size of the user space logs record
* - ecc-size: enables/disables ECC support and specifies ECC buffer size in
* bytes (0 disables it, 1 is a special value, means 16 bytes ECC)
*
* Return: zero on success, CMD_RET_USAGE in case of misuse and negative
* on error.
*/
static int pstore_set(struct cmd_tbl *cmdtp, int flag, int argc,
char * const argv[])
{
if (argc < 3)
return CMD_RET_USAGE;
/* Address is specified since argc > 2
*/
pstore_addr = simple_strtoul(argv[1], NULL, 16);
/* Length is specified since argc > 2
*/
pstore_length = simple_strtoul(argv[2], NULL, 16);
if (argc > 3)
pstore_record_size = simple_strtoul(argv[3], NULL, 16);
if (argc > 4)
pstore_console_size = simple_strtoul(argv[4], NULL, 16);
if (argc > 5)
pstore_ftrace_size = simple_strtoul(argv[5], NULL, 16);
if (argc > 6)
pstore_pmsg_size = simple_strtoul(argv[6], NULL, 16);
if (argc > 7)
pstore_ecc_size = simple_strtoul(argv[7], NULL, 16);
if (pstore_length < (pstore_record_size + pstore_console_size
+ pstore_ftrace_size + pstore_pmsg_size)) {
printf("pstore <len> should be larger than the sum of all records sizes\n");
pstore_length = 0;
}
log_debug("pstore set done: start 0x%08llx - length 0x%llx\n",
(unsigned long long)pstore_addr,
(unsigned long long)pstore_length);
return 0;
}
/**
* pstore_print_buffer() - Print buffer
* @type: buffer type
* @buffer: buffer to print
* @size: buffer size
*
* Print buffer type and content
*/
static void pstore_print_buffer(char *type, char *buffer, u32 size)
{
u32 i = 0;
printf("**** %s\n", type);
while (i < size && buffer[i] != 0) {
putc(buffer[i]);
i++;
}
}
/**
* pstore_display() - Display existing records in pstore reserved memory
* @cmdtp: Command data struct pointer
* @flag: Command flag
* @argc: Command-line argument count
* @argv: Array of command-line arguments
*
* A 'record-type' can be given to only display records of this kind.
* If no 'record-type' is given, all valid records are dispayed.
* 'record-type' can be one of 'dump', 'console', 'ftrace' or 'user'. For 'dump'
* and 'ftrace' types, a 'nb' can be given to only display one record.
*
* Return: zero on success, CMD_RET_USAGE in case of misuse and negative
* on error.
*/
static int pstore_display(struct cmd_tbl *cmdtp, int flag, int argc,
char * const argv[])
{
int type = PSTORE_TYPE_ALL;
phys_addr_t ptr;
char *buffer;
u32 size;
int header_len = 0;
bool compressed;
if (argc > 1) {
if (!strcmp(argv[1], "dump"))
type = PSTORE_TYPE_DMESG;
else if (!strcmp(argv[1], "console"))
type = PSTORE_TYPE_CONSOLE;
else if (!strcmp(argv[1], "ftrace"))
type = PSTORE_TYPE_FTRACE;
else if (!strcmp(argv[1], "user"))
type = PSTORE_TYPE_PMSG;
else
return CMD_RET_USAGE;
}
if (pstore_length == 0) {
printf("Please set PStore configuration\n");
return CMD_RET_USAGE;
}
if (buffer_size == 0)
pstore_init_buffer_size();
buffer = malloc_cache_aligned(buffer_size);
if (type == PSTORE_TYPE_DMESG || type == PSTORE_TYPE_ALL) {
ptr = pstore_addr;
phys_addr_t ptr_end = ptr + pstore_length - pstore_pmsg_size
- pstore_ftrace_size - pstore_console_size;
if (argc > 2) {
ptr += simple_strtoul(argv[2], NULL, 10)
* pstore_record_size;
ptr_end = ptr + pstore_record_size;
}
while (ptr < ptr_end) {
size = pstore_get_buffer(PERSISTENT_RAM_SIG, ptr,
pstore_record_size, buffer);
ptr += pstore_record_size;
if (size == 0)
continue;
header_len = pstore_read_kmsg_hdr(buffer, &compressed);
if (header_len == 0) {
log_debug("no valid kernel header\n");
continue;
}
if (compressed) {
printf("Compressed buffer, display not available\n");
continue;
}
pstore_print_buffer("Dump", buffer + header_len,
size - header_len);
}
}
if (type == PSTORE_TYPE_CONSOLE || type == PSTORE_TYPE_ALL) {
ptr = pstore_addr + pstore_length - pstore_pmsg_size
- pstore_ftrace_size - pstore_console_size;
size = pstore_get_buffer(PERSISTENT_RAM_SIG, ptr,
pstore_console_size, buffer);
if (size != 0)
pstore_print_buffer("Console", buffer, size);
}
if (type == PSTORE_TYPE_FTRACE || type == PSTORE_TYPE_ALL) {
ptr = pstore_addr + pstore_length - pstore_pmsg_size
- pstore_ftrace_size;
/* The FTrace record(s) uses LINUX_VERSION_CODE ^ 'DBGC'
* signature, pass 0 to pstore_get_buffer to prevent
* checking it
*/
size = pstore_get_buffer(0, ptr, pstore_ftrace_size, buffer);
if (size != 0)
pstore_print_buffer("FTrace", buffer, size);
}
if (type == PSTORE_TYPE_PMSG || type == PSTORE_TYPE_ALL) {
ptr = pstore_addr + pstore_length - pstore_pmsg_size;
size = pstore_get_buffer(PERSISTENT_RAM_SIG, ptr,
pstore_pmsg_size, buffer);
if (size != 0)
pstore_print_buffer("User", buffer, size);
}
free(buffer);
return 0;
}
/**
* pstore_save() - Save existing records from pstore reserved memory
* @cmdtp: Command data struct pointer
* @flag: Command flag
* @argc: Command-line argument count
* @argv: Array of command-line arguments
*
* the records are saved under 'directory path', which should already exist,
* to partition 'part' on device type 'interface' instance 'dev'
* Filenames are automatically generated, depending on record type, like in
* /sys/fs/pstore under Linux
*
* Return: zero on success, CMD_RET_USAGE in case of misuse and negative
* on error.
*/
static int pstore_save(struct cmd_tbl *cmdtp, int flag, int argc,
char * const argv[])
{
phys_addr_t ptr, ptr_end;
char *buffer;
char *save_argv[6];
char addr[19], length[19];
char path[256];
u32 size;
unsigned int index;
int header_len = 0;
bool compressed;
if (argc < 4)
return CMD_RET_USAGE;
if (pstore_length == 0) {
printf("Please set PStore configuration\n");
return CMD_RET_USAGE;
}
if (buffer_size == 0)
pstore_init_buffer_size();
buffer = malloc_cache_aligned(buffer_size);
sprintf(addr, "0x%p", buffer);
save_argv[0] = argv[0];
save_argv[1] = argv[1];
save_argv[2] = argv[2];
save_argv[3] = addr;
save_argv[4] = path;
save_argv[5] = length;
/* Save all Dump records */
ptr = pstore_addr;
ptr_end = ptr + pstore_length - pstore_pmsg_size - pstore_ftrace_size
- pstore_console_size;
index = 0;
while (ptr < ptr_end) {
size = pstore_get_buffer(PERSISTENT_RAM_SIG, ptr,
pstore_record_size, buffer);
ptr += pstore_record_size;
if (size == 0)
continue;
header_len = pstore_read_kmsg_hdr(buffer, &compressed);
if (header_len == 0) {
log_debug("no valid kernel header\n");
continue;
}
sprintf(addr, "0x%08lx", (ulong)map_to_sysmem(buffer + header_len));
sprintf(length, "0x%X", size - header_len);
sprintf(path, "%s/dmesg-ramoops-%u%s", argv[3], index,
compressed ? ".enc.z" : "");
do_save(cmdtp, flag, 6, save_argv, FS_TYPE_ANY);
index++;
}
sprintf(addr, "0x%08lx", (ulong)map_to_sysmem(buffer));
/* Save Console record */
size = pstore_get_buffer(PERSISTENT_RAM_SIG, ptr, pstore_console_size,
buffer);
if (size != 0) {
sprintf(length, "0x%X", size);
sprintf(path, "%s/console-ramoops-0", argv[3]);
do_save(cmdtp, flag, 6, save_argv, FS_TYPE_ANY);
}
ptr += pstore_console_size;
/* Save FTrace record(s)
* The FTrace record(s) uses LINUX_VERSION_CODE ^ 'DBGC' signature,
* pass 0 to pstore_get_buffer to prevent checking it
*/
size = pstore_get_buffer(0, ptr, pstore_ftrace_size, buffer);
if (size != 0) {
sprintf(length, "0x%X", size);
sprintf(path, "%s/ftrace-ramoops-0", argv[3]);
do_save(cmdtp, flag, 6, save_argv, FS_TYPE_ANY);
}
ptr += pstore_ftrace_size;
/* Save Console record */
size = pstore_get_buffer(PERSISTENT_RAM_SIG, ptr, pstore_pmsg_size,
buffer);
if (size != 0) {
sprintf(length, "0x%X", size);
sprintf(path, "%s/pmsg-ramoops-0", argv[3]);
do_save(cmdtp, flag, 6, save_argv, FS_TYPE_ANY);
}
free(buffer);
return 0;
}
static struct cmd_tbl cmd_pstore_sub[] = {
U_BOOT_CMD_MKENT(set, 8, 0, pstore_set, "", ""),
U_BOOT_CMD_MKENT(display, 3, 0, pstore_display, "", ""),
U_BOOT_CMD_MKENT(save, 4, 0, pstore_save, "", ""),
};
static int do_pstore(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
struct cmd_tbl *c;
if (argc < 2)
return CMD_RET_USAGE;
/* Strip off leading argument */
argc--;
argv++;
c = find_cmd_tbl(argv[0], cmd_pstore_sub, ARRAY_SIZE(cmd_pstore_sub));
if (!c)
return CMD_RET_USAGE;
return c->cmd(cmdtp, flag, argc, argv);
}
void fdt_fixup_pstore(void *blob)
{
char node[32];
int nodeoffset; /* node offset from libfdt */
nodeoffset = fdt_path_offset(blob, "/");
if (nodeoffset < 0) {
/* Not found or something else bad happened. */
log_err("fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset));
return;
}
nodeoffset = fdt_add_subnode(blob, nodeoffset, "reserved-memory");
if (nodeoffset < 0) {
log_err("Add 'reserved-memory' node failed: %s\n",
fdt_strerror(nodeoffset));
return;
}
fdt_setprop_u32(blob, nodeoffset, "#address-cells", 2);
fdt_setprop_u32(blob, nodeoffset, "#size-cells", 2);
fdt_setprop_empty(blob, nodeoffset, "ranges");
sprintf(node, "ramoops@%llx", (unsigned long long)pstore_addr);
nodeoffset = fdt_add_subnode(blob, nodeoffset, node);
if (nodeoffset < 0) {
log_err("Add '%s' node failed: %s\n", node, fdt_strerror(nodeoffset));
return;
}
fdt_setprop_string(blob, nodeoffset, "compatible", "ramoops");
fdt_setprop_u64(blob, nodeoffset, "reg", pstore_addr);
fdt_appendprop_u64(blob, nodeoffset, "reg", pstore_length);
fdt_setprop_u32(blob, nodeoffset, "record-size", pstore_record_size);
fdt_setprop_u32(blob, nodeoffset, "console-size", pstore_console_size);
fdt_setprop_u32(blob, nodeoffset, "ftrace-size", pstore_ftrace_size);
fdt_setprop_u32(blob, nodeoffset, "pmsg-size", pstore_pmsg_size);
fdt_setprop_u32(blob, nodeoffset, "ecc-size", pstore_ecc_size);
}
U_BOOT_CMD(pstore, 10, 0, do_pstore,
"Manage Linux Persistent Storage",
"set <addr> <len> [record-size] [console-size] [ftrace-size] [pmsg_size] [ecc-size]\n"
"- Set pstore reserved memory info, starting at 'addr' for 'len' bytes.\n"
" Default length for records is 4K.\n"
" 'record-size' is the size of one panic or oops record ('dump' type).\n"
" 'console-size' is the size of the kernel logs record.\n"
" 'ftrace-size' is the size of the ftrace record(s), this can be a single\n"
" record or divided in parts based on number of CPUs.\n"
" 'pmsg-size' is the size of the user space logs record.\n"
" 'ecc-size' enables/disables ECC support and specifies ECC buffer size in\n"
" bytes (0 disables it, 1 is a special value, means 16 bytes ECC).\n"
"pstore display [record-type] [nb]\n"
"- Display existing records in pstore reserved memory. A 'record-type' can\n"
" be given to only display records of this kind. 'record-type' can be one\n"
" of 'dump', 'console', 'ftrace' or 'user'. For 'dump' and 'ftrace' types,\n"
" a 'nb' can be given to only display one record.\n"
"pstore save <interface> <dev[:part]> <directory-path>\n"
"- Save existing records in pstore reserved memory under 'directory path'\n"
" to partition 'part' on device type 'interface' instance 'dev'.\n"
" Filenames are automatically generated, depending on record type, like\n"
" in /sys/fs/pstore under Linux.\n"
" The 'directory-path' should already exist.\n"
);
...@@ -567,6 +567,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, ...@@ -567,6 +567,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
/* Update ethernet nodes */ /* Update ethernet nodes */
fdt_fixup_ethernet(blob); fdt_fixup_ethernet(blob);
#if CONFIG_IS_ENABLED(CMD_PSTORE)
/* Append PStore configuration */
fdt_fixup_pstore(blob);
#endif
if (IMAGE_OF_BOARD_SETUP) { if (IMAGE_OF_BOARD_SETUP) {
fdt_ret = ft_board_setup(blob, gd->bd); fdt_ret = ft_board_setup(blob, gd->bd);
if (fdt_ret) { if (fdt_ret) {
......
...@@ -1237,6 +1237,7 @@ endchoice ...@@ -1237,6 +1237,7 @@ endchoice
config SPL_USB_SDP_SUPPORT config SPL_USB_SDP_SUPPORT
bool "Support SDP (Serial Download Protocol)" bool "Support SDP (Serial Download Protocol)"
depends on SPL_SERIAL_SUPPORT
help help
Enable Serial Download Protocol (SDP) device support in SPL. This Enable Serial Download Protocol (SDP) device support in SPL. This
allows to download images into memory and execute (jump to) them allows to download images into memory and execute (jump to) them
......
...@@ -552,7 +552,9 @@ static int boot_from_devices(struct spl_image_info *spl_image, ...@@ -552,7 +552,9 @@ static int boot_from_devices(struct spl_image_info *spl_image,
struct spl_image_loader *loader; struct spl_image_loader *loader;
loader = spl_ll_find_loader(spl_boot_list[i]); loader = spl_ll_find_loader(spl_boot_list[i]);
#if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT) #if defined(CONFIG_SPL_SERIAL_SUPPORT) \
&& defined(CONFIG_SPL_LIBCOMMON_SUPPORT) \
&& !defined(CONFIG_SILENT_CONSOLE)
if (loader) if (loader)
printf("Trying to boot from %s\n", loader->name); printf("Trying to boot from %s\n", loader->name);
else else
......
...@@ -80,6 +80,8 @@ CONFIG_CMD_CBFS=y ...@@ -80,6 +80,8 @@ CONFIG_CMD_CBFS=y
CONFIG_CMD_CRAMFS=y CONFIG_CMD_CRAMFS=y
CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_MTDPARTS=y CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_PSTORE=y
CONFIG_CMD_PSTORE_MEM_ADDR=0x3000000
CONFIG_MAC_PARTITION=y CONFIG_MAC_PARTITION=y
CONFIG_AMIGA_PARTITION=y CONFIG_AMIGA_PARTITION=y
CONFIG_OF_CONTROL=y CONFIG_OF_CONTROL=y
......
...@@ -93,6 +93,8 @@ CONFIG_CMD_CRAMFS=y ...@@ -93,6 +93,8 @@ CONFIG_CMD_CRAMFS=y
CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_SQUASHFS=y CONFIG_CMD_SQUASHFS=y
CONFIG_CMD_MTDPARTS=y CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_PSTORE=y
CONFIG_CMD_PSTORE_MEM_ADDR=0x3000000
CONFIG_MAC_PARTITION=y CONFIG_MAC_PARTITION=y
CONFIG_AMIGA_PARTITION=y CONFIG_AMIGA_PARTITION=y
CONFIG_OF_CONTROL=y CONFIG_OF_CONTROL=y
......
.. SPDX-License-Identifier: GPL-2.0+
Global data
===========
Globally required fields are held in the global data structure. A pointer to the
structure is available as symbol gd. The symbol is made available by the macro
%DECLARE_GLOBAL_DATA_PTR.
Register pointing to global data
--------------------------------
On most architectures the global data pointer is stored in a register.
+------------+----------+
| ARC | r25 |
+------------+----------+
| ARM 32bit | r9 |
+------------+----------+
| ARM 64bit | x18 |
+------------+----------+
| M68000 | d7 |
+------------+----------+
| MicroBlaze | r31 |
+------------+----------+
| NDS32 | r10 |
+------------+----------+
| Nios II | gp |
+------------+----------+
| PowerPC | r2 |
+------------+----------+
| RISC-V | gp (x3) |
+------------+----------+
| SuperH | r13 |
+------------+----------+
The sandbox, x86, and Xtensa are notable exceptions.
Clang for ARM does not support assigning a global register. When using Clang
gd is defined as an inline function using assembly code. This adds a few bytes
to the code size.
Binaries called by U-Boot are not aware of the register usage and will not
conserve gd. UEFI binaries call the API provided by U-Boot and may return to
U-Boot. The value of gd has to be saved every time U-Boot is left and restored
whenever U-Boot is reentered. This is also relevant for the implementation of
function tracing. For setting the value of gd function set_gd() can be used.
Global data structure
---------------------
.. kernel-doc:: include/asm-generic/global_data.h
:internal:
...@@ -9,4 +9,5 @@ Develop U-Boot ...@@ -9,4 +9,5 @@ Develop U-Boot
coccinelle coccinelle
crash_dumps crash_dumps
global_data
logging logging
...@@ -109,6 +109,13 @@ Android-specific features available in U-Boot. ...@@ -109,6 +109,13 @@ Android-specific features available in U-Boot.
android/index android/index
Command line
------------
.. toctree::
:maxdepth: 2
pstore.rst
Indices and tables Indices and tables
================== ==================
......
.. SPDX-License-Identifier: GPL-2.0+
PStore command
==============
Design
------
Linux PStore and Ramoops modules (Linux config options PSTORE and PSTORE_RAM)
allow to use memory to pass data from the dying breath of a crashing kernel to
its successor. This command allows to read those records from U-Boot command
line.
Ramoops is an oops/panic logger that writes its logs to RAM before the system
crashes. It works by logging oopses and panics in a circular buffer. Ramoops
needs a system with persistent RAM so that the content of that area can survive
after a restart.
Ramoops uses a predefined memory area to store the dump.
Ramoops parameters can be passed as kernel parameters or through Device Tree,
i.e.::
ramoops.mem_address=0x30000000 ramoops.mem_size=0x100000 ramoops.record_size=0x2000 ramoops.console_size=0x2000 memmap=0x100000$0x30000000
The same values should be set in U-Boot to be able to retrieve the records.
This values can be set at build time in U-Boot configuration file, or at runtime.
U-Boot automatically patches the Device Tree to pass the Ramoops parameters to
the kernel.
The PStore configuration parameters are:
======================= ==========
Name Default
======================= ==========
CMD_PSTORE_MEM_ADDR
CMD_PSTORE_MEM_SIZE 0x10000
CMD_PSTORE_RECORD_SIZE 0x1000
CMD_PSTORE_CONSOLE_SIZE 0x1000
CMD_PSTORE_FTRACE_SIZE 0x1000
CMD_PSTORE_PMSG_SIZE 0x1000
CMD_PSTORE_ECC_SIZE 0
======================= ==========
Records sizes should be a power of 2.
The memory size and the record/console size must be non-zero.
Multiple 'dump' records can be stored in the memory reserved for PStore.
The memory size has to be larger than the sum of the record sizes, i.e.::
MEM_SIZE >= RECORD_SIZE * n + CONSOLE_SIZE + FTRACE_SIZE + PMSG_SIZE
Usage
-----
Generate kernel crash
~~~~~~~~~~~~~~~~~~~~~
For test purpose, you can generate a kernel crash by setting reboot timeout to
10 seconds and trigger a panic::
$ sudo sh -c "echo 1 > /proc/sys/kernel/sysrq"
$ sudo sh -c "echo 10 > /proc/sys/kernel/panic"
$ sudo sh -c "echo c > /proc/sysrq-trigger"
Retrieve logs in U-Boot
~~~~~~~~~~~~~~~~~~~~~~~
First of all, unless PStore parameters as been set during U-Boot configuration
and match kernel ramoops parameters, it needs to be set using 'pstore set', e.g.::
=> pstore set 0x30000000 0x100000 0x2000 0x2000
Then all available dumps can be displayed
using::
=> pstore display
Or saved to an existing directory in an Ext2 or Ext4 partition, e.g. on root
directory of 1st partition of the 2nd MMC::
=> pstore save mmc 1:1 /
...@@ -48,7 +48,10 @@ major, minor, patch = sphinx.version_info[:3] ...@@ -48,7 +48,10 @@ major, minor, patch = sphinx.version_info[:3]
def setup(app): def setup(app):
if (major == 1 and minor < 8):
app.override_domain(CDomain) app.override_domain(CDomain)
else:
app.add_domain(CDomain, override=True)
return dict( return dict(
version = __version__, version = __version__,
......
...@@ -1592,7 +1592,7 @@ static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev) ...@@ -1592,7 +1592,7 @@ static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
static int rk3399_pmuclk_bind(struct udevice *dev) static int rk3399_pmuclk_bind(struct udevice *dev)
{ {
#if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP) #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
int ret; int ret;
ret = offsetof(struct rk3399_pmucru, pmucru_softrst_con[0]); ret = offsetof(struct rk3399_pmucru, pmucru_softrst_con[0]);
......
...@@ -185,6 +185,14 @@ static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, ...@@ -185,6 +185,14 @@ static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
dir_flags = get_gpio_dir_flags(dev, offset); dir_flags = get_gpio_dir_flags(dev, offset);
/*
* For testing purposes keep the output value when switching to input.
* This allows us to manipulate the input value via the gpio command.
*/
if (flags & GPIOD_IS_IN)
*dir_flags = (flags & ~GPIOD_IS_OUT_ACTIVE) |
(*dir_flags & GPIOD_IS_OUT_ACTIVE);
else
*dir_flags = flags; *dir_flags = flags;
return 0; return 0;
......
...@@ -3111,3 +3111,12 @@ int mmc_set_bkops_enable(struct mmc *mmc) ...@@ -3111,3 +3111,12 @@ int mmc_set_bkops_enable(struct mmc *mmc)
return 0; return 0;
} }
#endif #endif
__weak int mmc_get_env_dev(void)
{
#ifdef CONFIG_SYS_MMC_ENV_DEV
return CONFIG_SYS_MMC_ENV_DEV;
#else
return 0;
#endif
}
...@@ -1644,6 +1644,11 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -1644,6 +1644,11 @@ e1000_reset_hw(struct e1000_hw *hw)
E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP); E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
if (hw->mac_type == e1000_igb) {
E1000_WRITE_REG(hw, RXPBS, I210_RXPBSIZE_DEFAULT);
E1000_WRITE_REG(hw, TXPBS, I210_TXPBSIZE_DEFAULT);
}
/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */ /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
hw->tbi_compatibility_on = false; hw->tbi_compatibility_on = false;
......
...@@ -735,6 +735,7 @@ struct e1000_ffvt_entry { ...@@ -735,6 +735,7 @@ struct e1000_ffvt_entry {
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */ #define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
...@@ -745,6 +746,7 @@ struct e1000_ffvt_entry { ...@@ -745,6 +746,7 @@ struct e1000_ffvt_entry {
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ #define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ #define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ #define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ #define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ #define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */ #define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
...@@ -2589,4 +2591,8 @@ struct e1000_hw { ...@@ -2589,4 +2591,8 @@ struct e1000_hw {
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers
after IMS clear */ after IMS clear */
#define I210_RXPBSIZE_DEFAULT 0x000000A2 /* RXPBSIZE default */
#define I210_TXPBSIZE_DEFAULT 0x04000014 /* TXPBSIZE default */
#endif /* _E1000_HW_H_ */ #endif /* _E1000_HW_H_ */
...@@ -520,7 +520,7 @@ static void nxp_fspi_prepare_lut(struct nxp_fspi *f, ...@@ -520,7 +520,7 @@ static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
fspi_writel(f, FSPI_LCKER_LOCK, f->iobase + FSPI_LCKCR); fspi_writel(f, FSPI_LCKER_LOCK, f->iobase + FSPI_LCKCR);
} }
#if CONFIG_IS_ENABLED(CONFIG_CLK) #if CONFIG_IS_ENABLED(CLK)
static int nxp_fspi_clk_prep_enable(struct nxp_fspi *f) static int nxp_fspi_clk_prep_enable(struct nxp_fspi *f)
{ {
int ret; int ret;
...@@ -808,7 +808,7 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f) ...@@ -808,7 +808,7 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
int ret, i; int ret, i;
u32 reg; u32 reg;
#if CONFIG_IS_ENABLED(CONFIG_CLK) #if CONFIG_IS_ENABLED(CLK)
/* disable and unprepare clock to avoid glitch pass to controller */ /* disable and unprepare clock to avoid glitch pass to controller */
nxp_fspi_clk_disable_unprep(f); nxp_fspi_clk_disable_unprep(f);
...@@ -898,7 +898,7 @@ static int nxp_fspi_claim_bus(struct udevice *dev) ...@@ -898,7 +898,7 @@ static int nxp_fspi_claim_bus(struct udevice *dev)
static int nxp_fspi_set_speed(struct udevice *bus, uint speed) static int nxp_fspi_set_speed(struct udevice *bus, uint speed)
{ {
#if CONFIG_IS_ENABLED(CONFIG_CLK) #if CONFIG_IS_ENABLED(CLK)
struct nxp_fspi *f = dev_get_priv(bus); struct nxp_fspi *f = dev_get_priv(bus);
int ret; int ret;
...@@ -924,7 +924,7 @@ static int nxp_fspi_set_mode(struct udevice *bus, uint mode) ...@@ -924,7 +924,7 @@ static int nxp_fspi_set_mode(struct udevice *bus, uint mode)
static int nxp_fspi_ofdata_to_platdata(struct udevice *bus) static int nxp_fspi_ofdata_to_platdata(struct udevice *bus)
{ {
struct nxp_fspi *f = dev_get_priv(bus); struct nxp_fspi *f = dev_get_priv(bus);
#if CONFIG_IS_ENABLED(CONFIG_CLK) #if CONFIG_IS_ENABLED(CLK)
int ret; int ret;
#endif #endif
...@@ -950,7 +950,7 @@ static int nxp_fspi_ofdata_to_platdata(struct udevice *bus) ...@@ -950,7 +950,7 @@ static int nxp_fspi_ofdata_to_platdata(struct udevice *bus)
f->ahb_addr = map_physmem(ahb_addr, ahb_size, MAP_NOCACHE); f->ahb_addr = map_physmem(ahb_addr, ahb_size, MAP_NOCACHE);
f->memmap_phy_size = ahb_size; f->memmap_phy_size = ahb_size;
#if CONFIG_IS_ENABLED(CONFIG_CLK) #if CONFIG_IS_ENABLED(CLK)
ret = clk_get_by_name(bus, "fspi_en", &f->clk_en); ret = clk_get_by_name(bus, "fspi_en", &f->clk_en);
if (ret) { if (ret) {
dev_err(bus, "failed to get fspi_en clock\n"); dev_err(bus, "failed to get fspi_en clock\n");
......
...@@ -106,7 +106,7 @@ static int print_83xx_arb_event(bool force, char *buf, int size) ...@@ -106,7 +106,7 @@ static int print_83xx_arb_event(bool force, char *buf, int size)
if (!force && !gd->arch.arbiter_event_address) if (!force && !gd->arch.arbiter_event_address)
return 0; return 0;
if (CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_FULL)) { if (CONFIG_IS_ENABLED(DISPLAY_AER_FULL)) {
res = snprintf(buf, size, res = snprintf(buf, size,
"Arbiter Event Status:\n" "Arbiter Event Status:\n"
" %s: 0x%08lX\n" " %s: 0x%08lX\n"
...@@ -119,7 +119,7 @@ static int print_83xx_arb_event(bool force, char *buf, int size) ...@@ -119,7 +119,7 @@ static int print_83xx_arb_event(bool force, char *buf, int size)
"Master ID", mstr_id, master[mstr_id], "Master ID", mstr_id, master[mstr_id],
"Transfer Size", tsize_val, tsize_bytes, "Transfer Size", tsize_val, tsize_bytes,
"Transfer Type", ttype, transfer[ttype]); "Transfer Type", ttype, transfer[ttype]);
} else if (CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_BRIEF)) { } else if (CONFIG_IS_ENABLED(DISPLAY_AER_BRIEF)) {
res = snprintf(buf, size, res = snprintf(buf, size,
"Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n", "Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n",
gd->arch.arbiter_event_attributes, gd->arch.arbiter_event_attributes,
...@@ -183,8 +183,8 @@ static int mpc83xx_sysreset_get_status(struct udevice *dev, char *buf, int size) ...@@ -183,8 +183,8 @@ static int mpc83xx_sysreset_get_status(struct udevice *dev, char *buf, int size)
* TODO(mario.six@gdsys.cc): Move this into a dedicated * TODO(mario.six@gdsys.cc): Move this into a dedicated
* arbiter driver * arbiter driver
*/ */
if (CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_FULL) || if (CONFIG_IS_ENABLED(DISPLAY_AER_FULL) ||
CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_BRIEF)) { CONFIG_IS_ENABLED(DISPLAY_AER_BRIEF)) {
/* /*
* If there was a bus monitor reset event, we force the arbiter * If there was a bus monitor reset event, we force the arbiter
* event to be printed * event to be printed
......
...@@ -477,6 +477,10 @@ config ENV_EXT4_DEVICE_AND_PART ...@@ -477,6 +477,10 @@ config ENV_EXT4_DEVICE_AND_PART
If none, first valid partition in device D. If no If none, first valid partition in device D. If no
partition table then means device D. partition table then means device D.
If ENV_EXT4_INTERFACE is set to "mmc" then device 'D' can be omitted,
leaving the string starting with a colon, and the boot device will
be used.
config ENV_EXT4_FILE config ENV_EXT4_FILE
string "Name of the EXT4 file to use for the environment" string "Name of the EXT4 file to use for the environment"
depends on ENV_IS_IN_EXT4 depends on ENV_IS_IN_EXT4
......
...@@ -41,7 +41,21 @@ __weak const char *env_ext4_get_intf(void) ...@@ -41,7 +41,21 @@ __weak const char *env_ext4_get_intf(void)
__weak const char *env_ext4_get_dev_part(void) __weak const char *env_ext4_get_dev_part(void)
{ {
#ifdef CONFIG_MMC
static char *part_str;
if (!part_str) {
part_str = CONFIG_ENV_EXT4_DEVICE_AND_PART;
if (!strcmp(CONFIG_ENV_EXT4_INTERFACE, "mmc") && part_str[0] == ':') {
part_str = "0" CONFIG_ENV_EXT4_DEVICE_AND_PART;
part_str[0] += mmc_get_env_dev();
}
}
return part_str;
#else
return (const char *)CONFIG_ENV_EXT4_DEVICE_AND_PART; return (const char *)CONFIG_ENV_EXT4_DEVICE_AND_PART;
#endif
} }
static int env_ext4_save_buffer(env_t *env_new) static int env_ext4_save_buffer(env_t *env_new)
......
...@@ -29,15 +29,6 @@ ...@@ -29,15 +29,6 @@
# define LOADENV # define LOADENV
#endif #endif
__weak int mmc_get_env_dev(void)
{
#ifdef CONFIG_SYS_MMC_ENV_DEV
return CONFIG_SYS_MMC_ENV_DEV;
#else
return 0;
#endif
}
static char *env_fat_device_and_part(void) static char *env_fat_device_and_part(void)
{ {
#ifdef CONFIG_MMC #ifdef CONFIG_MMC
......
...@@ -24,11 +24,6 @@ ...@@ -24,11 +24,6 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
__weak int mmc_get_env_dev(void)
{
return CONFIG_SYS_MMC_ENV_DEV;
}
#if CONFIG_IS_ENABLED(OF_CONTROL) #if CONFIG_IS_ENABLED(OF_CONTROL)
static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val) static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val)
{ {
......
...@@ -24,149 +24,473 @@ ...@@ -24,149 +24,473 @@
#include <membuff.h> #include <membuff.h>
#include <linux/list.h> #include <linux/list.h>
typedef struct global_data { typedef struct global_data gd_t;
/**
* struct global_data - global data structure
*/
struct global_data {
/**
* @bd: board information
*/
struct bd_info *bd; struct bd_info *bd;
/**
* @flags: global data flags
*
* See &enum gd_flags
*/
unsigned long flags; unsigned long flags;
/**
* @baudrate: baud rate of the serial interface
*/
unsigned int baudrate; unsigned int baudrate;
unsigned long cpu_clk; /* CPU clock in Hz! */ /**
* @cpu_clk: CPU clock rate in Hz
*/
unsigned long cpu_clk;
/**
* @bus_clk: platform clock rate in Hz
*/
unsigned long bus_clk; unsigned long bus_clk;
/**
* @pci_clk: PCI clock rate in Hz
*/
/* We cannot bracket this with CONFIG_PCI due to mpc5xxx */ /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
unsigned long pci_clk; unsigned long pci_clk;
/**
* @mem_clk: memory clock rate in Hz
*/
unsigned long mem_clk; unsigned long mem_clk;
#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) || defined(CONFIG_DM_VIDEO) #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) || defined(CONFIG_DM_VIDEO)
unsigned long fb_base; /* Base address of framebuffer mem */ /**
* @fb_base: base address of frame buffer memory
*/
unsigned long fb_base;
#endif #endif
#if defined(CONFIG_POST) #if defined(CONFIG_POST)
unsigned long post_log_word; /* Record POST activities */ /**
unsigned long post_log_res; /* success of POST test */ * @post_log_word: active POST tests
unsigned long post_init_f_time; /* When post_init_f started */ *
* @post_log_word is a bit mask defining which POST tests are recorded
* (see constants POST_*).
*/
unsigned long post_log_word;
/**
* @post_log_res: POST results
*
* @post_log_res is a bit mask with the POST results. A bit with value 1
* indicates successful execution.
*/
unsigned long post_log_res;
/**
* @post_init_f_time: time in ms when post_init_f() started
*/
unsigned long post_init_f_time;
#endif #endif
#ifdef CONFIG_BOARD_TYPES #ifdef CONFIG_BOARD_TYPES
/**
* @board_type: board type
*
* If a U-Boot configuration supports multiple board types, the actual
* board type may be stored in this field.
*/
unsigned long board_type; unsigned long board_type;
#endif #endif
unsigned long have_console; /* serial_init() was called */ /**
* @have_console: console is available
*
* A value of 1 indicates that serial_init() was called and a console
* is available.
* A value of 0 indicates that console input and output drivers shall
* not be called.
*/
unsigned long have_console;
#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER) #if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
unsigned long precon_buf_idx; /* Pre-Console buffer index */ /**
* @precon_buf_idx: pre-console buffer index
*
* @precon_buf_idx indicates the current position of the buffer used to
* collect output before the console becomes available
*/
unsigned long precon_buf_idx;
#endif #endif
unsigned long env_addr; /* Address of Environment struct */ /**
unsigned long env_valid; /* Environment valid? enum env_valid */ * @env_addr: address of environment structure
unsigned long env_has_init; /* Bitmask of boolean of struct env_location offsets */ *
int env_load_prio; /* Priority of the loaded environment */ * @env_addr contains the address of the structure holding the
* environment variables.
unsigned long ram_base; /* Base address of RAM used by U-Boot */ */
unsigned long ram_top; /* Top address of RAM used by U-Boot */ unsigned long env_addr;
unsigned long relocaddr; /* Start address of U-Boot in RAM */ /**
phys_size_t ram_size; /* RAM size */ * @env_valid: environment is valid
unsigned long mon_len; /* monitor len */ *
unsigned long irq_sp; /* irq stack pointer */ * See &enum env_valid
unsigned long start_addr_sp; /* start_addr_stackpointer */ */
unsigned long env_valid;
/**
* @env_has_init: bit mask indicating environment locations
*
* &enum env_location defines which bit relates to which location
*/
unsigned long env_has_init;
/**
* @env_load_prio: priority of the loaded environment
*/
int env_load_prio;
/**
* @ram_base: base address of RAM used by U-Boot
*/
unsigned long ram_base;
/**
* @ram_top: top address of RAM used by U-Boot
*/
unsigned long ram_top;
/**
* @relocaddr: start address of U-Boot in RAM
*
* After relocation this field indicates the address to which U-Boot
* has been relocated. It can be displayed using the bdinfo command.
* Its value is needed to display the source code when debugging with
* GDB using the 'add-symbol-file u-boot <relocaddr>' command.
*/
unsigned long relocaddr;
/**
* @ram_size: RAM size in bytes
*/
phys_size_t ram_size;
/**
* @mon_len: monitor length in bytes
*/
unsigned long mon_len;
/**
* @irq_sp: IRQ stack pointer
*/
unsigned long irq_sp;
/**
* @start_addr_sp: initial stack pointer address
*/
unsigned long start_addr_sp;
/**
* @reloc_off: relocation offset
*/
unsigned long reloc_off; unsigned long reloc_off;
struct global_data *new_gd; /* relocated global data */ /**
* @new_gd: pointer to relocated global data
*/
struct global_data *new_gd;
#ifdef CONFIG_DM #ifdef CONFIG_DM
struct udevice *dm_root; /* Root instance for Driver Model */ /**
struct udevice *dm_root_f; /* Pre-relocation root instance */ * @dm_root: root instance for Driver Model
struct list_head uclass_root; /* Head of core tree */ */
struct udevice *dm_root;
/**
* @dm_root_f: pre-relocation root instance
*/
struct udevice *dm_root_f;
/**
* @uclass_root: head of core tree
*/
struct list_head uclass_root;
#endif #endif
#ifdef CONFIG_TIMER #ifdef CONFIG_TIMER
struct udevice *timer; /* Timer instance for Driver Model */ /**
* @timer: timer instance for Driver Model
*/
struct udevice *timer;
#endif #endif
/**
const void *fdt_blob; /* Our device tree, NULL if none */ * @fdt_blob: U-Boot's own device tree, NULL if none
void *new_fdt; /* Relocated FDT */ */
unsigned long fdt_size; /* Space reserved for relocated FDT */ const void *fdt_blob;
/**
* @new_fdt: relocated device tree
*/
void *new_fdt;
/**
* @fdt_size: space reserved for relocated device space
*/
unsigned long fdt_size;
#ifdef CONFIG_OF_LIVE #ifdef CONFIG_OF_LIVE
/**
* @of_root: root node of the live tree
*/
struct device_node *of_root; struct device_node *of_root;
#endif #endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT) #if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
const void *multi_dtb_fit; /* uncompressed multi-dtb FIT image */ /**
* @multi_dtb_fit: pointer to uncompressed multi-dtb FIT image
*/
const void *multi_dtb_fit;
#endif #endif
struct jt_funcs *jt; /* jump table */ /**
char env_buf[32]; /* buffer for env_get() before reloc. */ * @jt: jump table
*
* The jump table contains pointers to exported functions. A pointer to
* the jump table is passed to standalone applications.
*/
struct jt_funcs *jt;
/**
* @env_buf: buffer for env_get() before reloc
*/
char env_buf[32];
#ifdef CONFIG_TRACE #ifdef CONFIG_TRACE
void *trace_buff; /* The trace buffer */ /**
* @trace_buff: trace buffer
*
* When tracing function in U-Boot this field points to the buffer
* recording the function calls.
*/
void *trace_buff;
#endif #endif
#if defined(CONFIG_SYS_I2C) #if defined(CONFIG_SYS_I2C)
int cur_i2c_bus; /* current used i2c bus */ /**
* @cur_i2c_bus: currently used I2C bus
*/
int cur_i2c_bus;
#endif #endif
/**
* @timebase_h: high 32 bits of timer
*/
unsigned int timebase_h; unsigned int timebase_h;
/**
* @timebase_l: low 32 bits of timer
*/
unsigned int timebase_l; unsigned int timebase_l;
#if CONFIG_VAL(SYS_MALLOC_F_LEN) #if CONFIG_VAL(SYS_MALLOC_F_LEN)
unsigned long malloc_base; /* base address of early malloc() */ /**
unsigned long malloc_limit; /* limit address */ * @malloc_base: base address of early malloc()
unsigned long malloc_ptr; /* current address */ */
unsigned long malloc_base;
/**
* @malloc_limit: limit address of early malloc()
*/
unsigned long malloc_limit;
/**
* @malloc_ptr: current address of early malloc()
*/
unsigned long malloc_ptr;
#endif #endif
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
struct pci_controller *hose; /* PCI hose for early use */ /**
phys_addr_t pci_ram_top; /* top of region accessible to PCI */ * @hose: PCI hose for early use
*/
struct pci_controller *hose;
/**
* @pci_ram_top: top of region accessible to PCI
*/
phys_addr_t pci_ram_top;
#endif #endif
#ifdef CONFIG_PCI_BOOTDELAY #ifdef CONFIG_PCI_BOOTDELAY
/**
* @pcidelay_done: delay time before scanning of PIC hose expired
*
* If CONFIG_PCI_BOOTDELAY=y, pci_hose_scan() waits for the number of
* milliseconds defined by environment variable pcidelay before
* scanning. Once this delay has expired the flag @pcidelay_done
* is set to 1.
*/
int pcidelay_done; int pcidelay_done;
#endif #endif
struct udevice *cur_serial_dev; /* current serial device */ /**
struct arch_global_data arch; /* architecture-specific data */ * @cur_serial_dev: current serial device
*/
struct udevice *cur_serial_dev;
/**
* @arch: architecture-specific data
*/
struct arch_global_data arch;
#ifdef CONFIG_CONSOLE_RECORD #ifdef CONFIG_CONSOLE_RECORD
struct membuff console_out; /* console output */ /**
struct membuff console_in; /* console input */ * @console_out: output buffer for console recording
*
* This buffer is used to collect output during console recording.
*/
struct membuff console_out;
/**
* @console_in: input buffer for console recording
*
* If console recording is activated, this buffer can be used to
* emulate input.
*/
struct membuff console_in;
#endif #endif
#ifdef CONFIG_DM_VIDEO #ifdef CONFIG_DM_VIDEO
ulong video_top; /* Top of video frame buffer area */ /**
ulong video_bottom; /* Bottom of video frame buffer area */ * @video_top: top of video frame buffer area
*/
ulong video_top;
/**
* @video_bottom: bottom of video frame buffer area
*/
ulong video_bottom;
#endif #endif
#ifdef CONFIG_BOOTSTAGE #ifdef CONFIG_BOOTSTAGE
struct bootstage_data *bootstage; /* Bootstage information */ /**
struct bootstage_data *new_bootstage; /* Relocated bootstage info */ * @bootstage: boot stage information
*/
struct bootstage_data *bootstage;
/**
* @new_bootstage: relocated boot stage information
*/
struct bootstage_data *new_bootstage;
#endif #endif
#ifdef CONFIG_LOG #ifdef CONFIG_LOG
int log_drop_count; /* Number of dropped log messages */ /**
int default_log_level; /* For devices with no filters */ * @log_drop_count: number of dropped log messages
struct list_head log_head; /* List of struct log_device */ *
int log_fmt; /* Mask containing log format info */ * This counter is incremented for each log message which can not
* be processed because logging is not yet available as signaled by
* flag %GD_FLG_LOG_READY in @flags.
*/
int log_drop_count;
/**
* @default_log_level: default logging level
*
* For logging devices without filters @default_log_level defines the
* logging level, cf. &enum log_level_t.
*/
int default_log_level;
/**
* @log_head: list of logging devices
*/
struct list_head log_head;
/**
* @log_fmt: bit mask for logging format
*
* The @log_fmt bit mask selects the fields to be shown in log messages.
* &enum log_fmt defines the bits of the bit mask.
*/
int log_fmt;
#endif #endif
#if CONFIG_IS_ENABLED(BLOBLIST) #if CONFIG_IS_ENABLED(BLOBLIST)
struct bloblist_hdr *bloblist; /* Bloblist information */ /**
struct bloblist_hdr *new_bloblist; /* Relocated blolist info */ * @bloblist: blob list information
*/
struct bloblist_hdr *bloblist;
/**
* @new_bloblist: relocated blob list information
*/
struct bloblist_hdr *new_bloblist;
# ifdef CONFIG_SPL # ifdef CONFIG_SPL
/**
* @spl_handoff: SPL hand-off information
*/
struct spl_handoff *spl_handoff; struct spl_handoff *spl_handoff;
# endif # endif
#endif #endif
#if defined(CONFIG_TRANSLATION_OFFSET) #if defined(CONFIG_TRANSLATION_OFFSET)
fdt_addr_t translation_offset; /* optional translation offset */ /**
* @translation_offset: optional translation offset
*
* See CONFIG_TRANSLATION_OFFSET.
*/
fdt_addr_t translation_offset;
#endif #endif
#if CONFIG_IS_ENABLED(WDT) #if CONFIG_IS_ENABLED(WDT)
/**
* @watchdog_dev: watchdog device
*/
struct udevice *watchdog_dev; struct udevice *watchdog_dev;
#endif #endif
} gd_t; };
#endif
/**
* gd_board_type() - retrieve board type
*
* Return: global board type
*/
#ifdef CONFIG_BOARD_TYPES #ifdef CONFIG_BOARD_TYPES
#define gd_board_type() gd->board_type #define gd_board_type() gd->board_type
#else #else
#define gd_board_type() 0 #define gd_board_type() 0
#endif #endif
/* /**
* Global Data Flags * enum gd_flags - global data flags
*/ *
#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ * See field flags of &struct global_data.
#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ */
#define GD_FLG_SILENT 0x00004 /* Silent mode */ enum gd_flags {
#define GD_FLG_POSTFAIL 0x00008 /* Critical POST test failed */ /**
#define GD_FLG_POSTSTOP 0x00010 /* POST seqeunce aborted */ * @GD_FLG_RELOC: code was relocated to RAM
#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */ */
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ GD_FLG_RELOC = 0x00001,
#define GD_FLG_ENV_READY 0x00080 /* Env. imported into hash table */ /**
#define GD_FLG_SERIAL_READY 0x00100 /* Pre-reloc serial console ready */ * @GD_FLG_DEVINIT: devices have been initialized
#define GD_FLG_FULL_MALLOC_INIT 0x00200 /* Full malloc() is ready */ */
#define GD_FLG_SPL_INIT 0x00400 /* spl_init() has been called */ GD_FLG_DEVINIT = 0x00002,
#define GD_FLG_SKIP_RELOC 0x00800 /* Don't relocate */ /**
#define GD_FLG_RECORD 0x01000 /* Record console */ * @GD_FLG_SILENT: silent mode
#define GD_FLG_ENV_DEFAULT 0x02000 /* Default variable flag */ */
#define GD_FLG_SPL_EARLY_INIT 0x04000 /* Early SPL init is done */ GD_FLG_SILENT = 0x00004,
#define GD_FLG_LOG_READY 0x08000 /* Log system is ready for use */ /**
#define GD_FLG_WDT_READY 0x10000 /* Watchdog is ready for use */ * @GD_FLG_POSTFAIL: critical POST test failed
#define GD_FLG_SKIP_LL_INIT 0x20000 /* Don't perform low-level init */ */
#define GD_FLG_SMP_READY 0x40000 /* SMP init is complete */ GD_FLG_POSTFAIL = 0x00008,
/**
* @GD_FLG_POSTSTOP: POST sequence aborted
*/
GD_FLG_POSTSTOP = 0x00010,
/**
* @GD_FLG_LOGINIT: log Buffer has been initialized
*/
GD_FLG_LOGINIT = 0x00020,
/**
* @GD_FLG_DISABLE_CONSOLE: disable console (in & out)
*/
GD_FLG_DISABLE_CONSOLE = 0x00040,
/**
* @GD_FLG_ENV_READY: environment imported into hash table
*/
GD_FLG_ENV_READY = 0x00080,
/**
* @GD_FLG_SERIAL_READY: pre-relocation serial console ready
*/
GD_FLG_SERIAL_READY = 0x00100,
/**
* @GD_FLG_FULL_MALLOC_INIT: full malloc() is ready
*/
GD_FLG_FULL_MALLOC_INIT = 0x00200,
/**
* @GD_FLG_SPL_INIT: spl_init() has been called
*/
GD_FLG_SPL_INIT = 0x00400,
/**
* @GD_FLG_SKIP_RELOC: don't relocate
*/
GD_FLG_SKIP_RELOC = 0x00800,
/**
* @GD_FLG_RECORD: record console
*/
GD_FLG_RECORD = 0x01000,
/**
* @GD_FLG_ENV_DEFAULT: default variable flag
*/
GD_FLG_ENV_DEFAULT = 0x02000,
/**
* @GD_FLG_SPL_EARLY_INIT: early SPL initialization is done
*/
GD_FLG_SPL_EARLY_INIT = 0x04000,
/**
* @GD_FLG_LOG_READY: log system is ready for use
*/
GD_FLG_LOG_READY = 0x08000,
/**
* @GD_FLG_WDT_READY: watchdog is ready for use
*/
GD_FLG_WDT_READY = 0x10000,
/**
* @GD_FLG_SKIP_LL_INIT: don't perform low-level initialization
*/
GD_FLG_SKIP_LL_INIT = 0x20000,
/**
* @GD_FLG_SMP_READY: SMP initialization is complete
*/
GD_FLG_SMP_READY = 0x40000,
};
#endif /* __ASSEMBLY__ */
#endif /* __ASM_GENERIC_GBL_DATA_H */ #endif /* __ASM_GENERIC_GBL_DATA_H */
...@@ -75,4 +75,14 @@ void board_quiesce_devices(void); ...@@ -75,4 +75,14 @@ void board_quiesce_devices(void);
*/ */
void switch_to_non_secure_mode(void); void switch_to_non_secure_mode(void);
/**
* arch_preboot_os() - arch specific configuration before booting
*/
void arch_preboot_os(void);
/**
* board_preboot_os() - board specific configuration before booting
*/
void board_preboot_os(void);
#endif #endif
...@@ -359,4 +359,7 @@ int fdt_update_ethernet_dt(void *blob); ...@@ -359,4 +359,7 @@ int fdt_update_ethernet_dt(void *blob);
#ifdef CONFIG_FSL_MC_ENET #ifdef CONFIG_FSL_MC_ENET
void fdt_fixup_board_enet(void *blob); void fdt_fixup_board_enet(void *blob);
#endif #endif
#ifdef CONFIG_CMD_PSTORE
void fdt_fixup_pstore(void *blob);
#endif
#endif /* ifndef __FDT_SUPPORT_H */ #endif /* ifndef __FDT_SUPPORT_H */
...@@ -91,13 +91,13 @@ uint64_t notrace get_ticks(void) ...@@ -91,13 +91,13 @@ uint64_t notrace get_ticks(void)
ret = dm_timer_init(); ret = dm_timer_init();
if (ret) if (ret)
return ret; panic("Could not initialize timer (err %d)\n", ret);
#endif #endif
} }
ret = timer_get_count(gd->timer, &count); ret = timer_get_count(gd->timer, &count);
if (ret) if (ret)
return ret; panic("Could not read count from timer (err %d)\n", ret);
return count; return count;
} }
......
...@@ -2365,6 +2365,12 @@ sub u_boot_line { ...@@ -2365,6 +2365,12 @@ sub u_boot_line {
ERROR("DISABLE_FDT_OR_INITRD_RELOC", ERROR("DISABLE_FDT_OR_INITRD_RELOC",
"fdt or initrd relocation disabled at boot time\n" . $herecurr); "fdt or initrd relocation disabled at boot time\n" . $herecurr);
} }
# Do not use CONFIG_ prefix in CONFIG_IS_ENABLED() calls
if ($line =~ /^\+.*CONFIG_IS_ENABLED\(CONFIG_\w*\).*/) {
ERROR("CONFIG_IS_ENABLED_CONFIG",
"CONFIG_IS_ENABLED() takes values without the CONFIG_ prefix\n" . $herecurr);
}
} }
sub process { sub process {
......
...@@ -57,17 +57,17 @@ static int dm_test_button_label(struct unit_test_state *uts) ...@@ -57,17 +57,17 @@ static int dm_test_button_label(struct unit_test_state *uts)
{ {
struct udevice *dev, *cmp; struct udevice *dev, *cmp;
ut_assertok(button_get_by_label("summer", &dev)); ut_assertok(button_get_by_label("button1", &dev));
ut_asserteq(1, device_active(dev)); ut_asserteq(1, device_active(dev));
ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &cmp)); ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &cmp));
ut_asserteq_ptr(dev, cmp); ut_asserteq_ptr(dev, cmp);
ut_assertok(button_get_by_label("christmas", &dev)); ut_assertok(button_get_by_label("button2", &dev));
ut_asserteq(1, device_active(dev)); ut_asserteq(1, device_active(dev));
ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &cmp)); ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &cmp));
ut_asserteq_ptr(dev, cmp); ut_asserteq_ptr(dev, cmp);
ut_asserteq(-ENODEV, button_get_by_label("spring", &dev)); ut_asserteq(-ENODEV, button_get_by_label("nobutton", &dev));
return 0; return 0;
} }
......
...@@ -4,16 +4,34 @@ import pytest ...@@ -4,16 +4,34 @@ import pytest
@pytest.mark.boardspec('sandbox') @pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_button') @pytest.mark.buildconfigspec('cmd_button')
def test_button_exit_statuses(u_boot_console): def test_button_list(u_boot_console):
"""Test that non-input button commands correctly return the command """Test listing buttons"""
success/failure status."""
expected_response = 'rc:0'
response = u_boot_console.run_command('button list; echo rc:$?') response = u_boot_console.run_command('button list; echo rc:$?')
assert(expected_response in response) assert('button1' in response)
response = u_boot_console.run_command('button summer; echo rc:$?') assert('button2' in response)
assert(expected_response in response) assert('rc:0' in response)
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_button')
@pytest.mark.buildconfigspec('cmd_gpio')
def test_button_return_code(u_boot_console):
"""Test correct reporting of the button status
The sandbox gpio driver reports the last output value as input value.
We can use this in our test to emulate different input statuses.
"""
u_boot_console.run_command('gpio set a3; gpio input a3');
response = u_boot_console.run_command('button button1; echo rc:$?')
assert('on' in response)
assert('rc:0' in response)
u_boot_console.run_command('gpio clear a3; gpio input a3');
response = u_boot_console.run_command('button button1; echo rc:$?')
assert('off' in response)
assert('rc:1' in response)
expected_response = 'rc:1'
response = u_boot_console.run_command('button nonexistent-button; echo rc:$?') response = u_boot_console.run_command('button nonexistent-button; echo rc:$?')
assert(expected_response in response) assert('not found' in response)
assert('rc:1' in response)
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2020, Collabora
# Author: Frédéric Danis <frederic.danis@collabora.com>
import pytest
import u_boot_utils
import os
import tempfile
import shutil
PSTORE_ADDR=0x3000000
PSTORE_LENGTH=0x100000
PSTORE_PANIC1='test/py/tests/test_pstore_data_panic1.hex'
PSTORE_PANIC2='test/py/tests/test_pstore_data_panic2.hex'
PSTORE_CONSOLE='test/py/tests/test_pstore_data_console.hex'
ADDR=0x01000008
def load_pstore(u_boot_console):
"""Load PStore records from sample files"""
output = u_boot_console.run_command_list([
'host load hostfs - 0x%x %s' % (PSTORE_ADDR,
os.path.join(u_boot_console.config.source_dir, PSTORE_PANIC1)),
'host load hostfs - 0x%x %s' % (PSTORE_ADDR + 4096,
os.path.join(u_boot_console.config.source_dir, PSTORE_PANIC2)),
'host load hostfs - 0x%x %s' % (PSTORE_ADDR + 253 * 4096,
os.path.join(u_boot_console.config.source_dir, PSTORE_CONSOLE)),
'pstore set 0x%x 0x%x' % (PSTORE_ADDR, PSTORE_LENGTH)])
def checkfile(u_boot_console, path, filesize, checksum):
"""Check file against MD5 checksum"""
output = u_boot_console.run_command_list([
'load hostfs - %x %s' % (ADDR, path),
'printenv filesize'])
assert('filesize=%x' % (filesize) in ''.join(output))
output = u_boot_console.run_command_list([
'md5sum %x $filesize' % ADDR,
'setenv filesize'])
assert(checksum in ''.join(output))
@pytest.mark.buildconfigspec('cmd_pstore')
def test_pstore_display_all_records(u_boot_console):
"""Test that pstore displays all records."""
u_boot_console.run_command('')
load_pstore(u_boot_console)
response = u_boot_console.run_command('pstore display')
assert('**** Dump' in response)
assert('**** Console' in response)
@pytest.mark.buildconfigspec('cmd_pstore')
def test_pstore_display_one_record(u_boot_console):
"""Test that pstore displays only one record."""
u_boot_console.run_command('')
load_pstore(u_boot_console)
response = u_boot_console.run_command('pstore display dump 1')
assert('Panic#2 Part1' in response)
assert('**** Console' not in response)
@pytest.mark.buildconfigspec('cmd_pstore')
def test_pstore_save_records(u_boot_console):
"""Test that pstore saves all records."""
outdir = tempfile.mkdtemp()
u_boot_console.run_command('')
load_pstore(u_boot_console)
u_boot_console.run_command('pstore save hostfs - %s' % (outdir))
checkfile(u_boot_console, '%s/dmesg-ramoops-0' % (outdir), 3798, '8059335ab4cfa62c77324c491659c503')
checkfile(u_boot_console, '%s/dmesg-ramoops-1' % (outdir), 4035, '3ff30df3429d81939c75d0070b5187b9')
checkfile(u_boot_console, '%s/console-ramoops-0' % (outdir), 4084, 'bb44de4a9b8ebd9b17ae98003287325b')
shutil.rmtree(outdir)
...@@ -405,6 +405,12 @@ index 0000000..2234c87 ...@@ -405,6 +405,12 @@ index 0000000..2234c87
pm.add_line('include/myfile.h', '#include <dm.h>') pm.add_line('include/myfile.h', '#include <dm.h>')
self.checkSingleMessage(pm, 'BARRED_INCLUDE_IN_HDR', 'error') self.checkSingleMessage(pm, 'BARRED_INCLUDE_IN_HDR', 'error')
def testConfigIsEnabledConfig(self):
"""Test for accidental CONFIG_IS_ENABLED(CONFIG_*) calls"""
pm = PatchMaker()
pm.add_line('common/main.c', 'if (CONFIG_IS_ENABLED(CONFIG_CLK))')
self.checkSingleMessage(pm, 'CONFIG_IS_ENABLED_CONFIG', 'error')
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册