fsl_debug_server.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Copyright (C) 2014 Freescale Semiconductor
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <errno.h>
  8. #include <asm/io.h>
  9. #include <asm/system.h>
  10. #include <fsl-mc/fsl_mc.h>
  11. #include <fsl_debug_server.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. static int debug_server_ver_info_maj, debug_server_ver_info_min;
  14. /**
  15. * Copying Debug Server firmware to DDR
  16. */
  17. static int debug_server_copy_image(const char *title, u64 image_addr,
  18. u32 image_size, u64 debug_server_ram_addr)
  19. {
  20. debug("%s copied to address %p\n", title,
  21. (void *)debug_server_ram_addr);
  22. memcpy((void *)debug_server_ram_addr, (void *)image_addr, image_size);
  23. return 0;
  24. }
  25. /**
  26. * Debug Server FIT image parser checks if the image is in FIT
  27. * format, verifies integrity of the image and calculates
  28. * raw image address and size values.
  29. *
  30. * Returns 0 if success and -1 if any of the above mentioned
  31. * task fail.
  32. **/
  33. int debug_server_parse_firmware_fit_image(const void **raw_image_addr,
  34. size_t *raw_image_size)
  35. {
  36. int format;
  37. void *fit_hdr;
  38. int node_offset;
  39. const void *data;
  40. size_t size;
  41. const char *uname = "firmware";
  42. char *desc;
  43. char *debug_server_ver_info;
  44. char *debug_server_ver_info_major, *debug_server_ver_info_minor;
  45. /* Check if the image is in NOR flash */
  46. #ifdef CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
  47. fit_hdr = (void *)CONFIG_SYS_DEBUG_SERVER_FW_ADDR;
  48. #else
  49. #error "CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR not defined"
  50. #endif
  51. /* Check if Image is in FIT format */
  52. format = genimg_get_format(fit_hdr);
  53. if (format != IMAGE_FORMAT_FIT) {
  54. printf("Debug Server FW: Not a FIT image\n");
  55. goto out_error;
  56. }
  57. if (!fit_check_format(fit_hdr)) {
  58. printf("Debug Server FW: Bad FIT image format\n");
  59. goto out_error;
  60. }
  61. node_offset = fit_image_get_node(fit_hdr, uname);
  62. if (node_offset < 0) {
  63. printf("Debug Server FW:Can not find %s subimage\n", uname);
  64. goto out_error;
  65. }
  66. /* Verify Debug Server firmware image */
  67. if (!fit_image_verify(fit_hdr, node_offset)) {
  68. printf("Debug Server FW: Bad Debug Server firmware hash");
  69. goto out_error;
  70. }
  71. if (fit_get_desc(fit_hdr, node_offset, &desc) < 0) {
  72. printf("Debug Server FW: Failed to get FW description");
  73. goto out_error;
  74. }
  75. debug_server_ver_info = strstr(desc, "Version");
  76. debug_server_ver_info_major = strtok(debug_server_ver_info, ".");
  77. debug_server_ver_info_minor = strtok(NULL, ".");
  78. debug_server_ver_info_maj =
  79. simple_strtoul(debug_server_ver_info_major, NULL, 10);
  80. debug_server_ver_info_min =
  81. simple_strtoul(debug_server_ver_info_minor, NULL, 10);
  82. /* Debug server version checking */
  83. if ((debug_server_ver_info_maj < DEBUG_SERVER_VER_MAJOR) ||
  84. (debug_server_ver_info_min < DEBUG_SERVER_VER_MINOR)) {
  85. printf("Debug server FW mismatches the min version required\n");
  86. printf("Expected:%d.%d, Got %d.%d\n",
  87. DEBUG_SERVER_VER_MAJOR, DEBUG_SERVER_VER_MINOR,
  88. debug_server_ver_info_maj,
  89. debug_server_ver_info_min);
  90. goto out_error;
  91. }
  92. /* Get address and size of raw image */
  93. fit_image_get_data(fit_hdr, node_offset, &data, &size);
  94. *raw_image_addr = data;
  95. *raw_image_size = size;
  96. return 0;
  97. out_error:
  98. return -1;
  99. }
  100. /**
  101. * Return the actual size of the Debug Server private DRAM block.
  102. *
  103. * NOTE: For now this function always returns the minimum required size,
  104. * However, in the future, the actual size may be obtained from an environment
  105. * variable.
  106. */
  107. unsigned long debug_server_get_dram_block_size(void)
  108. {
  109. return CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE;
  110. }
  111. int debug_server_init(void)
  112. {
  113. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  114. int error, timeout = CONFIG_SYS_DEBUG_SERVER_TIMEOUT;
  115. int debug_server_boot_status;
  116. u64 debug_server_ram_addr, debug_server_ram_size;
  117. const void *raw_image_addr;
  118. size_t raw_image_size = 0;
  119. debug("debug_server_init called\n");
  120. /*
  121. * The Debug Server private DRAM block was already carved at the end of
  122. * DRAM by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
  123. */
  124. debug_server_ram_size = debug_server_get_dram_block_size();
  125. if (gd->bd->bi_dram[1].start)
  126. debug_server_ram_addr =
  127. gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
  128. else
  129. debug_server_ram_addr =
  130. gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
  131. #ifdef CONFIG_FSL_MC_ENET
  132. debug_server_ram_addr += mc_get_dram_block_size();
  133. #endif
  134. error = debug_server_parse_firmware_fit_image(&raw_image_addr,
  135. &raw_image_size);
  136. if (error != 0)
  137. goto out;
  138. debug("debug server (ram addr = 0x%llx, ram size = 0x%llx)\n",
  139. debug_server_ram_addr, debug_server_ram_size);
  140. /*
  141. * Load the Debug Server FW at the beginning of the Debug Server
  142. * private DRAM block:
  143. */
  144. debug_server_copy_image("Debug Server Firmware",
  145. (u64)raw_image_addr, raw_image_size,
  146. debug_server_ram_addr);
  147. /* flush dcache */
  148. flush_dcache_range((unsigned long)debug_server_ram_addr,
  149. (unsigned long)debug_server_ram_addr +
  150. (unsigned long)debug_server_ram_size);
  151. /*
  152. * Tell SP that the Debug Server FW is about to be launched. Before that
  153. * populate the following:
  154. * 1. Write the size allocated to SP Memory region into Bits {31:16} of
  155. * SCRATCHRW5.
  156. * 2. Write the start address of the SP memory regions into
  157. * SCRATCHRW5 (Bits {15:0}, contain most significant bits, Bits
  158. * {47:32} of the SP Memory Region physical start address
  159. * (SoC address)) and SCRATCHRW6 (Bits {31:0}).
  160. * 3. To know the Debug Server FW boot status, set bit 0 of SCRATCHRW11
  161. * to 1. The Debug Server sets this to 0 to indicate a
  162. * successul boot.
  163. * 4. Wakeup SP by writing 0x1F to VSG GIC reg VIGR2.
  164. */
  165. /* 512 MB */
  166. out_le32(&gur->scratchrw[5 - 1],
  167. (u32)((u64)debug_server_ram_addr >> 32) | (0x000D << 16));
  168. out_le32(&gur->scratchrw[6 - 1],
  169. ((u32)debug_server_ram_addr) & 0xFFFFFFFF);
  170. out_le32(&gur->scratchrw[11 - 1], DEBUG_SERVER_INIT_STATUS);
  171. /* Allow the changes to reflect in GUR block */
  172. mb();
  173. /*
  174. * Program VGIC to raise an interrupt to SP
  175. */
  176. out_le32(CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2, 0x1F);
  177. /* Allow the changes to reflect in VIGR2 */
  178. mb();
  179. dmb();
  180. debug("Polling for Debug server to launch ...\n");
  181. while (1) {
  182. debug_server_boot_status = in_le32(&gur->scratchrw[11 - 1]);
  183. if (!(debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK))
  184. break;
  185. udelay(1); /* throttle polling */
  186. if (timeout-- <= 0)
  187. break;
  188. }
  189. if (timeout <= 0) {
  190. printf("Debug Server FW timed out (boot status: 0x%x)\n",
  191. debug_server_boot_status);
  192. error = -ETIMEDOUT;
  193. goto out;
  194. }
  195. if (debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK) {
  196. printf("Debug server FW error'ed out (boot status: 0x%x)\n",
  197. debug_server_boot_status);
  198. error = -ENODEV;
  199. goto out;
  200. }
  201. printf("Debug server booted\n");
  202. printf("Detected firmware %d.%d, (boot status: 0x0%x)\n",
  203. debug_server_ver_info_maj, debug_server_ver_info_min,
  204. debug_server_boot_status);
  205. out:
  206. if (error != 0)
  207. debug_server_boot_status = -error;
  208. else
  209. debug_server_boot_status = 0;
  210. return debug_server_boot_status;
  211. }