fuse.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2009-2013 ADVANSEE
  4. * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
  5. *
  6. * Based on the mpc512x iim code:
  7. * Copyright 2008 Silicon Turnkey Express, Inc.
  8. * Martha Marx <mmarx@silicontkx.com>
  9. */
  10. #include <common.h>
  11. #include <command.h>
  12. #include <console.h>
  13. #include <fuse.h>
  14. #include <linux/errno.h>
  15. static int strtou32(const char *str, unsigned int base, u32 *result)
  16. {
  17. char *ep;
  18. *result = simple_strtoul(str, &ep, base);
  19. if (ep == str || *ep != '\0')
  20. return -EINVAL;
  21. return 0;
  22. }
  23. static int confirm_prog(void)
  24. {
  25. puts("Warning: Programming fuses is an irreversible operation!\n"
  26. " This may brick your system.\n"
  27. " Use this command only if you are sure of "
  28. "what you are doing!\n"
  29. "\nReally perform this fuse programming? <y/N>\n");
  30. if (confirm_yesno())
  31. return 1;
  32. puts("Fuse programming aborted\n");
  33. return 0;
  34. }
  35. static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  36. {
  37. const char *op = argc >= 2 ? argv[1] : NULL;
  38. int confirmed = argc >= 3 && !strcmp(argv[2], "-y");
  39. u32 bank, word, cnt, val;
  40. int ret, i;
  41. argc -= 2 + confirmed;
  42. argv += 2 + confirmed;
  43. if (argc < 2 || strtou32(argv[0], 0, &bank) ||
  44. strtou32(argv[1], 0, &word))
  45. return CMD_RET_USAGE;
  46. if (!strcmp(op, "read")) {
  47. if (argc == 2)
  48. cnt = 1;
  49. else if (argc != 3 || strtou32(argv[2], 0, &cnt))
  50. return CMD_RET_USAGE;
  51. printf("Reading bank %u:\n", bank);
  52. for (i = 0; i < cnt; i++, word++) {
  53. if (!(i % 4))
  54. printf("\nWord 0x%.8x:", word);
  55. ret = fuse_read(bank, word, &val);
  56. if (ret)
  57. goto err;
  58. printf(" %.8x", val);
  59. }
  60. putc('\n');
  61. } else if (!strcmp(op, "sense")) {
  62. if (argc == 2)
  63. cnt = 1;
  64. else if (argc != 3 || strtou32(argv[2], 0, &cnt))
  65. return CMD_RET_USAGE;
  66. printf("Sensing bank %u:\n", bank);
  67. for (i = 0; i < cnt; i++, word++) {
  68. if (!(i % 4))
  69. printf("\nWord 0x%.8x:", word);
  70. ret = fuse_sense(bank, word, &val);
  71. if (ret)
  72. goto err;
  73. printf(" %.8x", val);
  74. }
  75. putc('\n');
  76. } else if (!strcmp(op, "prog")) {
  77. if (argc < 3)
  78. return CMD_RET_USAGE;
  79. for (i = 2; i < argc; i++, word++) {
  80. if (strtou32(argv[i], 16, &val))
  81. return CMD_RET_USAGE;
  82. printf("Programming bank %u word 0x%.8x to 0x%.8x...\n",
  83. bank, word, val);
  84. if (!confirmed && !confirm_prog())
  85. return CMD_RET_FAILURE;
  86. ret = fuse_prog(bank, word, val);
  87. if (ret)
  88. goto err;
  89. }
  90. } else if (!strcmp(op, "override")) {
  91. if (argc < 3)
  92. return CMD_RET_USAGE;
  93. for (i = 2; i < argc; i++, word++) {
  94. if (strtou32(argv[i], 16, &val))
  95. return CMD_RET_USAGE;
  96. printf("Overriding bank %u word 0x%.8x with "
  97. "0x%.8x...\n", bank, word, val);
  98. ret = fuse_override(bank, word, val);
  99. if (ret)
  100. goto err;
  101. }
  102. } else {
  103. return CMD_RET_USAGE;
  104. }
  105. return 0;
  106. err:
  107. puts("ERROR\n");
  108. return CMD_RET_FAILURE;
  109. }
  110. U_BOOT_CMD(
  111. fuse, CONFIG_SYS_MAXARGS, 0, do_fuse,
  112. "Fuse sub-system",
  113. "read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n"
  114. " starting at 'word'\n"
  115. "fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n"
  116. " starting at 'word'\n"
  117. "fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or\n"
  118. " several fuse words, starting at 'word' (PERMANENT)\n"
  119. "fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or\n"
  120. " several fuse words, starting at 'word'"
  121. );