ppa.c 7.1 KB

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