summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig31
-rw-r--r--cmd/Makefile3
-rw-r--r--cmd/bootefi.c187
-rw-r--r--cmd/clk.c37
-rw-r--r--cmd/conitrace.c51
-rw-r--r--cmd/elf.c5
-rw-r--r--cmd/fat.c34
-rw-r--r--cmd/nvedit.c3
-rw-r--r--cmd/osd.c291
-rw-r--r--cmd/ubi.c3
-rw-r--r--cmd/ubifs.c40
-rw-r--r--cmd/w1.c126
12 files changed, 715 insertions, 96 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 12d19fd675..7ed3c9c3b3 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -304,11 +304,6 @@ config CMD_XIMG
help
Extract a part of a multi-image.
-config CMD_POWEROFF
- bool "poweroff"
- help
- Poweroff/Shutdown the system
-
config CMD_SPL
bool "spl export - Export boot information for Falcon boot"
depends on SPL
@@ -832,6 +827,13 @@ config CMD_I2C
help
I2C support.
+config CMD_W1
+ depends on W1
+ default y if W1
+ bool "w1 - Support for Dallas 1-Wire protocol"
+ help
+ Dallas 1-wire protocol support
+
config CMD_LOADB
bool "loadb"
default y
@@ -919,6 +921,14 @@ config CMD_ONENAND
and erasing blocks. It allso provides a way to show and change
bad blocks, and test the device.
+config CMD_OSD
+ bool "osd"
+ help
+ Enable the 'osd' command which allows to query information from and
+ write text data to a on-screen display (OSD) device; a virtual device
+ associated with a display capable of displaying a text overlay on the
+ display it's associated with..
+
config CMD_PART
bool "part"
select HAVE_BLOCK_DEVICE
@@ -943,6 +953,11 @@ config CMD_PCMCIA
about 1990. These devices are typically removable memory or network
cards using a standard 68-pin connector.
+config CMD_POWEROFF
+ bool "poweroff"
+ help
+ Poweroff/Shutdown the system
+
config CMD_READ
bool "read - Read binary data from a partition"
help
@@ -1344,6 +1359,12 @@ config CMD_CACHE
help
Enable the "icache" and "dcache" commands
+config CMD_CONITRACE
+ bool "conitrace - trace console input codes"
+ help
+ Enable the 'conitrace' command which displays the codes received
+ from the console input as hexadecimal numbers.
+
config CMD_DISPLAY
bool "Enable the 'display' command, for character displays"
help
diff --git a/cmd/Makefile b/cmd/Makefile
index 3ba65d4d93..d9cdaf6064 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_CMD_CACHE) += cache.o
obj-$(CONFIG_CMD_CBFS) += cbfs.o
obj-$(CONFIG_CMD_CLK) += clk.o
obj-$(CONFIG_CMD_CONFIG) += config.o
+obj-$(CONFIG_CMD_CONITRACE) += conitrace.o
obj-$(CONFIG_CMD_CONSOLE) += console.o
obj-$(CONFIG_CMD_CPU) += cpu.o
obj-$(CONFIG_DATAFLASH_MMC_SELECT) += dataflash_mmc_mux.o
@@ -97,6 +98,7 @@ obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o
obj-$(CONFIG_CMD_NAND) += nand.o
obj-$(CONFIG_CMD_NET) += net.o
obj-$(CONFIG_CMD_ONENAND) += onenand.o
+obj-$(CONFIG_CMD_OSD) += osd.o
obj-$(CONFIG_CMD_PART) += part.o
ifdef CONFIG_PCI
obj-$(CONFIG_CMD_PCI) += pci.o
@@ -146,6 +148,7 @@ obj-$(CONFIG_CMD_THOR_DOWNLOAD) += thordown.o
obj-$(CONFIG_CMD_XIMG) += ximg.o
obj-$(CONFIG_CMD_YAFFS2) += yaffs2.o
obj-$(CONFIG_CMD_SPL) += spl.o
+obj-$(CONFIG_CMD_W1) += w1.o
obj-$(CONFIG_CMD_ZIP) += zip.o
obj-$(CONFIG_CMD_ZFS) += zfs.o
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index b60c151fb4..82d755ceb3 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -49,6 +49,11 @@ efi_status_t efi_init_obj_list(void)
if (ret != EFI_SUCCESS)
goto out;
+ /* Initialize root node */
+ ret = efi_root_node_register();
+ if (ret != EFI_SUCCESS)
+ goto out;
+
/* Initialize EFI driver uclass */
ret = efi_driver_init();
if (ret != EFI_SUCCESS)
@@ -116,32 +121,47 @@ static void set_load_options(struct efi_loaded_image *loaded_image_info,
{
size_t size;
const char *env = env_get(env_var);
+ u16 *pos;
loaded_image_info->load_options = NULL;
loaded_image_info->load_options_size = 0;
if (!env)
return;
- size = strlen(env) + 1;
+ size = utf8_utf16_strlen(env) + 1;
loaded_image_info->load_options = calloc(size, sizeof(u16));
if (!loaded_image_info->load_options) {
printf("ERROR: Out of memory\n");
return;
}
- utf8_to_utf16(loaded_image_info->load_options, (u8 *)env, size);
+ pos = loaded_image_info->load_options;
+ utf8_utf16_strcpy(&pos, env);
loaded_image_info->load_options_size = size * 2;
}
-static void *copy_fdt(void *fdt)
+/**
+ * copy_fdt() - Copy the device tree to a new location available to EFI
+ *
+ * The FDT is relocated into a suitable location within the EFI memory map.
+ * An additional 12KB is added to the space in case the device tree needs to be
+ * expanded later with fdt_open_into().
+ *
+ * @fdt_addr: On entry, address of start of FDT. On exit, address of relocated
+ * FDT start
+ * @fdt_sizep: Returns new size of FDT, including
+ * @return new relocated address of FDT
+ */
+static efi_status_t copy_fdt(ulong *fdt_addrp, ulong *fdt_sizep)
{
- u64 fdt_size = fdt_totalsize(fdt);
unsigned long fdt_ram_start = -1L, fdt_pages;
+ efi_status_t ret = 0;
+ void *fdt, *new_fdt;
u64 new_fdt_addr;
- void *new_fdt;
+ uint fdt_size;
int i;
- for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
- u64 ram_start = gd->bd->bi_dram[i].start;
- u64 ram_size = gd->bd->bi_dram[i].size;
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ u64 ram_start = gd->bd->bi_dram[i].start;
+ u64 ram_size = gd->bd->bi_dram[i].size;
if (!ram_size)
continue;
@@ -154,30 +174,37 @@ static void *copy_fdt(void *fdt)
* Give us at least 4KB of breathing room in case the device tree needs
* to be expanded later. Round up to the nearest EFI page boundary.
*/
- fdt_size += 4096;
+ fdt = map_sysmem(*fdt_addrp, 0);
+ fdt_size = fdt_totalsize(fdt);
+ fdt_size += 4096 * 3;
fdt_size = ALIGN(fdt_size + EFI_PAGE_SIZE - 1, EFI_PAGE_SIZE);
fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
- /* Safe fdt location is at 128MB */
- new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size;
- if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
- EFI_RUNTIME_SERVICES_DATA, fdt_pages,
- &new_fdt_addr) != EFI_SUCCESS) {
+ /* Safe fdt location is at 127MB */
+ new_fdt_addr = fdt_ram_start + (127 * 1024 * 1024) + fdt_size;
+ ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+ EFI_RUNTIME_SERVICES_DATA, fdt_pages,
+ &new_fdt_addr);
+ if (ret != EFI_SUCCESS) {
/* If we can't put it there, put it somewhere */
new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size);
- if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
- EFI_RUNTIME_SERVICES_DATA, fdt_pages,
- &new_fdt_addr) != EFI_SUCCESS) {
+ ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+ EFI_RUNTIME_SERVICES_DATA, fdt_pages,
+ &new_fdt_addr);
+ if (ret != EFI_SUCCESS) {
printf("ERROR: Failed to reserve space for FDT\n");
- return NULL;
+ goto done;
}
}
- new_fdt = (void*)(ulong)new_fdt_addr;
+ new_fdt = map_sysmem(new_fdt_addr, fdt_size);
memcpy(new_fdt, fdt, fdt_totalsize(fdt));
fdt_set_totalsize(new_fdt, fdt_size);
- return new_fdt;
+ *fdt_addrp = new_fdt_addr;
+ *fdt_sizep = fdt_size;
+done:
+ return ret;
}
static efi_status_t efi_do_enter(
@@ -250,22 +277,27 @@ static void efi_carve_out_dt_rsv(void *fdt)
}
}
-static efi_status_t efi_install_fdt(void *fdt)
+static efi_status_t efi_install_fdt(ulong fdt_addr)
{
bootm_headers_t img = { 0 };
- ulong fdt_pages, fdt_size, fdt_start, fdt_end;
+ ulong fdt_pages, fdt_size, fdt_start;
efi_status_t ret;
+ void *fdt;
+ fdt = map_sysmem(fdt_addr, 0);
if (fdt_check_header(fdt)) {
printf("ERROR: invalid device tree\n");
return EFI_INVALID_PARAMETER;
}
/* Prepare fdt for payload */
- fdt = copy_fdt(fdt);
- if (!fdt)
- return EFI_OUT_OF_RESOURCES;
+ ret = copy_fdt(&fdt_addr, &fdt_size);
+ if (ret)
+ return ret;
+ unmap_sysmem(fdt);
+ fdt = map_sysmem(fdt_addr, 0);
+ fdt_size = fdt_totalsize(fdt);
if (image_setup_libfdt(&img, fdt, 0, NULL)) {
printf("ERROR: failed to process device tree\n");
return EFI_LOAD_ERROR;
@@ -279,30 +311,35 @@ static efi_status_t efi_install_fdt(void *fdt)
return EFI_OUT_OF_RESOURCES;
/* And reserve the space in the memory map */
- fdt_start = ((ulong)fdt) & ~EFI_PAGE_MASK;
- fdt_end = ((ulong)fdt) + fdt_totalsize(fdt);
- fdt_size = (fdt_end - fdt_start) + EFI_PAGE_MASK;
+ fdt_start = fdt_addr;
fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
- /* Give a bootloader the chance to modify the device tree */
- fdt_pages += 2;
+
ret = efi_add_memory_map(fdt_start, fdt_pages,
EFI_BOOT_SERVICES_DATA, true);
+
return ret;
}
-/*
- * Load an EFI payload into a newly allocated piece of memory, register all
- * EFI objects it would want to access and jump to it.
+/**
+ * do_bootefi_exec() - execute EFI binary
+ *
+ * @efi: address of the binary
+ * @device_path: path of the device from which the binary was loaded
+ * @image_path: device path of the binary
+ * Return: status code
+ *
+ * Load the EFI binary into a newly assigned memory unwinding the relocation
+ * information, install the loaded image protocol, and call the binary.
*/
static efi_status_t do_bootefi_exec(void *efi,
struct efi_device_path *device_path,
struct efi_device_path *image_path)
{
- struct efi_loaded_image loaded_image_info = {};
- struct efi_object loaded_image_info_obj = {};
- struct efi_object mem_obj = {};
+ efi_handle_t mem_handle = NULL;
struct efi_device_path *memdp = NULL;
efi_status_t ret;
+ struct efi_loaded_image_obj *image_handle = NULL;
+ struct efi_loaded_image *loaded_image_info = NULL;
EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
struct efi_system_table *st);
@@ -310,16 +347,21 @@ static efi_status_t do_bootefi_exec(void *efi,
/*
* Special case for efi payload not loaded from disk, such as
* 'bootefi hello' or for example payload loaded directly into
- * memory via jtag/etc:
+ * memory via jtag, etc:
*/
if (!device_path && !image_path) {
printf("WARNING: using memory device/image path, this may confuse some payloads!\n");
/* actual addresses filled in after efi_load_pe() */
memdp = efi_dp_from_mem(0, 0, 0);
device_path = image_path = memdp;
- efi_add_handle(&mem_obj);
-
- ret = efi_add_protocol(mem_obj.handle, &efi_guid_device_path,
+ /*
+ * Grub expects that the device path of the loaded image is
+ * installed on a handle.
+ */
+ ret = efi_create_handle(&mem_handle);
+ if (ret != EFI_SUCCESS)
+ goto exit;
+ ret = efi_add_protocol(mem_handle, &efi_guid_device_path,
device_path);
if (ret != EFI_SUCCESS)
goto exit;
@@ -327,8 +369,10 @@ static efi_status_t do_bootefi_exec(void *efi,
assert(device_path && image_path);
}
- efi_setup_loaded_image(&loaded_image_info, &loaded_image_info_obj,
- device_path, image_path);
+ ret = efi_setup_loaded_image(device_path, image_path, &image_handle,
+ &loaded_image_info);
+ if (ret != EFI_SUCCESS)
+ goto exit;
/*
* gd lives in a fixed register which may get clobbered while we execute
@@ -337,9 +381,9 @@ static efi_status_t do_bootefi_exec(void *efi,
efi_save_gd();
/* Transfer environment variable bootargs as load options */
- set_load_options(&loaded_image_info, "bootargs");
+ set_load_options(loaded_image_info, "bootargs");
/* Load the EFI payload */
- entry = efi_load_pe(efi, &loaded_image_info);
+ entry = efi_load_pe(image_handle, efi, loaded_image_info);
if (!entry) {
ret = EFI_LOAD_ERROR;
goto exit;
@@ -347,10 +391,10 @@ static efi_status_t do_bootefi_exec(void *efi,
if (memdp) {
struct efi_device_path_memory *mdp = (void *)memdp;
- mdp->memory_type = loaded_image_info.image_code_type;
- mdp->start_address = (uintptr_t)loaded_image_info.image_base;
+ mdp->memory_type = loaded_image_info->image_code_type;
+ mdp->start_address = (uintptr_t)loaded_image_info->image_base;
mdp->end_address = mdp->start_address +
- loaded_image_info.image_size;
+ loaded_image_info->image_size;
}
/* we don't support much: */
@@ -360,8 +404,8 @@ static efi_status_t do_bootefi_exec(void *efi,
/* Call our payload! */
debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
- if (setjmp(&loaded_image_info.exit_jmp)) {
- ret = loaded_image_info.exit_status;
+ if (setjmp(&image_handle->exit_jmp)) {
+ ret = image_handle->exit_status;
goto exit;
}
@@ -373,7 +417,7 @@ static efi_status_t do_bootefi_exec(void *efi,
/* Move into EL2 and keep running there */
armv8_switch_to_el2((ulong)entry,
- (ulong)&loaded_image_info_obj.handle,
+ (ulong)image_handle,
(ulong)&systab, 0, (ulong)efi_run_in_el2,
ES_TO_AARCH64);
@@ -390,7 +434,7 @@ static efi_status_t do_bootefi_exec(void *efi,
secure_ram_addr(_do_nonsec_entry)(
efi_run_in_hyp,
(uintptr_t)entry,
- (uintptr_t)loaded_image_info_obj.handle,
+ (uintptr_t)image_handle,
(uintptr_t)&systab);
/* Should never reach here, efi exits with longjmp */
@@ -398,13 +442,14 @@ static efi_status_t do_bootefi_exec(void *efi,
}
#endif
- ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry);
+ ret = efi_do_enter(image_handle, &systab, entry);
exit:
/* image has returned, loaded-image obj goes *poof*: */
- list_del(&loaded_image_info_obj.link);
- if (mem_obj.handle)
- list_del(&mem_obj.link);
+ if (image_handle)
+ efi_delete_handle(&image_handle->parent);
+ if (mem_handle)
+ efi_delete_handle(mem_handle);
return ret;
}
@@ -443,7 +488,6 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char *saddr;
efi_status_t r;
unsigned long fdt_addr;
- void *fdt;
/* Allow unaligned memory access */
allow_unaligned();
@@ -464,8 +508,7 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (!fdt_addr && *argv[2] != '0')
return CMD_RET_USAGE;
/* Install device tree */
- fdt = map_sysmem(fdt_addr, 0);
- r = efi_install_fdt(fdt);
+ r = efi_install_fdt(fdt_addr);
if (r != EFI_SUCCESS) {
printf("ERROR: failed to install device tree\n");
return CMD_RET_FAILURE;
@@ -489,8 +532,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#endif
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
if (!strcmp(argv[1], "selftest")) {
- struct efi_loaded_image loaded_image_info = {};
- struct efi_object loaded_image_info_obj = {};
+ struct efi_loaded_image_obj *image_handle;
+ struct efi_loaded_image *loaded_image_info;
/* Construct a dummy device path. */
bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
@@ -498,9 +541,12 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
(uintptr_t)&efi_selftest);
bootefi_image_path = efi_dp_from_file(NULL, 0, "\\selftest");
- efi_setup_loaded_image(&loaded_image_info,
- &loaded_image_info_obj,
- bootefi_device_path, bootefi_image_path);
+ r = efi_setup_loaded_image(bootefi_device_path,
+ bootefi_image_path, &image_handle,
+ &loaded_image_info);
+ if (r != EFI_SUCCESS)
+ return CMD_RET_FAILURE;
+
/*
* gd lives in a fixed register which may get clobbered while we
* execute the payload. So save it here and restore it on every
@@ -508,12 +554,12 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*/
efi_save_gd();
/* Transfer environment variable efi_selftest as load options */
- set_load_options(&loaded_image_info, "efi_selftest");
+ set_load_options(loaded_image_info, "efi_selftest");
/* Execute the test */
- r = efi_selftest(loaded_image_info_obj.handle, &systab);
+ r = efi_selftest(image_handle, &systab);
efi_restore_gd();
- free(loaded_image_info.load_options);
- list_del(&loaded_image_info_obj.link);
+ free(loaded_image_info->load_options);
+ efi_delete_handle(&image_handle->parent);
return r != EFI_SUCCESS;
} else
#endif
@@ -575,6 +621,13 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
char filename[32] = { 0 }; /* dp->str is u16[32] long */
char *s;
+ /* efi_set_bootdev is typically called repeatedly, recover memory */
+ efi_free_pool(bootefi_device_path);
+ efi_free_pool(bootefi_image_path);
+ /* If blk_get_device_part_str fails, avoid duplicate free. */
+ bootefi_device_path = NULL;
+ bootefi_image_path = NULL;
+
if (strcmp(dev, "Net")) {
struct blk_desc *desc;
disk_partition_t fs_partition;
diff --git a/cmd/clk.c b/cmd/clk.c
index 73fb25092b..fd4231589c 100644
--- a/cmd/clk.c
+++ b/cmd/clk.c
@@ -5,11 +5,48 @@
#include <common.h>
#include <command.h>
#include <clk.h>
+#if defined(CONFIG_DM) && defined(CONFIG_CLK)
+#include <dm.h>
+#include <dm/device-internal.h>
+#endif
int __weak soc_clk_dump(void)
{
+#if defined(CONFIG_DM) && defined(CONFIG_CLK)
+ struct udevice *dev;
+ struct uclass *uc;
+ struct clk clk;
+ int ret;
+
+ /* Device addresses start at 1 */
+ ret = uclass_get(UCLASS_CLK, &uc);
+ if (ret)
+ return ret;
+
+ uclass_foreach_dev(dev, uc) {
+ memset(&clk, 0, sizeof(clk));
+ ret = device_probe(dev);
+ if (ret) {
+ printf("%-30.30s : ? Hz\n", dev->name);
+ continue;
+ }
+
+ ret = clk_request(dev, &clk);
+ if (ret) {
+ printf("%-30.30s : ? Hz\n", dev->name);
+ continue;
+ }
+
+ printf("%-30.30s : %lu Hz\n", dev->name, clk_get_rate(&clk));
+
+ clk_free(&clk);
+ }
+
+ return 0;
+#else
puts("Not implemented\n");
return 1;
+#endif
}
static int do_clk_dump(cmd_tbl_t *cmdtp, int flag, int argc,
diff --git a/cmd/conitrace.c b/cmd/conitrace.c
new file mode 100644
index 0000000000..85c5422b7e
--- /dev/null
+++ b/cmd/conitrace.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'conitrace' command prints the codes received from the console input as
+ * hexadecimal numbers.
+ *
+ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+#include <common.h>
+#include <command.h>
+
+static int do_conitrace(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ bool first = true;
+
+ printf("Waiting for your input\n");
+ printf("To terminate type 'x'\n");
+
+ /* Empty input buffer */
+ while (tstc())
+ getc();
+
+ for (;;) {
+ int c = getc();
+
+ if (first && (c == 'x' || c == 'X'))
+ break;
+
+ printf("%02x ", c);
+ first = false;
+
+ /* 1 ms delay - serves to detect separate keystrokes */
+ udelay(1000);
+ if (!tstc()) {
+ printf("\n");
+ first = true;
+ }
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char conitrace_help_text[] = "";
+#endif
+
+U_BOOT_CMD_COMPLETE(
+ conitrace, 2, 0, do_conitrace,
+ "trace console input",
+ conitrace_help_text, NULL
+);
diff --git a/cmd/elf.c b/cmd/elf.c
index c8e6e7424c..7bad1f80d4 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -219,7 +219,10 @@ static unsigned long load_elf_image_shdr(unsigned long addr)
memcpy((void *)(uintptr_t)shdr->sh_addr,
(const void *)image, shdr->sh_size);
}
- flush_cache(shdr->sh_addr, shdr->sh_size);
+ flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+ roundup((shdr->sh_addr + shdr->sh_size),
+ ARCH_DMA_MINALIGN) -
+ rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
}
return ehdr->e_entry;
diff --git a/cmd/fat.c b/cmd/fat.c
index 03de5d11af..4b9a7eaab0 100644
--- a/cmd/fat.c
+++ b/cmd/fat.c
@@ -104,6 +104,7 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
int ret;
unsigned long addr;
unsigned long count;
+ long offset;
struct blk_desc *dev_desc = NULL;
disk_partition_t info;
int dev = 0;
@@ -126,9 +127,11 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
}
addr = simple_strtoul(argv[3], NULL, 16);
count = (argc <= 5) ? 0 : simple_strtoul(argv[5], NULL, 16);
+ /* offset should be a hex, but "-1" is allowed */
+ offset = (argc <= 6) ? 0 : simple_strtol(argv[6], NULL, 16);
buf = map_sysmem(addr, count);
- ret = file_fat_write(argv[4], buf, 0, count, &size);
+ ret = file_fat_write(argv[4], buf, offset, count, &size);
unmap_sysmem(buf);
if (ret < 0) {
printf("\n** Unable to write \"%s\" from %s %d:%d **\n",
@@ -142,10 +145,35 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
}
U_BOOT_CMD(
- fatwrite, 6, 0, do_fat_fswrite,
+ fatwrite, 7, 0, do_fat_fswrite,
"write file into a dos filesystem",
- "<interface> <dev[:part]> <addr> <filename> [<bytes>]\n"
+ "<interface> <dev[:part]> <addr> <filename> [<bytes> [<offset>]]\n"
" - write file 'filename' from the address 'addr' in RAM\n"
" to 'dev' on 'interface'"
);
+
+static int do_fat_rm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ return do_rm(cmdtp, flag, argc, argv, FS_TYPE_FAT);
+}
+
+U_BOOT_CMD(
+ fatrm, 4, 1, do_fat_rm,
+ "delete a file",
+ "<interface> [<dev[:part]>] <filename>\n"
+ " - delete a file from 'dev' on 'interface'"
+);
+
+static int do_fat_mkdir(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_mkdir(cmdtp, flag, argc, argv, FS_TYPE_FAT);
+}
+
+U_BOOT_CMD(
+ fatmkdir, 4, 1, do_fat_mkdir,
+ "create a directory",
+ "<interface> [<dev[:part]>] <directory>\n"
+ " - create a directory in 'dev' on 'interface'"
+);
#endif
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 793b68b887..de16c72c23 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -987,7 +987,8 @@ NXTARG: ;
}
if (chk) {
- envp->crc = crc32(0, envp->data, ENV_SIZE);
+ envp->crc = crc32(0, envp->data,
+ size ? size - offsetof(env_t, data) : ENV_SIZE);
#ifdef CONFIG_ENV_ADDR_REDUND
envp->flags = ACTIVE_FLAG;
#endif
diff --git a/cmd/osd.c b/cmd/osd.c
new file mode 100644
index 0000000000..0b1fa49936
--- /dev/null
+++ b/cmd/osd.c
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017
+ * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
+ *
+ * based on the gdsys osd driver, which is
+ *
+ * (C) Copyright 2010
+ * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <hexdump.h>
+#include <video_osd.h>
+#include <malloc.h>
+
+/* Container for selected OSD device */
+static struct udevice *osd_cur;
+
+/**
+ * cmd_osd_set_osd_num() - Set the OSD selected for operation
+ *
+ * Set the OSD device, which will be used by all subsequent OSD commands.
+ *
+ * Devices are identified by their uclass sequence number (as listed by 'osd
+ * show').
+ *
+ * @osdnum: The OSD device to be selected, identified by its sequence number.
+ * Return: 0 if OK, -ve on error
+ */
+static int cmd_osd_set_osd_num(unsigned int osdnum)
+{
+ struct udevice *osd;
+ int res;
+
+ res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, osdnum, &osd);
+ if (res) {
+ printf("%s: No OSD %u (err = %d)\n", __func__, osdnum, res);
+ return res;
+ }
+ osd_cur = osd;
+
+ return 0;
+}
+
+/**
+ * osd_get_osd_cur() - Get the selected OSD device
+ *
+ * Get the OSD device that is used by all OSD commands.
+ *
+ * @osdp: Pointer to structure that will receive the currently selected OSD
+ * device.
+ * Return: 0 if OK, -ve on error
+ */
+static int osd_get_osd_cur(struct udevice **osdp)
+{
+ if (!osd_cur) {
+ puts("No osd selected\n");
+ return -ENODEV;
+ }
+ *osdp = osd_cur;
+
+ return 0;
+}
+
+/**
+ * show_osd() - Display information about a OSD device
+ *
+ * Display a device's ID (sequence number), and whether it is active (i.e.
+ * probed) or not.
+ *
+ * @osd: OSD device to print information for
+ */
+static void show_osd(struct udevice *osd)
+{
+ printf("OSD %d:\t%s", osd->req_seq, osd->name);
+ if (device_active(osd))
+ printf(" (active %d)", osd->seq);
+ printf("\n");
+}
+
+static int do_osd_write(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ uint x, y;
+ uint count;
+ char *hexstr;
+ u8 *buffer;
+ size_t buflen;
+ int res;
+
+ if (argc < 4 || (strlen(argv[3]) % 2))
+ return CMD_RET_USAGE;
+
+ if (!osd_cur) {
+ puts("No osd selected\n");
+ return CMD_RET_FAILURE;
+ }
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+ hexstr = argv[3];
+ count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;
+
+ buflen = strlen(hexstr) / 2;
+
+ buffer = malloc(buflen);
+ if (!buffer) {
+ puts("Memory allocation failure\n");
+ return CMD_RET_FAILURE;
+ }
+
+ res = hex2bin(buffer, hexstr, buflen);
+ if (res) {
+ free(buffer);
+ puts("Hexadecimal input contained invalid characters\n");
+ return CMD_RET_FAILURE;
+ }
+
+ res = video_osd_set_mem(osd_cur, x, y, buffer, buflen, count);
+ if (res) {
+ free(buffer);
+ printf("%s: Could not write to video mem\n",
+ osd_cur->name);
+ return CMD_RET_FAILURE;
+ }
+
+ free(buffer);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_osd_print(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ uint x, y;
+ u8 color;
+ char *text;
+ int res;
+
+ if (argc < 5)
+ return CMD_RET_USAGE;
+
+ if (!osd_cur) {
+ puts("No osd selected\n");
+ return CMD_RET_FAILURE;
+ }
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+ color = simple_strtoul(argv[3], NULL, 16);
+ text = argv[4];
+
+ res = video_osd_print(osd_cur, x, y, color, text);
+ if (res) {
+ printf("Could not print string to osd %s\n", osd_cur->name);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_osd_size(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ uint x, y;
+ int res;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ if (!osd_cur) {
+ puts("No osd selected\n");
+ return CMD_RET_FAILURE;
+ }
+
+ x = simple_strtoul(argv[1], NULL, 16);
+ y = simple_strtoul(argv[2], NULL, 16);
+
+ res = video_osd_set_size(osd_cur, x, y);
+ if (res) {
+ printf("Could not set size on osd %s\n", osd_cur->name);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_show_osd(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ struct udevice *osd;
+
+ if (argc == 1) {
+ /* show all OSDs */
+ struct uclass *uc;
+ int res;
+
+ res = uclass_get(UCLASS_VIDEO_OSD, &uc);
+ if (res) {
+ printf("Error while getting OSD uclass (err=%d)\n",
+ res);
+ return CMD_RET_FAILURE;
+ }
+
+ uclass_foreach_dev(osd, uc)
+ show_osd(osd);
+ } else {
+ int i, res;
+
+ /* show specific OSD */
+ i = simple_strtoul(argv[1], NULL, 10);
+
+ res = uclass_get_device_by_seq(UCLASS_VIDEO_OSD, i, &osd);
+ if (res) {
+ printf("Invalid osd %d: err=%d\n", i, res);
+ return CMD_RET_FAILURE;
+ }
+ show_osd(osd);
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_osd_num(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int osd_no;
+ int res = 0;
+
+ if (argc == 1) {
+ /* querying current setting */
+ struct udevice *osd;
+
+ if (!osd_get_osd_cur(&osd))
+ osd_no = osd->seq;
+ else
+ osd_no = -1;
+ printf("Current osd is %d\n", osd_no);
+ } else {
+ osd_no = simple_strtoul(argv[1], NULL, 10);
+ printf("Setting osd to %d\n", osd_no);
+
+ res = cmd_osd_set_osd_num(osd_no);
+ if (res)
+ printf("Failure changing osd number (err = %d)\n", res);
+ }
+
+ return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+static cmd_tbl_t cmd_osd_sub[] = {
+ U_BOOT_CMD_MKENT(show, 1, 1, do_show_osd, "", ""),
+ U_BOOT_CMD_MKENT(dev, 1, 1, do_osd_num, "", ""),
+ U_BOOT_CMD_MKENT(write, 4, 1, do_osd_write, "", ""),
+ U_BOOT_CMD_MKENT(print, 4, 1, do_osd_print, "", ""),
+ U_BOOT_CMD_MKENT(size, 2, 1, do_osd_size, "", ""),
+};
+
+static int do_osd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ cmd_tbl_t *c;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ /* Strip off leading 'osd' command argument */
+ argc--;
+ argv++;
+
+ c = find_cmd_tbl(argv[0], &cmd_osd_sub[0], ARRAY_SIZE(cmd_osd_sub));
+
+ if (c)
+ return c->cmd(cmdtp, flag, argc, argv);
+ else
+ return CMD_RET_USAGE;
+}
+
+static char osd_help_text[] =
+ "show - show OSD info\n"
+ "osd dev [dev] - show or set current OSD\n"
+ "write [pos_x] [pos_y] [buffer] [count] - write 8-bit hex encoded buffer to osd memory at a given position\n"
+ "print [pos_x] [pos_y] [color] [text] - write ASCII buffer (given by text data and driver-specific color information) to osd memory\n"
+ "size [size_x] [size_y] - set OSD XY size in characters\n";
+
+U_BOOT_CMD(
+ osd, 6, 1, do_osd,
+ "OSD sub-system",
+ osd_help_text
+);
diff --git a/cmd/ubi.c b/cmd/ubi.c
index bb8f97fc28..767a4a4536 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -32,8 +32,7 @@
static struct ubi_device *ubi;
#ifdef CONFIG_CMD_UBIFS
-int ubifs_is_mounted(void);
-void cmd_ubifs_umount(void);
+#include <ubifs_uboot.h>
#endif
static void display_volume_info(struct ubi_device *ubi)
diff --git a/cmd/ubifs.c b/cmd/ubifs.c
index 11bab7a1a1..e4000b7ad1 100644
--- a/cmd/ubifs.c
+++ b/cmd/ubifs.c
@@ -19,16 +19,10 @@
static int ubifs_initialized;
static int ubifs_mounted;
-static int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
+int cmd_ubifs_mount(char *vol_name)
{
- char *vol_name;
int ret;
- if (argc != 2)
- return CMD_RET_USAGE;
-
- vol_name = argv[1];
debug("Using volume %s\n", vol_name);
if (ubifs_initialized == 0) {
@@ -42,7 +36,19 @@ static int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc,
ubifs_mounted = 1;
- return 0;
+ return ret;
+}
+static int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ char *vol_name;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+
+ vol_name = argv[1];
+
+ return cmd_ubifs_mount(vol_name);
}
int ubifs_is_mounted(void)
@@ -50,11 +56,18 @@ int ubifs_is_mounted(void)
return ubifs_mounted;
}
-void cmd_ubifs_umount(void)
+int cmd_ubifs_umount(void)
{
+ if (ubifs_initialized == 0) {
+ printf("No UBIFS volume mounted!\n");
+ return -1;
+ }
+
uboot_ubifs_umount();
ubifs_mounted = 0;
ubifs_initialized = 0;
+
+ return 0;
}
static int do_ubifs_umount(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -63,14 +76,7 @@ static int do_ubifs_umount(cmd_tbl_t *cmdtp, int flag, int argc,
if (argc != 1)
return CMD_RET_USAGE;
- if (ubifs_initialized == 0) {
- printf("No UBIFS volume mounted!\n");
- return -1;
- }
-
- cmd_ubifs_umount();
-
- return 0;
+ return cmd_ubifs_umount();
}
static int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc,
diff --git a/cmd/w1.c b/cmd/w1.c
new file mode 100644
index 0000000000..9c95fcf9cd
--- /dev/null
+++ b/cmd/w1.c
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * (C) Copyright 2018
+ * Microchip Technology, Inc.
+ * Eugen Hristev <eugen.hristev@microchip.com>
+ */
+#include <common.h>
+#include <command.h>
+#include <w1.h>
+#include <w1-eeprom.h>
+#include <dm/device-internal.h>
+
+static int w1_bus(void)
+{
+ struct udevice *bus, *dev;
+ int ret;
+
+ ret = w1_get_bus(0, &bus);
+ if (ret) {
+ printf("one wire interface not found\n");
+ return CMD_RET_FAILURE;
+ }
+ printf("Bus %d:\t%s", bus->seq, bus->name);
+ if (device_active(bus))
+ printf(" (active)");
+ printf("\n");
+
+ for (device_find_first_child(bus, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ ret = device_probe(dev);
+
+ printf("\t%s (%d) uclass %s : ", dev->name, dev->seq,
+ dev->uclass->uc_drv->name);
+
+ if (ret)
+ printf("device error\n");
+ else
+ printf("family 0x%x\n", w1_get_device_family(dev));
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int w1_read(int argc, char *const argv[])
+{
+ int bus_n = 0, dev_n = 0, offset = 0, len = 512;
+ int i;
+ struct udevice *bus, *dev;
+ int ret;
+ u8 buf[512];
+
+ if (argc > 2)
+ bus_n = simple_strtoul(argv[2], NULL, 10);
+
+ if (argc > 3)
+ dev_n = simple_strtoul(argv[3], NULL, 10);
+
+ if (argc > 4)
+ offset = simple_strtoul(argv[4], NULL, 10);
+
+ if (argc > 5)
+ len = simple_strtoul(argv[5], NULL, 10);
+
+ if (len > 512) {
+ printf("len needs to be <= 512\n");
+ return CMD_RET_FAILURE;
+ }
+
+ ret = w1_get_bus(bus_n, &bus);
+ if (ret) {
+ printf("one wire interface not found\n");
+ return CMD_RET_FAILURE;
+ }
+
+ for (device_find_first_child(bus, &dev), i = 0;
+ dev && i <= dev_n;
+ device_find_next_child(&dev), i++) {
+ ret = device_probe(dev);
+ if (!ret && i == dev_n)
+ break;
+ }
+
+ if (i != dev_n || ret || !dev) {
+ printf("invalid dev\n");
+ return CMD_RET_FAILURE;
+ }
+
+ if (strcmp(dev->uclass->uc_drv->name, "w1_eeprom")) {
+ printf("the device present on the interface is of unknown device class\n");
+ return CMD_RET_FAILURE;
+ }
+
+ ret = w1_eeprom_read_buf(dev, offset, (u8 *)buf, len);
+ if (ret) {
+ printf("error reading device %s\n", dev->name);
+ return CMD_RET_FAILURE;
+ }
+
+ for (i = 0; i < len; i++)
+ printf("%x", buf[i]);
+ printf("\n");
+
+ return CMD_RET_SUCCESS;
+}
+
+int do_w1(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[1], "bus"))
+ return w1_bus();
+
+ if (!strcmp(argv[1], "read"))
+ return w1_read(argc, argv);
+
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(w1, 6, 0, do_w1,
+ "onewire interface utility commands",
+ "bus - show onewire bus info (all)\n"
+ "w1 read [<bus> [<dev> [offset [length]]]]"
+ " - read from onewire device 'dev' on onewire bus 'bus'"
+ " starting from offset 'offset' and length 'length'\n"
+ " defaults: bus 0, dev 0, offset 0, length 512 bytes.");