[PATCH 0/8] stm32mp: command stm32prog improvements

Several patches to improve the command stm32prog command. This command is used to program the STMicroelectronics boards with the tools STM32CubeProgrammer and flashlayout file.
Patrick Delaunay (8): stm32mp: stm32prog: fix comment stm32mp: stm32prog: add CONFIG_CMD_STM32PROG_OTP stm32mp: stm32prog: add TEE support in stm32prog command stm32mp: stm32prog: add support of STM32IMAGE version 2 stm32mp: stm32prog: add support of UUID for FIP partition stm32mp: stm32prog: handle interruption during the first enumeration stm32mp: stm32prog: handle U-Boot script in flashlayout alternate stm32mp: stm32prog: handle flashlayout without STM32 image header
arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 7 + .../cmd_stm32prog/cmd_stm32prog.c | 13 +- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 418 ++++++++++++++---- .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 47 +- .../cmd_stm32prog/stm32prog_usb.c | 9 +- 5 files changed, 378 insertions(+), 116 deletions(-)

Fix "partition" in comment.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 61cba157fd..d513a60efb 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -46,7 +46,7 @@ EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \ 0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18)
-/* RAW parttion (binary / bootloader) used Linux - reserved UUID */ +/* RAW partition (binary / bootloader) used Linux - reserved UUID */ #define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908"
/*

Hi Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
Fix "partition" in comment.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 61cba157fd..d513a60efb 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -46,7 +46,7 @@ EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \ 0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18)
-/* RAW parttion (binary / bootloader) used Linux - reserved UUID */ +/* RAW partition (binary / bootloader) used Linux - reserved UUID */ #define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908"
/*
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
Fix "partition" in comment.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 61cba157fd..d513a60efb 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -46,7 +46,7 @@ EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \ 0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18)
-/* RAW parttion (binary / bootloader) used Linux - reserved UUID */ +/* RAW partition (binary / bootloader) used Linux - reserved UUID */ #define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908"
/*
Applied to u-boot-stm32
Thanks Patrice

Add a configuration flag CONFIG_CMD_STM32PROG_OTP to enable the support of OTP update in stm32prog command.
This new configuration allows to deactivate this feature for security reason and it is a preliminary step for support of OPT update with the OP-TEE provisioning TA.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 7 ++ .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 66 +++++++++++-------- 2 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig index dd166a1f91..81d2b87035 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig @@ -31,3 +31,10 @@ config CMD_STM32PROG_SERIAL activate the command "stm32prog serial" for STM32MP soc family with the tools STM32CubeProgrammer using U-Boot serial device and UART protocol. + +config CMD_STM32PROG_OTP + bool "support stm32prog for OTP update" + depends on CMD_STM32PROG + default y if ARM_SMCCC + help + Support the OTP update with the command "stm32prog" for STM32MP diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d513a60efb..3e9354b51d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1154,7 +1154,9 @@ static int dfu_init_entities(struct stm32prog_data *data) struct dfu_entity *dfu; int alt_nb;
- alt_nb = 2; /* number of virtual = CMD, OTP*/ + alt_nb = 1; /* number of virtual = CMD*/ + if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) + alt_nb++; /* OTP*/ if (CONFIG_IS_ENABLED(DM_PMIC)) alt_nb++; /* PMIC NVMEM*/
@@ -1205,7 +1207,7 @@ static int dfu_init_entities(struct stm32prog_data *data) if (!ret) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
- if (!ret) + if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE);
if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) @@ -1226,6 +1228,11 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, { log_debug("%s: %x %lx\n", __func__, offset, *size);
+ if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { + stm32prog_err("OTP update not supported"); + + return -EOPNOTSUPP; + } if (!data->otp_part) { data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); if (!data->otp_part) @@ -1248,10 +1255,10 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, { int result = 0;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) { + if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { stm32prog_err("OTP update not supported");
- return -1; + return -EOPNOTSUPP; }
log_debug("%s: %x %lx\n", __func__, offset, *size); @@ -1270,8 +1277,10 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, memset(data->otp_part, 0, OTP_SIZE);
/* call the service */ - result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, - (u32)data->otp_part, 0); + result = -EOPNOTSUPP; + if (IS_ENABLED(CONFIG_ARM_SMCCC)) + result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, + (u32)data->otp_part, 0); if (result) goto end_otp_read; } @@ -1296,10 +1305,10 @@ int stm32prog_otp_start(struct stm32prog_data *data) int result = 0; struct arm_smccc_res res;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) { + if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { stm32prog_err("OTP update not supported");
- return -1; + return -EOPNOTSUPP; }
if (!data->otp_part) { @@ -1307,28 +1316,31 @@ int stm32prog_otp_start(struct stm32prog_data *data) return -1; }
- arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, - (u32)data->otp_part, 0, 0, 0, 0, 0, &res); + result = -EOPNOTSUPP; + if (IS_ENABLED(CONFIG_ARM_SMCCC)) { + arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, + (u32)data->otp_part, 0, 0, 0, 0, 0, &res);
- if (!res.a0) { - switch (res.a1) { - case 0: - result = 0; - break; - case 1: - stm32prog_err("Provisioning"); - result = 0; - break; - default: - log_err("%s: OTP incorrect value (err = %ld)\n", - __func__, res.a1); + if (!res.a0) { + switch (res.a1) { + case 0: + result = 0; + break; + case 1: + stm32prog_err("Provisioning"); + result = 0; + break; + default: + log_err("%s: OTP incorrect value (err = %ld)\n", + __func__, res.a1); + result = -EINVAL; + break; + } + } else { + log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n", + __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); result = -EINVAL; - break; } - } else { - log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n", - __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); - result = -EINVAL; }
free(data->otp_part);

Hi Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
Add a configuration flag CONFIG_CMD_STM32PROG_OTP to enable the support of OTP update in stm32prog command.
This new configuration allows to deactivate this feature for security reason and it is a preliminary step for support of OPT update with the OP-TEE provisioning TA.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 7 ++ .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 66 +++++++++++-------- 2 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig index dd166a1f91..81d2b87035 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig @@ -31,3 +31,10 @@ config CMD_STM32PROG_SERIAL activate the command "stm32prog serial" for STM32MP soc family with the tools STM32CubeProgrammer using U-Boot serial device and UART protocol.
+config CMD_STM32PROG_OTP
- bool "support stm32prog for OTP update"
- depends on CMD_STM32PROG
- default y if ARM_SMCCC
- help
Support the OTP update with the command "stm32prog" for STM32MP
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d513a60efb..3e9354b51d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1154,7 +1154,9 @@ static int dfu_init_entities(struct stm32prog_data *data) struct dfu_entity *dfu; int alt_nb;
- alt_nb = 2; /* number of virtual = CMD, OTP*/
- alt_nb = 1; /* number of virtual = CMD*/
- if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP))
if (CONFIG_IS_ENABLED(DM_PMIC)) alt_nb++; /* PMIC NVMEM*/alt_nb++; /* OTP*/
@@ -1205,7 +1207,7 @@ static int dfu_init_entities(struct stm32prog_data *data) if (!ret) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
- if (!ret)
if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE);
if (!ret && CONFIG_IS_ENABLED(DM_PMIC))
@@ -1226,6 +1228,11 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, { log_debug("%s: %x %lx\n", __func__, offset, *size);
- if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
stm32prog_err("OTP update not supported");
return -EOPNOTSUPP;
- } if (!data->otp_part) { data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); if (!data->otp_part)
@@ -1248,10 +1255,10 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, { int result = 0;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) {
- if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { stm32prog_err("OTP update not supported");
return -1;
return -EOPNOTSUPP;
}
log_debug("%s: %x %lx\n", __func__, offset, *size);
@@ -1270,8 +1277,10 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, memset(data->otp_part, 0, OTP_SIZE);
/* call the service */
result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL,
(u32)data->otp_part, 0);
result = -EOPNOTSUPP;
if (IS_ENABLED(CONFIG_ARM_SMCCC))
result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL,
if (result) goto end_otp_read; }(u32)data->otp_part, 0);
@@ -1296,10 +1305,10 @@ int stm32prog_otp_start(struct stm32prog_data *data) int result = 0; struct arm_smccc_res res;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) {
- if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { stm32prog_err("OTP update not supported");
return -1;
return -EOPNOTSUPP;
}
if (!data->otp_part) {
@@ -1307,28 +1316,31 @@ int stm32prog_otp_start(struct stm32prog_data *data) return -1; }
- arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL,
(u32)data->otp_part, 0, 0, 0, 0, 0, &res);
- result = -EOPNOTSUPP;
- if (IS_ENABLED(CONFIG_ARM_SMCCC)) {
arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL,
(u32)data->otp_part, 0, 0, 0, 0, 0, &res);
- if (!res.a0) {
switch (res.a1) {
case 0:
result = 0;
break;
case 1:
stm32prog_err("Provisioning");
result = 0;
break;
default:
log_err("%s: OTP incorrect value (err = %ld)\n",
__func__, res.a1);
if (!res.a0) {
switch (res.a1) {
case 0:
result = 0;
break;
case 1:
stm32prog_err("Provisioning");
result = 0;
break;
default:
log_err("%s: OTP incorrect value (err = %ld)\n",
__func__, res.a1);
result = -EINVAL;
break;
}
} else {
log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n",
__func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); result = -EINVAL;
break;
}
} else {
log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n",
__func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0);
result = -EINVAL;
}
free(data->otp_part);
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
Add a configuration flag CONFIG_CMD_STM32PROG_OTP to enable the support of OTP update in stm32prog command.
This new configuration allows to deactivate this feature for security reason and it is a preliminary step for support of OPT update with the OP-TEE provisioning TA.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 7 ++ .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 66 +++++++++++-------- 2 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig index dd166a1f91..81d2b87035 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig @@ -31,3 +31,10 @@ config CMD_STM32PROG_SERIAL activate the command "stm32prog serial" for STM32MP soc family with the tools STM32CubeProgrammer using U-Boot serial device and UART protocol.
+config CMD_STM32PROG_OTP
- bool "support stm32prog for OTP update"
- depends on CMD_STM32PROG
- default y if ARM_SMCCC
- help
Support the OTP update with the command "stm32prog" for STM32MP
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d513a60efb..3e9354b51d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1154,7 +1154,9 @@ static int dfu_init_entities(struct stm32prog_data *data) struct dfu_entity *dfu; int alt_nb;
- alt_nb = 2; /* number of virtual = CMD, OTP*/
- alt_nb = 1; /* number of virtual = CMD*/
- if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP))
if (CONFIG_IS_ENABLED(DM_PMIC)) alt_nb++; /* PMIC NVMEM*/alt_nb++; /* OTP*/
@@ -1205,7 +1207,7 @@ static int dfu_init_entities(struct stm32prog_data *data) if (!ret) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
- if (!ret)
if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE);
if (!ret && CONFIG_IS_ENABLED(DM_PMIC))
@@ -1226,6 +1228,11 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, { log_debug("%s: %x %lx\n", __func__, offset, *size);
- if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
stm32prog_err("OTP update not supported");
return -EOPNOTSUPP;
- } if (!data->otp_part) { data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); if (!data->otp_part)
@@ -1248,10 +1255,10 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, { int result = 0;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) {
- if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { stm32prog_err("OTP update not supported");
return -1;
return -EOPNOTSUPP;
}
log_debug("%s: %x %lx\n", __func__, offset, *size);
@@ -1270,8 +1277,10 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, memset(data->otp_part, 0, OTP_SIZE);
/* call the service */
result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL,
(u32)data->otp_part, 0);
result = -EOPNOTSUPP;
if (IS_ENABLED(CONFIG_ARM_SMCCC))
result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL,
if (result) goto end_otp_read; }(u32)data->otp_part, 0);
@@ -1296,10 +1305,10 @@ int stm32prog_otp_start(struct stm32prog_data *data) int result = 0; struct arm_smccc_res res;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) {
- if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { stm32prog_err("OTP update not supported");
return -1;
return -EOPNOTSUPP;
}
if (!data->otp_part) {
@@ -1307,28 +1316,31 @@ int stm32prog_otp_start(struct stm32prog_data *data) return -1; }
- arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL,
(u32)data->otp_part, 0, 0, 0, 0, 0, &res);
- result = -EOPNOTSUPP;
- if (IS_ENABLED(CONFIG_ARM_SMCCC)) {
arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL,
(u32)data->otp_part, 0, 0, 0, 0, 0, &res);
- if (!res.a0) {
switch (res.a1) {
case 0:
result = 0;
break;
case 1:
stm32prog_err("Provisioning");
result = 0;
break;
default:
log_err("%s: OTP incorrect value (err = %ld)\n",
__func__, res.a1);
if (!res.a0) {
switch (res.a1) {
case 0:
result = 0;
break;
case 1:
stm32prog_err("Provisioning");
result = 0;
break;
default:
log_err("%s: OTP incorrect value (err = %ld)\n",
__func__, res.a1);
result = -EINVAL;
break;
}
} else {
log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n",
__func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); result = -EINVAL;
break;
}
} else {
log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n",
__func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0);
result = -EINVAL;
}
free(data->otp_part);
Applied to u-boot-stm32
Thanks Patrice

When OP-TEE is used, the SMC for BSEC management are not available and the PTA provisioning for OTP must be used.
U-Boot opens the session to this PTA and use it for OTP access.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 2 +- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 145 ++++++++++++++++-- .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 7 +- .../cmd_stm32prog/stm32prog_usb.c | 2 +- 4 files changed, 142 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig index 81d2b87035..8f91db4b46 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig @@ -35,6 +35,6 @@ config CMD_STM32PROG_SERIAL config CMD_STM32PROG_OTP bool "support stm32prog for OTP update" depends on CMD_STM32PROG - default y if ARM_SMCCC + default y if ARM_SMCCC || OPTEE help Support the OTP update with the command "stm32prog" for STM32MP diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 3e9354b51d..5d53e6146f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -10,8 +10,10 @@ #include <misc.h> #include <mmc.h> #include <part.h> +#include <tee.h> #include <asm/arch/stm32mp1_smc.h> #include <asm/global_data.h> +#include <dm/device_compat.h> #include <dm/uclass.h> #include <jffs2/load_kernel.h> #include <linux/list.h> @@ -79,8 +81,110 @@ struct fip_toc_header { u64 flags; };
+#define TA_NVMEM_UUID { 0x1a8342cc, 0x81a5, 0x4512, \ + { 0x99, 0xfe, 0x9e, 0x2b, 0x3e, 0x37, 0xd6, 0x26 } } + +/* + * Read NVMEM memory for STM32CubeProgrammer + * + * [in] value[0].a: Type (0 for OTP access) + * [out] memref[1].buffer Output buffer to return all read values + * [out] memref[1].size Size of buffer to be read + * + * Return codes: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + */ +#define TA_NVMEM_READ 0x0 + +/* + * Write NVMEM memory for STM32CubeProgrammer + * + * [in] value[0].a Type (0 for OTP access) + * [in] memref[1].buffer Input buffer with the values to write + * [in] memref[1].size Size of buffer to be written + * + * Return codes: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + */ +#define TA_NVMEM_WRITE 0x1 + +/* value of TA_NVMEM type = value[in] a */ +#define NVMEM_OTP 0 + DECLARE_GLOBAL_DATA_PTR;
+/* OPTEE TA NVMEM open helper */ +static int optee_ta_open(struct stm32prog_data *data) +{ + const struct tee_optee_ta_uuid uuid = TA_NVMEM_UUID; + struct tee_open_session_arg arg; + struct udevice *tee = NULL; + int rc; + + if (data->tee) + return 0; + + tee = tee_find_device(NULL, NULL, NULL, NULL); + if (!tee) + return -ENODEV; + + memset(&arg, 0, sizeof(arg)); + tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); + rc = tee_open_session(tee, &arg, 0, NULL); + if (rc < 0) + return -ENODEV; + + data->tee = tee; + data->tee_session = arg.session; + + return 0; +} + +/* OPTEE TA NVMEM invoke helper */ +static int optee_ta_invoke(struct stm32prog_data *data, int cmd, int type, + void *buff, ulong size) +{ + struct tee_invoke_arg arg; + struct tee_param param[2]; + struct tee_shm *buff_shm; + int rc; + + rc = tee_shm_register(data->tee, buff, size, 0, &buff_shm); + if (rc) + return rc; + + memset(&arg, 0, sizeof(arg)); + arg.func = cmd; + arg.session = data->tee_session; + + memset(param, 0, sizeof(param)); + param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = type; + + if (cmd == TA_NVMEM_WRITE) + param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; + else + param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + + param[1].u.memref.shm = buff_shm; + param[1].u.memref.size = size; + + rc = tee_invoke_func(data->tee, &arg, 2, param); + if (rc < 0 || arg.ret != 0) { + dev_err(data->tee, + "TA_NVMEM invoke failed TEE err: %x, err:%x\n", + arg.ret, rc); + if (!rc) + rc = -EIO; + } + + tee_shm_free(buff_shm); + + return rc; +} + /* partition handling routines : CONFIG_CMD_MTDPARTS */ int mtdparts_init(void); int find_dev_and_part(const char *id, struct mtd_device **dev, @@ -1208,7 +1312,11 @@ static int dfu_init_entities(struct stm32prog_data *data) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { - ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE); + ret = optee_ta_open(data); + log_debug("optee_ta result %d\n", ret); + ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, + data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC); + }
if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE); @@ -1226,6 +1334,7 @@ static int dfu_init_entities(struct stm32prog_data *data) int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) { + u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; log_debug("%s: %x %lx\n", __func__, offset, *size);
if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { @@ -1233,17 +1342,18 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer,
return -EOPNOTSUPP; } + if (!data->otp_part) { - data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); + data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size); if (!data->otp_part) return -ENOMEM; }
if (!offset) - memset(data->otp_part, 0, OTP_SIZE); + memset(data->otp_part, 0, otp_size);
- if (offset + *size > OTP_SIZE) - *size = OTP_SIZE - offset; + if (offset + *size > otp_size) + *size = otp_size - offset;
memcpy((void *)((u32)data->otp_part + offset), buffer, *size);
@@ -1253,6 +1363,7 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) { + u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; int result = 0;
if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { @@ -1266,7 +1377,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, if (!offset) { if (!data->otp_part) data->otp_part = - memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); + memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size);
if (!data->otp_part) { result = -ENOMEM; @@ -1274,11 +1385,14 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, }
/* init struct with 0 */ - memset(data->otp_part, 0, OTP_SIZE); + memset(data->otp_part, 0, otp_size);
/* call the service */ result = -EOPNOTSUPP; - if (IS_ENABLED(CONFIG_ARM_SMCCC)) + if (data->tee && CONFIG_IS_ENABLED(OPTEE)) + result = optee_ta_invoke(data, TA_NVMEM_READ, NVMEM_OTP, + data->otp_part, OTP_SIZE_TA); + else if (IS_ENABLED(CONFIG_ARM_SMCCC)) result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, (u32)data->otp_part, 0); if (result) @@ -1290,8 +1404,8 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, goto end_otp_read; }
- if (offset + *size > OTP_SIZE) - *size = OTP_SIZE - offset; + if (offset + *size > otp_size) + *size = otp_size - offset; memcpy(buffer, (void *)((u32)data->otp_part + offset), *size);
end_otp_read: @@ -1317,7 +1431,10 @@ int stm32prog_otp_start(struct stm32prog_data *data) }
result = -EOPNOTSUPP; - if (IS_ENABLED(CONFIG_ARM_SMCCC)) { + if (data->tee && CONFIG_IS_ENABLED(OPTEE)) { + result = optee_ta_invoke(data, TA_NVMEM_WRITE, NVMEM_OTP, + data->otp_part, OTP_SIZE_TA); + } else if (IS_ENABLED(CONFIG_ARM_SMCCC)) { arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, (u32)data->otp_part, 0, 0, 0, 0, 0, &res);
@@ -1751,6 +1868,12 @@ void stm32prog_clean(struct stm32prog_data *data) free(data->part_array); free(data->otp_part); free(data->buffer); + + if (CONFIG_IS_ENABLED(OPTEE) && data->tee) { + tee_close_session(data->tee, data->tee_session); + data->tee = NULL; + data->tee_session = 0x0; + } }
/* DFU callback: used after serial and direct DFU USB access */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 240c5c44bc..928b7b3a0e 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -20,7 +20,8 @@ #define DEFAULT_ADDRESS 0xFFFFFFFF
#define CMD_SIZE 512 -#define OTP_SIZE 1024 +#define OTP_SIZE_SMC 1024 +#define OTP_SIZE_TA 776 #define PMIC_SIZE 8
enum stm32prog_target { @@ -147,6 +148,10 @@ struct stm32prog_data { u32 dtb; u32 initrd; u32 initrd_size; + + /* OPTEE PTA NVMEM */ + struct udevice *tee; + u32 tee_session; };
extern struct stm32prog_data *stm32prog_data; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index e8acc302f9..82b702f93b 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -181,7 +181,7 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) *size = CMD_SIZE; break; case PHASE_OTP: - *size = OTP_SIZE; + *size = stm32prog_data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; break; case PHASE_PMIC: *size = PMIC_SIZE;

HI Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
When OP-TEE is used, the SMC for BSEC management are not available and the PTA provisioning for OTP must be used.
U-Boot opens the session to this PTA and use it for OTP access.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 2 +- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 145 ++++++++++++++++-- .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 7 +- .../cmd_stm32prog/stm32prog_usb.c | 2 +- 4 files changed, 142 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig index 81d2b87035..8f91db4b46 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig @@ -35,6 +35,6 @@ config CMD_STM32PROG_SERIAL config CMD_STM32PROG_OTP bool "support stm32prog for OTP update" depends on CMD_STM32PROG
- default y if ARM_SMCCC
- default y if ARM_SMCCC || OPTEE help Support the OTP update with the command "stm32prog" for STM32MP
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 3e9354b51d..5d53e6146f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -10,8 +10,10 @@ #include <misc.h> #include <mmc.h> #include <part.h> +#include <tee.h> #include <asm/arch/stm32mp1_smc.h> #include <asm/global_data.h> +#include <dm/device_compat.h> #include <dm/uclass.h> #include <jffs2/load_kernel.h> #include <linux/list.h> @@ -79,8 +81,110 @@ struct fip_toc_header { u64 flags; };
+#define TA_NVMEM_UUID { 0x1a8342cc, 0x81a5, 0x4512, \
{ 0x99, 0xfe, 0x9e, 0x2b, 0x3e, 0x37, 0xd6, 0x26 } }
+/*
- Read NVMEM memory for STM32CubeProgrammer
- [in] value[0].a: Type (0 for OTP access)
- [out] memref[1].buffer Output buffer to return all read values
- [out] memref[1].size Size of buffer to be read
- Return codes:
- TEE_SUCCESS - Invoke command success
- TEE_ERROR_BAD_PARAMETERS - Incorrect input param
- */
+#define TA_NVMEM_READ 0x0
+/*
- Write NVMEM memory for STM32CubeProgrammer
- [in] value[0].a Type (0 for OTP access)
- [in] memref[1].buffer Input buffer with the values to write
- [in] memref[1].size Size of buffer to be written
- Return codes:
- TEE_SUCCESS - Invoke command success
- TEE_ERROR_BAD_PARAMETERS - Incorrect input param
- */
+#define TA_NVMEM_WRITE 0x1
+/* value of TA_NVMEM type = value[in] a */ +#define NVMEM_OTP 0
DECLARE_GLOBAL_DATA_PTR;
+/* OPTEE TA NVMEM open helper */ +static int optee_ta_open(struct stm32prog_data *data) +{
- const struct tee_optee_ta_uuid uuid = TA_NVMEM_UUID;
- struct tee_open_session_arg arg;
- struct udevice *tee = NULL;
- int rc;
- if (data->tee)
return 0;
- tee = tee_find_device(NULL, NULL, NULL, NULL);
- if (!tee)
return -ENODEV;
- memset(&arg, 0, sizeof(arg));
- tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
- rc = tee_open_session(tee, &arg, 0, NULL);
- if (rc < 0)
return -ENODEV;
- data->tee = tee;
- data->tee_session = arg.session;
- return 0;
+}
+/* OPTEE TA NVMEM invoke helper */ +static int optee_ta_invoke(struct stm32prog_data *data, int cmd, int type,
void *buff, ulong size)
+{
- struct tee_invoke_arg arg;
- struct tee_param param[2];
- struct tee_shm *buff_shm;
- int rc;
- rc = tee_shm_register(data->tee, buff, size, 0, &buff_shm);
- if (rc)
return rc;
- memset(&arg, 0, sizeof(arg));
- arg.func = cmd;
- arg.session = data->tee_session;
- memset(param, 0, sizeof(param));
- param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
- param[0].u.value.a = type;
- if (cmd == TA_NVMEM_WRITE)
param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
- else
param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
- param[1].u.memref.shm = buff_shm;
- param[1].u.memref.size = size;
- rc = tee_invoke_func(data->tee, &arg, 2, param);
- if (rc < 0 || arg.ret != 0) {
dev_err(data->tee,
"TA_NVMEM invoke failed TEE err: %x, err:%x\n",
arg.ret, rc);
if (!rc)
rc = -EIO;
- }
- tee_shm_free(buff_shm);
- return rc;
+}
/* partition handling routines : CONFIG_CMD_MTDPARTS */ int mtdparts_init(void); int find_dev_and_part(const char *id, struct mtd_device **dev, @@ -1208,7 +1312,11 @@ static int dfu_init_entities(struct stm32prog_data *data) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE);
ret = optee_ta_open(data);
log_debug("optee_ta result %d\n", ret);
ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP,
data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC);
}
if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE);
@@ -1226,6 +1334,7 @@ static int dfu_init_entities(struct stm32prog_data *data) int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) {
u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; log_debug("%s: %x %lx\n", __func__, offset, *size);
if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
@@ -1233,17 +1342,18 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer,
return -EOPNOTSUPP;
}
- if (!data->otp_part) {
data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE);
data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size);
if (!data->otp_part) return -ENOMEM; }
if (!offset)
memset(data->otp_part, 0, OTP_SIZE);
memset(data->otp_part, 0, otp_size);
- if (offset + *size > OTP_SIZE)
*size = OTP_SIZE - offset;
if (offset + *size > otp_size)
*size = otp_size - offset;
memcpy((void *)((u32)data->otp_part + offset), buffer, *size);
@@ -1253,6 +1363,7 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) {
u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; int result = 0;
if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
@@ -1266,7 +1377,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, if (!offset) { if (!data->otp_part) data->otp_part =
memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE);
memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size);
if (!data->otp_part) { result = -ENOMEM;
@@ -1274,11 +1385,14 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, }
/* init struct with 0 */
memset(data->otp_part, 0, OTP_SIZE);
memset(data->otp_part, 0, otp_size);
/* call the service */ result = -EOPNOTSUPP;
if (IS_ENABLED(CONFIG_ARM_SMCCC))
if (data->tee && CONFIG_IS_ENABLED(OPTEE))
result = optee_ta_invoke(data, TA_NVMEM_READ, NVMEM_OTP,
data->otp_part, OTP_SIZE_TA);
if (result)else if (IS_ENABLED(CONFIG_ARM_SMCCC)) result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, (u32)data->otp_part, 0);
@@ -1290,8 +1404,8 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, goto end_otp_read; }
- if (offset + *size > OTP_SIZE)
*size = OTP_SIZE - offset;
- if (offset + *size > otp_size)
memcpy(buffer, (void *)((u32)data->otp_part + offset), *size);*size = otp_size - offset;
end_otp_read: @@ -1317,7 +1431,10 @@ int stm32prog_otp_start(struct stm32prog_data *data) }
result = -EOPNOTSUPP;
- if (IS_ENABLED(CONFIG_ARM_SMCCC)) {
- if (data->tee && CONFIG_IS_ENABLED(OPTEE)) {
result = optee_ta_invoke(data, TA_NVMEM_WRITE, NVMEM_OTP,
data->otp_part, OTP_SIZE_TA);
- } else if (IS_ENABLED(CONFIG_ARM_SMCCC)) { arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, (u32)data->otp_part, 0, 0, 0, 0, 0, &res);
@@ -1751,6 +1868,12 @@ void stm32prog_clean(struct stm32prog_data *data) free(data->part_array); free(data->otp_part); free(data->buffer);
- if (CONFIG_IS_ENABLED(OPTEE) && data->tee) {
tee_close_session(data->tee, data->tee_session);
data->tee = NULL;
data->tee_session = 0x0;
- }
}
/* DFU callback: used after serial and direct DFU USB access */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 240c5c44bc..928b7b3a0e 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -20,7 +20,8 @@ #define DEFAULT_ADDRESS 0xFFFFFFFF
#define CMD_SIZE 512 -#define OTP_SIZE 1024 +#define OTP_SIZE_SMC 1024 +#define OTP_SIZE_TA 776 #define PMIC_SIZE 8
enum stm32prog_target { @@ -147,6 +148,10 @@ struct stm32prog_data { u32 dtb; u32 initrd; u32 initrd_size;
- /* OPTEE PTA NVMEM */
- struct udevice *tee;
- u32 tee_session;
};
extern struct stm32prog_data *stm32prog_data; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index e8acc302f9..82b702f93b 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -181,7 +181,7 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) *size = CMD_SIZE; break; case PHASE_OTP:
*size = OTP_SIZE;
break; case PHASE_PMIC: *size = PMIC_SIZE;*size = stm32prog_data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC;
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
When OP-TEE is used, the SMC for BSEC management are not available and the PTA provisioning for OTP must be used.
U-Boot opens the session to this PTA and use it for OTP access.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 2 +- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 145 ++++++++++++++++-- .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 7 +- .../cmd_stm32prog/stm32prog_usb.c | 2 +- 4 files changed, 142 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig index 81d2b87035..8f91db4b46 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig @@ -35,6 +35,6 @@ config CMD_STM32PROG_SERIAL config CMD_STM32PROG_OTP bool "support stm32prog for OTP update" depends on CMD_STM32PROG
- default y if ARM_SMCCC
- default y if ARM_SMCCC || OPTEE help Support the OTP update with the command "stm32prog" for STM32MP
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 3e9354b51d..5d53e6146f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -10,8 +10,10 @@ #include <misc.h> #include <mmc.h> #include <part.h> +#include <tee.h> #include <asm/arch/stm32mp1_smc.h> #include <asm/global_data.h> +#include <dm/device_compat.h> #include <dm/uclass.h> #include <jffs2/load_kernel.h> #include <linux/list.h> @@ -79,8 +81,110 @@ struct fip_toc_header { u64 flags; };
+#define TA_NVMEM_UUID { 0x1a8342cc, 0x81a5, 0x4512, \
{ 0x99, 0xfe, 0x9e, 0x2b, 0x3e, 0x37, 0xd6, 0x26 } }
+/*
- Read NVMEM memory for STM32CubeProgrammer
- [in] value[0].a: Type (0 for OTP access)
- [out] memref[1].buffer Output buffer to return all read values
- [out] memref[1].size Size of buffer to be read
- Return codes:
- TEE_SUCCESS - Invoke command success
- TEE_ERROR_BAD_PARAMETERS - Incorrect input param
- */
+#define TA_NVMEM_READ 0x0
+/*
- Write NVMEM memory for STM32CubeProgrammer
- [in] value[0].a Type (0 for OTP access)
- [in] memref[1].buffer Input buffer with the values to write
- [in] memref[1].size Size of buffer to be written
- Return codes:
- TEE_SUCCESS - Invoke command success
- TEE_ERROR_BAD_PARAMETERS - Incorrect input param
- */
+#define TA_NVMEM_WRITE 0x1
+/* value of TA_NVMEM type = value[in] a */ +#define NVMEM_OTP 0
DECLARE_GLOBAL_DATA_PTR;
+/* OPTEE TA NVMEM open helper */ +static int optee_ta_open(struct stm32prog_data *data) +{
- const struct tee_optee_ta_uuid uuid = TA_NVMEM_UUID;
- struct tee_open_session_arg arg;
- struct udevice *tee = NULL;
- int rc;
- if (data->tee)
return 0;
- tee = tee_find_device(NULL, NULL, NULL, NULL);
- if (!tee)
return -ENODEV;
- memset(&arg, 0, sizeof(arg));
- tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
- rc = tee_open_session(tee, &arg, 0, NULL);
- if (rc < 0)
return -ENODEV;
- data->tee = tee;
- data->tee_session = arg.session;
- return 0;
+}
+/* OPTEE TA NVMEM invoke helper */ +static int optee_ta_invoke(struct stm32prog_data *data, int cmd, int type,
void *buff, ulong size)
+{
- struct tee_invoke_arg arg;
- struct tee_param param[2];
- struct tee_shm *buff_shm;
- int rc;
- rc = tee_shm_register(data->tee, buff, size, 0, &buff_shm);
- if (rc)
return rc;
- memset(&arg, 0, sizeof(arg));
- arg.func = cmd;
- arg.session = data->tee_session;
- memset(param, 0, sizeof(param));
- param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
- param[0].u.value.a = type;
- if (cmd == TA_NVMEM_WRITE)
param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
- else
param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
- param[1].u.memref.shm = buff_shm;
- param[1].u.memref.size = size;
- rc = tee_invoke_func(data->tee, &arg, 2, param);
- if (rc < 0 || arg.ret != 0) {
dev_err(data->tee,
"TA_NVMEM invoke failed TEE err: %x, err:%x\n",
arg.ret, rc);
if (!rc)
rc = -EIO;
- }
- tee_shm_free(buff_shm);
- return rc;
+}
/* partition handling routines : CONFIG_CMD_MTDPARTS */ int mtdparts_init(void); int find_dev_and_part(const char *id, struct mtd_device **dev, @@ -1208,7 +1312,11 @@ static int dfu_init_entities(struct stm32prog_data *data) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE);
ret = optee_ta_open(data);
log_debug("optee_ta result %d\n", ret);
ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP,
data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC);
}
if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE);
@@ -1226,6 +1334,7 @@ static int dfu_init_entities(struct stm32prog_data *data) int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) {
u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; log_debug("%s: %x %lx\n", __func__, offset, *size);
if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
@@ -1233,17 +1342,18 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer,
return -EOPNOTSUPP;
}
- if (!data->otp_part) {
data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE);
data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size);
if (!data->otp_part) return -ENOMEM; }
if (!offset)
memset(data->otp_part, 0, OTP_SIZE);
memset(data->otp_part, 0, otp_size);
- if (offset + *size > OTP_SIZE)
*size = OTP_SIZE - offset;
if (offset + *size > otp_size)
*size = otp_size - offset;
memcpy((void *)((u32)data->otp_part + offset), buffer, *size);
@@ -1253,6 +1363,7 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) {
u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; int result = 0;
if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
@@ -1266,7 +1377,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, if (!offset) { if (!data->otp_part) data->otp_part =
memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE);
memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size);
if (!data->otp_part) { result = -ENOMEM;
@@ -1274,11 +1385,14 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, }
/* init struct with 0 */
memset(data->otp_part, 0, OTP_SIZE);
memset(data->otp_part, 0, otp_size);
/* call the service */ result = -EOPNOTSUPP;
if (IS_ENABLED(CONFIG_ARM_SMCCC))
if (data->tee && CONFIG_IS_ENABLED(OPTEE))
result = optee_ta_invoke(data, TA_NVMEM_READ, NVMEM_OTP,
data->otp_part, OTP_SIZE_TA);
if (result)else if (IS_ENABLED(CONFIG_ARM_SMCCC)) result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, (u32)data->otp_part, 0);
@@ -1290,8 +1404,8 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, goto end_otp_read; }
- if (offset + *size > OTP_SIZE)
*size = OTP_SIZE - offset;
- if (offset + *size > otp_size)
memcpy(buffer, (void *)((u32)data->otp_part + offset), *size);*size = otp_size - offset;
end_otp_read: @@ -1317,7 +1431,10 @@ int stm32prog_otp_start(struct stm32prog_data *data) }
result = -EOPNOTSUPP;
- if (IS_ENABLED(CONFIG_ARM_SMCCC)) {
- if (data->tee && CONFIG_IS_ENABLED(OPTEE)) {
result = optee_ta_invoke(data, TA_NVMEM_WRITE, NVMEM_OTP,
data->otp_part, OTP_SIZE_TA);
- } else if (IS_ENABLED(CONFIG_ARM_SMCCC)) { arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, (u32)data->otp_part, 0, 0, 0, 0, 0, &res);
@@ -1751,6 +1868,12 @@ void stm32prog_clean(struct stm32prog_data *data) free(data->part_array); free(data->otp_part); free(data->buffer);
- if (CONFIG_IS_ENABLED(OPTEE) && data->tee) {
tee_close_session(data->tee, data->tee_session);
data->tee = NULL;
data->tee_session = 0x0;
- }
}
/* DFU callback: used after serial and direct DFU USB access */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 240c5c44bc..928b7b3a0e 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -20,7 +20,8 @@ #define DEFAULT_ADDRESS 0xFFFFFFFF
#define CMD_SIZE 512 -#define OTP_SIZE 1024 +#define OTP_SIZE_SMC 1024 +#define OTP_SIZE_TA 776 #define PMIC_SIZE 8
enum stm32prog_target { @@ -147,6 +148,10 @@ struct stm32prog_data { u32 dtb; u32 initrd; u32 initrd_size;
- /* OPTEE PTA NVMEM */
- struct udevice *tee;
- u32 tee_session;
};
extern struct stm32prog_data *stm32prog_data; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index e8acc302f9..82b702f93b 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -181,7 +181,7 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) *size = CMD_SIZE; break; case PHASE_OTP:
*size = OTP_SIZE;
break; case PHASE_PMIC: *size = PMIC_SIZE;*size = stm32prog_data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC;
Applied to u-boot-stm32
Thanks Patrice

Add support of new header for the STM32IMAGE version V2 in command stm32prog command for STM32MP13x family.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
.../cmd_stm32prog/cmd_stm32prog.c | 8 +- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 119 ++++++++++++------ .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 35 ++++-- 3 files changed, 114 insertions(+), 48 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 41452b5a29..3957e06e5d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -73,15 +73,15 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
/* check STM32IMAGE presence */ if (size == 0) { - stm32prog_header_check((struct raw_header_s *)addr, &header); + stm32prog_header_check(addr, &header); if (header.type == HEADER_STM32IMAGE) { - size = header.image_length + BL_HEADER_SIZE; + size = header.image_length + header.length;
#if defined(CONFIG_LEGACY_IMAGE_FORMAT) /* uImage detected in STM32IMAGE, execute the script */ if (IMAGE_FORMAT_LEGACY == - genimg_get_format((void *)(addr + BL_HEADER_SIZE))) - return image_source_script(addr + BL_HEADER_SIZE, "script@1"); + genimg_get_format((void *)(addr + header.length))) + return image_source_script(addr + header.length, "script@1"); #endif } } diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 5d53e6146f..3e1fdee5b3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -205,52 +205,98 @@ static bool stm32prog_is_fip_header(struct fip_toc_header *header) return (header->name == FIP_TOC_HEADER_NAME) && header->serial_number; }
-void stm32prog_header_check(struct raw_header_s *raw_header, - struct image_header_s *header) +static bool stm32prog_is_stm32_header_v1(struct stm32_header_v1 *header) { unsigned int i;
- if (!raw_header || !header) { - log_debug("%s:no header data\n", __func__); - return; + if (header->magic_number != + (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { + log_debug("%s:invalid magic number : 0x%x\n", + __func__, header->magic_number); + return false; + } + if (header->header_version != 0x00010000) { + log_debug("%s:invalid header version : 0x%x\n", + __func__, header->header_version); + return false; }
- header->type = HEADER_NONE; - header->image_checksum = 0x0; - header->image_length = 0x0; - - if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) { - header->type = HEADER_FIP; - return; + if (header->reserved1 || header->reserved2) { + log_debug("%s:invalid reserved field\n", __func__); + return false; + } + for (i = 0; i < sizeof(header->padding); i++) { + if (header->padding[i] != 0) { + log_debug("%s:invalid padding field\n", __func__); + return false; + } }
- if (raw_header->magic_number != + return true; +} + +static bool stm32prog_is_stm32_header_v2(struct stm32_header_v2 *header) +{ + unsigned int i; + + if (header->magic_number != (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { log_debug("%s:invalid magic number : 0x%x\n", - __func__, raw_header->magic_number); - return; + __func__, header->magic_number); + return false; } - /* only header v1.0 supported */ - if (raw_header->header_version != 0x00010000) { + if (header->header_version != 0x00020000) { log_debug("%s:invalid header version : 0x%x\n", - __func__, raw_header->header_version); + __func__, header->header_version); + return false; + } + if (header->reserved1 || header->reserved2) + return false; + + for (i = 0; i < sizeof(header->padding); i++) { + if (header->padding[i] != 0) { + log_debug("%s:invalid padding field\n", __func__); + return false; + } + } + + return true; +} + +void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header) +{ + struct stm32_header_v1 *v1_header = (struct stm32_header_v1 *)raw_header; + struct stm32_header_v2 *v2_header = (struct stm32_header_v2 *)raw_header; + + if (!raw_header || !header) { + log_debug("%s:no header data\n", __func__); return; } - if (raw_header->reserved1 != 0x0 || raw_header->reserved2) { - log_debug("%s:invalid reserved field\n", __func__); + + if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) { + header->type = HEADER_FIP; + header->length = 0; return; } - for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) { - if (raw_header->padding[i] != 0) { - log_debug("%s:invalid padding field\n", __func__); - return; - } + if (stm32prog_is_stm32_header_v1(v1_header)) { + header->type = HEADER_STM32IMAGE; + header->image_checksum = le32_to_cpu(v1_header->image_checksum); + header->image_length = le32_to_cpu(v1_header->image_length); + header->length = sizeof(struct stm32_header_v1); + return; + } + if (stm32prog_is_stm32_header_v2(v2_header)) { + header->type = HEADER_STM32IMAGE_V2; + header->image_checksum = le32_to_cpu(v2_header->image_checksum); + header->image_length = le32_to_cpu(v2_header->image_length); + header->length = sizeof(struct stm32_header_v1) + + v2_header->extension_headers_length; + return; } - header->type = HEADER_STM32IMAGE; - header->image_checksum = le32_to_cpu(raw_header->image_checksum); - header->image_length = le32_to_cpu(raw_header->image_length);
- return; + header->type = HEADER_NONE; + header->image_checksum = 0x0; + header->image_length = 0x0; }
static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) @@ -480,11 +526,11 @@ static int parse_flash_layout(struct stm32prog_data *data, data->part_nb = 0;
/* check if STM32image is detected */ - stm32prog_header_check((struct raw_header_s *)addr, &header); + stm32prog_header_check(addr, &header); if (header.type == HEADER_STM32IMAGE) { u32 checksum;
- addr = addr + BL_HEADER_SIZE; + addr = addr + header.length; size = header.image_length;
checksum = stm32prog_header_checksum(addr, &header); @@ -1560,7 +1606,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) int ret, i; void *fsbl; struct image_header_s header; - struct raw_header_s raw_header; + struct stm32_header_v2 raw_header; /* V2 size > v1 size */ struct dfu_entity *dfu; long size, offset;
@@ -1572,17 +1618,18 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part)
/* read header */ dfu_transaction_cleanup(dfu); - size = BL_HEADER_SIZE; + size = sizeof(raw_header); ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size); if (ret) return ret;
- stm32prog_header_check(&raw_header, &header); - if (header.type != HEADER_STM32IMAGE) + stm32prog_header_check((ulong)&raw_header, &header); + if (header.type != HEADER_STM32IMAGE && + header.type != HEADER_STM32IMAGE_V2) return -ENOENT;
/* read header + payload */ - size = header.image_length + BL_HEADER_SIZE; + size = header.image_length + header.length; size = round_up(size, part->dev->mtd->erasesize); fsbl = calloc(1, size); if (!fsbl) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 928b7b3a0e..90cdc2ba47 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -42,6 +42,7 @@ enum stm32prog_link_t { enum stm32prog_header_t { HEADER_NONE, HEADER_STM32IMAGE, + HEADER_STM32IMAGE_V2, HEADER_FIP, };
@@ -49,11 +50,12 @@ struct image_header_s { enum stm32prog_header_t type; u32 image_checksum; u32 image_length; + u32 length; };
-struct raw_header_s { +struct stm32_header_v1 { u32 magic_number; - u32 image_signature[64 / 4]; + u8 image_signature[64]; u32 image_checksum; u32 header_version; u32 image_length; @@ -64,12 +66,30 @@ struct raw_header_s { u32 version_number; u32 option_flags; u32 ecdsa_algorithm; - u32 ecdsa_public_key[64 / 4]; - u32 padding[83 / 4]; - u32 binary_type; + u8 ecdsa_public_key[64]; + u8 padding[83]; + u8 binary_type; };
-#define BL_HEADER_SIZE sizeof(struct raw_header_s) +struct stm32_header_v2 { + u32 magic_number; + u8 image_signature[64]; + u32 image_checksum; + u32 header_version; + u32 image_length; + u32 image_entry_point; + u32 reserved1; + u32 load_address; + u32 reserved2; + u32 version_number; + u32 extension_flags; + u32 extension_headers_length; + u32 binary_type; + u8 padding[16]; + u32 extension_header_type; + u32 extension_header_length; + u8 extension_padding[376]; +};
/* partition type in flashlayout file */ enum stm32prog_part_type { @@ -171,8 +191,7 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, int stm32prog_pmic_start(struct stm32prog_data *data);
/* generic part*/ -void stm32prog_header_check(struct raw_header_s *raw_header, - struct image_header_s *header); +void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header); int stm32prog_dfu_init(struct stm32prog_data *data); void stm32prog_next_phase(struct stm32prog_data *data); void stm32prog_do_reset(struct stm32prog_data *data);

HI Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
Add support of new header for the STM32IMAGE version V2 in command stm32prog command for STM32MP13x family.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
.../cmd_stm32prog/cmd_stm32prog.c | 8 +- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 119 ++++++++++++------ .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 35 ++++-- 3 files changed, 114 insertions(+), 48 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 41452b5a29..3957e06e5d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -73,15 +73,15 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
/* check STM32IMAGE presence */ if (size == 0) {
stm32prog_header_check((struct raw_header_s *)addr, &header);
if (header.type == HEADER_STM32IMAGE) {stm32prog_header_check(addr, &header);
size = header.image_length + BL_HEADER_SIZE;
size = header.image_length + header.length;
#if defined(CONFIG_LEGACY_IMAGE_FORMAT) /* uImage detected in STM32IMAGE, execute the script */ if (IMAGE_FORMAT_LEGACY ==
genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
return image_source_script(addr + BL_HEADER_SIZE, "script@1");
genimg_get_format((void *)(addr + header.length)))
return image_source_script(addr + header.length, "script@1");
#endif } } diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 5d53e6146f..3e1fdee5b3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -205,52 +205,98 @@ static bool stm32prog_is_fip_header(struct fip_toc_header *header) return (header->name == FIP_TOC_HEADER_NAME) && header->serial_number; }
-void stm32prog_header_check(struct raw_header_s *raw_header,
struct image_header_s *header)
+static bool stm32prog_is_stm32_header_v1(struct stm32_header_v1 *header) { unsigned int i;
- if (!raw_header || !header) {
log_debug("%s:no header data\n", __func__);
return;
- if (header->magic_number !=
(('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) {
log_debug("%s:invalid magic number : 0x%x\n",
__func__, header->magic_number);
return false;
- }
- if (header->header_version != 0x00010000) {
log_debug("%s:invalid header version : 0x%x\n",
__func__, header->header_version);
}return false;
- header->type = HEADER_NONE;
- header->image_checksum = 0x0;
- header->image_length = 0x0;
- if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
header->type = HEADER_FIP;
return;
- if (header->reserved1 || header->reserved2) {
log_debug("%s:invalid reserved field\n", __func__);
return false;
- }
- for (i = 0; i < sizeof(header->padding); i++) {
if (header->padding[i] != 0) {
log_debug("%s:invalid padding field\n", __func__);
return false;
}}
- if (raw_header->magic_number !=
- return true;
+}
+static bool stm32prog_is_stm32_header_v2(struct stm32_header_v2 *header) +{
- unsigned int i;
- if (header->magic_number != (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { log_debug("%s:invalid magic number : 0x%x\n",
__func__, raw_header->magic_number);
return;
__func__, header->magic_number);
}return false;
- /* only header v1.0 supported */
- if (raw_header->header_version != 0x00010000) {
- if (header->header_version != 0x00020000) { log_debug("%s:invalid header version : 0x%x\n",
__func__, raw_header->header_version);
__func__, header->header_version);
return false;
- }
- if (header->reserved1 || header->reserved2)
return false;
- for (i = 0; i < sizeof(header->padding); i++) {
if (header->padding[i] != 0) {
log_debug("%s:invalid padding field\n", __func__);
return false;
}
- }
- return true;
+}
+void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header) +{
- struct stm32_header_v1 *v1_header = (struct stm32_header_v1 *)raw_header;
- struct stm32_header_v2 *v2_header = (struct stm32_header_v2 *)raw_header;
- if (!raw_header || !header) {
return; }log_debug("%s:no header data\n", __func__);
- if (raw_header->reserved1 != 0x0 || raw_header->reserved2) {
log_debug("%s:invalid reserved field\n", __func__);
- if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
header->type = HEADER_FIP;
return; }header->length = 0;
- for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) {
if (raw_header->padding[i] != 0) {
log_debug("%s:invalid padding field\n", __func__);
return;
}
- if (stm32prog_is_stm32_header_v1(v1_header)) {
header->type = HEADER_STM32IMAGE;
header->image_checksum = le32_to_cpu(v1_header->image_checksum);
header->image_length = le32_to_cpu(v1_header->image_length);
header->length = sizeof(struct stm32_header_v1);
return;
- }
- if (stm32prog_is_stm32_header_v2(v2_header)) {
header->type = HEADER_STM32IMAGE_V2;
header->image_checksum = le32_to_cpu(v2_header->image_checksum);
header->image_length = le32_to_cpu(v2_header->image_length);
header->length = sizeof(struct stm32_header_v1) +
v2_header->extension_headers_length;
}return;
header->type = HEADER_STM32IMAGE;
header->image_checksum = le32_to_cpu(raw_header->image_checksum);
header->image_length = le32_to_cpu(raw_header->image_length);
return;
- header->type = HEADER_NONE;
- header->image_checksum = 0x0;
- header->image_length = 0x0;
}
static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) @@ -480,11 +526,11 @@ static int parse_flash_layout(struct stm32prog_data *data, data->part_nb = 0;
/* check if STM32image is detected */
- stm32prog_header_check((struct raw_header_s *)addr, &header);
- stm32prog_header_check(addr, &header); if (header.type == HEADER_STM32IMAGE) { u32 checksum;
addr = addr + BL_HEADER_SIZE;
addr = addr + header.length;
size = header.image_length;
checksum = stm32prog_header_checksum(addr, &header);
@@ -1560,7 +1606,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) int ret, i; void *fsbl; struct image_header_s header;
- struct raw_header_s raw_header;
- struct stm32_header_v2 raw_header; /* V2 size > v1 size */ struct dfu_entity *dfu; long size, offset;
@@ -1572,17 +1618,18 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part)
/* read header */ dfu_transaction_cleanup(dfu);
- size = BL_HEADER_SIZE;
- size = sizeof(raw_header); ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size); if (ret) return ret;
- stm32prog_header_check(&raw_header, &header);
- if (header.type != HEADER_STM32IMAGE)
stm32prog_header_check((ulong)&raw_header, &header);
if (header.type != HEADER_STM32IMAGE &&
header.type != HEADER_STM32IMAGE_V2)
return -ENOENT;
/* read header + payload */
- size = header.image_length + BL_HEADER_SIZE;
- size = header.image_length + header.length; size = round_up(size, part->dev->mtd->erasesize); fsbl = calloc(1, size); if (!fsbl)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 928b7b3a0e..90cdc2ba47 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -42,6 +42,7 @@ enum stm32prog_link_t { enum stm32prog_header_t { HEADER_NONE, HEADER_STM32IMAGE,
- HEADER_STM32IMAGE_V2, HEADER_FIP,
};
@@ -49,11 +50,12 @@ struct image_header_s { enum stm32prog_header_t type; u32 image_checksum; u32 image_length;
- u32 length;
};
-struct raw_header_s { +struct stm32_header_v1 { u32 magic_number;
- u32 image_signature[64 / 4];
- u8 image_signature[64]; u32 image_checksum; u32 header_version; u32 image_length;
@@ -64,12 +66,30 @@ struct raw_header_s { u32 version_number; u32 option_flags; u32 ecdsa_algorithm;
- u32 ecdsa_public_key[64 / 4];
- u32 padding[83 / 4];
- u32 binary_type;
- u8 ecdsa_public_key[64];
- u8 padding[83];
- u8 binary_type;
};
-#define BL_HEADER_SIZE sizeof(struct raw_header_s) +struct stm32_header_v2 {
- u32 magic_number;
- u8 image_signature[64];
- u32 image_checksum;
- u32 header_version;
- u32 image_length;
- u32 image_entry_point;
- u32 reserved1;
- u32 load_address;
- u32 reserved2;
- u32 version_number;
- u32 extension_flags;
- u32 extension_headers_length;
- u32 binary_type;
- u8 padding[16];
- u32 extension_header_type;
- u32 extension_header_length;
- u8 extension_padding[376];
+};
/* partition type in flashlayout file */ enum stm32prog_part_type { @@ -171,8 +191,7 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, int stm32prog_pmic_start(struct stm32prog_data *data);
/* generic part*/ -void stm32prog_header_check(struct raw_header_s *raw_header,
struct image_header_s *header);
+void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header); int stm32prog_dfu_init(struct stm32prog_data *data); void stm32prog_next_phase(struct stm32prog_data *data); void stm32prog_do_reset(struct stm32prog_data *data);
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
Add support of new header for the STM32IMAGE version V2 in command stm32prog command for STM32MP13x family.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
.../cmd_stm32prog/cmd_stm32prog.c | 8 +- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 119 ++++++++++++------ .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 35 ++++-- 3 files changed, 114 insertions(+), 48 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 41452b5a29..3957e06e5d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -73,15 +73,15 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
/* check STM32IMAGE presence */ if (size == 0) {
stm32prog_header_check((struct raw_header_s *)addr, &header);
if (header.type == HEADER_STM32IMAGE) {stm32prog_header_check(addr, &header);
size = header.image_length + BL_HEADER_SIZE;
size = header.image_length + header.length;
#if defined(CONFIG_LEGACY_IMAGE_FORMAT) /* uImage detected in STM32IMAGE, execute the script */ if (IMAGE_FORMAT_LEGACY ==
genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
return image_source_script(addr + BL_HEADER_SIZE, "script@1");
genimg_get_format((void *)(addr + header.length)))
return image_source_script(addr + header.length, "script@1");
#endif } } diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 5d53e6146f..3e1fdee5b3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -205,52 +205,98 @@ static bool stm32prog_is_fip_header(struct fip_toc_header *header) return (header->name == FIP_TOC_HEADER_NAME) && header->serial_number; }
-void stm32prog_header_check(struct raw_header_s *raw_header,
struct image_header_s *header)
+static bool stm32prog_is_stm32_header_v1(struct stm32_header_v1 *header) { unsigned int i;
- if (!raw_header || !header) {
log_debug("%s:no header data\n", __func__);
return;
- if (header->magic_number !=
(('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) {
log_debug("%s:invalid magic number : 0x%x\n",
__func__, header->magic_number);
return false;
- }
- if (header->header_version != 0x00010000) {
log_debug("%s:invalid header version : 0x%x\n",
__func__, header->header_version);
}return false;
- header->type = HEADER_NONE;
- header->image_checksum = 0x0;
- header->image_length = 0x0;
- if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
header->type = HEADER_FIP;
return;
- if (header->reserved1 || header->reserved2) {
log_debug("%s:invalid reserved field\n", __func__);
return false;
- }
- for (i = 0; i < sizeof(header->padding); i++) {
if (header->padding[i] != 0) {
log_debug("%s:invalid padding field\n", __func__);
return false;
}}
- if (raw_header->magic_number !=
- return true;
+}
+static bool stm32prog_is_stm32_header_v2(struct stm32_header_v2 *header) +{
- unsigned int i;
- if (header->magic_number != (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { log_debug("%s:invalid magic number : 0x%x\n",
__func__, raw_header->magic_number);
return;
__func__, header->magic_number);
}return false;
- /* only header v1.0 supported */
- if (raw_header->header_version != 0x00010000) {
- if (header->header_version != 0x00020000) { log_debug("%s:invalid header version : 0x%x\n",
__func__, raw_header->header_version);
__func__, header->header_version);
return false;
- }
- if (header->reserved1 || header->reserved2)
return false;
- for (i = 0; i < sizeof(header->padding); i++) {
if (header->padding[i] != 0) {
log_debug("%s:invalid padding field\n", __func__);
return false;
}
- }
- return true;
+}
+void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header) +{
- struct stm32_header_v1 *v1_header = (struct stm32_header_v1 *)raw_header;
- struct stm32_header_v2 *v2_header = (struct stm32_header_v2 *)raw_header;
- if (!raw_header || !header) {
return; }log_debug("%s:no header data\n", __func__);
- if (raw_header->reserved1 != 0x0 || raw_header->reserved2) {
log_debug("%s:invalid reserved field\n", __func__);
- if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
header->type = HEADER_FIP;
return; }header->length = 0;
- for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) {
if (raw_header->padding[i] != 0) {
log_debug("%s:invalid padding field\n", __func__);
return;
}
- if (stm32prog_is_stm32_header_v1(v1_header)) {
header->type = HEADER_STM32IMAGE;
header->image_checksum = le32_to_cpu(v1_header->image_checksum);
header->image_length = le32_to_cpu(v1_header->image_length);
header->length = sizeof(struct stm32_header_v1);
return;
- }
- if (stm32prog_is_stm32_header_v2(v2_header)) {
header->type = HEADER_STM32IMAGE_V2;
header->image_checksum = le32_to_cpu(v2_header->image_checksum);
header->image_length = le32_to_cpu(v2_header->image_length);
header->length = sizeof(struct stm32_header_v1) +
v2_header->extension_headers_length;
}return;
header->type = HEADER_STM32IMAGE;
header->image_checksum = le32_to_cpu(raw_header->image_checksum);
header->image_length = le32_to_cpu(raw_header->image_length);
return;
- header->type = HEADER_NONE;
- header->image_checksum = 0x0;
- header->image_length = 0x0;
}
static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) @@ -480,11 +526,11 @@ static int parse_flash_layout(struct stm32prog_data *data, data->part_nb = 0;
/* check if STM32image is detected */
- stm32prog_header_check((struct raw_header_s *)addr, &header);
- stm32prog_header_check(addr, &header); if (header.type == HEADER_STM32IMAGE) { u32 checksum;
addr = addr + BL_HEADER_SIZE;
addr = addr + header.length;
size = header.image_length;
checksum = stm32prog_header_checksum(addr, &header);
@@ -1560,7 +1606,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) int ret, i; void *fsbl; struct image_header_s header;
- struct raw_header_s raw_header;
- struct stm32_header_v2 raw_header; /* V2 size > v1 size */ struct dfu_entity *dfu; long size, offset;
@@ -1572,17 +1618,18 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part)
/* read header */ dfu_transaction_cleanup(dfu);
- size = BL_HEADER_SIZE;
- size = sizeof(raw_header); ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size); if (ret) return ret;
- stm32prog_header_check(&raw_header, &header);
- if (header.type != HEADER_STM32IMAGE)
stm32prog_header_check((ulong)&raw_header, &header);
if (header.type != HEADER_STM32IMAGE &&
header.type != HEADER_STM32IMAGE_V2)
return -ENOENT;
/* read header + payload */
- size = header.image_length + BL_HEADER_SIZE;
- size = header.image_length + header.length; size = round_up(size, part->dev->mtd->erasesize); fsbl = calloc(1, size); if (!fsbl)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 928b7b3a0e..90cdc2ba47 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -42,6 +42,7 @@ enum stm32prog_link_t { enum stm32prog_header_t { HEADER_NONE, HEADER_STM32IMAGE,
- HEADER_STM32IMAGE_V2, HEADER_FIP,
};
@@ -49,11 +50,12 @@ struct image_header_s { enum stm32prog_header_t type; u32 image_checksum; u32 image_length;
- u32 length;
};
-struct raw_header_s { +struct stm32_header_v1 { u32 magic_number;
- u32 image_signature[64 / 4];
- u8 image_signature[64]; u32 image_checksum; u32 header_version; u32 image_length;
@@ -64,12 +66,30 @@ struct raw_header_s { u32 version_number; u32 option_flags; u32 ecdsa_algorithm;
- u32 ecdsa_public_key[64 / 4];
- u32 padding[83 / 4];
- u32 binary_type;
- u8 ecdsa_public_key[64];
- u8 padding[83];
- u8 binary_type;
};
-#define BL_HEADER_SIZE sizeof(struct raw_header_s) +struct stm32_header_v2 {
- u32 magic_number;
- u8 image_signature[64];
- u32 image_checksum;
- u32 header_version;
- u32 image_length;
- u32 image_entry_point;
- u32 reserved1;
- u32 load_address;
- u32 reserved2;
- u32 version_number;
- u32 extension_flags;
- u32 extension_headers_length;
- u32 binary_type;
- u8 padding[16];
- u32 extension_header_type;
- u32 extension_header_length;
- u8 extension_padding[376];
+};
/* partition type in flashlayout file */ enum stm32prog_part_type { @@ -171,8 +191,7 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, int stm32prog_pmic_start(struct stm32prog_data *data);
/* generic part*/ -void stm32prog_header_check(struct raw_header_s *raw_header,
struct image_header_s *header);
+void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header); int stm32prog_dfu_init(struct stm32prog_data *data); void stm32prog_next_phase(struct stm32prog_data *data); void stm32prog_do_reset(struct stm32prog_data *data);
Applied to u-boot-stm32
Thanks Patrice

Add support of UUID for FIP parttion, required by Firmware update support in TF-A: - UUID TYPE for FIP partition: 19d5df83-11b0-457b-be2c-7559c13142a5 - "fip-a" partition UUID: 4fd84c93-54ef-463f-a7ef-ae25ff887087 - "fip-b" partition UUID: 09c54952-d5bf-45af-acee-335303766fb3
This check is done with a new partition type "FIP" associated at the FIP UUID.
The A/B partition UUID is detected by the partition name: "fip-a", "fip-b".
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
.../mach-stm32mp/cmd_stm32prog/stm32prog.c | 76 ++++++++++++++----- .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 3 +- 2 files changed, 59 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 3e1fdee5b3..d3b3e1ed72 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -62,6 +62,28 @@ static const efi_guid_t uuid_mmc[3] = { ROOTFS_MMC2_UUID };
+/* FIP type partition UUID used by TF-A*/ +#define FIP_TYPE_UUID "19D5DF83-11B0-457B-BE2C-7559C13142A5" + +/* unique partition guid (uuid) for FIP partitions A/B */ +#define FIP_A_UUID \ + EFI_GUID(0x4FD84C93, 0x54EF, 0x463F, \ + 0xA7, 0xEF, 0xAE, 0x25, 0xFF, 0x88, 0x70, 0x87) + +#define FIP_B_UUID \ + EFI_GUID(0x09C54952, 0xD5BF, 0x45AF, \ + 0xAC, 0xEE, 0x33, 0x53, 0x03, 0x76, 0x6F, 0xB3) + +static const char * const fip_part_name[] = { + "fip-a", + "fip-b" +}; + +static const efi_guid_t fip_part_uuid[] = { + FIP_A_UUID, + FIP_B_UUID +}; + /* order of column in flash layout file */ enum stm32prog_col_t { COL_OPTION, @@ -405,6 +427,8 @@ static int parse_type(struct stm32prog_data *data, part->bin_nb = dectoul(&p[7], NULL); } + } else if (!strcmp(p, "FIP")) { + part->part_type = PART_FIP; } else if (!strcmp(p, "System")) { part->part_type = PART_SYSTEM; } else if (!strcmp(p, "FileSystem")) { @@ -1056,9 +1080,10 @@ static int create_gpt_partitions(struct stm32prog_data *data) char uuid[UUID_STR_LEN + 1]; unsigned char *uuid_bin; unsigned int mmc_id; - int i; + int i, j; bool rootfs_found; struct stm32prog_part_t *part; + const char *type_str;
buf = malloc(buflen); if (!buf) @@ -1100,33 +1125,46 @@ static int create_gpt_partitions(struct stm32prog_data *data) part->addr, part->size);
- if (part->part_type == PART_BINARY) - offset += snprintf(buf + offset, - buflen - offset, - ",type=" - LINUX_RESERVED_UUID); - else - offset += snprintf(buf + offset, - buflen - offset, - ",type=linux"); + switch (part->part_type) { + case PART_BINARY: + type_str = LINUX_RESERVED_UUID; + break; + case PART_FIP: + type_str = FIP_TYPE_UUID; + break; + default: + type_str = "linux"; + break; + } + offset += snprintf(buf + offset, + buflen - offset, + ",type=%s", type_str);
if (part->part_type == PART_SYSTEM) offset += snprintf(buf + offset, buflen - offset, ",bootable");
+ /* partition UUID */ + uuid_bin = NULL; if (!rootfs_found && !strcmp(part->name, "rootfs")) { mmc_id = part->dev_id; rootfs_found = true; - if (mmc_id < ARRAY_SIZE(uuid_mmc)) { - uuid_bin = - (unsigned char *)uuid_mmc[mmc_id].b; - uuid_bin_to_str(uuid_bin, uuid, - UUID_STR_FORMAT_GUID); - offset += snprintf(buf + offset, - buflen - offset, - ",uuid=%s", uuid); - } + if (mmc_id < ARRAY_SIZE(uuid_mmc)) + uuid_bin = (unsigned char *)uuid_mmc[mmc_id].b; + } + if (part->part_type == PART_FIP) { + for (j = 0; j < ARRAY_SIZE(fip_part_name); j++) + if (!strcmp(part->name, fip_part_name[j])) { + uuid_bin = (unsigned char *)fip_part_uuid[j].b; + break; + } + } + if (uuid_bin) { + uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); + offset += snprintf(buf + offset, + buflen - offset, + ",uuid=%s", uuid); }
offset += snprintf(buf + offset, buflen - offset, ";"); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 90cdc2ba47..b3e5c74810 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -94,9 +94,10 @@ struct stm32_header_v2 { /* partition type in flashlayout file */ enum stm32prog_part_type { PART_BINARY, + PART_FIP, PART_SYSTEM, PART_FILESYSTEM, - RAW_IMAGE + RAW_IMAGE, };
/* device information */

Hi Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
Add support of UUID for FIP parttion, required by Firmware update support in TF-A:
- UUID TYPE for FIP partition: 19d5df83-11b0-457b-be2c-7559c13142a5
- "fip-a" partition UUID: 4fd84c93-54ef-463f-a7ef-ae25ff887087
- "fip-b" partition UUID: 09c54952-d5bf-45af-acee-335303766fb3
This check is done with a new partition type "FIP" associated at the FIP UUID.
The A/B partition UUID is detected by the partition name: "fip-a", "fip-b".
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
.../mach-stm32mp/cmd_stm32prog/stm32prog.c | 76 ++++++++++++++----- .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 3 +- 2 files changed, 59 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 3e1fdee5b3..d3b3e1ed72 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -62,6 +62,28 @@ static const efi_guid_t uuid_mmc[3] = { ROOTFS_MMC2_UUID };
+/* FIP type partition UUID used by TF-A*/ +#define FIP_TYPE_UUID "19D5DF83-11B0-457B-BE2C-7559C13142A5"
+/* unique partition guid (uuid) for FIP partitions A/B */ +#define FIP_A_UUID \
- EFI_GUID(0x4FD84C93, 0x54EF, 0x463F, \
0xA7, 0xEF, 0xAE, 0x25, 0xFF, 0x88, 0x70, 0x87)
+#define FIP_B_UUID \
- EFI_GUID(0x09C54952, 0xD5BF, 0x45AF, \
0xAC, 0xEE, 0x33, 0x53, 0x03, 0x76, 0x6F, 0xB3)
+static const char * const fip_part_name[] = {
- "fip-a",
- "fip-b"
+};
+static const efi_guid_t fip_part_uuid[] = {
- FIP_A_UUID,
- FIP_B_UUID
+};
/* order of column in flash layout file */ enum stm32prog_col_t { COL_OPTION, @@ -405,6 +427,8 @@ static int parse_type(struct stm32prog_data *data, part->bin_nb = dectoul(&p[7], NULL); }
- } else if (!strcmp(p, "FIP")) {
} else if (!strcmp(p, "System")) { part->part_type = PART_SYSTEM; } else if (!strcmp(p, "FileSystem")) {part->part_type = PART_FIP;
@@ -1056,9 +1080,10 @@ static int create_gpt_partitions(struct stm32prog_data *data) char uuid[UUID_STR_LEN + 1]; unsigned char *uuid_bin; unsigned int mmc_id;
- int i;
int i, j; bool rootfs_found; struct stm32prog_part_t *part;
const char *type_str;
buf = malloc(buflen); if (!buf)
@@ -1100,33 +1125,46 @@ static int create_gpt_partitions(struct stm32prog_data *data) part->addr, part->size);
if (part->part_type == PART_BINARY)
offset += snprintf(buf + offset,
buflen - offset,
",type="
LINUX_RESERVED_UUID);
else
offset += snprintf(buf + offset,
buflen - offset,
",type=linux");
switch (part->part_type) {
case PART_BINARY:
type_str = LINUX_RESERVED_UUID;
break;
case PART_FIP:
type_str = FIP_TYPE_UUID;
break;
default:
type_str = "linux";
break;
}
offset += snprintf(buf + offset,
buflen - offset,
",type=%s", type_str); if (part->part_type == PART_SYSTEM) offset += snprintf(buf + offset, buflen - offset, ",bootable");
/* partition UUID */
uuid_bin = NULL; if (!rootfs_found && !strcmp(part->name, "rootfs")) { mmc_id = part->dev_id; rootfs_found = true;
if (mmc_id < ARRAY_SIZE(uuid_mmc)) {
uuid_bin =
(unsigned char *)uuid_mmc[mmc_id].b;
uuid_bin_to_str(uuid_bin, uuid,
UUID_STR_FORMAT_GUID);
offset += snprintf(buf + offset,
buflen - offset,
",uuid=%s", uuid);
}
if (mmc_id < ARRAY_SIZE(uuid_mmc))
uuid_bin = (unsigned char *)uuid_mmc[mmc_id].b;
}
if (part->part_type == PART_FIP) {
for (j = 0; j < ARRAY_SIZE(fip_part_name); j++)
if (!strcmp(part->name, fip_part_name[j])) {
uuid_bin = (unsigned char *)fip_part_uuid[j].b;
break;
}
}
if (uuid_bin) {
uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
offset += snprintf(buf + offset,
buflen - offset,
",uuid=%s", uuid); } offset += snprintf(buf + offset, buflen - offset, ";");
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 90cdc2ba47..b3e5c74810 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -94,9 +94,10 @@ struct stm32_header_v2 { /* partition type in flashlayout file */ enum stm32prog_part_type { PART_BINARY,
- PART_FIP, PART_SYSTEM, PART_FILESYSTEM,
- RAW_IMAGE
- RAW_IMAGE,
};
/* device information */
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
Add support of UUID for FIP parttion, required by Firmware update support in TF-A:
- UUID TYPE for FIP partition: 19d5df83-11b0-457b-be2c-7559c13142a5
- "fip-a" partition UUID: 4fd84c93-54ef-463f-a7ef-ae25ff887087
- "fip-b" partition UUID: 09c54952-d5bf-45af-acee-335303766fb3
This check is done with a new partition type "FIP" associated at the FIP UUID.
The A/B partition UUID is detected by the partition name: "fip-a", "fip-b".
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
.../mach-stm32mp/cmd_stm32prog/stm32prog.c | 76 ++++++++++++++----- .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 3 +- 2 files changed, 59 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 3e1fdee5b3..d3b3e1ed72 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -62,6 +62,28 @@ static const efi_guid_t uuid_mmc[3] = { ROOTFS_MMC2_UUID };
+/* FIP type partition UUID used by TF-A*/ +#define FIP_TYPE_UUID "19D5DF83-11B0-457B-BE2C-7559C13142A5"
+/* unique partition guid (uuid) for FIP partitions A/B */ +#define FIP_A_UUID \
- EFI_GUID(0x4FD84C93, 0x54EF, 0x463F, \
0xA7, 0xEF, 0xAE, 0x25, 0xFF, 0x88, 0x70, 0x87)
+#define FIP_B_UUID \
- EFI_GUID(0x09C54952, 0xD5BF, 0x45AF, \
0xAC, 0xEE, 0x33, 0x53, 0x03, 0x76, 0x6F, 0xB3)
+static const char * const fip_part_name[] = {
- "fip-a",
- "fip-b"
+};
+static const efi_guid_t fip_part_uuid[] = {
- FIP_A_UUID,
- FIP_B_UUID
+};
/* order of column in flash layout file */ enum stm32prog_col_t { COL_OPTION, @@ -405,6 +427,8 @@ static int parse_type(struct stm32prog_data *data, part->bin_nb = dectoul(&p[7], NULL); }
- } else if (!strcmp(p, "FIP")) {
} else if (!strcmp(p, "System")) { part->part_type = PART_SYSTEM; } else if (!strcmp(p, "FileSystem")) {part->part_type = PART_FIP;
@@ -1056,9 +1080,10 @@ static int create_gpt_partitions(struct stm32prog_data *data) char uuid[UUID_STR_LEN + 1]; unsigned char *uuid_bin; unsigned int mmc_id;
- int i;
int i, j; bool rootfs_found; struct stm32prog_part_t *part;
const char *type_str;
buf = malloc(buflen); if (!buf)
@@ -1100,33 +1125,46 @@ static int create_gpt_partitions(struct stm32prog_data *data) part->addr, part->size);
if (part->part_type == PART_BINARY)
offset += snprintf(buf + offset,
buflen - offset,
",type="
LINUX_RESERVED_UUID);
else
offset += snprintf(buf + offset,
buflen - offset,
",type=linux");
switch (part->part_type) {
case PART_BINARY:
type_str = LINUX_RESERVED_UUID;
break;
case PART_FIP:
type_str = FIP_TYPE_UUID;
break;
default:
type_str = "linux";
break;
}
offset += snprintf(buf + offset,
buflen - offset,
",type=%s", type_str); if (part->part_type == PART_SYSTEM) offset += snprintf(buf + offset, buflen - offset, ",bootable");
/* partition UUID */
uuid_bin = NULL; if (!rootfs_found && !strcmp(part->name, "rootfs")) { mmc_id = part->dev_id; rootfs_found = true;
if (mmc_id < ARRAY_SIZE(uuid_mmc)) {
uuid_bin =
(unsigned char *)uuid_mmc[mmc_id].b;
uuid_bin_to_str(uuid_bin, uuid,
UUID_STR_FORMAT_GUID);
offset += snprintf(buf + offset,
buflen - offset,
",uuid=%s", uuid);
}
if (mmc_id < ARRAY_SIZE(uuid_mmc))
uuid_bin = (unsigned char *)uuid_mmc[mmc_id].b;
}
if (part->part_type == PART_FIP) {
for (j = 0; j < ARRAY_SIZE(fip_part_name); j++)
if (!strcmp(part->name, fip_part_name[j])) {
uuid_bin = (unsigned char *)fip_part_uuid[j].b;
break;
}
}
if (uuid_bin) {
uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
offset += snprintf(buf + offset,
buflen - offset,
",uuid=%s", uuid); } offset += snprintf(buf + offset, buflen - offset, ";");
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 90cdc2ba47..b3e5c74810 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -94,9 +94,10 @@ struct stm32_header_v2 { /* partition type in flashlayout file */ enum stm32prog_part_type { PART_BINARY,
- PART_FIP, PART_SYSTEM, PART_FILESYSTEM,
- RAW_IMAGE
- RAW_IMAGE,
};
/* device information */
Applied to u-boot-stm32
Thanks Patrice

When an interruption is received during the first USB enumeration used to received the FlashLayout, with handle ctrl-c, the second enumeration is not needed and the result for stm32prog_usb_loop is false (reset is not needed).
This patch avoids the need of a second ctrl to interrupt the command stm32prog.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index 82b702f93b..a8b57c4d8f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -206,9 +206,12 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) g_dnl_set_product(product);
if (stm32prog_data->phase == PHASE_FLASHLAYOUT) { + /* forget any previous Control C */ + clear_ctrlc(); ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu"); - if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT) - return ret; + /* DFU reset received, no error or CtrlC */ + if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT || had_ctrlc()) + return ret; /* true = reset on DFU error */ /* prepare the second enumeration with the FlashLayout */ stm32prog_dfu_init(data); }

Hi Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
When an interruption is received during the first USB enumeration used to received the FlashLayout, with handle ctrl-c, the second enumeration is not needed and the result for stm32prog_usb_loop is false (reset is not needed).
This patch avoids the need of a second ctrl to interrupt the command stm32prog.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index 82b702f93b..a8b57c4d8f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -206,9 +206,12 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) g_dnl_set_product(product);
if (stm32prog_data->phase == PHASE_FLASHLAYOUT) {
/* forget any previous Control C */
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");clear_ctrlc();
if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT)
return ret;
/* DFU reset received, no error or CtrlC */
if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT || had_ctrlc())
/* prepare the second enumeration with the FlashLayout */ stm32prog_dfu_init(data); }return ret; /* true = reset on DFU error */
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
When an interruption is received during the first USB enumeration used to received the FlashLayout, with handle ctrl-c, the second enumeration is not needed and the result for stm32prog_usb_loop is false (reset is not needed).
This patch avoids the need of a second ctrl to interrupt the command stm32prog.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index 82b702f93b..a8b57c4d8f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -206,9 +206,12 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) g_dnl_set_product(product);
if (stm32prog_data->phase == PHASE_FLASHLAYOUT) {
/* forget any previous Control C */
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");clear_ctrlc();
if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT)
return ret;
/* DFU reset received, no error or CtrlC */
if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT || had_ctrlc())
/* prepare the second enumeration with the FlashLayout */ stm32prog_dfu_init(data); }return ret; /* true = reset on DFU error */
Applied to u-boot-stm32
Thanks Patrice

Update the stm32prog command to allow the reception of U-Boot script in the FlashLayout alternate during the first USB enumeration.
This patch is aligned with the last TF-A behavior: the Flashlayout is now loaded by U-Boot; it is no more present at STM32_DDR_BASE when the stm32prog is launched after a serial boot, on UART or on USB.
The received script must be a U-Boot legacy image, no more need to add a stm32image header.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 9 ++------- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 9 +++++++++ arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 2 ++ 3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 3957e06e5d..f59414e716 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -76,13 +76,6 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, stm32prog_header_check(addr, &header); if (header.type == HEADER_STM32IMAGE) { size = header.image_length + header.length; - -#if defined(CONFIG_LEGACY_IMAGE_FORMAT) - /* uImage detected in STM32IMAGE, execute the script */ - if (IMAGE_FORMAT_LEGACY == - genimg_get_format((void *)(addr + header.length))) - return image_source_script(addr + header.length, "script@1"); -#endif } }
@@ -160,6 +153,8 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, else if (CONFIG_IS_ENABLED(CMD_BOOTZ)) do_bootz(cmdtp, 0, 4, bootm_argv); } + if (data->script) + image_source_script(data->script, "script@stm32prog");
if (reset) { puts("Reset...\n"); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d3b3e1ed72..65655e25ca 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -6,6 +6,7 @@ #include <command.h> #include <console.h> #include <dfu.h> +#include <image.h> #include <malloc.h> #include <misc.h> #include <mmc.h> @@ -1697,6 +1698,14 @@ error: static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) { if (data->phase == PHASE_FLASHLAYOUT) { +#if defined(CONFIG_LEGACY_IMAGE_FORMAT) + if (genimg_get_format((void *)STM32_DDR_BASE) == IMAGE_FORMAT_LEGACY) { + data->script = STM32_DDR_BASE; + data->phase = PHASE_END; + log_notice("U-Boot script received\n"); + return; + } +#endif if (parse_flash_layout(data, STM32_DDR_BASE, 0)) stm32prog_err("Layout: invalid FlashLayout"); return; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index b3e5c74810..ac300768ca 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -170,6 +170,8 @@ struct stm32prog_data { u32 initrd; u32 initrd_size;
+ u32 script; + /* OPTEE PTA NVMEM */ struct udevice *tee; u32 tee_session;

Hi Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
Update the stm32prog command to allow the reception of U-Boot script in the FlashLayout alternate during the first USB enumeration.
This patch is aligned with the last TF-A behavior: the Flashlayout is now loaded by U-Boot; it is no more present at STM32_DDR_BASE when the stm32prog is launched after a serial boot, on UART or on USB.
The received script must be a U-Boot legacy image, no more need to add a stm32image header.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 9 ++------- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 9 +++++++++ arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 2 ++ 3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 3957e06e5d..f59414e716 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -76,13 +76,6 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, stm32prog_header_check(addr, &header); if (header.type == HEADER_STM32IMAGE) { size = header.image_length + header.length;
-#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
/* uImage detected in STM32IMAGE, execute the script */
if (IMAGE_FORMAT_LEGACY ==
genimg_get_format((void *)(addr + header.length)))
return image_source_script(addr + header.length, "script@1");
-#endif } }
@@ -160,6 +153,8 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, else if (CONFIG_IS_ENABLED(CMD_BOOTZ)) do_bootz(cmdtp, 0, 4, bootm_argv); }
if (data->script)
image_source_script(data->script, "script@stm32prog");
if (reset) { puts("Reset...\n");
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d3b3e1ed72..65655e25ca 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -6,6 +6,7 @@ #include <command.h> #include <console.h> #include <dfu.h> +#include <image.h> #include <malloc.h> #include <misc.h> #include <mmc.h> @@ -1697,6 +1698,14 @@ error: static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) { if (data->phase == PHASE_FLASHLAYOUT) { +#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
if (genimg_get_format((void *)STM32_DDR_BASE) == IMAGE_FORMAT_LEGACY) {
data->script = STM32_DDR_BASE;
data->phase = PHASE_END;
log_notice("U-Boot script received\n");
return;
}
+#endif if (parse_flash_layout(data, STM32_DDR_BASE, 0)) stm32prog_err("Layout: invalid FlashLayout"); return; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index b3e5c74810..ac300768ca 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -170,6 +170,8 @@ struct stm32prog_data { u32 initrd; u32 initrd_size;
- u32 script;
- /* OPTEE PTA NVMEM */ struct udevice *tee; u32 tee_session;
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
Update the stm32prog command to allow the reception of U-Boot script in the FlashLayout alternate during the first USB enumeration.
This patch is aligned with the last TF-A behavior: the Flashlayout is now loaded by U-Boot; it is no more present at STM32_DDR_BASE when the stm32prog is launched after a serial boot, on UART or on USB.
The received script must be a U-Boot legacy image, no more need to add a stm32image header.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 9 ++------- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 9 +++++++++ arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 2 ++ 3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 3957e06e5d..f59414e716 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -76,13 +76,6 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, stm32prog_header_check(addr, &header); if (header.type == HEADER_STM32IMAGE) { size = header.image_length + header.length;
-#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
/* uImage detected in STM32IMAGE, execute the script */
if (IMAGE_FORMAT_LEGACY ==
genimg_get_format((void *)(addr + header.length)))
return image_source_script(addr + header.length, "script@1");
-#endif } }
@@ -160,6 +153,8 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, else if (CONFIG_IS_ENABLED(CMD_BOOTZ)) do_bootz(cmdtp, 0, 4, bootm_argv); }
if (data->script)
image_source_script(data->script, "script@stm32prog");
if (reset) { puts("Reset...\n");
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d3b3e1ed72..65655e25ca 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -6,6 +6,7 @@ #include <command.h> #include <console.h> #include <dfu.h> +#include <image.h> #include <malloc.h> #include <misc.h> #include <mmc.h> @@ -1697,6 +1698,14 @@ error: static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) { if (data->phase == PHASE_FLASHLAYOUT) { +#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
if (genimg_get_format((void *)STM32_DDR_BASE) == IMAGE_FORMAT_LEGACY) {
data->script = STM32_DDR_BASE;
data->phase = PHASE_END;
log_notice("U-Boot script received\n");
return;
}
+#endif if (parse_flash_layout(data, STM32_DDR_BASE, 0)) stm32prog_err("Layout: invalid FlashLayout"); return; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index b3e5c74810..ac300768ca 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -170,6 +170,8 @@ struct stm32prog_data { u32 initrd; u32 initrd_size;
- u32 script;
- /* OPTEE PTA NVMEM */ struct udevice *tee; u32 tee_session;
Applied to u-boot-stm32
Thanks Patrice

Accept flashlayout without header in alternate 0, to simplify the support of stm32prog command with dfu-util.
By default the flashlayout file size is the size of the received binary, provided with the offset in the DFU alternate.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 65655e25ca..b7111123ba 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1706,7 +1706,8 @@ static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) return; } #endif - if (parse_flash_layout(data, STM32_DDR_BASE, 0)) + log_notice("\nFlashLayout received, size = %lld\n", offset); + if (parse_flash_layout(data, STM32_DDR_BASE, offset)) stm32prog_err("Layout: invalid FlashLayout"); return; }

Hi Patrick
On 3/28/22 19:25, Patrick Delaunay wrote:
Accept flashlayout without header in alternate 0, to simplify the support of stm32prog command with dfu-util.
By default the flashlayout file size is the size of the received binary, provided with the offset in the DFU alternate.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 65655e25ca..b7111123ba 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1706,7 +1706,8 @@ static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) return; } #endif
if (parse_flash_layout(data, STM32_DDR_BASE, 0))
log_notice("\nFlashLayout received, size = %lld\n", offset);
return; }if (parse_flash_layout(data, STM32_DDR_BASE, offset)) stm32prog_err("Layout: invalid FlashLayout");
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Thanks Patrice

On 3/28/22 19:25, Patrick Delaunay wrote:
Accept flashlayout without header in alternate 0, to simplify the support of stm32prog command with dfu-util.
By default the flashlayout file size is the size of the received binary, provided with the offset in the DFU alternate.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 65655e25ca..b7111123ba 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1706,7 +1706,8 @@ static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) return; } #endif
if (parse_flash_layout(data, STM32_DDR_BASE, 0))
log_notice("\nFlashLayout received, size = %lld\n", offset);
return; }if (parse_flash_layout(data, STM32_DDR_BASE, offset)) stm32prog_err("Layout: invalid FlashLayout");
Applied to u-boot-stm32
Thanks Patrice
participants (2)
-
Patrice CHOTARD
-
Patrick Delaunay