ppa.c 7.1 KB

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