stm32mp: stm32prog: add upport of partial update
authorPatrick Delaunay <patrick.delaunay@st.com>
Wed, 18 Mar 2020 08:24:53 +0000 (09:24 +0100)
committerPatrick Delaunay <patrick.delaunay@st.com>
Thu, 14 May 2020 07:02:12 +0000 (09:02 +0200)
Add support of partial update, update only some partitions,
and check the coherence of the layout with the existing GPT
partitions (offset and size).

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h

index f63036606e60ec087f454109607ae08c0bd9b75a..787bcdef7da2aa2e6ddfb6c83af62c3fbb1632f4 100644 (file)
@@ -481,8 +481,12 @@ static int init_device(struct stm32prog_data *data,
        struct mmc *mmc = NULL;
        struct blk_desc *block_dev = NULL;
        int part_id;
+       int ret;
        u64 first_addr = 0, last_addr = 0;
        struct stm32prog_part_t *part, *next_part;
+       u64 part_addr, part_size;
+       bool part_found;
+       const char *part_name;
 
        switch (dev->target) {
 #ifdef CONFIG_MMC
@@ -515,6 +519,7 @@ static int init_device(struct stm32prog_data *data,
                         block_dev->lba, block_dev->blksz);
                pr_debug(" available address = 0x%llx..0x%llx\n",
                         first_addr, last_addr);
+               pr_debug(" full_update = %d\n", dev->full_update);
                break;
 #endif
        default:
@@ -522,6 +527,7 @@ static int init_device(struct stm32prog_data *data,
                return -ENODEV;
        }
        pr_debug(" erase size = 0x%x\n", dev->erase_size);
+       pr_debug(" full_update = %d\n", dev->full_update);
 
        /* order partition list in offset order */
        list_sort(NULL, &dev->part_list, &part_cmp);
@@ -598,6 +604,61 @@ static int init_device(struct stm32prog_data *data,
                         part->part_id, part->option, part->id, part->name,
                         part->part_type, part->target,
                         part->dev_id, part->addr, part->size);
+
+               part_addr = 0;
+               part_size = 0;
+               part_found = false;
+
+               /* check coherency with existing partition */
+               if (block_dev) {
+                       /*
+                        * block devices with GPT: check user partition size
+                        * only for partial update, the GPT partions are be
+                        * created for full update
+                        */
+                       if (dev->full_update || part->part_id < 0) {
+                               pr_debug("\n");
+                               continue;
+                       }
+                       disk_partition_t partinfo;
+
+                       ret = part_get_info(block_dev, part->part_id,
+                                           &partinfo);
+
+                       if (ret) {
+                               stm32prog_err("%s (0x%x):Couldn't find part %d on device mmc %d",
+                                             part->name, part->id,
+                                             part_id, part->dev_id);
+                               return -ENODEV;
+                       }
+                       part_addr = (u64)partinfo.start * partinfo.blksz;
+                       part_size = (u64)partinfo.size * partinfo.blksz;
+                       part_name = (char *)partinfo.name;
+                       part_found = true;
+               }
+
+               if (!part_found) {
+                       stm32prog_err("%s (0x%x): Invalid partition",
+                                     part->name, part->id);
+                       pr_debug("\n");
+                       continue;
+               }
+
+               pr_debug(" %08llx %08llx\n", part_addr, part_size);
+
+               if (part->addr != part_addr) {
+                       stm32prog_err("%s (0x%x): Bad address for partition %d (%s) = 0x%llx <> 0x%llx expected",
+                                     part->name, part->id, part->part_id,
+                                     part_name, part->addr, part_addr);
+                       return -ENODEV;
+               }
+               if (part->size != part_size) {
+                       stm32prog_err("%s (0x%x): Bad size for partition %d (%s) at 0x%llx = 0x%llx <> 0x%llx expected",
+                                     part->name, part->id, part->part_id,
+                                     part_name, part->addr, part->size,
+                                     part_size);
+                       return -ENODEV;
+               }
        }
        return 0;
 }
@@ -644,6 +705,7 @@ static int treat_partition_list(struct stm32prog_data *data)
                                /* new device found */
                                data->dev[j].target = part->target;
                                data->dev[j].dev_id = part->dev_id;
+                               data->dev[j].full_update = true;
                                data->dev_nb++;
                                break;
                        } else if ((part->target == data->dev[j].target) &&
@@ -656,6 +718,8 @@ static int treat_partition_list(struct stm32prog_data *data)
                        return -EINVAL;
                }
                part->dev = &data->dev[j];
+               if (!IS_SELECT(part))
+                       part->dev->full_update = false;
                list_add_tail(&part->list, &data->dev[j].part_list);
        }
 
@@ -682,6 +746,11 @@ static int create_partitions(struct stm32prog_data *data)
        puts("partitions : ");
        /* initialize the selected device */
        for (i = 0; i < data->dev_nb; i++) {
+               /* create gpt partition support only for full update on MMC */
+               if (data->dev[i].target != STM32PROG_MMC ||
+                   !data->dev[i].full_update)
+                       continue;
+
                offset = 0;
                rootfs_found = false;
                memset(buf, 0, buflen);
index 6c3ad56a38b5b325c0840938992e97e932ac3730..ea88459896f7f2f9a8f1850398237ac4c495ff7e 100644 (file)
@@ -69,6 +69,7 @@ struct stm32prog_dev_t {
        struct mmc              *mmc;
        /* list of partition for this device / ordered in offset */
        struct list_head        part_list;
+       bool                    full_update;
 };
 
 /* partition information build from FlashLayout and device */