summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorPatrick Delaunay <patrick.delaunay@st.com>2020-03-18 09:24:53 +0100
committerPatrick Delaunay <patrick.delaunay@st.com>2020-05-14 09:02:12 +0200
commitffc405e63b945de77dca51364cd5c6335f11d5c4 (patch)
treec245542123db34058d0a6e73f3ab7950b9bc6e68 /arch/arm
parent878f7542f1880a73e703223de695c43d0f45e2bf (diff)
stm32mp: stm32prog: add upport of partial update
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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c69
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h1
2 files changed, 70 insertions, 0 deletions
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
index f63036606e..787bcdef7d 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
@@ -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);
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
index 6c3ad56a38..ea88459896 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
@@ -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 */