On 4/25/25 15:15, Patrice Chotard wrote:
> Update key table for stm32mp25 platform.
> 
> Signed-off-by: Lionel Debieve <lionel.debi...@foss.st.com>
> Signed-off-by: Thomas Bourgoin <thomas.bourg...@foss.st.com>
> Signed-off-by: Patrice Chotard <patrice.chot...@foss.st.com>
> ---
> 
> (no changes since v1)
> 
>  arch/arm/mach-stm32mp/cmd_stm32key.c | 264 +++++++++++++++++++++++----
>  1 file changed, 225 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c 
> b/arch/arm/mach-stm32mp/cmd_stm32key.c
> index 040a70f581c..d6bf72d8e32 100644
> --- a/arch/arm/mach-stm32mp/cmd_stm32key.c
> +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c
> @@ -14,12 +14,23 @@
>  
>  /*
>   * Closed device: OTP0
> - * STM32MP15x: bit 6 of OPT0
> + * STM32MP15x: bit 6 of OTP0
>   * STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device
> + * STM32MP25x: bit 0 of OTP18
>   */
> -#define STM32_OTP_CLOSE_ID           0
> -#define STM32_OTP_STM32MP13X_CLOSE_MASK      0x3F
> -#define STM32_OTP_STM32MP15X_CLOSE_MASK      BIT(6)
> +#define STM32MP1_OTP_CLOSE_ID                                0
> +#define STM32_OTP_STM32MP13X_CLOSE_MASK              GENMASK(5, 0)
> +#define STM32_OTP_STM32MP15X_CLOSE_MASK              BIT(6)
> +#define STM32MP25_OTP_WORD8                          8
> +#define STM32_OTP_STM32MP25X_BOOTROM_CLOSE_MASK      GENMASK(7, 0)
> +#define STM32MP25_OTP_CLOSE_ID                       18
> +#define STM32_OTP_STM32MP25X_CLOSE_MASK              GENMASK(3, 0)
> +#define STM32_OTP_STM32MP25X_PROVISIONING_DONE_MASK  GENMASK(7, 4)
> +#define STM32MP25_OTP_HWCONFIG                       124
> +#define STM32_OTP_STM32MP25X_DISABLE_SCAN_MASK       BIT(20)
> +
> +#define STM32MP25_OTP_BOOTROM_CONF8  17
> +#define STM32_OTP_STM32MP25X_OEM_KEY2_EN     BIT(8)
>  
>  /* PKH is the first element of the key list */
>  #define STM32KEY_PKH 0
> @@ -27,8 +38,9 @@
>  struct stm32key {
>       char *name;
>       char *desc;
> -     u8 start;
> +     u16 start;
>       u8 size;
> +     int (*post_process)(struct udevice *dev);
>  };
>  
>  const struct stm32key stm32mp13_list[] = {
> @@ -55,6 +67,99 @@ const struct stm32key stm32mp15_list[] = {
>       }
>  };
>  
> +static int post_process_oem_key2(struct udevice *dev);
> +
> +const struct stm32key stm32mp25_list[] = {
> +     [STM32KEY_PKH] = {
> +             .name = "OEM-KEY1",
> +             .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is 
> the authentication algorithm) for FSBLA or M",
> +             .start = 144,
> +             .size = 8,
> +     },
> +     {
> +             .name = "OEM-KEY2",
> +             .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is 
> the authentication algorithm) for FSBLM",
> +             .start = 152,
> +             .size = 8,
> +             .post_process = post_process_oem_key2,
> +     },
> +     {
> +             .name = "FIP-EDMK",
> +             .desc = "Encryption/Decryption Master Key for FIP",
> +             .start = 260,
> +             .size = 8,
> +     },
> +     {
> +             .name = "EDMK1",
> +             .desc = "Encryption/Decryption Master Key for FSBLA or M",
> +             .start = 364,
> +             .size = 4,
> +     },
> +     {
> +             .name = "EDMK2",
> +             .desc = "Encryption/Decryption Master Key for FSBLM",
> +             .start = 360,
> +             .size = 4,
> +     }
> +};
> +
> +struct otp_close {
> +     u32 word;
> +     u32 mask_wr;
> +     u32 mask_rd;
> +     bool (*close_status_ops)(u32 value, u32 mask);
> +};
> +
> +static bool compare_mask_exact(u32 value, u32 mask)
> +{
> +     return ((value & mask) == mask);
> +}
> +
> +static bool compare_any_bits(u32 value, u32 mask)
> +{
> +     return ((value & mask) != 0);
> +}
> +
> +const struct otp_close stm32mp13_close_state_otp[] = {
> +     {
> +             .word = STM32MP1_OTP_CLOSE_ID,
> +             .mask_wr = STM32_OTP_STM32MP13X_CLOSE_MASK,
> +             .mask_rd = STM32_OTP_STM32MP13X_CLOSE_MASK,
> +             .close_status_ops = compare_mask_exact,
> +     }
> +};
> +
> +const struct otp_close stm32mp15_close_state_otp[] = {
> +     {
> +             .word = STM32MP1_OTP_CLOSE_ID,
> +             .mask_wr = STM32_OTP_STM32MP15X_CLOSE_MASK,
> +             .mask_rd = STM32_OTP_STM32MP15X_CLOSE_MASK,
> +             .close_status_ops = compare_mask_exact,
> +     }
> +};
> +
> +const struct otp_close stm32mp25_close_state_otp[] = {
> +     {
> +             .word = STM32MP25_OTP_WORD8,
> +             .mask_wr = STM32_OTP_STM32MP25X_BOOTROM_CLOSE_MASK,
> +             .mask_rd = 0,
> +             .close_status_ops = NULL
> +     },
> +     {
> +             .word = STM32MP25_OTP_CLOSE_ID,
> +             .mask_wr = STM32_OTP_STM32MP25X_CLOSE_MASK |
> +                        STM32_OTP_STM32MP25X_PROVISIONING_DONE_MASK,
> +             .mask_rd = STM32_OTP_STM32MP25X_CLOSE_MASK,
> +             .close_status_ops = compare_any_bits
> +     },
> +     {
> +             .word = STM32MP25_OTP_HWCONFIG,
> +             .mask_wr = STM32_OTP_STM32MP25X_DISABLE_SCAN_MASK,
> +             .mask_rd = 0,
> +             .close_status_ops = NULL
> +     },
> +};
> +
>  /* index of current selected key in stm32key list, 0 = PKH by default */
>  static u8 stm32key_index;
>  
> @@ -65,6 +170,9 @@ static u8 get_key_nb(void)
>  
>       if (IS_ENABLED(CONFIG_STM32MP15X))
>               return ARRAY_SIZE(stm32mp15_list);
> +
> +     if (IS_ENABLED(CONFIG_STM32MP25X))
> +             return ARRAY_SIZE(stm32mp25_list);
>  }
>  
>  static const struct stm32key *get_key(u8 index)
> @@ -74,15 +182,33 @@ static const struct stm32key *get_key(u8 index)
>  
>       if (IS_ENABLED(CONFIG_STM32MP15X))
>               return &stm32mp15_list[index];
> +
> +     if (IS_ENABLED(CONFIG_STM32MP25X))
> +             return &stm32mp25_list[index];
> +}
> +
> +static u8 get_otp_close_state_nb(void)
> +{
> +     if (IS_ENABLED(CONFIG_STM32MP13X))
> +             return ARRAY_SIZE(stm32mp13_close_state_otp);
> +
> +     if (IS_ENABLED(CONFIG_STM32MP15X))
> +             return ARRAY_SIZE(stm32mp15_close_state_otp);
> +
> +     if (IS_ENABLED(CONFIG_STM32MP25X))
> +             return ARRAY_SIZE(stm32mp25_close_state_otp);
>  }
>  
> -static u32 get_otp_close_mask(void)
> +static const struct otp_close *get_otp_close_state(u8 index)
>  {
>       if (IS_ENABLED(CONFIG_STM32MP13X))
> -             return STM32_OTP_STM32MP13X_CLOSE_MASK;
> +             return &stm32mp13_close_state_otp[index];
>  
>       if (IS_ENABLED(CONFIG_STM32MP15X))
> -             return STM32_OTP_STM32MP15X_CLOSE_MASK;
> +             return &stm32mp15_close_state_otp[index];
> +
> +     if (IS_ENABLED(CONFIG_STM32MP25X))
> +             return &stm32mp25_close_state_otp[index];
>  }
>  
>  static int get_misc_dev(struct udevice **dev)
> @@ -96,13 +222,13 @@ static int get_misc_dev(struct udevice **dev)
>       return ret;
>  }
>  
> -static void read_key_value(const struct stm32key *key, u32 addr)
> +static void read_key_value(const struct stm32key *key, unsigned long addr)
>  {
>       int i;
>  
>       for (i = 0; i < key->size; i++) {
>               printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i,
> -                    addr, __be32_to_cpu(*(u32 *)addr));
> +                    (u32)addr, __be32_to_cpu(*(u32 *)addr));
>               addr += 4;
>       }
>  }
> @@ -157,26 +283,42 @@ static int read_key_otp(struct udevice *dev, const 
> struct stm32key *key, bool pr
>  
>  static int read_close_status(struct udevice *dev, bool print, bool *closed)
>  {
> -     int word, ret, result;
> -     u32 val, lock, mask;
> -     bool status;
> +     int ret, result, i;
> +     const struct otp_close *otp_close = NULL;
> +     u32 otp_close_nb = get_otp_close_state_nb();
> +     u32 val, lock, mask, word = 0;
> +     bool status = true;
> +     bool tested_once = false;
>  
>       result = 0;
> -     word = STM32_OTP_CLOSE_ID;
> -     ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
> -     if (ret < 0)
> -             result = ret;
> -     if (ret != 4)
> -             val = 0x0;
> -
> -     ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
> -     if (ret < 0)
> -             result = ret;
> -     if (ret != 4)
> -             lock = BSEC_LOCK_ERROR;
> -
> -     mask = get_otp_close_mask();
> -     status = (val & mask) == mask;
> +     for (i = 0; status && (i < otp_close_nb); i++) {
> +             otp_close = get_otp_close_state(i);
> +
> +             if (!otp_close->close_status_ops)
> +                     continue;
> +
> +             mask = otp_close->mask_rd;
> +             word = otp_close->word;
> +
> +             ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
> +             if (ret < 0)
> +                     result = ret;
> +             if (ret != 4)
> +                     val = 0x0;
> +
> +             ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
> +             if (ret < 0)
> +                     result = ret;
> +             if (ret != 4)
> +                     lock = BSEC_LOCK_ERROR;
> +
> +             status = otp_close->close_status_ops(val, mask);
> +             tested_once = true;
> +     }
> +
> +     if (!tested_once)
> +             status = false;
> +
>       if (closed)
>               *closed = status;
>       if (print)
> @@ -185,7 +327,49 @@ static int read_close_status(struct udevice *dev, bool 
> print, bool *closed)
>       return result;
>  }
>  
> -static int fuse_key_value(struct udevice *dev, const struct stm32key *key, 
> u32 addr, bool print)
> +static int write_close_status(struct udevice *dev)
> +{
> +     int i;
> +     u32 val, word, ret;
> +     const struct otp_close *otp_close = NULL;
> +     u32 otp_num = get_otp_close_state_nb();
> +
> +     for (i = 0; i < otp_num; i++) {
> +             otp_close = get_otp_close_state(i);
> +             val = otp_close->mask_wr;
> +             word = otp_close->word;
> +             ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
> +             if (ret != 4) {
> +                     log_err("Error: can't update OTP %d\n", word);
> +                     return ret;
> +             }
> +     }
> +     return 0;
> +}
> +
> +static int post_process_oem_key2(struct udevice *dev)
> +{
> +     int ret;
> +     u32 val;
> +
> +     ret = misc_read(dev, STM32_BSEC_OTP(STM32MP25_OTP_BOOTROM_CONF8), &val, 
> 4);
> +     if (ret != 4) {
> +             log_err("Error %d failed to read 
> STM32MP25_OTP_BOOTROM_CONF8\n", ret);
> +             return -EIO;
> +     }
> +
> +     val |= STM32_OTP_STM32MP25X_OEM_KEY2_EN;
> +     ret = misc_write(dev, STM32_BSEC_OTP(STM32MP25_OTP_BOOTROM_CONF8), 
> &val, 4);
> +     if (ret != 4) {
> +             log_err("Error %d failed to write OEM_KEY2_ENABLE\n", ret);
> +             return -EIO;
> +     }
> +
> +     return 0;
> +}
> +
> +static int fuse_key_value(struct udevice *dev, const struct stm32key *key, 
> unsigned long addr,
> +                       bool print)
>  {
>       u32 word, val;
>       int i, ret;
> @@ -229,7 +413,7 @@ static int confirm_prog(void)
>  static void display_key_info(const struct stm32key *key)
>  {
>       printf("%s : %s\n", key->name, key->desc);
> -     printf("\tOTP%d..%d\n", key->start, key->start + key->size);
> +     printf("\tOTP%d..%d\n", key->start, key->start + key->size - 1);
>  }
>  
>  static int do_stm32key_list(struct cmd_tbl *cmdtp, int flag, int argc, char 
> *const argv[])
> @@ -272,7 +456,7 @@ static int do_stm32key_read(struct cmd_tbl *cmdtp, int 
> flag, int argc, char *con
>  {
>       const struct stm32key *key;
>       struct udevice *dev;
> -     u32 addr;
> +     unsigned long addr;
>       int ret, i;
>       int result;
>  
> @@ -310,7 +494,7 @@ static int do_stm32key_read(struct cmd_tbl *cmdtp, int 
> flag, int argc, char *con
>               return CMD_RET_USAGE;
>  
>       key = get_key(stm32key_index);
> -     printf("Read %s at 0x%08x\n", key->name, addr);
> +     printf("Read %s at 0x%08x\n", key->name, (u32)addr);
>       read_key_value(key, addr);
>  
>       return CMD_RET_SUCCESS;
> @@ -320,7 +504,7 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int 
> flag, int argc, char *con
>  {
>       const struct stm32key *key = get_key(stm32key_index);
>       struct udevice *dev;
> -     u32 addr;
> +     unsigned long addr;
>       int ret;
>       bool yes = false, lock;
>  
> @@ -361,6 +545,13 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int 
> flag, int argc, char *con
>       if (fuse_key_value(dev, key, addr, !yes))
>               return CMD_RET_FAILURE;
>  
> +     if (key->post_process) {
> +             if (key->post_process(dev)) {
> +                     printf("Error: %s for post process\n", key->name);
> +                     return CMD_RET_FAILURE;
> +             }
> +     }
> +
>       printf("%s updated !\n", key->name);
>  
>       return CMD_RET_SUCCESS;
> @@ -371,7 +562,6 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int 
> flag, int argc, char *co
>       const struct stm32key *key;
>       bool yes, lock, closed;
>       struct udevice *dev;
> -     u32 val;
>       int ret;
>  
>       yes = false;
> @@ -407,12 +597,8 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int 
> flag, int argc, char *co
>       if (!yes && !confirm_prog())
>               return CMD_RET_FAILURE;
>  
> -     val = get_otp_close_mask();
> -     ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4);
> -     if (ret != 4) {
> -             printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID);
> +     if (write_close_status(dev))
>               return CMD_RET_FAILURE;
> -     }
>  
>       printf("Device is closed !\n");
>  
Applied to u-boot-stm32/master

Thanks
Patrice

Reply via email to