stm32mp: stm32prog: add support of boot partition for eMMC device

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@st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
This commit is contained in:
Patrick Delaunay 2020-03-18 09:24:52 +01:00
parent aff4c5dd82
commit 878f7542f1
2 changed files with 90 additions and 36 deletions

View file

@ -259,12 +259,30 @@ static int parse_offset(struct stm32prog_data *data,
char *tail; char *tail;
part->part_id = 0; part->part_id = 0;
part->addr = 0;
part->size = 0; part->size = 0;
part->addr = simple_strtoull(p, &tail, 0); /* eMMC boot parttion */
if (tail == p || *tail != '\0') { if (!strncmp(p, "boot", 4)) {
stm32prog_err("Layout line %d: invalid offset '%s'", if (strlen(p) != 5) {
i, p); result = -EINVAL;
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; 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); parta = container_of(a, struct stm32prog_part_t, list);
partb = container_of(b, 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, 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); part->dev_id, part->addr, part->size);
continue; continue;
} }
if (part->part_id < 0) { /* boot hw partition for eMMC */
part->part_id = part_id++; if (mmc) {
part->size = mmc->capacity_boot;
/* 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 { } 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->name, part->id,
part->addr, part->part_id);
next_part->name, return -ENODEV;
next_part->id,
next_part->addr);
return -EINVAL;
} }
} else { } else {
if (part->addr <= last_addr) { part->part_id = part_id++;
part->size = last_addr - part->addr;
/* 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 { } 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->name, part->id,
part->addr, last_addr); part->addr, first_addr);
return -EINVAL; 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) { 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", stm32prog_err("%s (0x%x): not aligned address : 0x%llx on erase size 0x%x",
part->name, part->id, part->addr, part->name, part->id, part->addr,
@ -657,6 +687,9 @@ static int create_partitions(struct stm32prog_data *data)
memset(buf, 0, buflen); memset(buf, 0, buflen);
list_for_each_entry(part, &data->dev[i].part_list, list) { list_for_each_entry(part, &data->dev[i].part_list, list) {
/* skip eMMC boot partitions */
if (part->part_id < 0)
continue;
/* skip Raw Image */ /* skip Raw Image */
if (part->part_type == RAW_IMAGE) if (part->part_type == RAW_IMAGE)
continue; continue;
@ -787,6 +820,14 @@ static int stm32prog_alt_add(struct stm32prog_data *data,
dfu_size = part->size; dfu_size = part->size;
offset += snprintf(buf + offset, ALT_BUF_LEN - offset, offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
"raw 0x0 0x%llx", dfu_size); "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 { } else {
offset += snprintf(buf + offset, offset += snprintf(buf + offset,
ALT_BUF_LEN - offset, ALT_BUF_LEN - offset,
@ -908,6 +949,19 @@ static void stm32prog_end_phase(struct stm32prog_data *data)
if (!data->cur_part) if (!data->cur_part)
return; 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) void stm32prog_do_reset(struct stm32prog_data *data)

View file

@ -89,7 +89,7 @@ struct stm32prog_part_t {
/* information on associated device */ /* information on associated device */
struct stm32prog_dev_t *dev; /* pointer to 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 */ int alt_id; /* alt id in usb/dfu */
struct list_head list; struct list_head list;