imx_sip_handler.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * Copyright 2019 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <arch.h>
  7. #include <stdlib.h>
  8. #include <stdint.h>
  9. #include <services/std_svc.h>
  10. #include <string.h>
  11. #include <common/build_message.h>
  12. #include <common/debug.h>
  13. #include <common/runtime_svc.h>
  14. #include <platform_def.h>
  15. #include <imx_sip_svc.h>
  16. #include <lib/el3_runtime/context_mgmt.h>
  17. #include <lib/mmio.h>
  18. #include <sci/sci.h>
  19. #if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
  20. /*
  21. * Defined in
  22. * table 11. ROM event log buffer address location
  23. * AN12853 "i.MX ROMs Log Events"
  24. */
  25. #define ROM_LOG_BUFFER_ADDR 0x9E0
  26. #endif
  27. #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
  28. #ifdef PLAT_imx8qm
  29. static const int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
  30. SC_R_A53, SC_R_A72,
  31. };
  32. #endif
  33. static int imx_srtc_set_time(uint32_t year_mon,
  34. unsigned long day_hour,
  35. unsigned long min_sec)
  36. {
  37. return sc_timer_set_rtc_time(ipc_handle,
  38. year_mon >> 16, year_mon & 0xffff,
  39. day_hour >> 16, day_hour & 0xffff,
  40. min_sec >> 16, min_sec & 0xffff);
  41. }
  42. int imx_srtc_handler(uint32_t smc_fid,
  43. void *handle,
  44. u_register_t x1,
  45. u_register_t x2,
  46. u_register_t x3,
  47. u_register_t x4)
  48. {
  49. int ret;
  50. switch (x1) {
  51. case IMX_SIP_SRTC_SET_TIME:
  52. ret = imx_srtc_set_time(x2, x3, x4);
  53. break;
  54. default:
  55. ret = SMC_UNK;
  56. }
  57. SMC_RET1(handle, ret);
  58. }
  59. static void imx_cpufreq_set_target(uint32_t cluster_id, unsigned long freq)
  60. {
  61. sc_pm_clock_rate_t rate = (sc_pm_clock_rate_t)freq;
  62. #ifdef PLAT_imx8qm
  63. sc_pm_set_clock_rate(ipc_handle, ap_cluster_index[cluster_id], SC_PM_CLK_CPU, &rate);
  64. #endif
  65. #ifdef PLAT_imx8qx
  66. sc_pm_set_clock_rate(ipc_handle, SC_R_A35, SC_PM_CLK_CPU, &rate);
  67. #endif
  68. }
  69. int imx_cpufreq_handler(uint32_t smc_fid,
  70. u_register_t x1,
  71. u_register_t x2,
  72. u_register_t x3)
  73. {
  74. switch (x1) {
  75. case IMX_SIP_SET_CPUFREQ:
  76. imx_cpufreq_set_target(x2, x3);
  77. break;
  78. default:
  79. return SMC_UNK;
  80. }
  81. return 0;
  82. }
  83. static bool wakeup_src_irqsteer;
  84. bool imx_is_wakeup_src_irqsteer(void)
  85. {
  86. return wakeup_src_irqsteer;
  87. }
  88. int imx_wakeup_src_handler(uint32_t smc_fid,
  89. u_register_t x1,
  90. u_register_t x2,
  91. u_register_t x3)
  92. {
  93. switch (x1) {
  94. case IMX_SIP_WAKEUP_SRC_IRQSTEER:
  95. wakeup_src_irqsteer = true;
  96. break;
  97. case IMX_SIP_WAKEUP_SRC_SCU:
  98. wakeup_src_irqsteer = false;
  99. break;
  100. default:
  101. return SMC_UNK;
  102. }
  103. return SMC_OK;
  104. }
  105. int imx_otp_handler(uint32_t smc_fid,
  106. void *handle,
  107. u_register_t x1,
  108. u_register_t x2)
  109. {
  110. int ret;
  111. uint32_t fuse;
  112. switch (smc_fid) {
  113. case IMX_SIP_OTP_READ:
  114. ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse);
  115. SMC_RET2(handle, ret, fuse);
  116. break;
  117. case IMX_SIP_OTP_WRITE:
  118. ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2);
  119. SMC_RET1(handle, ret);
  120. break;
  121. default:
  122. ret = SMC_UNK;
  123. SMC_RET1(handle, ret);
  124. break;
  125. }
  126. return ret;
  127. }
  128. int imx_misc_set_temp_handler(uint32_t smc_fid,
  129. u_register_t x1,
  130. u_register_t x2,
  131. u_register_t x3,
  132. u_register_t x4)
  133. {
  134. return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4);
  135. }
  136. #endif /* defined(PLAT_imx8qm) || defined(PLAT_imx8qx) */
  137. #if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
  138. int imx_src_handler(uint32_t smc_fid,
  139. u_register_t x1,
  140. u_register_t x2,
  141. u_register_t x3,
  142. void *handle)
  143. {
  144. uint32_t val;
  145. switch (x1) {
  146. case IMX_SIP_SRC_SET_SECONDARY_BOOT:
  147. if (x2 != 0U) {
  148. mmio_setbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET,
  149. SRC_GPR10_PERSIST_SECONDARY_BOOT);
  150. } else {
  151. mmio_clrbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET,
  152. SRC_GPR10_PERSIST_SECONDARY_BOOT);
  153. }
  154. break;
  155. case IMX_SIP_SRC_IS_SECONDARY_BOOT:
  156. val = mmio_read_32(IMX_SRC_BASE + SRC_GPR10_OFFSET);
  157. return !!(val & SRC_GPR10_PERSIST_SECONDARY_BOOT);
  158. default:
  159. return SMC_UNK;
  160. };
  161. return 0;
  162. }
  163. #endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */
  164. #if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
  165. static bool is_secondary_boot(void)
  166. {
  167. uint32_t *rom_log_addr = (uint32_t *)ROM_LOG_BUFFER_ADDR;
  168. bool is_secondary = false;
  169. uint32_t *rom_log;
  170. uint8_t event_id;
  171. /* If the ROM event log pointer is not valid. */
  172. if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xB00000 ||
  173. *rom_log_addr & 0x3) {
  174. return false;
  175. }
  176. /* Parse the ROM event ID version 2 log */
  177. rom_log = (uint32_t *)(uintptr_t)(*rom_log_addr);
  178. for (size_t i = 0; i < 128; i++) {
  179. event_id = rom_log[i] >> 24;
  180. switch (event_id) {
  181. case 0x00: /* End of list */
  182. return is_secondary;
  183. /* Log entries with 1 parameter, skip 1 */
  184. case 0x80: /* Perform the device initialization */
  185. case 0x81: /* The boot device initialization completes */
  186. case 0x82: /* Execute boot device driver pre-config */
  187. case 0x8F: /* The boot device initialization fails */
  188. case 0x90: /* Start to read data from boot device */
  189. case 0x91: /* Reading data from boot device completes */
  190. case 0x9F: /* Reading data from boot device fails */
  191. i += 1;
  192. continue;
  193. /* Log entries with 2 parameters, skip 2 */
  194. case 0xA0: /* Image authentication result */
  195. case 0xC0: /* Jump to the boot image soon */
  196. i += 2;
  197. continue;
  198. /* Booted the primary boot image */
  199. case 0x50:
  200. is_secondary = false;
  201. continue;
  202. /* Booted the secondary boot image */
  203. case 0x51:
  204. is_secondary = true;
  205. continue;
  206. }
  207. }
  208. return is_secondary;
  209. }
  210. int imx_src_handler(uint32_t smc_fid,
  211. u_register_t x1,
  212. u_register_t x2,
  213. u_register_t x3,
  214. void *handle)
  215. {
  216. switch (x1) {
  217. case IMX_SIP_SRC_SET_SECONDARY_BOOT:
  218. /* we do support that on these SoCs */
  219. break;
  220. case IMX_SIP_SRC_IS_SECONDARY_BOOT:
  221. return is_secondary_boot();
  222. default:
  223. return SMC_UNK;
  224. };
  225. return 0;
  226. }
  227. #endif /* defined(PLAT_imx8mn) || defined(PLAT_imx8mp) */
  228. static uint64_t imx_get_commit_hash(u_register_t x2,
  229. u_register_t x3,
  230. u_register_t x4)
  231. {
  232. /* Parse the version_string */
  233. char *parse = (char *)build_version_string;
  234. uint64_t hash = 0;
  235. do {
  236. parse = strchr(parse, '-');
  237. if (parse) {
  238. parse += 1;
  239. if (*(parse) == 'g') {
  240. /* Default is 7 hexadecimal digits */
  241. memcpy((void *)&hash, (void *)(parse + 1), 7);
  242. break;
  243. }
  244. }
  245. } while (parse != NULL);
  246. return hash;
  247. }
  248. uint64_t imx_buildinfo_handler(uint32_t smc_fid,
  249. u_register_t x1,
  250. u_register_t x2,
  251. u_register_t x3,
  252. u_register_t x4)
  253. {
  254. uint64_t ret;
  255. switch (x1) {
  256. case IMX_SIP_BUILDINFO_GET_COMMITHASH:
  257. ret = imx_get_commit_hash(x2, x3, x4);
  258. break;
  259. default:
  260. return SMC_UNK;
  261. }
  262. return ret;
  263. }
  264. int imx_kernel_entry_handler(uint32_t smc_fid,
  265. u_register_t x1,
  266. u_register_t x2,
  267. u_register_t x3,
  268. u_register_t x4)
  269. {
  270. static entry_point_info_t bl33_image_ep_info;
  271. entry_point_info_t *next_image_info;
  272. unsigned int mode;
  273. if (x1 < (PLAT_NS_IMAGE_OFFSET & 0xF0000000))
  274. return SMC_UNK;
  275. mode = MODE32_svc;
  276. next_image_info = &bl33_image_ep_info;
  277. next_image_info->pc = x1;
  278. next_image_info->spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
  279. (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
  280. next_image_info->args.arg0 = 0;
  281. next_image_info->args.arg1 = 0;
  282. next_image_info->args.arg2 = x3;
  283. SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
  284. cm_init_my_context(next_image_info);
  285. cm_prepare_el3_exit(NON_SECURE);
  286. return 0;
  287. }
  288. #if defined(PLAT_imx8ulp)
  289. int imx_hifi_xrdc(uint32_t smc_fid)
  290. {
  291. mmio_setbits_32(IMX_SIM2_BASE + 0x8, BIT_32(19) | BIT_32(17) | BIT_32(18));
  292. mmio_clrbits_32(IMX_SIM2_BASE + 0x8, BIT_32(16));
  293. extern int xrdc_apply_hifi_config(void);
  294. xrdc_apply_hifi_config();
  295. return 0;
  296. }
  297. #endif