diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/Kconfig | 29 | ||||
-rw-r--r-- | cmd/Makefile | 8 | ||||
-rw-r--r-- | cmd/bdinfo.c | 11 | ||||
-rw-r--r-- | cmd/bootefi.c | 19 | ||||
-rw-r--r-- | cmd/bootflow.c | 8 | ||||
-rw-r--r-- | cmd/cls.c | 20 | ||||
-rw-r--r-- | cmd/efi.c | 31 | ||||
-rw-r--r-- | cmd/efi_common.c | 26 | ||||
-rw-r--r-- | cmd/efidebug.c | 6 | ||||
-rw-r--r-- | cmd/fdt.c | 32 | ||||
-rw-r--r-- | cmd/font.c | 6 | ||||
-rw-r--r-- | cmd/mvebu/Kconfig | 18 | ||||
-rw-r--r-- | cmd/mvebu/bubt.c | 253 | ||||
-rw-r--r-- | cmd/nand.c | 9 | ||||
-rw-r--r-- | cmd/nvedit.c | 11 | ||||
-rw-r--r-- | cmd/pci_mps.c | 164 | ||||
-rw-r--r-- | cmd/read.c | 61 | ||||
-rw-r--r-- | cmd/smccc.c | 2 | ||||
-rw-r--r-- | cmd/usb_mass_storage.c | 10 |
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, + ®val); + 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(); } |