bl31_plat_setup.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * Copyright (c) 2019-2024, ARM Limited and Contributors. All rights reserved.
  3. * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  4. * Copyright (c) 2024, Altera Corporation. All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include <assert.h>
  9. #include <arch.h>
  10. #include <arch_helpers.h>
  11. #include <common/bl_common.h>
  12. #include <drivers/arm/gic_common.h>
  13. #include <drivers/arm/gicv3.h>
  14. #include <drivers/ti/uart/uart_16550.h>
  15. #include <lib/mmio.h>
  16. #include <lib/xlat_tables/xlat_mmu_helpers.h>
  17. #include <lib/xlat_tables/xlat_tables_v2.h>
  18. #include <plat/common/platform.h>
  19. #include "agilex5_cache.h"
  20. #include "agilex5_power_manager.h"
  21. #include "ccu/ncore_ccu.h"
  22. #include "socfpga_mailbox.h"
  23. #include "socfpga_private.h"
  24. #include "socfpga_reset_manager.h"
  25. /* Get non-secure SPSR for BL33. Zephyr and Linux */
  26. uint32_t arm_get_spsr_for_bl33_entry(void);
  27. static entry_point_info_t bl32_image_ep_info;
  28. static entry_point_info_t bl33_image_ep_info;
  29. /* The GICv3 driver only needs to be initialized in EL3 */
  30. static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
  31. #define SMMU_SDMMC
  32. entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
  33. {
  34. entry_point_info_t *next_image_info;
  35. next_image_info = (type == NON_SECURE) ?
  36. &bl33_image_ep_info : &bl32_image_ep_info;
  37. /* None of the images on this platform can have 0x0 as the entrypoint */
  38. if (next_image_info->pc)
  39. return next_image_info;
  40. else
  41. return NULL;
  42. }
  43. void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
  44. u_register_t arg2, u_register_t arg3)
  45. {
  46. static console_t console;
  47. mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
  48. console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
  49. PLAT_BAUDRATE, &console);
  50. setup_smmu_stream_id();
  51. /*
  52. * Check params passed from BL31 should not be NULL,
  53. */
  54. void *from_bl2 = (void *) arg0;
  55. #if RESET_TO_BL31
  56. /* There are no parameters from BL2 if BL31 is a reset vector */
  57. assert(from_bl2 == NULL);
  58. void *plat_params_from_bl2 = (void *) arg3;
  59. assert(plat_params_from_bl2 == NULL);
  60. /* Populate entry point information for BL33 */
  61. SET_PARAM_HEAD(&bl33_image_ep_info,
  62. PARAM_EP,
  63. VERSION_1,
  64. 0);
  65. # if ARM_LINUX_KERNEL_AS_BL33
  66. /*
  67. * According to the file ``Documentation/arm64/booting.txt`` of the
  68. * Linux kernel tree, Linux expects the physical address of the device
  69. * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
  70. * must be 0.
  71. */
  72. bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
  73. bl33_image_ep_info.args.arg1 = 0U;
  74. bl33_image_ep_info.args.arg2 = 0U;
  75. bl33_image_ep_info.args.arg3 = 0U;
  76. # endif
  77. #else /* RESET_TO_BL31 */
  78. bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
  79. assert(params_from_bl2 != NULL);
  80. /*
  81. * Copy BL32 (if populated by BL31) and BL33 entry point information.
  82. * They are stored in Secure RAM, in BL31's address space.
  83. */
  84. if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
  85. params_from_bl2->h.version >= VERSION_2) {
  86. bl_params_node_t *bl_params = params_from_bl2->head;
  87. while (bl_params) {
  88. if (bl_params->image_id == BL33_IMAGE_ID) {
  89. bl33_image_ep_info = *bl_params->ep_info;
  90. }
  91. bl_params = bl_params->next_params_info;
  92. }
  93. } else {
  94. struct socfpga_bl31_params *arg_from_bl2 =
  95. (struct socfpga_bl31_params *) from_bl2;
  96. assert(arg_from_bl2->h.type == PARAM_BL31);
  97. assert(arg_from_bl2->h.version >= VERSION_1);
  98. bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
  99. bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
  100. }
  101. bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
  102. bl33_image_ep_info.args.arg1 = 0U;
  103. bl33_image_ep_info.args.arg2 = 0U;
  104. bl33_image_ep_info.args.arg3 = 0U;
  105. #endif
  106. /*
  107. * Tell BL31 where the non-trusted software image
  108. * is located and the entry state information
  109. */
  110. bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
  111. bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
  112. SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
  113. }
  114. static const interrupt_prop_t agx5_interrupt_props[] = {
  115. PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(INTR_GROUP1S),
  116. PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(INTR_GROUP0)
  117. };
  118. static const gicv3_driver_data_t plat_gicv3_gic_data = {
  119. .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
  120. .gicr_base = PLAT_INTEL_SOCFPGA_GICR_BASE,
  121. .interrupt_props = agx5_interrupt_props,
  122. .interrupt_props_num = ARRAY_SIZE(agx5_interrupt_props),
  123. .rdistif_num = PLATFORM_CORE_COUNT,
  124. .rdistif_base_addrs = rdistif_base_addrs,
  125. };
  126. /*******************************************************************************
  127. * Perform any BL3-1 platform setup code
  128. ******************************************************************************/
  129. void bl31_platform_setup(void)
  130. {
  131. socfpga_delay_timer_init();
  132. /* Initialize the gic cpu and distributor interfaces */
  133. gicv3_driver_init(&plat_gicv3_gic_data);
  134. gicv3_distif_init();
  135. gicv3_rdistif_init(plat_my_core_pos());
  136. gicv3_cpuif_enable(plat_my_core_pos());
  137. mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
  138. }
  139. const mmap_region_t plat_agilex_mmap[] = {
  140. MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
  141. MAP_REGION_FLAT(PSS_BASE, PSS_SIZE, MT_DEVICE | MT_RW | MT_NS),
  142. MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
  143. MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, MT_NON_CACHEABLE | MT_RW | MT_SECURE),
  144. MAP_REGION_FLAT(CCU_BASE, CCU_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
  145. MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS),
  146. MAP_REGION_FLAT(GIC_BASE, GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
  147. {0}
  148. };
  149. /*******************************************************************************
  150. * Perform the very early platform specific architectural setup here. At the
  151. * moment this is only initializes the mmu in a quick and dirty way.
  152. ******************************************************************************/
  153. void bl31_plat_arch_setup(void)
  154. {
  155. uint32_t boot_core = 0x00;
  156. uint32_t cpuid = 0x00;
  157. cpuid = MPIDR_AFFLVL1_VAL(read_mpidr());
  158. boot_core = ((mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00) >> 10);
  159. NOTICE("BL31: Boot Core = %x\n", boot_core);
  160. NOTICE("BL31: CPU ID = %x\n", cpuid);
  161. INFO("BL31: Invalidate Data cache\n");
  162. invalidate_dcache_all();
  163. }
  164. /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
  165. uintptr_t plat_get_ns_image_entrypoint(void)
  166. {
  167. #ifdef PRELOADED_BL33_BASE
  168. return PRELOADED_BL33_BASE;
  169. #else
  170. return PLAT_NS_IMAGE_OFFSET;
  171. #endif
  172. }
  173. /* Get non-secure SPSR for BL33. Zephyr and Linux */
  174. uint32_t arm_get_spsr_for_bl33_entry(void)
  175. {
  176. unsigned int mode;
  177. uint32_t spsr;
  178. /* Figure out what mode we enter the non-secure world in */
  179. mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
  180. /*
  181. * TODO: Consider the possibility of specifying the SPSR in
  182. * the FIP ToC and allowing the platform to have a say as
  183. * well.
  184. */
  185. spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
  186. return spsr;
  187. }
  188. /* SMP: Secondary cores BL31 setup reset vector */
  189. void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id)
  190. {
  191. unsigned int pch_cpu = 0x00;
  192. unsigned int pchctlr_old = 0x00;
  193. unsigned int pchctlr_new = 0x00;
  194. uint32_t boot_core = 0x00;
  195. /* Store magic number for SMP secondary cores boot */
  196. mmio_write_32(L2_RESET_DONE_REG, SMP_SEC_CORE_BOOT_REQ);
  197. boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
  198. /* Update the p-channel based on cpu id */
  199. pch_cpu = 1 << cpu_id;
  200. if (boot_core == 0x00) {
  201. /* Update reset vector to 0x00 */
  202. mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU2,
  203. (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
  204. } else {
  205. /* Update reset vector to 0x00 */
  206. mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU0,
  207. (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
  208. }
  209. /* Update reset vector to 0x00 */
  210. mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU1, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
  211. mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU3, (uint64_t) plat_secondary_cpus_bl31_entry >> 2);
  212. /* On all cores - temporary */
  213. pchctlr_old = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
  214. pchctlr_new = pchctlr_old | (pch_cpu<<1);
  215. mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pchctlr_new);
  216. /* We will only release the target secondary CPUs */
  217. /* Bit mask for each CPU BIT0-3 */
  218. mmio_write_32(RSTMGR_CPUSTRELEASE_CPUx, pch_cpu);
  219. }
  220. void bl31_plat_set_secondary_cpu_off(void)
  221. {
  222. unsigned int pch_cpu = 0x00;
  223. unsigned int pch_cpu_off = 0x00;
  224. unsigned int cpu_id = plat_my_core_pos();
  225. pch_cpu_off = 1 << cpu_id;
  226. pch_cpu = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR));
  227. pch_cpu = pch_cpu & ~(pch_cpu_off << 1);
  228. mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pch_cpu);
  229. }
  230. void bl31_plat_enable_mmu(uint32_t flags)
  231. {
  232. /* TODO: Enable mmu when needed */
  233. }