summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig29
-rw-r--r--cmd/Makefile8
-rw-r--r--cmd/bdinfo.c11
-rw-r--r--cmd/bootefi.c19
-rw-r--r--cmd/bootflow.c8
-rw-r--r--cmd/cls.c20
-rw-r--r--cmd/efi.c31
-rw-r--r--cmd/efi_common.c26
-rw-r--r--cmd/efidebug.c6
-rw-r--r--cmd/fdt.c32
-rw-r--r--cmd/font.c6
-rw-r--r--cmd/mvebu/Kconfig18
-rw-r--r--cmd/mvebu/bubt.c253
-rw-r--r--cmd/nand.c9
-rw-r--r--cmd/nvedit.c11
-rw-r--r--cmd/pci_mps.c164
-rw-r--r--cmd/read.c61
-rw-r--r--cmd/smccc.c2
-rw-r--r--cmd/usb_mass_storage.c10
19 files changed, 595 insertions, 129 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 2caa4af71cb..8c9b430f99f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1396,6 +1396,16 @@ config CMD_PCI
peripherals. Sub-commands allow bus enumeration, displaying and
changing configuration space and a few other features.
+config CMD_PCI_MPS
+ bool "pci_mps - Configure PCI device MPS"
+ depends on PCI
+ help
+ Enables PCI Express Maximum Packet Size (MPS) tuning. This
+ command configures the PCI Express MPS of each endpoint to the
+ largest value supported by all devices below the root complex.
+ The Maximum Read Request Size will not be altered. This method is
+ the same algorithm as used by Linux pci=pcie_bus_safe.
+
config CMD_PINMUX
bool "pinmux - show pins muxing"
depends on PINCTRL
@@ -1542,6 +1552,12 @@ config CMD_USB_MASS_STORAGE
export a block device: U-Boot, the USB device, acts as a simple
external hard drive plugged on the host USB port.
+config CMD_UMS_ABORT_KEYED
+ bool "UMS abort with any key"
+ depends on CMD_USB_MASS_STORAGE
+ help
+ Allow interruption of usb mass storage run with any key pressed.
+
config CMD_PVBLOCK
bool "Xen para-virtualized block device"
depends on XEN
@@ -1562,6 +1578,11 @@ config CMD_WDT
help
This provides commands to control the watchdog timer devices.
+config CMD_WRITE
+ bool "write - Write binary data to a partition"
+ help
+ Provides low-level write access to a partition.
+
config CMD_AXI
bool "axi"
depends on AXI
@@ -2226,6 +2247,14 @@ config CMD_VIDCONSOLE
The name 'lcdputs' is a bit of a misnomer, but so named because the
video device is often an LCD.
+config CMD_SELECT_FONT
+ bool "select font size"
+ depends on VIDEO
+ default n
+ help
+ Enabling this will provide 'font' command.
+ Allows font selection at runtime.
+
endmenu
source "cmd/ti/Kconfig"
diff --git a/cmd/Makefile b/cmd/Makefile
index 36d2daf22a1..e032091621d 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -62,8 +62,8 @@ obj-$(CONFIG_CMD_EXTENSION) += extension_board.o
obj-$(CONFIG_CMD_ECHO) += echo.o
obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o
obj-$(CONFIG_CMD_EEPROM) += eeprom.o
-obj-$(CONFIG_EFI) += efi.o
-obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o
+obj-$(CONFIG_EFI) += efi.o efi_common.o
+obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o efi_common.o
obj-$(CONFIG_CMD_EFICONFIG) += eficonfig.o
ifdef CONFIG_CMD_EFICONFIG
ifdef CONFIG_EFI_MM_COMM_TEE
@@ -78,7 +78,7 @@ obj-$(CONFIG_CMD_EXT2) += ext2.o
obj-$(CONFIG_CMD_FAT) += fat.o
obj-$(CONFIG_CMD_FDT) += fdt.o
obj-$(CONFIG_CMD_SQUASHFS) += sqfs.o
-obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o
+obj-$(CONFIG_CMD_SELECT_FONT) += font.o
obj-$(CONFIG_CMD_FLASH) += flash.o
obj-$(CONFIG_CMD_FPGA) += fpga.o
obj-$(CONFIG_CMD_FPGAD) += fpgad.o
@@ -131,6 +131,7 @@ obj-$(CONFIG_CMD_PART) += part.o
obj-$(CONFIG_CMD_PCAP) += pcap.o
ifdef CONFIG_PCI
obj-$(CONFIG_CMD_PCI) += pci.o
+obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
endif
obj-$(CONFIG_CMD_PINMUX) += pinmux.o
obj-$(CONFIG_CMD_PMC) += pmc.o
@@ -140,6 +141,7 @@ obj-$(CONFIG_CMD_PXE) += pxe.o
obj-$(CONFIG_CMD_WOL) += wol.o
obj-$(CONFIG_CMD_QFW) += qfw.o
obj-$(CONFIG_CMD_READ) += read.o
+obj-$(CONFIG_CMD_WRITE) += read.o
obj-$(CONFIG_CMD_REGINFO) += reginfo.o
obj-$(CONFIG_CMD_REISER) += reiser.o
obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index bf002f84475..f709904c516 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -26,6 +26,11 @@ void bdinfo_print_size(const char *name, uint64_t size)
print_size(size, "\n");
}
+void bdinfo_print_str(const char *name, const char *str)
+{
+ printf("%-12s= %s\n", name, str);
+}
+
void bdinfo_print_num_l(const char *name, ulong value)
{
printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value);
@@ -83,11 +88,15 @@ static void show_video_info(void)
device_active(dev) ? "" : "in");
if (device_active(dev)) {
struct video_priv *upriv = dev_get_uclass_priv(dev);
+ struct video_uc_plat *plat = dev_get_uclass_plat(dev);
bdinfo_print_num_ll("FB base", (ulong)upriv->fb);
- if (upriv->copy_fb)
+ if (upriv->copy_fb) {
bdinfo_print_num_ll("FB copy",
(ulong)upriv->copy_fb);
+ bdinfo_print_num_l(" copy size",
+ plat->copy_size);
+ }
printf("%-12s= %dx%dx%d\n", "FB size", upriv->xsize,
upriv->ysize, 1 << upriv->bpix);
}
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 6618335ddf9..8aa15a64c83 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -204,25 +204,12 @@ static efi_status_t copy_fdt(void **fdtp)
fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000);
fdt_size = fdt_pages << EFI_PAGE_SHIFT;
- /*
- * Safe fdt location is at 127 MiB.
- * On the sandbox convert from the sandbox address space.
- */
- new_fdt_addr = (uintptr_t)map_sysmem(fdt_ram_start + 0x7f00000 +
- fdt_size, 0);
- ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+ ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
EFI_ACPI_RECLAIM_MEMORY, 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);
- ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
- EFI_ACPI_RECLAIM_MEMORY, fdt_pages,
- &new_fdt_addr);
- if (ret != EFI_SUCCESS) {
- log_err("ERROR: Failed to reserve space for FDT\n");
- goto done;
- }
+ log_err("ERROR: Failed to reserve space for FDT\n");
+ goto done;
}
new_fdt = (void *)(uintptr_t)new_fdt_addr;
memcpy(new_fdt, fdt, fdt_totalsize(fdt));
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 3548bbb6830..42f6e14a437 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -135,13 +135,13 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
flags = 0;
if (list)
- flags |= BOOTFLOWF_SHOW;
+ flags |= BOOTFLOWIF_SHOW;
if (all)
- flags |= BOOTFLOWF_ALL;
+ flags |= BOOTFLOWIF_ALL;
if (no_global)
- flags |= BOOTFLOWF_SKIP_GLOBAL;
+ flags |= BOOTFLOWIF_SKIP_GLOBAL;
if (!no_hunter)
- flags |= BOOTFLOWF_HUNT;
+ flags |= BOOTFLOWIF_HUNT;
/*
* If we have a device, just scan for bootflows attached to that device
diff --git a/cmd/cls.c b/cmd/cls.c
index 40a32eeab63..1125a3f81bb 100644
--- a/cmd/cls.c
+++ b/cmd/cls.c
@@ -8,7 +8,7 @@
#include <common.h>
#include <command.h>
#include <dm.h>
-#include <video.h>
+#include <video_console.h>
#define CSI "\x1b["
@@ -17,14 +17,24 @@ static int do_video_clear(struct cmd_tbl *cmdtp, int flag, int argc,
{
__maybe_unused struct udevice *dev;
- /* Send clear screen and home */
+ /*
+ * Send clear screen and home
+ *
+ * FIXME(Heinrich Schuchardt <xypron.glpk@gmx.de>): This should go
+ * through an API and only be written to serial terminals, not video
+ * displays
+ */
printf(CSI "2J" CSI "1;1H");
- if (IS_ENABLED(CONFIG_VIDEO) && !IS_ENABLED(CONFIG_VIDEO_ANSI)) {
- if (uclass_first_device_err(UCLASS_VIDEO, &dev))
+ if (IS_ENABLED(CONFIG_VIDEO_ANSI))
+ return 0;
+
+ if (IS_ENABLED(CONFIG_VIDEO)) {
+ if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
return CMD_RET_FAILURE;
- if (video_clear(dev))
+ if (vidconsole_clear_and_reset(dev))
return CMD_RET_FAILURE;
}
+
return CMD_RET_SUCCESS;
}
diff --git a/cmd/efi.c b/cmd/efi.c
index c0384e0db28..6cd5361aca5 100644
--- a/cmd/efi.c
+++ b/cmd/efi.c
@@ -7,10 +7,12 @@
#include <common.h>
#include <command.h>
#include <efi.h>
+#include <efi_api.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <sort.h>
+#include <uuid.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -273,8 +275,34 @@ done:
return ret ? CMD_RET_FAILURE : 0;
}
+static int do_efi_tables(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct efi_system_table *systab;
+
+ if (IS_ENABLED(CONFIG_EFI_APP)) {
+ systab = efi_get_sys_table();
+ if (!systab) {
+ printf("Cannot read system table\n");
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ int size;
+ int ret;
+
+ ret = efi_info_get(EFIET_SYS_TABLE, (void **)&systab, &size);
+ if (ret) /* this should not happen */
+ return CMD_RET_FAILURE;
+ }
+
+ efi_show_tables(systab);
+
+ return 0;
+}
+
static struct cmd_tbl efi_commands[] = {
U_BOOT_CMD_MKENT(mem, 1, 1, do_efi_mem, "", ""),
+ U_BOOT_CMD_MKENT(tables, 1, 1, do_efi_tables, "", ""),
};
static int do_efi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
@@ -298,5 +326,6 @@ static int do_efi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
U_BOOT_CMD(
efi, 3, 1, do_efi,
"EFI access",
- "mem [all] Dump memory information [include boot services]"
+ "mem [all] Dump memory information [include boot services]\n"
+ "tables Dump tables"
);
diff --git a/cmd/efi_common.c b/cmd/efi_common.c
new file mode 100644
index 00000000000..f4056096cd3
--- /dev/null
+++ b/cmd/efi_common.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Common code for EFI commands
+ *
+ * Copyright 2023 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <efi_api.h>
+#include <uuid.h>
+
+void efi_show_tables(struct efi_system_table *systab)
+{
+ int i;
+
+ for (i = 0; i < systab->nr_tables; i++) {
+ struct efi_configuration_table *tab = &systab->tables[i];
+ char guid_str[37];
+
+ uuid_bin_to_str(tab->guid.b, guid_str, 1);
+ printf("%p %pUl %s\n", tab->table, guid_str,
+ uuid_guid_get_str(tab->guid.b) ?: "(unknown)");
+ }
+}
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index e6959ede930..9622430c475 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -649,11 +649,7 @@ static int do_efi_show_memmap(struct cmd_tbl *cmdtp, int flag,
static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- efi_uintn_t i;
-
- for (i = 0; i < systab.nr_tables; ++i)
- printf("%pUl (%pUs)\n",
- &systab.tables[i].guid, &systab.tables[i].guid);
+ efi_show_tables(&systab);
return CMD_RET_SUCCESS;
}
diff --git a/cmd/fdt.c b/cmd/fdt.c
index f38fe909c3e..aae3278526c 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -36,16 +36,21 @@ static int is_printable_string(const void *data, int len);
*/
struct fdt_header *working_fdt;
-void set_working_fdt_addr(ulong addr)
+static void set_working_fdt_addr_quiet(ulong addr)
{
void *buf;
- printf("Working FDT set to %lx\n", addr);
buf = map_sysmem(addr, 0);
working_fdt = buf;
env_set_hex("fdtaddr", addr);
}
+void set_working_fdt_addr(ulong addr)
+{
+ printf("Working FDT set to %lx\n", addr);
+ set_working_fdt_addr_quiet(addr);
+}
+
/*
* Get a value from the fdt and format it to be set in the environment
*/
@@ -192,10 +197,14 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if ((quiet && fdt_check_header(blob)) ||
(!quiet && !fdt_valid(&blob)))
return 1;
- if (control)
+ if (control) {
gd->fdt_blob = blob;
- else
- set_working_fdt_addr(addr);
+ } else {
+ if (quiet)
+ set_working_fdt_addr_quiet(addr);
+ else
+ set_working_fdt_addr(addr);
+ }
if (argc >= 2) {
int len;
@@ -475,18 +484,9 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (ret != 0)
return ret;
} else if (subcmd[0] == 'a') {
- /* Get address */
- char buf[19];
-
- snprintf(buf, sizeof(buf), "0x%lx",
- (ulong)map_to_sysmem(nodep));
- env_set(var, buf);
+ env_set_hex(var, (ulong)map_to_sysmem(nodep));
} else if (subcmd[0] == 's') {
- /* Get size */
- char buf[11];
-
- sprintf(buf, "0x%08X", len);
- env_set(var, buf);
+ env_set_hex(var, len);
} else
return CMD_RET_USAGE;
return 0;
diff --git a/cmd/font.c b/cmd/font.c
index 7b4347f32b5..fe2d65caaf7 100644
--- a/cmd/font.c
+++ b/cmd/font.c
@@ -61,7 +61,11 @@ static int do_font_size(struct cmd_tbl *cmdtp, int flag, int argc,
if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
return CMD_RET_FAILURE;
- font_name = vidconsole_get_font_size(dev, &size);
+ ret = vidconsole_get_font_size(dev, &font_name, &size);
+ if (ret) {
+ printf("Failed (error %d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
size = dectoul(argv[1], NULL);
diff --git a/cmd/mvebu/Kconfig b/cmd/mvebu/Kconfig
index 9ec3aa983a5..e83a9829491 100644
--- a/cmd/mvebu/Kconfig
+++ b/cmd/mvebu/Kconfig
@@ -3,8 +3,12 @@ depends on ARCH_MVEBU
config CMD_MVEBU_BUBT
bool "bubt"
+ default y
select SHA256 if ARMADA_3700
select SHA512 if ARMADA_3700
+ select DOS_PARTITION if ARMADA_3700
+ select EFI_PARTITION if ARMADA_3700
+ select PARTITION_TYPE_GUID if ARMADA_3700
select MVEBU_EFUSE if ARMADA_38X || ARMADA_3700
help
bubt - Burn a u-boot image to flash
@@ -15,6 +19,10 @@ if CMD_MVEBU_BUBT
choice
prompt "Flash for image"
+ default MVEBU_SPI_BOOT if MVEBU_SPL_BOOT_DEVICE_SPI
+ default MVEBU_NAND_BOOT if MVEBU_SPL_BOOT_DEVICE_NAND
+ default MVEBU_MMC_BOOT if MVEBU_SPL_BOOT_DEVICE_MMC
+ default MVEBU_SATA_BOOT if MVEBU_SPL_BOOT_DEVICE_SATA
default MVEBU_SPI_BOOT
config MVEBU_NAND_BOOT
@@ -44,10 +52,20 @@ config MVEBU_MMC_BOOT
For details about bubt command please see the documentation
in doc/mvebu/cmd/bubt.txt
+config MVEBU_SATA_BOOT
+ bool "SATA flash boot"
+ depends on SCSI
+ help
+ Enable boot from SATA disk.
+ Allow usage of SATA disk as a target for "bubt" command
+ For details about bubt command please see the documentation
+ in doc/mvebu/cmd/bubt.txt
+
endchoice
config MVEBU_UBOOT_DFLT_NAME
string "Default image name for bubt command"
+ default BUILD_TARGET if ARMADA_32BIT && BUILD_TARGET != ""
default "flash-image.bin"
help
This option should contain a default file name to be used with
diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c
index 1efbe2e607c..49797b23144 100644
--- a/cmd/mvebu/bubt.c
+++ b/cmd/mvebu/bubt.c
@@ -19,6 +19,7 @@
#include <spi_flash.h>
#include <spi.h>
#include <nand.h>
+#include <scsi.h>
#include <usb.h>
#include <fs.h>
#include <mmc.h>
@@ -189,6 +190,11 @@ static int mmc_burn_image(size_t image_size)
#ifdef CONFIG_BLK
struct blk_desc *blk_desc;
#endif
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+ u8 part;
+ u8 orig_part;
+#endif
+
mmc = find_mmc_device(mmc_dev_num);
if (!mmc) {
printf("No SD/MMC/eMMC card found\n");
@@ -202,6 +208,38 @@ static int mmc_burn_image(size_t image_size)
return err;
}
+#ifdef CONFIG_BLK
+ blk_desc = mmc_get_blk_desc(mmc);
+ if (!blk_desc) {
+ printf("Error - failed to obtain block descriptor\n");
+ return -ENODEV;
+ }
+#endif
+
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#ifdef CONFIG_BLK
+ orig_part = blk_desc->hwpart;
+#else
+ orig_part = mmc->block_dev.hwpart;
+#endif
+
+ part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
+
+ if (part == 7)
+ part = 0;
+
+#ifdef CONFIG_BLK
+ err = blk_dselect_hwpart(blk_desc, part);
+#else
+ err = mmc_switch_part(mmc, part);
+#endif
+
+ if (err) {
+ printf("Error - MMC partition switch failed\n");
+ return err;
+ }
+#endif
+
/* SD reserves LBA-0 for MBR and boots from LBA-1,
* MMC/eMMC boots from LBA-0
*/
@@ -211,11 +249,6 @@ static int mmc_burn_image(size_t image_size)
if (image_size % mmc->write_bl_len)
blk_count += 1;
- blk_desc = mmc_get_blk_desc(mmc);
- if (!blk_desc) {
- printf("Error - failed to obtain block descriptor\n");
- return -ENODEV;
- }
blk_written = blk_dwrite(blk_desc, start_lba, blk_count,
(void *)get_load_addr());
#else
@@ -227,6 +260,17 @@ static int mmc_burn_image(size_t image_size)
start_lba, blk_count,
(void *)get_load_addr());
#endif /* CONFIG_BLK */
+
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#ifdef CONFIG_BLK
+ err = blk_dselect_hwpart(blk_desc, orig_part);
+#else
+ err = mmc_switch_part(mmc, orig_part);
+#endif
+ if (err)
+ printf("Error - MMC failed to switch back to original partition\n");
+#endif
+
if (blk_written != blk_count) {
printf("Error - written %#lx blocks\n", blk_written);
return -ENOSPC;
@@ -291,6 +335,143 @@ static int is_mmc_active(void)
#endif /* CONFIG_DM_MMC */
/********************************************************************
+ * SATA services
+ ********************************************************************/
+#if defined(CONFIG_SCSI) && defined(CONFIG_BLK)
+static int sata_burn_image(size_t image_size)
+{
+#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_32BIT)
+ lbaint_t start_lba;
+ lbaint_t blk_count;
+ ulong blk_written;
+ struct blk_desc *blk_desc;
+#ifdef CONFIG_ARMADA_3700
+ struct disk_partition info;
+ int part;
+#endif
+
+ scsi_scan(false);
+
+ blk_desc = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0);
+ if (!blk_desc)
+ return -ENODEV;
+
+#ifdef CONFIG_ARMADA_3700
+ /*
+ * 64-bit Armada 3700 BootROM loads SATA firmware from
+ * GPT 'Marvell Armada 3700 Boot partition' or from
+ * MBR 'M' (0x4d) partition.
+ */
+ switch (blk_desc->part_type) {
+ case PART_TYPE_DOS:
+ for (part = 1; part <= 4; part++) {
+ info.sys_ind = 0;
+ if (part_get_info(blk_desc, part, &info))
+ continue;
+ if (info.sys_ind == 'M')
+ break;
+ }
+ if (part > 4) {
+ printf("Error - cannot find MBR 'M' (0x4d) partition on SATA disk\n");
+ return -ENODEV;
+ }
+ start_lba = info.start;
+ break;
+ case PART_TYPE_EFI:
+ for (part = 1; part <= 64; part++) {
+ info.type_guid[0] = 0;
+ if (part_get_info(blk_desc, part, &info))
+ continue;
+ /* Check for GPT type GUID of 'Marvell Armada 3700 Boot partition' */
+ if (strcmp(info.type_guid, "6828311A-BA55-42A4-BCDE-A89BB5EDECAE") == 0)
+ break;
+ }
+ if (part > 64) {
+ printf("Error - cannot find GPT 'Marvell Armada 3700 Boot partition' on SATA disk\n");
+ return -ENODEV;
+ }
+ start_lba = info.start;
+ break;
+ default:
+ printf("Error - no partitions on SATA disk\n");
+ return -ENODEV;
+ }
+#else
+ /* 32-bit Armada BootROM loads SATA firmware from the sector 1. */
+ start_lba = 1;
+#endif
+
+ blk_count = image_size / blk_desc->blksz;
+ if (image_size % blk_desc->blksz)
+ blk_count += 1;
+
+ blk_written = blk_dwrite(blk_desc, start_lba, blk_count,
+ (void *)get_load_addr());
+
+ if (blk_written != blk_count) {
+ printf("Error - written %#lx blocks\n", blk_written);
+ return -ENOSPC;
+ }
+
+ printf("Done!\n");
+ return 0;
+#else
+ return -ENODEV;
+#endif
+}
+
+static size_t sata_read_file(const char *file_name)
+{
+ loff_t act_read = 0;
+ struct udevice *dev;
+ int rc;
+
+ /* try to recognize storage devices immediately */
+ scsi_scan(false);
+
+ /* Try to recognize storage devices immediately */
+ blk_first_device(UCLASS_SCSI, &dev);
+ if (!dev) {
+ printf("Error: SATA device not found\n");
+ return 0;
+ }
+
+ /* Always load from scsi 0 */
+ if (fs_set_blk_dev("scsi", "0", FS_TYPE_ANY)) {
+ printf("Error: SATA 0 not found\n");
+ return 0;
+ }
+
+ /* Perfrom file read */
+ rc = fs_read(file_name, get_load_addr(), 0, 0, &act_read);
+ if (rc)
+ return 0;
+
+ return act_read;
+}
+
+static int is_sata_active(void)
+{
+ return 1;
+}
+#else /* CONFIG_SCSI */
+static int sata_burn_image(size_t image_size)
+{
+ return -ENODEV;
+}
+
+static size_t sata_read_file(const char *file_name)
+{
+ return 0;
+}
+
+static int is_sata_active(void)
+{
+ return 0;
+}
+#endif /* CONFIG_SCSI */
+
+/********************************************************************
* SPI services
********************************************************************/
#ifdef CONFIG_SPI_FLASH
@@ -499,16 +680,18 @@ enum bubt_devices {
BUBT_DEV_NET = 0,
BUBT_DEV_USB,
BUBT_DEV_MMC,
+ BUBT_DEV_SATA,
BUBT_DEV_SPI,
BUBT_DEV_NAND,
BUBT_MAX_DEV
};
-struct bubt_dev bubt_devs[BUBT_MAX_DEV] = {
+static struct bubt_dev bubt_devs[BUBT_MAX_DEV] = {
{"tftp", tftp_read_file, NULL, is_tftp_active},
{"usb", usb_read_file, NULL, is_usb_active},
{"mmc", mmc_read_file, mmc_burn_image, is_mmc_active},
+ {"sata", sata_read_file, sata_burn_image, is_sata_active},
{"spi", NULL, spi_burn_image, is_spi_active},
{"nand", NULL, nand_burn_image, is_nand_active},
};
@@ -524,7 +707,7 @@ static int bubt_write_file(struct bubt_dev *dst, size_t image_size)
}
#if defined(CONFIG_ARMADA_8K)
-u32 do_checksum32(u32 *start, int32_t len)
+static u32 do_checksum32(u32 *start, int32_t len)
{
u32 sum = 0;
u32 *startp = start;
@@ -542,9 +725,8 @@ static int check_image_header(void)
{
struct mvebu_image_header *hdr =
(struct mvebu_image_header *)get_load_addr();
- u32 header_len = hdr->prolog_size;
u32 checksum;
- u32 checksum_ref = hdr->prolog_checksum;
+ u32 checksum_ref;
/*
* For now compare checksum, and magic. Later we can
@@ -556,18 +738,23 @@ static int check_image_header(void)
return -ENOEXEC;
}
- /* The checksum value is discarded from checksum calculation */
- hdr->prolog_checksum = 0;
+ checksum_ref = hdr->prolog_checksum;
+ checksum = do_checksum32((u32 *)hdr, hdr->prolog_size);
+ checksum -= hdr->prolog_checksum;
+ if (checksum != checksum_ref) {
+ printf("Error: Bad Prolog checksum. 0x%x != 0x%x\n",
+ checksum, checksum_ref);
+ return -ENOEXEC;
+ }
- checksum = do_checksum32((u32 *)hdr, header_len);
+ checksum_ref = hdr->boot_image_checksum;
+ checksum = do_checksum32((u32 *)((u8 *)hdr + hdr->prolog_size), hdr->boot_image_size);
if (checksum != checksum_ref) {
printf("Error: Bad Image checksum. 0x%x != 0x%x\n",
checksum, checksum_ref);
return -ENOEXEC;
}
- /* Restore the checksum before writing */
- hdr->prolog_checksum = checksum_ref;
printf("Image checksum...OK!\n");
return 0;
@@ -722,12 +909,12 @@ static int check_image_header(void)
u32 offset, size;
const struct a38x_main_hdr_v1 *hdr =
(struct a38x_main_hdr_v1 *)get_load_addr();
- const size_t image_size = a38x_header_size(hdr);
+ const size_t hdr_size = a38x_header_size(hdr);
- if (!image_size)
+ if (!hdr_size)
return -ENOEXEC;
- checksum = image_checksum8(hdr, image_size);
+ checksum = image_checksum8(hdr, hdr_size);
checksum -= hdr->checksum;
if (checksum != hdr->checksum) {
printf("Error: Bad A38x image header checksum. 0x%x != 0x%x\n",
@@ -738,16 +925,7 @@ static int check_image_header(void)
offset = le32_to_cpu(hdr->srcaddr);
size = le32_to_cpu(hdr->blocksize);
- if (hdr->blockid == 0x78) { /* SATA id */
- if (offset < 1) {
- printf("Error: Bad A38x image srcaddr.\n");
- return -ENOEXEC;
- }
- offset -= 1;
- offset *= 512;
- }
-
- if (hdr->blockid == 0xAE) /* SDIO id */
+ if (hdr->blockid == 0x78) /* SATA id */
offset *= 512;
if (offset % 4 != 0 || size < 4 || size % 4 != 0) {
@@ -770,7 +948,7 @@ static int check_image_header(void)
#if defined(CONFIG_ARMADA_38X)
static int a38x_image_is_secure(const struct a38x_main_hdr_v1 *hdr)
{
- u32 image_size = a38x_header_size(hdr);
+ const size_t hdr_size = a38x_header_size(hdr);
struct a38x_opt_hdr_v1 *ohdr;
u32 ohdr_size;
@@ -791,7 +969,7 @@ static int a38x_image_is_secure(const struct a38x_main_hdr_v1 *hdr)
break;
ohdr = (struct a38x_opt_hdr_v1 *)((u8 *)ohdr + ohdr_size);
- if ((u8 *)ohdr >= (u8 *)hdr + image_size)
+ if ((u8 *)ohdr >= (u8 *)hdr + hdr_size)
break;
} while (1);
@@ -806,7 +984,7 @@ static int check_image_header(void)
}
#endif
-#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_32BIT)
+#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_38X)
static u64 fuse_read_u64(u32 bank)
{
u32 val[2];
@@ -835,7 +1013,10 @@ static inline u8 maj3(u8 val)
static int bubt_check_boot_mode(const struct bubt_dev *dst)
{
#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_32BIT)
- int mode, secure_mode;
+ int mode;
+#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_38X)
+ int secure_mode;
+#endif
#if defined(CONFIG_ARMADA_3700)
const struct tim_boot_flash_sign *boot_modes = tim_boot_flash_signs;
const struct common_tim_data *hdr =
@@ -966,7 +1147,7 @@ static int bubt_is_dev_active(struct bubt_dev *dev)
return 1;
}
-struct bubt_dev *find_bubt_dev(char *dev_name)
+static struct bubt_dev *find_bubt_dev(char *dev_name)
{
int dev;
@@ -987,12 +1168,14 @@ struct bubt_dev *find_bubt_dev(char *dev_name)
#define DEFAULT_BUBT_DST "nand"
#elif defined(CONFIG_MVEBU_MMC_BOOT)
#define DEFAULT_BUBT_DST "mmc"
+#elif defined(CONFIG_MVEBU_SATA_BOOT)
+#define DEFAULT_BUBT_DST "sata"
#else
#define DEFAULT_BUBT_DST "error"
#endif
#endif /* DEFAULT_BUBT_DST */
-int do_bubt_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+static int do_bubt_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct bubt_dev *src, *dst;
size_t image_size;
@@ -1064,8 +1247,8 @@ U_BOOT_CMD(
"Burn a u-boot image to flash",
"[file-name] [destination [source]]\n"
"\t-file-name The image file name to burn. Default = " CONFIG_MVEBU_UBOOT_DFLT_NAME "\n"
- "\t-destination Flash to burn to [spi, nand, mmc]. Default = " DEFAULT_BUBT_DST "\n"
- "\t-source The source to load image from [tftp, usb, mmc]. Default = " DEFAULT_BUBT_SRC "\n"
+ "\t-destination Flash to burn to [spi, nand, mmc, sata]. Default = " DEFAULT_BUBT_DST "\n"
+ "\t-source The source to load image from [tftp, usb, mmc, sata]. Default = " DEFAULT_BUBT_SRC "\n"
"Examples:\n"
"\tbubt - Burn flash-image.bin from tftp to active boot device\n"
"\tbubt flash-image-new.bin nand - Burn flash-image-new.bin from tftp to NAND flash\n"
diff --git a/cmd/nand.c b/cmd/nand.c
index 9a723f57579..b41e54ec422 100644
--- a/cmd/nand.c
+++ b/cmd/nand.c
@@ -567,9 +567,12 @@ static int do_nand(struct cmd_tbl *cmdtp, int flag, int argc,
if (strcmp(cmd, "bad") == 0) {
printf("\nDevice %d bad blocks:\n", dev);
- for (off = 0; off < mtd->size; off += mtd->erasesize)
- if (nand_block_isbad(mtd, off))
- printf(" %08llx\n", (unsigned long long)off);
+ for (off = 0; off < mtd->size; off += mtd->erasesize) {
+ ret = nand_block_isbad(mtd, off);
+ if (ret)
+ printf(" 0x%08llx%s\n", (unsigned long long)off,
+ ret == 2 ? "\t (bbt reserved)" : "");
+ }
return 0;
}
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 7cbc3fd573a..12eae0627bb 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -1025,6 +1025,7 @@ static int do_env_indirect(struct cmd_tbl *cmdtp, int flag,
char *from = argv[2];
char *default_value = NULL;
int ret = 0;
+ char *val;
if (argc < 3 || argc > 4) {
return CMD_RET_USAGE;
@@ -1034,18 +1035,14 @@ static int do_env_indirect(struct cmd_tbl *cmdtp, int flag,
default_value = argv[3];
}
- if (env_get(from) == NULL && default_value == NULL) {
+ val = env_get(from) ?: default_value;
+ if (!val) {
printf("## env indirect: Environment variable for <from> (%s) does not exist.\n", from);
return CMD_RET_FAILURE;
}
- if (env_get(from) == NULL) {
- ret = env_set(to, default_value);
- }
- else {
- ret = env_set(to, env_get(from));
- }
+ ret = env_set(to, val);
if (ret == 0) {
return CMD_RET_SUCCESS;
diff --git a/cmd/pci_mps.c b/cmd/pci_mps.c
new file mode 100644
index 00000000000..555a5fdd8e6
--- /dev/null
+++ b/cmd/pci_mps.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 Microsoft Corporation <www.microsoft.com>
+ * Stephen Carlson <stcarlso@linux.microsoft.com>
+ *
+ * PCI Express Maximum Packet Size (MPS) configuration
+ */
+
+#include <common.h>
+#include <bootretry.h>
+#include <cli.h>
+#include <command.h>
+#include <console.h>
+#include <dm.h>
+#include <init.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define PCI_MPS_SAFE 0
+#define PCI_MPS_PEER2PEER 1
+
+static int pci_mps_find_safe(struct udevice *bus, unsigned int *min_mps,
+ unsigned int *n)
+{
+ struct udevice *dev;
+ int res = 0, addr;
+ unsigned int mpss;
+ u32 regval;
+
+ if (!min_mps || !n)
+ return -EINVAL;
+
+ for (device_find_first_child(bus, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ addr = dm_pci_find_capability(dev, PCI_CAP_ID_EXP);
+ if (addr <= 0)
+ continue;
+
+ res = dm_pci_read_config32(dev, addr + PCI_EXP_DEVCAP,
+ &regval);
+ if (res != 0)
+ return res;
+ mpss = (unsigned int)(regval & PCI_EXP_DEVCAP_PAYLOAD);
+ *n += 1;
+ if (mpss < *min_mps)
+ *min_mps = mpss;
+ }
+
+ return res;
+}
+
+static int pci_mps_set_bus(struct udevice *bus, unsigned int target)
+{
+ struct udevice *dev;
+ u32 mpss, target_mps = (u32)(target << 5);
+ u16 mps;
+ int res = 0, addr;
+
+ for (device_find_first_child(bus, &dev);
+ dev && res == 0;
+ device_find_next_child(&dev)) {
+ addr = dm_pci_find_capability(dev, PCI_CAP_ID_EXP);
+ if (addr <= 0)
+ continue;
+
+ res = dm_pci_read_config32(dev, addr + PCI_EXP_DEVCAP,
+ &mpss);
+ if (res != 0)
+ return res;
+
+ /* Do not set device above its maximum MPSS */
+ mpss = (mpss & PCI_EXP_DEVCAP_PAYLOAD) << 5;
+ if (target_mps < mpss)
+ mps = (u16)target_mps;
+ else
+ mps = (u16)mpss;
+ res = dm_pci_clrset_config16(dev, addr + PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_PAYLOAD, mps);
+ }
+
+ return res;
+}
+
+/*
+ * Sets the MPS of each PCI Express device to the specified policy.
+ */
+static int pci_mps_set(int policy)
+{
+ struct udevice *bus;
+ int i, res = 0;
+ /* 0 = 128B, min value for hotplug */
+ unsigned int mps = 0;
+
+ if (policy == PCI_MPS_SAFE) {
+ unsigned int min_mps = PCI_EXP_DEVCAP_PAYLOAD_4096B, n = 0;
+
+ /* Find maximum MPS supported by all devices */
+ for (i = 0;
+ uclass_get_device_by_seq(UCLASS_PCI, i, &bus) == 0 &&
+ res == 0;
+ i++)
+ res = pci_mps_find_safe(bus, &min_mps, &n);
+
+ /* If no devices were found, do not reconfigure */
+ if (n == 0)
+ return res;
+ mps = min_mps;
+ }
+
+ /* This message is checked by the sandbox test */
+ printf("Setting MPS of all devices to %uB\n", 128U << mps);
+ for (i = 0;
+ uclass_get_device_by_seq(UCLASS_PCI, i, &bus) == 0 && res == 0;
+ i++)
+ res = pci_mps_set_bus(bus, mps);
+
+ return res;
+}
+
+/*
+ * PCI MPS tuning commands
+ *
+ * Syntax:
+ * pci_mps safe
+ * pci_mps peer2peer
+ */
+static int do_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ char cmd = 'u';
+ int ret = 0;
+
+ if (argc > 1)
+ cmd = argv[1][0];
+
+ switch (cmd) {
+ case 's': /* safe */
+ ret = pci_mps_set(PCI_MPS_SAFE);
+ break;
+ case 'p': /* peer2peer/hotplug */
+ ret = pci_mps_set(PCI_MPS_PEER2PEER);
+ break;
+ default: /* usage, help */
+ goto usage;
+ }
+
+ return ret;
+usage:
+ return CMD_RET_USAGE;
+}
+
+/***************************************************/
+
+#ifdef CONFIG_SYS_LONGHELP
+static char pci_mps_help_text[] =
+ "safe\n"
+ " - Set PCI Express MPS of all devices to safe values\n"
+ "pci_mps peer2peer\n"
+ " - Set PCI Express MPS of all devices to support hotplug and peer-to-peer DMA\n";
+#endif
+
+U_BOOT_CMD(pci_mps, 2, 0, do_pci_mps,
+ "configure PCI Express MPS", pci_mps_help_text);
diff --git a/cmd/read.c b/cmd/read.c
index fecfadaa1fa..1218e7acfd0 100644
--- a/cmd/read.c
+++ b/cmd/read.c
@@ -13,70 +13,69 @@
#include <mapmem.h>
#include <part.h>
-int do_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+static int
+do_rw(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- char *ep;
struct blk_desc *dev_desc = NULL;
- int dev;
- int part = 0;
struct disk_partition part_info;
- ulong offset = 0u;
- ulong limit = 0u;
+ ulong offset, limit;
+ uint blk, cnt, res;
void *addr;
- uint blk;
- uint cnt;
+ int part;
if (argc != 6) {
cmd_usage(cmdtp);
return 1;
}
- dev = (int)hextoul(argv[2], &ep);
- if (*ep) {
- if (*ep != ':') {
- printf("Invalid block device %s\n", argv[2]);
- return 1;
- }
- part = (int)hextoul(++ep, NULL);
- }
-
- dev_desc = blk_get_dev(argv[1], dev);
- if (dev_desc == NULL) {
- printf("Block device %s %d not supported\n", argv[1], dev);
+ part = part_get_info_by_dev_and_name_or_num(argv[1], argv[2],
+ &dev_desc, &part_info, 1);
+ if (part < 0)
return 1;
- }
addr = map_sysmem(hextoul(argv[3], NULL), 0);
blk = hextoul(argv[4], NULL);
cnt = hextoul(argv[5], NULL);
- if (part != 0) {
- if (part_get_info(dev_desc, part, &part_info)) {
- printf("Cannot find partition %d\n", part);
- return 1;
- }
+ if (part > 0) {
offset = part_info.start;
limit = part_info.size;
} else {
/* Largest address not available in struct blk_desc. */
+ offset = 0;
limit = ~0;
}
if (cnt + blk > limit) {
- printf("Read out of range\n");
+ printf("%s out of range\n", cmdtp->name);
return 1;
}
- if (blk_dread(dev_desc, offset + blk, cnt, addr) != cnt) {
- printf("Error reading blocks\n");
+ if (IS_ENABLED(CONFIG_CMD_WRITE) && !strcmp(cmdtp->name, "write"))
+ res = blk_dwrite(dev_desc, offset + blk, cnt, addr);
+ else
+ res = blk_dread(dev_desc, offset + blk, cnt, addr);
+
+ if (res != cnt) {
+ printf("%s error\n", cmdtp->name);
return 1;
}
return 0;
}
+#ifdef CONFIG_CMD_READ
U_BOOT_CMD(
- read, 6, 0, do_read,
+ read, 6, 0, do_rw,
"Load binary data from a partition",
- "<interface> <dev[:part]> addr blk# cnt"
+ "<interface> <dev[:part|#partname]> addr blk# cnt"
+);
+#endif
+
+#ifdef CONFIG_CMD_WRITE
+U_BOOT_CMD(
+ write, 6, 0, do_rw,
+ "Store binary data to a partition",
+ "<interface> <dev[:part|#partname]> addr blk# cnt"
);
+#endif
diff --git a/cmd/smccc.c b/cmd/smccc.c
index 0539a42587e..fb80431ad1d 100644
--- a/cmd/smccc.c
+++ b/cmd/smccc.c
@@ -43,7 +43,7 @@ static int do_call(struct cmd_tbl *cmdtp, int flag, int argc,
else
arm_smccc_hvc(fid, a1, a2, a3, a4, a5, a6, a7, &res);
- printf("Res: %ld %ld %ld %ld\n", res.a0, res.a1, res.a2, res.a3);
+ printf("Res: 0x%lx 0x%lx 0x%lx 0x%lx\n", res.a0, res.a1, res.a2, res.a3);
return 0;
}
diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c
index b7daaa6e8e8..c3cc1975f9d 100644
--- a/cmd/usb_mass_storage.c
+++ b/cmd/usb_mass_storage.c
@@ -231,6 +231,16 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag,
goto cleanup_register;
}
+ if (IS_ENABLED(CONFIG_CMD_UMS_ABORT_KEYED)) {
+ /* Abort by pressing any key */
+ if (tstc()) {
+ getchar();
+ printf("\rOperation aborted.\n");
+ rc = CMD_RET_SUCCESS;
+ goto cleanup_register;
+ }
+ }
+
schedule();
}