aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-09-05 12:13:24 -0600
committerTom Rini <trini@konsulko.com>2024-09-05 12:13:24 -0600
commit208fc7a9f9022240e47ae4969227f60d2b84dbb9 (patch)
tree322334b378783facdf053cc9f2bf9e29742aaeaa
parent360aaddd9cea8c256f50c576794415cadfb61819 (diff)
parent1f239b6febf1bf8dd914419856638b2d94e13f97 (diff)
downloadu-boot-208fc7a9f9022240e47ae4969227f60d2b84dbb9.tar.gz
Merge patch series "provide names for emmc hardware partitions"
Tim Harvey <tharvey@gateworks.com> says: Modern eMMC v4+ devices have multiple hardware partitions per the JEDEC specification described as: Boot Area Partition 1 Boot Area Partition 2 RPMB Partition General Purpose Partition 1 General Purpose Partition 2 General Purpose Partition 3 General Purpose Partition 4 User Data Area These are referenced by fields in the PARTITION_CONFIG register (Extended CSD Register 179) which is defined as: bit 7: reserved bit 6: BOOT_ACK 0x0: No boot acknowledge sent (default 0x1: Boot acknowledge sent during boot operation Bit bit 5:3: BOOT_PARTITION_ENABLE 0x0: Device not boot enabled (default) 0x1: Boot Area partition 1 enabled for boot 0x2: Boot Area partition 2 enabled for boot 0x3-0x6: Reserved 0x7: User area enabled for boot bit 2:0 PARTITION_ACCESS 0x0: No access to boot partition (default) 0x1: Boot Area partition 1 0x2: Boot Area partition 2 0x3: Replay Protected Memory Block (RPMB) 0x4: Access to General Purpose partition 1 0x5: Access to General Purpose partition 2 0x6: Access to General Purpose partition 3 0x7: Access to General Purpose partition 4 Note that setting PARTITION_ACCESS to 0x0 results in selecting the User Data Area partition. You can see above that the two fields BOOT_PARTITION_ENABLE and PARTITION_ACCESS do not use the same enumerated values. U-Boot uses a set of macros to access fields of the PARTITION_CONFIG register: EXT_CSD_BOOT_ACK_ENABLE (1 << 6) EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) EXT_CSD_PARTITION_ACCESS_DISABLE (0 << 0) EXT_CSD_BOOT_ACK(x) (x << 6) EXT_CSD_BOOT_PART_NUM(x) (x << 3) EXT_CSD_PARTITION_ACCESS(x) (x << 0) EXT_CSD_EXTRACT_BOOT_ACK(x) (((x) >> 6) & 0x1) EXT_CSD_EXTRACT_BOOT_PART(x) (((x) >> 3) & 0x7) EXT_CSD_EXTRACT_PARTITION_ACCESS(x) ((x) & 0x7) There are various places in U-Boot where the BOOT_PARTITION_ENABLE field is accessed via EXT_CSD_EXTRACT_PARTITION_ACCESS and converted to a hardware partition consistent with the definition of the PARTITION_ACCESS field used by the various mmc_switch incarnations. To add some sanity to the distinction between BOOT_PARTITION_ENABLE (used to specify the active device on power-cycle) and PARTITION_ACCESS (used to switch between hardware partitions) create two enumerated types and use them wherever struct mmc * part_config is used or the above macros are used. Additionally provide arrays of the field names and allow those to be used in the 'mmc partconf' command and in board support files. The first patch adds enumerated types and makes use of them which represents no compiled code change. The 2nd patch adds the array of names and uses them in the 'mmc partconf' command. The 3rd patch uses the array of hardware partition names in a board support file to show what emmc hardware partition U-Boot is being loaded from.
-rw-r--r--arch/arm/mach-imx/image-container.c10
-rw-r--r--arch/arm/mach-sunxi/board.c2
-rw-r--r--board/gateworks/venice/spl.c20
-rw-r--r--board/gateworks/venice/venice.c22
-rw-r--r--board/purism/librem5/librem5.c4
-rw-r--r--board/storopack/smegw01/smegw01.c4
-rw-r--r--cmd/mmc.c27
-rw-r--r--cmd/mvebu/bubt.c4
-rw-r--r--common/spl/spl_mmc.c4
-rw-r--r--drivers/mmc/mmc.c35
-rw-r--r--include/mmc.h26
11 files changed, 123 insertions, 35 deletions
diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c
index e2388e3fef8..2afe9d38a06 100644
--- a/arch/arm/mach-imx/image-container.c
+++ b/arch/arm/mach-imx/image-container.c
@@ -205,7 +205,7 @@ static unsigned long get_boot_device_offset(void *dev, int dev_type)
} else {
u8 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
- if (part == 1 || part == 2) {
+ if (part == EMMC_BOOT_PART_BOOT1 || part == EMMC_BOOT_PART_BOOT2) {
if (is_imx8qxp() && is_soc_rev(CHIP_REV_B))
offset = CONTAINER_HDR_MMCSD_OFFSET;
else
@@ -294,15 +294,15 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc)
int part;
part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
- if (part == 1 || part == 2) {
+ if (part == EMMC_BOOT_PART_BOOT1 || part == EMMC_BOOT_PART_BOOT2) {
unsigned long sec_set_off = 0;
bool sec_boot = false;
sec_boot = check_secondary_cnt_set(&sec_set_off);
if (sec_boot)
- part = (part == 1) ? 2 : 1;
- } else if (part == 7) {
- part = 0;
+ part = (part == EMMC_BOOT_PART_BOOT1) ? EMMC_HWPART_BOOT2 : EMMC_HWPART_BOOT1;
+ } else if (part == EMMC_BOOT_PART_USER) {
+ part = EMMC_HWPART_DEFAULT;
}
return part;
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 046e9fbfc67..2b64ddc0dc7 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -399,7 +399,7 @@ static bool sunxi_valid_emmc_boot(struct mmc *mmc)
return false;
/* Partition 0 is the user data partition, bootpart must be 1 or 2. */
- if (bootpart != 1 && bootpart != 2)
+ if (bootpart != EMMC_BOOT_PART_BOOT1 && bootpart != EMMC_BOOT_PART_BOOT2)
return false;
/* Failure to switch to the boot partition is fatal. */
diff --git a/board/gateworks/venice/spl.c b/board/gateworks/venice/spl.c
index e9cdede6214..002d7bbf864 100644
--- a/board/gateworks/venice/spl.c
+++ b/board/gateworks/venice/spl.c
@@ -366,8 +366,8 @@ unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long
{
if (!IS_SD(mmc)) {
switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
- case 1:
- case 2:
+ case EMMC_BOOT_PART_BOOT1:
+ case EMMC_BOOT_PART_BOOT2:
if (IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP))
raw_sect -= 32 * 2;
break;
@@ -379,16 +379,24 @@ unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long
const char *spl_board_loader_name(u32 boot_device)
{
+ static char name[16];
+ struct mmc *mmc;
+
switch (boot_device) {
/* SDHC2 */
case BOOT_DEVICE_MMC1:
- return "eMMC";
+ mmc_init_device(0);
+ mmc = find_mmc_device(0);
+ mmc_init(mmc);
+ snprintf(name, sizeof(name), "eMMC %s", emmc_hwpart_names[EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)]);
+ return name;
/* SDHC3 */
case BOOT_DEVICE_MMC2:
- return "SD card";
- default:
- return NULL;
+ sprintf(name, "SD card");
+ return name;
}
+
+ return NULL;
}
void spl_board_init(void)
diff --git a/board/gateworks/venice/venice.c b/board/gateworks/venice/venice.c
index d4c22121497..98b33624f04 100644
--- a/board/gateworks/venice/venice.c
+++ b/board/gateworks/venice/venice.c
@@ -157,20 +157,20 @@ int board_late_init(void)
int bootpart;
switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
- case 1: /* boot0 */
- bootpart = 1;
+ case EMMC_BOOT_PART_BOOT1:
+ bootpart = EMMC_HWPART_BOOT1;
break;
- case 2: /* boot1 */
- bootpart = 2;
+ case EMMC_BOOT_PART_BOOT2:
+ bootpart = EMMC_HWPART_BOOT2;
break;
- case 7: /* user */
+ case EMMC_BOOT_PART_USER:
default:
- bootpart = 0;
+ bootpart = EMMC_HWPART_DEFAULT;
break;
}
/* IMX8MP/IMX8MN BOOTROM v2 uses offset=0 for boot parts */
if ((IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP)) &&
- (bootpart == 1 || bootpart == 2))
+ (bootpart == EMMC_BOOT_PART_BOOT1 || bootpart == EMMC_BOOT_PART_BOOT2))
bootblk = 0;
env_set_hex("bootpart", bootpart);
env_set_hex("bootblk", bootblk);
@@ -201,10 +201,10 @@ uint mmc_get_env_part(struct mmc *mmc)
{
if (!IS_SD(mmc)) {
switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
- case 1:
- return 1;
- case 2:
- return 2;
+ case EMMC_BOOT_PART_BOOT1:
+ return EMMC_HWPART_BOOT1;
+ case EMMC_BOOT_PART_BOOT2:
+ return EMMC_HWPART_BOOT2;
}
}
diff --git a/board/purism/librem5/librem5.c b/board/purism/librem5/librem5.c
index a3c421572af..8ca8792fa42 100644
--- a/board/purism/librem5/librem5.c
+++ b/board/purism/librem5/librem5.c
@@ -42,8 +42,8 @@ uint board_mmc_get_env_part(struct mmc *mmc)
{
uint part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
- if (part == 7)
- part = 0;
+ if (part == EMMC_BOOT_PART_USER)
+ part = EMMC_HWPART_DEFAULT;
return part;
}
#endif
diff --git a/board/storopack/smegw01/smegw01.c b/board/storopack/smegw01/smegw01.c
index 910feeda31f..c9513ddbc68 100644
--- a/board/storopack/smegw01/smegw01.c
+++ b/board/storopack/smegw01/smegw01.c
@@ -105,8 +105,8 @@ uint mmc_get_env_part(struct mmc *mmc)
{
uint part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
- if (part == 7)
- part = 0;
+ if (part == EMMC_BOOT_PART_USER)
+ part = EMMC_HWPART_DEFAULT;
return part;
}
diff --git a/cmd/mmc.c b/cmd/mmc.c
index ff7b8e555ba..9a841c25d3d 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -14,6 +14,7 @@
#include <sparse_format.h>
#include <image-sparse.h>
#include <vsprintf.h>
+#include <linux/ctype.h>
static int curr_device = -1;
@@ -918,8 +919,9 @@ static int mmc_partconf_print(struct mmc *mmc, const char *varname)
printf("EXT_CSD[179], PARTITION_CONFIG:\n"
"BOOT_ACK: 0x%x\n"
- "BOOT_PARTITION_ENABLE: 0x%x\n"
- "PARTITION_ACCESS: 0x%x\n", ack, part, access);
+ "BOOT_PARTITION_ENABLE: 0x%x (%s)\n"
+ "PARTITION_ACCESS: 0x%x (%s)\n", ack, part, emmc_boot_part_names[part],
+ access, emmc_hwpart_names[access]);
return CMD_RET_SUCCESS;
}
@@ -948,9 +950,26 @@ static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
if (argc == 2 || argc == 3)
return mmc_partconf_print(mmc, cmd_arg2(argc, argv));
+ /* BOOT_ACK */
ack = dectoul(argv[2], NULL);
- part_num = dectoul(argv[3], NULL);
- access = dectoul(argv[4], NULL);
+ /* BOOT_PARTITION_ENABLE */
+ if (!isdigit(*argv[3])) {
+ for (part_num = ARRAY_SIZE(emmc_boot_part_names) - 1; part_num > 0; part_num--) {
+ if (!strcmp(argv[3], emmc_boot_part_names[part_num]))
+ break;
+ }
+ } else {
+ part_num = dectoul(argv[3], NULL);
+ }
+ /* PARTITION_ACCESS */
+ if (!isdigit(*argv[4])) {
+ for (access = ARRAY_SIZE(emmc_hwpart_names) - 1; access > 0; access--) {
+ if (!strcmp(argv[4], emmc_hwpart_names[access]))
+ break;
+ }
+ } else {
+ access = dectoul(argv[4], NULL);
+ }
/* acknowledge to be sent during boot operation */
ret = mmc_set_part_conf(mmc, ack, part_num, access);
diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c
index e3f21dd0d81..5e4ffc40d72 100644
--- a/cmd/mvebu/bubt.c
+++ b/cmd/mvebu/bubt.c
@@ -223,8 +223,8 @@ static int mmc_burn_image(size_t image_size)
#endif
part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
- if (part == 7)
- part = 0;
+ if (part == EMMC_BOOT_PART_USER)
+ part = EMMC_HWPART_DEFAULT;
#ifdef CONFIG_BLK
err = blk_dselect_hwpart(blk_desc, part);
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 3fd81608e9f..1337596eca0 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -300,8 +300,8 @@ int default_spl_mmc_emmc_boot_partition(struct mmc *mmc)
* which is the first physical partition (0).
*/
part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
- if (part == 7)
- part = 0;
+ if (part == EMMC_BOOT_PART_USER)
+ part = EMMC_HWPART_DEFAULT;
#endif
return part;
}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 9644aa7aa43..0b881f11b4a 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -30,6 +30,41 @@
#define DEFAULT_CMD6_TIMEOUT_MS 500
+/**
+ * names of emmc BOOT_PARTITION_ENABLE values
+ *
+ * Boot Area Partitions - name consistent with Linux
+ */
+const char *emmc_boot_part_names[] = {
+ "default", /* EMMC_BOOT_PART_DEFAULT */
+ "boot0", /* EMMC_BOOT_PART_BOOT1 */
+ "boot1", /* EMMC_BOOT_PART_BOOT2 */
+ "",
+ "",
+ "",
+ "",
+ "user", /* EMMC_BOOT_PART_USER */
+};
+
+/**
+ * names of emmc 'hardware partitions' consistent with:
+ * - value used in mmc_switch()
+ * - value used by PARTITION_CONFIG PARTITION_ACCESS field
+ *
+ * Boot Area Partitions - name consistent with Linux
+ * General Perpose Partitions - name consistent with 'mmc hwpartition' usage
+ */
+const char *emmc_hwpart_names[] = {
+ "user", /* EMMC_HWPART_DEFAULT */
+ "boot0", /* EMMC_HWPART_BOOT1 */
+ "boot1", /* EMMC_HWPART_BOOT2 */
+ "rpmb", /* EMMC_HWPART_RPMB */
+ "gp1", /* EMMC_HWPART_GP1 */
+ "gp2", /* EMMC_HWPART_GP2 */
+ "gp3", /* EMMC_HWPART_GP3 */
+ "gp4", /* EMMC_HWPART_GP4 */
+};
+
static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
#if !CONFIG_IS_ENABLED(DM_MMC)
diff --git a/include/mmc.h b/include/mmc.h
index 155a8e9f420..f508cd15700 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -372,6 +372,32 @@ enum mmc_voltage {
#define MMC_TIMING_MMC_HS200 9
#define MMC_TIMING_MMC_HS400 10
+/* emmc PARTITION_CONFIG BOOT_PARTITION_ENABLE values */
+enum emmc_boot_part {
+ EMMC_BOOT_PART_DEFAULT = 0,
+ EMMC_BOOT_PART_BOOT1 = 1,
+ EMMC_BOOT_PART_BOOT2 = 2,
+ EMMC_BOOT_PART_USER = 7,
+};
+
+/* emmc PARTITION_CONFIG BOOT_PARTITION_ENABLE names */
+extern const char *emmc_boot_part_names[8];
+
+/* emmc PARTITION_CONFIG ACCESS_ENABLE values */
+enum emmc_hwpart {
+ EMMC_HWPART_DEFAULT = 0, /* user */
+ EMMC_HWPART_BOOT1 = 1,
+ EMMC_HWPART_BOOT2 = 2,
+ EMMC_HWPART_RPMB = 3,
+ EMMC_HWPART_GP1 = 4,
+ EMMC_HWPART_GP2 = 5,
+ EMMC_HWPART_GP3 = 6,
+ EMMC_HWPART_GP4 = 7,
+};
+
+/* emmc PARTITION_CONFIG ACCESS_ENABLE names */
+extern const char *emmc_hwpart_names[8];
+
/* Driver model support */
/**