cmd_stm32key.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  2. /*
  3. * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
  4. */
  5. #include <common.h>
  6. #include <command.h>
  7. #include <console.h>
  8. #include <misc.h>
  9. #include <dm/device.h>
  10. #include <dm/uclass.h>
  11. #define STM32_OTP_HASH_KEY_START 24
  12. #define STM32_OTP_HASH_KEY_SIZE 8
  13. static void read_hash_value(u32 addr)
  14. {
  15. int i;
  16. for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
  17. printf("OTP value %i: %x\n", STM32_OTP_HASH_KEY_START + i,
  18. __be32_to_cpu(*(u32 *)addr));
  19. addr += 4;
  20. }
  21. }
  22. static void fuse_hash_value(u32 addr, bool print)
  23. {
  24. struct udevice *dev;
  25. u32 word, val;
  26. int i, ret;
  27. ret = uclass_get_device_by_driver(UCLASS_MISC,
  28. DM_GET_DRIVER(stm32mp_bsec),
  29. &dev);
  30. if (ret) {
  31. pr_err("Can't find stm32mp_bsec driver\n");
  32. return;
  33. }
  34. for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
  35. if (print)
  36. printf("Fuse OTP %i : %x\n",
  37. STM32_OTP_HASH_KEY_START + i,
  38. __be32_to_cpu(*(u32 *)addr));
  39. word = STM32_OTP_HASH_KEY_START + i;
  40. val = __be32_to_cpu(*(u32 *)addr);
  41. misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
  42. addr += 4;
  43. }
  44. }
  45. static int confirm_prog(void)
  46. {
  47. puts("Warning: Programming fuses is an irreversible operation!\n"
  48. " This may brick your system.\n"
  49. " Use this command only if you are sure of what you are doing!\n"
  50. "\nReally perform this fuse programming? <y/N>\n");
  51. if (confirm_yesno())
  52. return 1;
  53. puts("Fuse programming aborted\n");
  54. return 0;
  55. }
  56. static int do_stm32key(struct cmd_tbl *cmdtp, int flag, int argc,
  57. char *const argv[])
  58. {
  59. u32 addr;
  60. const char *op = argc >= 2 ? argv[1] : NULL;
  61. int confirmed = argc > 3 && !strcmp(argv[2], "-y");
  62. argc -= 2 + confirmed;
  63. argv += 2 + confirmed;
  64. if (argc < 1)
  65. return CMD_RET_USAGE;
  66. addr = simple_strtoul(argv[0], NULL, 16);
  67. if (!addr)
  68. return CMD_RET_USAGE;
  69. if (!strcmp(op, "read"))
  70. read_hash_value(addr);
  71. if (!strcmp(op, "fuse")) {
  72. if (!confirmed && !confirm_prog())
  73. return CMD_RET_FAILURE;
  74. fuse_hash_value(addr, !confirmed);
  75. }
  76. return CMD_RET_SUCCESS;
  77. }
  78. U_BOOT_CMD(stm32key, 4, 1, do_stm32key,
  79. "Fuse ST Hash key",
  80. "read <addr>: Read the hash store at addr in memory\n"
  81. "stm32key fuse [-y] <addr> : Fuse hash store at addr in otp\n");