[PATCH RFC u-boot-mvebu 21/59] cmd: mvebu/bubt: Add support for writing image to SATA disk

Pali Rohár pali at kernel.org
Tue Feb 21 21:18:47 CET 2023


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 <pali at kernel.org>
---
 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 9ec3aa983a51..8f30a0c22be3 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 4bad9a69527c..1d51fde579b5 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>
@@ -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 1fe1f07dd187..515e4fb1b0e8 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.20.1



More information about the U-Boot mailing list