From c8f5009029d2e00bff45f998996a3e0a37a5aead Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pali=20Roh=C3=A1r?= Date: Sun, 22 Jan 2023 01:25:12 +0100 Subject: [PATCH] cmd: mvebu/bubt: Add support for writing image to SATA disk MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit All 32-bit Armada SoCs and also 64-bit Armada 3720 SoC can load and boot firmware from SATA disk. This adds support for updating firmware binary for these SoCs. On 32-bit Armada SoC is firmware stored at sector 1 and on Armada 3720 is stored at MBR partition 0x4d or GPT partition with type GUID 6828311A-BA55-42A4-BCDE-A89BB5EDECAE (Marvell Armada 3700 Boot partition). Signed-off-by: Pali Rohár --- cmd/mvebu/Kconfig | 12 +++++ cmd/mvebu/bubt.c | 109 ++++++++++++++++++++++++++++++++++++++++- doc/mvebu/cmd/bubt.txt | 2 +- 3 files changed, 121 insertions(+), 2 deletions(-) diff --git a/cmd/mvebu/Kconfig b/cmd/mvebu/Kconfig index 9ec3aa983a..8f30a0c22b 100644 --- a/cmd/mvebu/Kconfig +++ b/cmd/mvebu/Kconfig @@ -5,6 +5,9 @@ config CMD_MVEBU_BUBT bool "bubt" 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 @@ -44,6 +47,15 @@ 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 diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c index 4bad9a6952..1d51fde579 100644 --- a/cmd/mvebu/bubt.c +++ b/cmd/mvebu/bubt.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -333,6 +334,108 @@ 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 int is_sata_active(void) +{ + return 1; +} +#else /* CONFIG_SCSI */ +static int sata_burn_image(size_t image_size) +{ + return -ENODEV; +} + +static int is_sata_active(void) +{ + return 0; +} +#endif /* CONFIG_SCSI */ + /******************************************************************** * SPI services ********************************************************************/ @@ -542,6 +645,7 @@ enum bubt_devices { BUBT_DEV_NET = 0, BUBT_DEV_USB, BUBT_DEV_MMC, + BUBT_DEV_SATA, BUBT_DEV_SPI, BUBT_DEV_NAND, @@ -552,6 +656,7 @@ 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", NULL, sata_burn_image, is_sata_active}, {"spi", NULL, spi_burn_image, is_spi_active}, {"nand", NULL, nand_burn_image, is_nand_active}, }; @@ -1021,6 +1126,8 @@ 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 @@ -1098,7 +1205,7 @@ 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-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]. Default = " DEFAULT_BUBT_SRC "\n" "Examples:\n" "\tbubt - Burn flash-image.bin from tftp to active boot device\n" diff --git a/doc/mvebu/cmd/bubt.txt b/doc/mvebu/cmd/bubt.txt index 1fe1f07dd1..515e4fb1b0 100644 --- a/doc/mvebu/cmd/bubt.txt +++ b/doc/mvebu/cmd/bubt.txt @@ -5,7 +5,7 @@ Bubt command is used to burn a new ATF image to flash device. The bubt command gets the following parameters: ATF file name, destination device and source device. bubt [file-name] [destination [source]] - file-name Image file name to burn. default = flash-image.bin - - destination Flash to burn to [spi, nand, mmc]. default = active flash + - destination Flash to burn to [spi, nand, mmc, sata]. default = active flash - source Source to load image from [tftp, usb]. default = tftp Examples: -- 2.39.5