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/cache.h>
  10. #include <asm/system.h>
  11. #include <asm/types.h>
  12. #include <asm/arch/soc.h>
  13. #ifdef CONFIG_FSL_LSCH3
  14. #include <asm/arch/immap_lsch3.h>
  15. #elif defined(CONFIG_FSL_LSCH2)
  16. #include <asm/arch/immap_lsch2.h>
  17. #endif
  18. #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
  19. #include <asm/armv8/sec_firmware.h>
  20. #endif
  21. #ifdef CONFIG_CHAIN_OF_TRUST
  22. #include <fsl_validate.h>
  23. #endif
  24. #ifdef CONFIG_SYS_LS_PPA_FW_IN_NAND
  25. #include <nand.h>
  26. #elif defined(CONFIG_SYS_LS_PPA_FW_IN_MMC)
  27. #include <mmc.h>
  28. #endif
  29. DECLARE_GLOBAL_DATA_PTR;
  30. int ppa_init(void)
  31. {
  32. unsigned int el = current_el();
  33. void *ppa_fit_addr;
  34. u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
  35. u32 *loadable_l, *loadable_h;
  36. int ret;
  37. #ifdef CONFIG_CHAIN_OF_TRUST
  38. uintptr_t ppa_esbc_hdr = 0;
  39. uintptr_t ppa_img_addr = 0;
  40. #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
  41. defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
  42. void *ppa_hdr_ddr;
  43. #endif
  44. #endif
  45. /* Skip if running at lower exception level */
  46. if (el < 3) {
  47. debug("Skipping PPA init, running at EL%d\n", el);
  48. return 0;
  49. }
  50. #ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP
  51. ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
  52. debug("%s: PPA image load from XIP\n", __func__);
  53. #ifdef CONFIG_CHAIN_OF_TRUST
  54. ppa_esbc_hdr = CONFIG_SYS_LS_PPA_ESBC_ADDR;
  55. #endif
  56. #else /* !CONFIG_SYS_LS_PPA_FW_IN_XIP */
  57. size_t fw_length, fdt_header_len = sizeof(struct fdt_header);
  58. /* Copy PPA image from MMC/SD/NAND to allocated memory */
  59. #ifdef CONFIG_SYS_LS_PPA_FW_IN_MMC
  60. struct mmc *mmc;
  61. int dev = CONFIG_SYS_MMC_ENV_DEV;
  62. struct fdt_header *fitp;
  63. u32 cnt;
  64. u32 blk;
  65. debug("%s: PPA image load from eMMC/SD\n", __func__);
  66. ret = mmc_initialize(gd->bd);
  67. if (ret) {
  68. printf("%s: mmc_initialize() failed\n", __func__);
  69. return ret;
  70. }
  71. mmc = find_mmc_device(dev);
  72. if (!mmc) {
  73. printf("PPA: MMC cannot find device for PPA firmware\n");
  74. return -ENODEV;
  75. }
  76. ret = mmc_init(mmc);
  77. if (ret) {
  78. printf("%s: mmc_init() failed\n", __func__);
  79. return ret;
  80. }
  81. fitp = malloc(roundup(fdt_header_len, 512));
  82. if (!fitp) {
  83. printf("PPA: malloc failed for FIT header(size 0x%zx)\n",
  84. roundup(fdt_header_len, 512));
  85. return -ENOMEM;
  86. }
  87. blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
  88. cnt = DIV_ROUND_UP(fdt_header_len, 512);
  89. debug("%s: MMC read PPA FIT header: dev # %u, block # %u, count %u\n",
  90. __func__, dev, blk, cnt);
  91. ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, fitp);
  92. if (ret != cnt) {
  93. free(fitp);
  94. printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n",
  95. CONFIG_SYS_LS_PPA_FW_ADDR);
  96. return -EIO;
  97. }
  98. ret = fdt_check_header(fitp);
  99. if (ret) {
  100. free(fitp);
  101. printf("%s: fdt_check_header() failed\n", __func__);
  102. return ret;
  103. }
  104. #ifdef CONFIG_CHAIN_OF_TRUST
  105. ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE);
  106. if (!ppa_hdr_ddr) {
  107. printf("PPA: malloc failed for PPA header\n");
  108. return -ENOMEM;
  109. }
  110. blk = CONFIG_SYS_LS_PPA_ESBC_ADDR >> 9;
  111. cnt = DIV_ROUND_UP(CONFIG_LS_PPA_ESBC_HDR_SIZE, 512);
  112. ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, ppa_hdr_ddr);
  113. if (ret != cnt) {
  114. free(ppa_hdr_ddr);
  115. printf("MMC/SD read of PPA header failed\n");
  116. return -EIO;
  117. }
  118. debug("Read PPA header to 0x%p\n", ppa_hdr_ddr);
  119. ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr;
  120. #endif
  121. fw_length = fdt_totalsize(fitp);
  122. free(fitp);
  123. fw_length = roundup(fw_length, 512);
  124. ppa_fit_addr = malloc(fw_length);
  125. if (!ppa_fit_addr) {
  126. printf("PPA: malloc failed for PPA image(size 0x%zx)\n",
  127. fw_length);
  128. return -ENOMEM;
  129. }
  130. blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
  131. cnt = DIV_ROUND_UP(fw_length, 512);
  132. debug("%s: MMC read PPA FIT image: dev # %u, block # %u, count %u\n",
  133. __func__, dev, blk, cnt);
  134. ret = blk_dread(mmc_get_blk_desc(mmc), 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. }