diff mbox series

[v3] mmc: allow use of hardware partition names for mmc partconf

Message ID 20240427001157.1460302-1-tharvey@gateworks.com
State New
Delegated to: Jaehoon Chung
Headers show
Series [v3] mmc: allow use of hardware partition names for mmc partconf | expand

Commit Message

Tim Harvey April 27, 2024, 12:11 a.m. UTC
eMMC devices have hardware partitions such as user, boot0, and boot1.

Add an enumerated type defining the hardware partition values and an
array of names describing them by name that can be used throughout
U-Boot.

Allow these names to be displayed when reading and used when setting
the mmc PARTITION_CONFIG field via 'mmc partconf'.

Before:
u-boot=> mmc partconf 2 1 1 0 && mmc partconf 2
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x2
PARTITION_ACCESS: 0x0

After:
u-boot=> mmc partconf 2 1 1 0 && mmc partconf 2
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x1 (boot0)
PARTITION_ACCESS: 0x0
u-boot=> mmc partconf 2 1 boot1 0 && mmc partconf 2
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x2 (boot1)
PARTITION_ACCESS: 0x0

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
v3:
 - define partition names and values in mmc.h/mmc.c for others to use

v2:
 - fix typo in subject
 - add names for gp1..gp4
---
 cmd/mmc.c         | 14 +++++++++++---
 drivers/mmc/mmc.c | 11 +++++++++++
 include/mmc.h     | 15 +++++++++++++++
 3 files changed, 37 insertions(+), 3 deletions(-)

Comments

Marek Vasut April 27, 2024, 12:48 a.m. UTC | #1
[...]

> diff --git a/include/mmc.h b/include/mmc.h
> index 4b8327f1f93b..7243bd761202 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -381,6 +381,21 @@ enum mmc_voltage {
>   #define MMC_TIMING_MMC_HS200	9
>   #define MMC_TIMING_MMC_HS400	10
>   
> +/* emmc hardware partition values */
> +enum emmc_hwpart {
> +	EMMC_HWPART_DEFAULT = 0,
> +	EMMC_HWPART_BOOT0 = 1,
> +	EMMC_HWPART_BOOT1 = 2,
> +	EMMC_HWPART_GP1 = 3,
> +	EMMC_HWPART_GP2 = 4,
> +	EMMC_HWPART_GP3 = 5,
> +	EMMC_HWPART_GP4 = 6,
> +	EMMC_HWPART_USER = 7,
> +};
> +
> +/* emmc hardware partition names */
> +extern const char *emmc_hwpart_names[];

Maybe the array should have fixed size here, i.e. 8 ?
E Shattow April 27, 2024, 1:29 a.m. UTC | #2
Hi Marek,

On Fri, Apr 26, 2024 at 5:49 PM Marek Vasut <marex@denx.de> wrote:
>
> [...]
>
> > diff --git a/include/mmc.h b/include/mmc.h
> > index 4b8327f1f93b..7243bd761202 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -381,6 +381,21 @@ enum mmc_voltage {
> >   #define MMC_TIMING_MMC_HS200        9
> >   #define MMC_TIMING_MMC_HS400        10
> >
> > +/* emmc hardware partition values */
> > +enum emmc_hwpart {
> > +     EMMC_HWPART_DEFAULT = 0,
> > +     EMMC_HWPART_BOOT0 = 1,
> > +     EMMC_HWPART_BOOT1 = 2,
> > +     EMMC_HWPART_GP1 = 3,
> > +     EMMC_HWPART_GP2 = 4,
> > +     EMMC_HWPART_GP3 = 5,
> > +     EMMC_HWPART_GP4 = 6,
> > +     EMMC_HWPART_USER = 7,
> > +};
> > +
> > +/* emmc hardware partition names */
> > +extern const char *emmc_hwpart_names[];
>
> Maybe the array should have fixed size here, i.e. 8 ?

Is there an ABI reason to do so? Can you explain further why it would
be needed to do that?
Marek Vasut April 27, 2024, 10:22 a.m. UTC | #3
On 4/27/24 3:29 AM, E Shattow wrote:
> Hi Marek,
> 
> On Fri, Apr 26, 2024 at 5:49 PM Marek Vasut <marex@denx.de> wrote:
>>
>> [...]
>>
>>> diff --git a/include/mmc.h b/include/mmc.h
>>> index 4b8327f1f93b..7243bd761202 100644
>>> --- a/include/mmc.h
>>> +++ b/include/mmc.h
>>> @@ -381,6 +381,21 @@ enum mmc_voltage {
>>>    #define MMC_TIMING_MMC_HS200        9
>>>    #define MMC_TIMING_MMC_HS400        10
>>>
>>> +/* emmc hardware partition values */
>>> +enum emmc_hwpart {
>>> +     EMMC_HWPART_DEFAULT = 0,
>>> +     EMMC_HWPART_BOOT0 = 1,
>>> +     EMMC_HWPART_BOOT1 = 2,
>>> +     EMMC_HWPART_GP1 = 3,
>>> +     EMMC_HWPART_GP2 = 4,
>>> +     EMMC_HWPART_GP3 = 5,
>>> +     EMMC_HWPART_GP4 = 6,
>>> +     EMMC_HWPART_USER = 7,
>>> +};
>>> +
>>> +/* emmc hardware partition names */
>>> +extern const char *emmc_hwpart_names[];
>>
>> Maybe the array should have fixed size here, i.e. 8 ?
> 
> Is there an ABI reason to do so? Can you explain further why it would
> be needed to do that?

It has nothing to do with ABI, it is only to let the compiler validate 
that nobody would index the array with index > 7 by accident.
E Shattow April 27, 2024, 12:06 p.m. UTC | #4
On Sat, Apr 27, 2024 at 3:22 AM Marek Vasut <marex@denx.de> wrote:
>
> On 4/27/24 3:29 AM, E Shattow wrote:
> > Hi Marek,
> >
> > On Fri, Apr 26, 2024 at 5:49 PM Marek Vasut <marex@denx.de> wrote:
> >>
> >> [...]
> >>
> >>> diff --git a/include/mmc.h b/include/mmc.h
> >>> index 4b8327f1f93b..7243bd761202 100644
> >>> --- a/include/mmc.h
> >>> +++ b/include/mmc.h
> >>> @@ -381,6 +381,21 @@ enum mmc_voltage {
> >>>    #define MMC_TIMING_MMC_HS200        9
> >>>    #define MMC_TIMING_MMC_HS400        10
> >>>
> >>> +/* emmc hardware partition values */
> >>> +enum emmc_hwpart {
> >>> +     EMMC_HWPART_DEFAULT = 0,
> >>> +     EMMC_HWPART_BOOT0 = 1,
> >>> +     EMMC_HWPART_BOOT1 = 2,
> >>> +     EMMC_HWPART_GP1 = 3,
> >>> +     EMMC_HWPART_GP2 = 4,
> >>> +     EMMC_HWPART_GP3 = 5,
> >>> +     EMMC_HWPART_GP4 = 6,
> >>> +     EMMC_HWPART_USER = 7,
> >>> +};
> >>> +
> >>> +/* emmc hardware partition names */
> >>> +extern const char *emmc_hwpart_names[];
> >>
> >> Maybe the array should have fixed size here, i.e. 8 ?
> >
> > Is there an ABI reason to do so? Can you explain further why it would
> > be needed to do that?
>
> It has nothing to do with ABI, it is only to let the compiler validate
> that nobody would index the array with index > 7 by accident.

At least GCC knows this without doing its work again ourselves. How
about a const for the upper limit, where currently EMMC_HWPART_USER
substitutes for expressing an upper limit? You may as well be writing
EMMC_HWPART_MAX = 8 in the enum and using that for the initializer
also any iterators with a less-than condition to make it more
expressive.

$ gcc -o testobj test.c -Wall -Wextra -O2
test.c: In function ‘main’:
test.c:16:5: warning: array subscript 8 is above array bounds of
‘const char *[8]’ [-Warray-bounds=]
   16 |     printf(emmc_hwpart_names[8]);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.c:3:13: note: while referencing ‘emmc_hwpart_names’
    3 | const char *emmc_hwpart_names[] = {
      |             ^~~~~~~~~~~~~~~~~

#include <stdio.h>

const char *emmc_hwpart_names[] = {
       "user",
       "boot0",
       "boot1",
       "gp1",
       "gp2",
       "gp3",
       "gp4",
       "user",
};

int main(int argc, char** argv) {
    (void) argc; (void) argv;
    printf(emmc_hwpart_names[8]);

    return 0;
}

Sorry to belabor this and I'm not a professional programmer. Best regards, -E
Marek Vasut April 27, 2024, 11:19 p.m. UTC | #5
On 4/27/24 2:06 PM, E Shattow wrote:
> On Sat, Apr 27, 2024 at 3:22 AM Marek Vasut <marex@denx.de> wrote:
>>
>> On 4/27/24 3:29 AM, E Shattow wrote:
>>> Hi Marek,
>>>
>>> On Fri, Apr 26, 2024 at 5:49 PM Marek Vasut <marex@denx.de> wrote:
>>>>
>>>> [...]
>>>>
>>>>> diff --git a/include/mmc.h b/include/mmc.h
>>>>> index 4b8327f1f93b..7243bd761202 100644
>>>>> --- a/include/mmc.h
>>>>> +++ b/include/mmc.h
>>>>> @@ -381,6 +381,21 @@ enum mmc_voltage {
>>>>>     #define MMC_TIMING_MMC_HS200        9
>>>>>     #define MMC_TIMING_MMC_HS400        10
>>>>>
>>>>> +/* emmc hardware partition values */
>>>>> +enum emmc_hwpart {
>>>>> +     EMMC_HWPART_DEFAULT = 0,
>>>>> +     EMMC_HWPART_BOOT0 = 1,
>>>>> +     EMMC_HWPART_BOOT1 = 2,
>>>>> +     EMMC_HWPART_GP1 = 3,
>>>>> +     EMMC_HWPART_GP2 = 4,
>>>>> +     EMMC_HWPART_GP3 = 5,
>>>>> +     EMMC_HWPART_GP4 = 6,
>>>>> +     EMMC_HWPART_USER = 7,
>>>>> +};
>>>>> +
>>>>> +/* emmc hardware partition names */
>>>>> +extern const char *emmc_hwpart_names[];
>>>>
>>>> Maybe the array should have fixed size here, i.e. 8 ?
>>>
>>> Is there an ABI reason to do so? Can you explain further why it would
>>> be needed to do that?
>>
>> It has nothing to do with ABI, it is only to let the compiler validate
>> that nobody would index the array with index > 7 by accident.
> 
> At least GCC knows this without doing its work again ourselves. How
> about a const for the upper limit, where currently EMMC_HWPART_USER
> substitutes for expressing an upper limit? You may as well be writing
> EMMC_HWPART_MAX = 8 in the enum and using that for the initializer
> also any iterators with a less-than condition to make it more
> expressive.

You could use ARRAY_SIZE(emmc_hwpart_names) in iterators, no extra 
symbols should be necessary.

> $ gcc -o testobj test.c -Wall -Wextra -O2
> test.c: In function ‘main’:
> test.c:16:5: warning: array subscript 8 is above array bounds of
> ‘const char *[8]’ [-Warray-bounds=]
>     16 |     printf(emmc_hwpart_names[8]);
>        |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> test.c:3:13: note: while referencing ‘emmc_hwpart_names’
>      3 | const char *emmc_hwpart_names[] = {
>        |             ^~~~~~~~~~~~~~~~~
> 
> #include <stdio.h>
> 
> const char *emmc_hwpart_names[] = {
>         "user",
>         "boot0",
>         "boot1",
>         "gp1",
>         "gp2",
>         "gp3",
>         "gp4",
>         "user",
> };
> 
> int main(int argc, char** argv) {
>      (void) argc; (void) argv;
>      printf(emmc_hwpart_names[8]);
> 
>      return 0;
> }

In case of this patched code here, the example is more like this:

a.c:
#include <stdio.h>
#include "h.h"

int main(void)
{
     printf("%d\n", arr[8]); // This code contains a bug here
     return 0;
}

b.c:
int arr[2] = { 1, 2 };

h.h:
extern int arr[];

Compile:
$ gcc -O2 -Wall -c -o a.o a.c
$ gcc -O2 -Wall -c -o b.o b.c
$ gcc -O2 -Wall -o out a.o b.o

You won't get warning when compiling a.c , because gcc does not know the 
size of the array until the linking step. You will get a warning if you 
change the header like this:

h.h:
-extern int arr[];
+extern int arr[2];
Marek Vasut April 27, 2024, 11:20 p.m. UTC | #6
On 4/27/24 2:11 AM, Tim Harvey wrote:

[...]

> diff --git a/include/mmc.h b/include/mmc.h
> index 4b8327f1f93b..7243bd761202 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -381,6 +381,21 @@ enum mmc_voltage {
>   #define MMC_TIMING_MMC_HS200	9
>   #define MMC_TIMING_MMC_HS400	10
>   
> +/* emmc hardware partition values */
> +enum emmc_hwpart {
> +	EMMC_HWPART_DEFAULT = 0,

One more thing ... eMMC hardware partition 0 and 7 are both referring to 
USER HW partition. Have a look at the git log, there have been patches 
which handled this case in the MMC subsystem from about a year ago.

> +	EMMC_HWPART_BOOT0 = 1,
> +	EMMC_HWPART_BOOT1 = 2,
> +	EMMC_HWPART_GP1 = 3,
> +	EMMC_HWPART_GP2 = 4,
> +	EMMC_HWPART_GP3 = 5,
> +	EMMC_HWPART_GP4 = 6,
> +	EMMC_HWPART_USER = 7,

[...]
Tim Harvey April 29, 2024, 4:48 p.m. UTC | #7
On Sat, Apr 27, 2024 at 4:20 PM Marek Vasut <marex@denx.de> wrote:
>
> On 4/27/24 2:11 AM, Tim Harvey wrote:
>
> [...]
>
> > diff --git a/include/mmc.h b/include/mmc.h
> > index 4b8327f1f93b..7243bd761202 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -381,6 +381,21 @@ enum mmc_voltage {
> >   #define MMC_TIMING_MMC_HS200        9
> >   #define MMC_TIMING_MMC_HS400        10
> >
> > +/* emmc hardware partition values */
> > +enum emmc_hwpart {
> > +     EMMC_HWPART_DEFAULT = 0,
>
> One more thing ... eMMC hardware partition 0 and 7 are both referring to
> USER HW partition. Have a look at the git log, there have been patches
> which handled this case in the MMC subsystem from about a year ago.

Hi Marek,

I can't find what you are referring to. I assume you are talking about
calling the first name something other than 'user' as technically it's
not (but it gets treated as user).

Can you find the commit or discussion you are thinking about?

Best Regards,

Tim
Marek Vasut April 29, 2024, 8:15 p.m. UTC | #8
On 4/29/24 6:48 PM, Tim Harvey wrote:
> On Sat, Apr 27, 2024 at 4:20 PM Marek Vasut <marex@denx.de> wrote:
>>
>> On 4/27/24 2:11 AM, Tim Harvey wrote:
>>
>> [...]
>>
>>> diff --git a/include/mmc.h b/include/mmc.h
>>> index 4b8327f1f93b..7243bd761202 100644
>>> --- a/include/mmc.h
>>> +++ b/include/mmc.h
>>> @@ -381,6 +381,21 @@ enum mmc_voltage {
>>>    #define MMC_TIMING_MMC_HS200        9
>>>    #define MMC_TIMING_MMC_HS400        10
>>>
>>> +/* emmc hardware partition values */
>>> +enum emmc_hwpart {
>>> +     EMMC_HWPART_DEFAULT = 0,
>>
>> One more thing ... eMMC hardware partition 0 and 7 are both referring to
>> USER HW partition. Have a look at the git log, there have been patches
>> which handled this case in the MMC subsystem from about a year ago.
> 
> Hi Marek,
> 
> I can't find what you are referring to. I assume you are talking about
> calling the first name something other than 'user' as technically it's
> not (but it gets treated as user).
> 
> Can you find the commit or discussion you are thinking about?

It seems this whole thing is much older:

7dbe63bc950b ("SPL: Add CONFIG_SUPPORT_EMMC_BOOT support to 
CONFIG_SPL_FRAMEWORK")

+                * We need to check what the partition is configured to.
+                * 1 and 2 match up to boot0 / boot1 and 7 is user data
+                * which is the first physical partition (0).
+                */
+               int part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
+
+               if (part == 7)
+                       part = 0;
diff mbox series

Patch

diff --git a/cmd/mmc.c b/cmd/mmc.c
index 2d5430a53079..26ab4450816b 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -14,6 +14,7 @@ 
 #include <part.h>
 #include <sparse_format.h>
 #include <image-sparse.h>
+#include <linux/ctype.h>
 
 static int curr_device = -1;
 
@@ -918,8 +919,8 @@  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\n", ack, part, emmc_hwpart_names[part], access);
 
 	return CMD_RET_SUCCESS;
 }
@@ -949,7 +950,14 @@  static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
 		return mmc_partconf_print(mmc, cmd_arg2(argc, argv));
 
 	ack = dectoul(argv[2], NULL);
-	part_num = dectoul(argv[3], NULL);
+	if (!isdigit(*argv[3])) {
+		for (part_num = 0; part_num <= EMMC_HWPART_USER; part_num++) {
+			if (!strcmp(argv[3], emmc_hwpart_names[part_num]))
+				break;
+		}
+	} else {
+		part_num = dectoul(argv[3], NULL);
+	}
 	access = dectoul(argv[4], NULL);
 
 	/* acknowledge to be sent during boot operation */
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7b068c71ff37..132afe1b8a29 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -29,6 +29,17 @@ 
 
 #define DEFAULT_CMD6_TIMEOUT_MS  500
 
+const char *emmc_hwpart_names[] = {
+	"user",
+	"boot0",
+	"boot1",
+	"gp1",
+	"gp2",
+	"gp3",
+	"gp4",
+	"user",
+};
+
 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 4b8327f1f93b..7243bd761202 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -381,6 +381,21 @@  enum mmc_voltage {
 #define MMC_TIMING_MMC_HS200	9
 #define MMC_TIMING_MMC_HS400	10
 
+/* emmc hardware partition values */
+enum emmc_hwpart {
+	EMMC_HWPART_DEFAULT = 0,
+	EMMC_HWPART_BOOT0 = 1,
+	EMMC_HWPART_BOOT1 = 2,
+	EMMC_HWPART_GP1 = 3,
+	EMMC_HWPART_GP2 = 4,
+	EMMC_HWPART_GP3 = 5,
+	EMMC_HWPART_GP4 = 6,
+	EMMC_HWPART_USER = 7,
+};
+
+/* emmc hardware partition names */
+extern const char *emmc_hwpart_names[];
+
 /* Driver model support */
 
 /**