cmd_bmode.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright (C) 2012 Boundary Devices Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <linux/errno.h>
  8. #include <asm/io.h>
  9. #include <asm/imx-common/boot_mode.h>
  10. #include <malloc.h>
  11. #include <command.h>
  12. static const struct boot_mode *modes[2];
  13. static const struct boot_mode *search_modes(char *arg)
  14. {
  15. int i;
  16. for (i = 0; i < ARRAY_SIZE(modes); i++) {
  17. const struct boot_mode *p = modes[i];
  18. if (p) {
  19. while (p->name) {
  20. if (!strcmp(p->name, arg))
  21. return p;
  22. p++;
  23. }
  24. }
  25. }
  26. return NULL;
  27. }
  28. static int create_usage(char *dest)
  29. {
  30. int i;
  31. int size = 0;
  32. for (i = 0; i < ARRAY_SIZE(modes); i++) {
  33. const struct boot_mode *p = modes[i];
  34. if (p) {
  35. while (p->name) {
  36. int len = strlen(p->name);
  37. if (dest) {
  38. memcpy(dest, p->name, len);
  39. dest += len;
  40. *dest++ = '|';
  41. }
  42. size += len + 1;
  43. p++;
  44. }
  45. }
  46. }
  47. if (dest)
  48. memcpy(dest - 1, " [noreset]", 11); /* include trailing 0 */
  49. size += 10;
  50. return size;
  51. }
  52. static int do_boot_mode(cmd_tbl_t *cmdtp, int flag, int argc,
  53. char * const argv[])
  54. {
  55. const struct boot_mode *p;
  56. int reset_requested = 1;
  57. if (argc < 2)
  58. return CMD_RET_USAGE;
  59. p = search_modes(argv[1]);
  60. if (!p)
  61. return CMD_RET_USAGE;
  62. if (argc == 3) {
  63. if (strcmp(argv[2], "noreset"))
  64. return CMD_RET_USAGE;
  65. reset_requested = 0;
  66. }
  67. boot_mode_apply(p->cfg_val);
  68. if (reset_requested && p->cfg_val)
  69. do_reset(NULL, 0, 0, NULL);
  70. return 0;
  71. }
  72. U_BOOT_CMD(
  73. bmode, 3, 0, do_boot_mode,
  74. NULL,
  75. "");
  76. void add_board_boot_modes(const struct boot_mode *p)
  77. {
  78. int size;
  79. char *dest;
  80. cmd_tbl_t *entry = ll_entry_get(cmd_tbl_t, bmode, cmd);
  81. if (entry->usage) {
  82. free(entry->usage);
  83. entry->usage = NULL;
  84. }
  85. modes[0] = p;
  86. modes[1] = soc_boot_modes;
  87. size = create_usage(NULL);
  88. dest = malloc(size);
  89. if (dest) {
  90. create_usage(dest);
  91. entry->usage = dest;
  92. }
  93. }