[PATCH 07/18] stm32mp: stm32prog: add support of boot partition for eMMC device
Patrice CHOTARD
patrice.chotard at st.com
Tue Apr 14 15:05:23 CEST 2020
Hi
On 3/18/20 9:24 AM, Patrick Delaunay wrote:
> Add support of eMMC device boot partition with
> part_id = -1 for offset="boot1"
> or = -2 for offset="boot2"
>
> The stm32prog command configures the MMC DFU backend with "mmcpart"
> and configure the eMMC (command "mmc bootbus" and "mmc partconf")
> when the update is done.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com>
> ---
>
> .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 124 +++++++++++++-----
> .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 2 +-
> 2 files changed, 90 insertions(+), 36 deletions(-)
>
> diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
> index feb83670b5..f63036606e 100644
> --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
> +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
> @@ -259,12 +259,30 @@ static int parse_offset(struct stm32prog_data *data,
> char *tail;
>
> part->part_id = 0;
> + part->addr = 0;
> part->size = 0;
> - part->addr = simple_strtoull(p, &tail, 0);
> - if (tail == p || *tail != '\0') {
> - stm32prog_err("Layout line %d: invalid offset '%s'",
> - i, p);
> - result = -EINVAL;
> + /* eMMC boot parttion */
> + if (!strncmp(p, "boot", 4)) {
> + if (strlen(p) != 5) {
> + result = -EINVAL;
> + } else {
> + if (p[4] == '1')
> + part->part_id = -1;
> + else if (p[4] == '2')
> + part->part_id = -2;
> + else
> + result = -EINVAL;
> + }
> + if (result)
> + stm32prog_err("Layout line %d: invalid part '%s'",
> + i, p);
> + } else {
> + part->addr = simple_strtoull(p, &tail, 0);
> + if (tail == p || *tail != '\0') {
> + stm32prog_err("Layout line %d: invalid offset '%s'",
> + i, p);
> + result = -EINVAL;
> + }
> }
>
> return result;
> @@ -451,7 +469,10 @@ static int __init part_cmp(void *priv, struct list_head *a, struct list_head *b)
> parta = container_of(a, struct stm32prog_part_t, list);
> partb = container_of(b, struct stm32prog_part_t, list);
>
> - return parta->addr > partb->addr ? 1 : -1;
> + if (parta->part_id != partb->part_id)
> + return parta->part_id - partb->part_id;
> + else
> + return parta->addr > partb->addr ? 1 : -1;
> }
>
> static int init_device(struct stm32prog_data *data,
> @@ -520,44 +541,53 @@ static int init_device(struct stm32prog_data *data,
> part->dev_id, part->addr, part->size);
> continue;
> }
> -
> - part->part_id = part_id++;
> -
> - /* last partition : size to the end of the device */
> - if (part->list.next != &dev->part_list) {
> - next_part =
> - container_of(part->list.next,
> - struct stm32prog_part_t,
> - list);
> - if (part->addr < next_part->addr) {
> - part->size = next_part->addr -
> - part->addr;
> + if (part->part_id < 0) { /* boot hw partition for eMMC */
> + if (mmc) {
> + part->size = mmc->capacity_boot;
> } else {
> - stm32prog_err("%s (0x%x): same address : 0x%llx == %s (0x%x): 0x%llx",
> + stm32prog_err("%s (0x%x): hw partition not expected : %d",
> part->name, part->id,
> - part->addr,
> - next_part->name,
> - next_part->id,
> - next_part->addr);
> - return -EINVAL;
> + part->part_id);
> + return -ENODEV;
> }
> } else {
> - if (part->addr <= last_addr) {
> - part->size = last_addr - part->addr;
> + part->part_id = part_id++;
> +
> + /* last partition : size to the end of the device */
> + if (part->list.next != &dev->part_list) {
> + next_part =
> + container_of(part->list.next,
> + struct stm32prog_part_t,
> + list);
> + if (part->addr < next_part->addr) {
> + part->size = next_part->addr -
> + part->addr;
> + } else {
> + stm32prog_err("%s (0x%x): same address : 0x%llx == %s (0x%x): 0x%llx",
> + part->name, part->id,
> + part->addr,
> + next_part->name,
> + next_part->id,
> + next_part->addr);
> + return -EINVAL;
> + }
> } else {
> - stm32prog_err("%s (0x%x): invalid address 0x%llx (max=0x%llx)",
> + if (part->addr <= last_addr) {
> + part->size = last_addr - part->addr;
> + } else {
> + stm32prog_err("%s (0x%x): invalid address 0x%llx (max=0x%llx)",
> + part->name, part->id,
> + part->addr, last_addr);
> + return -EINVAL;
> + }
> + }
> + if (part->addr < first_addr) {
> + stm32prog_err("%s (0x%x): invalid address 0x%llx (min=0x%llx)",
> part->name, part->id,
> - part->addr, last_addr);
> + part->addr, first_addr);
> return -EINVAL;
> }
> }
> - if (part->addr < first_addr) {
> - stm32prog_err("%s (0x%x): invalid address 0x%llx (min=0x%llx)",
> - part->name, part->id,
> - part->addr, first_addr);
> - return -EINVAL;
> - }
> -
> if ((part->addr & ((u64)part->dev->erase_size - 1)) != 0) {
> stm32prog_err("%s (0x%x): not aligned address : 0x%llx on erase size 0x%x",
> part->name, part->id, part->addr,
> @@ -657,6 +687,9 @@ static int create_partitions(struct stm32prog_data *data)
> memset(buf, 0, buflen);
>
> list_for_each_entry(part, &data->dev[i].part_list, list) {
> + /* skip eMMC boot partitions */
> + if (part->part_id < 0)
> + continue;
> /* skip Raw Image */
> if (part->part_type == RAW_IMAGE)
> continue;
> @@ -787,6 +820,14 @@ static int stm32prog_alt_add(struct stm32prog_data *data,
> dfu_size = part->size;
> offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
> "raw 0x0 0x%llx", dfu_size);
> + } else if (part->part_id < 0) {
> + u64 nb_blk = part->size / part->dev->mmc->read_bl_len;
> +
> + offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
> + "raw 0x%llx 0x%llx",
> + part->addr, nb_blk);
> + offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
> + " mmcpart %d;", -(part->part_id));
> } else {
> offset += snprintf(buf + offset,
> ALT_BUF_LEN - offset,
> @@ -908,6 +949,19 @@ static void stm32prog_end_phase(struct stm32prog_data *data)
>
> if (!data->cur_part)
> return;
> +
> + if (CONFIG_IS_ENABLED(MMC) &&
> + data->cur_part->part_id < 0) {
> + char cmdbuf[60];
> +
> + sprintf(cmdbuf, "mmc bootbus %d 0 0 0; mmc partconf %d 1 %d 0",
> + data->cur_part->dev_id, data->cur_part->dev_id,
> + -(data->cur_part->part_id));
> + if (run_command(cmdbuf, 0)) {
> + stm32prog_err("commands '%s' failed", cmdbuf);
> + return;
> + }
> + }
> }
>
> void stm32prog_do_reset(struct stm32prog_data *data)
> diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
> index 228a25d37f..6c3ad56a38 100644
> --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
> +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
> @@ -89,7 +89,7 @@ struct stm32prog_part_t {
>
> /* information on associated device */
> struct stm32prog_dev_t *dev; /* pointer to device */
> - u16 part_id; /* partition id in device */
> + s16 part_id; /* partition id in device */
> int alt_id; /* alt id in usb/dfu */
>
> struct list_head list;
Reviewed-by: Patrice Chotard <patrice.chotard at st.com>
Thanks
Patrice
More information about the U-Boot
mailing list