ppa.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2016 NXP Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <log.h>
  7. #include <malloc.h>
  8. #include <config.h>
  9. #include <errno.h>
  10. #include <asm/cache.h>
  11. #include <asm/global_data.h>
  12. #include <asm/system.h>
  13. #include <asm/types.h>
  14. #include <asm/arch/soc.h>
  15. #ifdef CONFIG_FSL_LSCH3
  16. #include <asm/arch/immap_lsch3.h>
  17. #elif defined(CONFIG_FSL_LSCH2)
  18. #include <asm/arch/immap_lsch2.h>
  19. #endif
  20. #if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT)
  21. #include <asm/armv8/sec_firmware.h>
  22. #endif
  23. #ifdef CONFIG_CHAIN_OF_TRUST
  24. #include <fsl_validate.h>
  25. #endif
  26. #ifdef CONFIG_SYS_LS_PPA_FW_IN_NAND
  27. #include <nand.h>
  28. #elif defined(CONFIG_SYS_LS_PPA_FW_IN_MMC)
  29. #include <mmc.h>
  30. #endif
  31. DECLARE_GLOBAL_DATA_PTR;
  32. int ppa_init(void)
  33. {
  34. unsigned int el = current_el();
  35. void *ppa_fit_addr;
  36. u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
  37. u32 *loadable_l, *loadable_h;
  38. int ret;
  39. #ifdef CONFIG_CHAIN_OF_TRUST
  40. uintptr_t ppa_esbc_hdr = 0;
  41. uintptr_t ppa_img_addr = 0;
  42. #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
  43. defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
  44. void *ppa_hdr_ddr;
  45. #endif
  46. #endif
  47. /* Skip if running at lower exception level */
  48. if (el < 3) {
  49. debug("Skipping PPA init, running at EL%d\n", el);
  50. return 0;
  51. }
  52. #ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP
  53. ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
  54. debug("%s: PPA image load from XIP\n", __func__);
  55. #ifdef CONFIG_CHAIN_OF_TRUST
  56. ppa_esbc_hdr = CONFIG_SYS_LS_PPA_ESBC_ADDR;
  57. #endif
  58. #else /* !CONFIG_SYS_LS_PPA_FW_IN_XIP */
  59. size_t fw_length, fdt_header_len = sizeof(struct fdt_header);
  60. /* Copy PPA image from MMC/SD/NAND to allocated memory */
  61. #ifdef CONFIG_SYS_LS_PPA_FW_IN_MMC
  62. struct mmc *mmc;
  63. int dev = CONFIG_SYS_MMC_ENV_DEV;
  64. struct fdt_header *fitp;
  65. u32 cnt;
  66. u32 blk;
  67. debug("%s: PPA image load from eMMC/SD\n", __func__);
  68. ret = mmc_initialize(gd->bd);
  69. if (ret) {
  70. printf("%s: mmc_initialize() failed\n", __func__);
  71. return ret;
  72. }
  73. mmc = find_mmc_device(dev);
  74. if (!mmc) {
  75. printf("PPA: MMC cannot find device for PPA firmware\n");
  76. return -ENODEV;
  77. }
  78. ret = mmc_init(mmc);
  79. if (ret) {
  80. printf("%s: mmc_init() failed\n", __func__);
  81. return ret;
  82. }
  83. fitp = malloc(roundup(fdt_header_len, 512));
  84. if (!fitp) {
  85. printf("PPA: malloc failed for FIT header(size 0x%zx)\n",
  86. roundup(fdt_header_len, 512));
  87. return -ENOMEM;
  88. }
  89. blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
  90. cnt = DIV_ROUND_UP(fdt_header_len, 512);
  91. debug("%s: MMC read PPA FIT header: dev # %u, block # %u, count %u\n",
  92. __func__, dev, blk, cnt);
  93. ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, fitp);
  94. if (ret != cnt) {
  95. free(fitp);
  96. printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n",
  97. CONFIG_SYS_LS_PPA_FW_ADDR);
  98. return -EIO;
  99. }
  100. ret = fdt_check_header(fitp);
  101. if (ret) {
  102. free(fitp);
  103. printf("%s: fdt_check_header() failed\n", __func__);
  104. return ret;
  105. }
  106. #ifdef CONFIG_CHAIN_OF_TRUST
  107. ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE);
  108. if (!ppa_hdr_ddr) {
  109. printf("PPA: malloc failed for PPA header\n");
  110. return -ENOMEM;
  111. }
  112. blk = CONFIG_SYS_LS_PPA_ESBC_ADDR >> 9;
  113. cnt = DIV_ROUND_UP(CONFIG_LS_PPA_ESBC_HDR_SIZE, 512);
  114. ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, ppa_hdr_ddr);
  115. if (ret != cnt) {
  116. free(ppa_hdr_ddr);
  117. printf("MMC/SD read of PPA header failed\n");
  118. return -EIO;
  119. }
  120. debug("Read PPA header to 0x%p\n", ppa_hdr_ddr);
  121. ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr;
  122. #endif
  123. fw_length = fdt_totalsize(fitp);
  124. free(fitp);
  125. fw_length = roundup(fw_length, 512);
  126. ppa_fit_addr = malloc(fw_length);
  127. if (!ppa_fit_addr) {
  128. printf("PPA: malloc failed for PPA image(size 0x%zx)\n",
  129. fw_length);
  130. return -ENOMEM;
  131. }
  132. blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
  133. cnt = DIV_ROUND_UP(fw_length, 512);
  134. debug("%s: MMC read PPA FIT image: dev # %u, block # %u, count %u\n",
  135. __func__, dev, blk, cnt);
  136. ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, ppa_fit_addr);
  137. if (ret != cnt) {
  138. free(ppa_fit_addr);
  139. printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n",
  140. CONFIG_SYS_LS_PPA_FW_ADDR);
  141. return -EIO;
  142. }
  143. #elif defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
  144. struct fdt_header fit;
  145. debug("%s: PPA image load from NAND\n", __func__);
  146. nand_init();
  147. ret = nand_read(get_nand_dev_by_index(0),
  148. (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR,
  149. &fdt_header_len, (u_char *)&fit);
  150. if (ret == -EUCLEAN) {
  151. printf("NAND read of PPA FIT header at offset 0x%x failed\n",
  152. CONFIG_SYS_LS_PPA_FW_ADDR);
  153. return -EIO;
  154. }
  155. ret = fdt_check_header(&fit);
  156. if (ret) {
  157. printf("%s: fdt_check_header() failed\n", __func__);
  158. return ret;
  159. }
  160. #ifdef CONFIG_CHAIN_OF_TRUST
  161. ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE);
  162. if (!ppa_hdr_ddr) {
  163. printf("PPA: malloc failed for PPA header\n");
  164. return -ENOMEM;
  165. }
  166. fw_length = CONFIG_LS_PPA_ESBC_HDR_SIZE;
  167. ret = nand_read(get_nand_dev_by_index(0),
  168. (loff_t)CONFIG_SYS_LS_PPA_ESBC_ADDR,
  169. &fw_length, (u_char *)ppa_hdr_ddr);
  170. if (ret == -EUCLEAN) {
  171. free(ppa_hdr_ddr);
  172. printf("NAND read of PPA firmware at offset 0x%x failed\n",
  173. CONFIG_SYS_LS_PPA_FW_ADDR);
  174. return -EIO;
  175. }
  176. debug("Read PPA header to 0x%p\n", ppa_hdr_ddr);
  177. ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr;
  178. #endif
  179. fw_length = fdt_totalsize(&fit);
  180. ppa_fit_addr = malloc(fw_length);
  181. if (!ppa_fit_addr) {
  182. printf("PPA: malloc failed for PPA image(size 0x%zx)\n",
  183. fw_length);
  184. return -ENOMEM;
  185. }
  186. ret = nand_read(get_nand_dev_by_index(0),
  187. (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR,
  188. &fw_length, (u_char *)ppa_fit_addr);
  189. if (ret == -EUCLEAN) {
  190. free(ppa_fit_addr);
  191. printf("NAND read of PPA firmware at offset 0x%x failed\n",
  192. CONFIG_SYS_LS_PPA_FW_ADDR);
  193. return -EIO;
  194. }
  195. #else
  196. #error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined"
  197. #endif
  198. #endif
  199. #ifdef CONFIG_CHAIN_OF_TRUST
  200. ppa_img_addr = (uintptr_t)ppa_fit_addr;
  201. if (fsl_check_boot_mode_secure() != 0) {
  202. /*
  203. * In case of failure in validation, fsl_secboot_validate
  204. * would not return back in case of Production environment
  205. * with ITS=1. In Development environment (ITS=0 and
  206. * SB_EN=1), the function may return back in case of
  207. * non-fatal failures.
  208. */
  209. ret = fsl_secboot_validate(ppa_esbc_hdr,
  210. PPA_KEY_HASH,
  211. &ppa_img_addr);
  212. if (ret != 0)
  213. printf("SEC firmware(s) validation failed\n");
  214. else
  215. printf("SEC firmware(s) validation Successful\n");
  216. }
  217. #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
  218. defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
  219. free(ppa_hdr_ddr);
  220. #endif
  221. #endif
  222. #ifdef CONFIG_FSL_LSCH3
  223. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  224. boot_loc_ptr_l = &gur->bootlocptrl;
  225. boot_loc_ptr_h = &gur->bootlocptrh;
  226. /* Assign addresses to loadable ptrs */
  227. loadable_l = &gur->scratchrw[4];
  228. loadable_h = &gur->scratchrw[5];
  229. #elif defined(CONFIG_FSL_LSCH2)
  230. struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR);
  231. boot_loc_ptr_l = &scfg->scratchrw[1];
  232. boot_loc_ptr_h = &scfg->scratchrw[0];
  233. /* Assign addresses to loadable ptrs */
  234. loadable_l = &scfg->scratchrw[2];
  235. loadable_h = &scfg->scratchrw[3];
  236. #endif
  237. debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n",
  238. boot_loc_ptr_l, boot_loc_ptr_h);
  239. ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h,
  240. loadable_l, loadable_h);
  241. #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
  242. defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
  243. free(ppa_fit_addr);
  244. #endif
  245. return ret;
  246. }