fsl_chain_of_trust.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2015 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <fsl_validate.h>
  8. #include <fsl_secboot_err.h>
  9. #include <fsl_sfp.h>
  10. #include <dm/root.h>
  11. #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_FRAMEWORK)
  12. #include <spl.h>
  13. #endif
  14. #ifdef CONFIG_ADDR_MAP
  15. #include <asm/mmu.h>
  16. #endif
  17. #ifdef CONFIG_FSL_CORENET
  18. #include <asm/fsl_pamu.h>
  19. #endif
  20. #ifdef CONFIG_ARCH_LS1021A
  21. #include <asm/arch/immap_ls102xa.h>
  22. #endif
  23. #if defined(CONFIG_MPC85xx)
  24. #define CONFIG_DCFG_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
  25. #else
  26. #define CONFIG_DCFG_ADDR CONFIG_SYS_FSL_GUTS_ADDR
  27. #endif
  28. #ifdef CONFIG_SYS_FSL_CCSR_GUR_LE
  29. #define gur_in32(a) in_le32(a)
  30. #else
  31. #define gur_in32(a) in_be32(a)
  32. #endif
  33. /* Check the Boot Mode. If Secure, return 1 else return 0 */
  34. int fsl_check_boot_mode_secure(void)
  35. {
  36. uint32_t val;
  37. struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
  38. struct ccsr_gur __iomem *gur = (void *)(CONFIG_DCFG_ADDR);
  39. val = sfp_in32(&sfp_regs->ospr) & ITS_MASK;
  40. if (val == ITS_MASK)
  41. return 1;
  42. #if defined(CONFIG_FSL_CORENET) || !defined(CONFIG_MPC85xx)
  43. /* For PBL based platforms check the SB_EN bit in RCWSR */
  44. val = gur_in32(&gur->rcwsr[RCW_SB_EN_REG_INDEX - 1]) & RCW_SB_EN_MASK;
  45. if (val == RCW_SB_EN_MASK)
  46. return 1;
  47. #endif
  48. #if defined(CONFIG_MPC85xx) && !defined(CONFIG_FSL_CORENET)
  49. /* For Non-PBL Platforms, check the Device Status register 2*/
  50. val = gur_in32(&gur->pordevsr2) & MPC85xx_PORDEVSR2_SBC_MASK;
  51. if (val != MPC85xx_PORDEVSR2_SBC_MASK)
  52. return 1;
  53. #endif
  54. return 0;
  55. }
  56. #ifndef CONFIG_SPL_BUILD
  57. int fsl_setenv_chain_of_trust(void)
  58. {
  59. /* Check Boot Mode
  60. * If Boot Mode is Non-Secure, no changes are required
  61. */
  62. if (fsl_check_boot_mode_secure() == 0)
  63. return 0;
  64. /* If Boot mode is Secure, set the environment variables
  65. * bootdelay = 0 (To disable Boot Prompt)
  66. * bootcmd = CONFIG_CHAIN_BOOT_CMD (Validate and execute Boot script)
  67. */
  68. env_set("bootdelay", "0");
  69. #ifdef CONFIG_ARM
  70. env_set("secureboot", "y");
  71. #else
  72. env_set("bootcmd", CONFIG_CHAIN_BOOT_CMD);
  73. #endif
  74. return 0;
  75. }
  76. #endif
  77. #ifdef CONFIG_SPL_BUILD
  78. void spl_validate_uboot(uint32_t hdr_addr, uintptr_t img_addr)
  79. {
  80. int res;
  81. /*
  82. * Check Boot Mode
  83. * If Boot Mode is Non-Secure, skip validation
  84. */
  85. if (fsl_check_boot_mode_secure() == 0)
  86. return;
  87. printf("SPL: Validating U-Boot image\n");
  88. #ifdef CONFIG_ADDR_MAP
  89. init_addr_map();
  90. #endif
  91. #ifdef CONFIG_FSL_CORENET
  92. if (pamu_init() < 0)
  93. fsl_secboot_handle_error(ERROR_ESBC_PAMU_INIT);
  94. #endif
  95. #ifdef CONFIG_FSL_CAAM
  96. if (sec_init() < 0)
  97. fsl_secboot_handle_error(ERROR_ESBC_SEC_INIT);
  98. #endif
  99. /*
  100. * dm_init_and_scan() is called as part of common SPL framework, so no
  101. * need to call it again but in case of powerpc platforms which currently
  102. * do not use common SPL framework, so need to call this function here.
  103. */
  104. #if defined(CONFIG_SPL_DM) && (!defined(CONFIG_SPL_FRAMEWORK))
  105. dm_init_and_scan(true);
  106. #endif
  107. res = fsl_secboot_validate(hdr_addr, CONFIG_SPL_UBOOT_KEY_HASH,
  108. &img_addr);
  109. if (res == 0)
  110. printf("SPL: Validation of U-boot successful\n");
  111. }
  112. #ifdef CONFIG_SPL_FRAMEWORK
  113. /* Override weak funtion defined in SPL framework to enable validation
  114. * of main u-boot image before jumping to u-boot image.
  115. */
  116. void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
  117. {
  118. typedef void __noreturn (*image_entry_noargs_t)(void);
  119. uint32_t hdr_addr;
  120. image_entry_noargs_t image_entry =
  121. (image_entry_noargs_t)(unsigned long)spl_image->entry_point;
  122. hdr_addr = (spl_image->entry_point + spl_image->size -
  123. CONFIG_U_BOOT_HDR_SIZE);
  124. spl_validate_uboot(hdr_addr, (uintptr_t)spl_image->entry_point);
  125. /*
  126. * In case of failure in validation, spl_validate_uboot would
  127. * not return back in case of Production environment with ITS=1.
  128. * Thus U-Boot will not start.
  129. * In Development environment (ITS=0 and SB_EN=1), the function
  130. * may return back in case of non-fatal failures.
  131. */
  132. debug("image entry point: 0x%lX\n", spl_image->entry_point);
  133. image_entry();
  134. }
  135. #endif /* ifdef CONFIG_SPL_FRAMEWORK */
  136. #endif /* ifdef CONFIG_SPL_BUILD */