cmd_stm32prog.c 4.5 KB

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