cmd_stm32prog.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  2. /*
  3. * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
  4. */
  5. #include <common.h>
  6. #include <command.h>
  7. #include <dfu.h>
  8. #include <image.h>
  9. #include <asm/arch/stm32prog.h>
  10. #include "stm32prog.h"
  11. struct stm32prog_data *stm32prog_data;
  12. static void enable_vidconsole(void)
  13. {
  14. #ifdef CONFIG_DM_VIDEO
  15. char *stdname;
  16. char buf[64];
  17. stdname = env_get("stdout");
  18. if (!stdname || !strstr(stdname, "vidconsole")) {
  19. if (!stdname)
  20. snprintf(buf, sizeof(buf), "serial,vidconsole");
  21. else
  22. snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
  23. env_set("stdout", buf);
  24. }
  25. stdname = env_get("stderr");
  26. if (!stdname || !strstr(stdname, "vidconsole")) {
  27. if (!stdname)
  28. snprintf(buf, sizeof(buf), "serial,vidconsole");
  29. else
  30. snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
  31. env_set("stderr", buf);
  32. }
  33. #endif
  34. }
  35. static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
  36. char * const argv[])
  37. {
  38. ulong addr, size;
  39. int dev, ret;
  40. enum stm32prog_link_t link = LINK_UNDEFINED;
  41. bool reset = false;
  42. struct image_header_s header;
  43. struct stm32prog_data *data;
  44. u32 uimage, dtb;
  45. if (argc < 3 || argc > 5)
  46. return CMD_RET_USAGE;
  47. if (!strcmp(argv[1], "usb"))
  48. link = LINK_USB;
  49. else if (!strcmp(argv[1], "serial"))
  50. link = LINK_SERIAL;
  51. if (link == LINK_UNDEFINED) {
  52. pr_err("not supported link=%s\n", argv[1]);
  53. return CMD_RET_USAGE;
  54. }
  55. dev = (int)simple_strtoul(argv[2], NULL, 10);
  56. addr = STM32_DDR_BASE;
  57. size = 0;
  58. if (argc > 3) {
  59. addr = simple_strtoul(argv[3], NULL, 16);
  60. if (!addr)
  61. return CMD_RET_FAILURE;
  62. }
  63. if (argc > 4)
  64. size = simple_strtoul(argv[4], NULL, 16);
  65. /* check STM32IMAGE presence */
  66. if (size == 0 &&
  67. !stm32prog_header_check((struct raw_header_s *)addr, &header)) {
  68. size = header.image_length + BL_HEADER_SIZE;
  69. /* uImage detected in STM32IMAGE, execute the script */
  70. if (IMAGE_FORMAT_LEGACY ==
  71. genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
  72. return image_source_script(addr + BL_HEADER_SIZE,
  73. "script@1");
  74. }
  75. enable_vidconsole();
  76. data = (struct stm32prog_data *)malloc(sizeof(*data));
  77. if (!data) {
  78. pr_err("Alloc failed.");
  79. return CMD_RET_FAILURE;
  80. }
  81. stm32prog_data = data;
  82. ret = stm32prog_init(data, addr, size);
  83. if (ret)
  84. printf("Invalid or missing layout file.");
  85. /* prepare DFU for device read/write */
  86. ret = stm32prog_dfu_init(data);
  87. if (ret)
  88. goto cleanup;
  89. switch (link) {
  90. case LINK_SERIAL:
  91. ret = stm32prog_serial_init(data, dev);
  92. if (ret)
  93. goto cleanup;
  94. reset = stm32prog_serial_loop(data);
  95. break;
  96. case LINK_USB:
  97. reset = stm32prog_usb_loop(data, dev);
  98. break;
  99. default:
  100. goto cleanup;
  101. }
  102. uimage = data->uimage;
  103. dtb = data->dtb;
  104. stm32prog_clean(data);
  105. free(stm32prog_data);
  106. stm32prog_data = NULL;
  107. puts("Download done\n");
  108. if (uimage) {
  109. char boot_addr_start[20];
  110. char dtb_addr[20];
  111. char *bootm_argv[5] = {
  112. "bootm", boot_addr_start, "-", dtb_addr, NULL
  113. };
  114. if (!dtb)
  115. bootm_argv[3] = env_get("fdtcontroladdr");
  116. else
  117. snprintf(dtb_addr, sizeof(dtb_addr) - 1,
  118. "0x%x", dtb);
  119. snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
  120. "0x%x", uimage);
  121. printf("Booting kernel at %s - %s...\n\n\n",
  122. boot_addr_start, bootm_argv[3]);
  123. /* Try bootm for legacy and FIT format image */
  124. if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
  125. do_bootm(cmdtp, 0, 4, bootm_argv);
  126. else if CONFIG_IS_ENABLED(CMD_BOOTZ)
  127. do_bootz(cmdtp, 0, 4, bootm_argv);
  128. }
  129. if (reset) {
  130. puts("Reset...\n");
  131. run_command("reset", 0);
  132. }
  133. return CMD_RET_SUCCESS;
  134. cleanup:
  135. stm32prog_clean(data);
  136. free(stm32prog_data);
  137. stm32prog_data = NULL;
  138. return CMD_RET_FAILURE;
  139. }
  140. U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
  141. "<link> <dev> [<addr>] [<size>]\n"
  142. "start communication with tools STM32Cubeprogrammer on <link> with Flashlayout at <addr>",
  143. "<link> = serial|usb\n"
  144. "<dev> = device instance\n"
  145. "<addr> = address of flashlayout\n"
  146. "<size> = size of flashlayout\n"
  147. );
  148. bool stm32prog_get_tee_partitions(void)
  149. {
  150. if (stm32prog_data)
  151. return stm32prog_data->tee_detected;
  152. return false;
  153. }
  154. bool stm32prog_get_fsbl_nor(void)
  155. {
  156. if (stm32prog_data)
  157. return stm32prog_data->fsbl_nor_detected;
  158. return false;
  159. }