fvp_bl31_setup.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <common/bl_common.h>
  8. #include <common/debug.h>
  9. #include <drivers/arm/smmu_v3.h>
  10. #include <fconf_hw_config_getter.h>
  11. #include <lib/fconf/fconf.h>
  12. #include <lib/fconf/fconf_dyn_cfg_getter.h>
  13. #include <lib/mmio.h>
  14. #include <plat/arm/common/arm_config.h>
  15. #include <plat/arm/common/plat_arm.h>
  16. #include <plat/common/platform.h>
  17. #include "fvp_private.h"
  18. static const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
  19. void __init bl31_early_platform_setup2(u_register_t arg0,
  20. u_register_t arg1, u_register_t arg2, u_register_t arg3)
  21. {
  22. /* Initialize the console to provide early debug support */
  23. arm_console_boot_init();
  24. #if TRANSFER_LIST
  25. arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
  26. #else
  27. #if !RESET_TO_BL31 && !RESET_TO_BL2
  28. const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
  29. INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
  30. /* Fill the properties struct with the info from the config dtb */
  31. fconf_populate("FW_CONFIG", arg1);
  32. soc_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, SOC_FW_CONFIG_ID);
  33. if (soc_fw_config_info != NULL) {
  34. arg1 = soc_fw_config_info->config_addr;
  35. }
  36. /*
  37. * arg2 is currently holding the 'secure' address of HW_CONFIG.
  38. * But arm_bl31_early_platform_setup() below expects the 'non-secure'
  39. * address of HW_CONFIG (which it will pass to BL33).
  40. * This why we need to override arg2 here.
  41. */
  42. hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
  43. assert(hw_config_info != NULL);
  44. assert(hw_config_info->secondary_config_addr != 0UL);
  45. arg2 = hw_config_info->secondary_config_addr;
  46. #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 */
  47. arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
  48. #endif /* TRANSFER_LIST */
  49. /* Initialize the platform config for future decision making */
  50. fvp_config_setup();
  51. /*
  52. * Initialize the correct interconnect for this cluster during cold
  53. * boot. No need for locks as no other CPU is active.
  54. */
  55. fvp_interconnect_init();
  56. /*
  57. * Enable coherency in interconnect for the primary CPU's cluster.
  58. * Earlier bootloader stages might already do this (e.g. Trusted
  59. * Firmware's BL1 does it) but we can't assume so. There is no harm in
  60. * executing this code twice anyway.
  61. * FVP PSCI code will enable coherency for other clusters.
  62. */
  63. fvp_interconnect_enable();
  64. /* Initialize System level generic or SP804 timer */
  65. fvp_timer_init();
  66. /* On FVP RevC, initialize SMMUv3 */
  67. if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) {
  68. if (smmuv3_security_init(PLAT_FVP_SMMUV3_BASE) != 0) {
  69. /*
  70. * Don't proceed for smmuv3 initialization if the
  71. * security init failed.
  72. */
  73. return;
  74. }
  75. /* SMMUv3 initialization failure is not fatal */
  76. if (smmuv3_init(PLAT_FVP_SMMUV3_BASE) != 0) {
  77. WARN("Failed initializing SMMU.\n");
  78. }
  79. }
  80. }
  81. #if !TRANSFER_LIST
  82. void __init bl31_plat_arch_setup(void)
  83. {
  84. int rc __unused;
  85. uintptr_t hw_config_base_align __unused;
  86. size_t mapped_size_align __unused;
  87. arm_bl31_plat_arch_setup();
  88. /*
  89. * For RESET_TO_BL31 systems, BL31 is the first bootloader to run.
  90. * So there is no BL2 to load the HW_CONFIG dtb into memory before
  91. * control is passed to BL31. The code below relies on dynamic mapping
  92. * capability, which is not supported by xlat tables lib V1.
  93. * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
  94. * gets deprecated.
  95. */
  96. #if !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1
  97. assert(hw_config_info != NULL);
  98. assert(hw_config_info->config_addr != 0UL);
  99. /* Page aligned address and size if necessary */
  100. hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
  101. mapped_size_align = page_align(hw_config_info->config_max_size, UP);
  102. if ((hw_config_info->config_addr != hw_config_base_align) &&
  103. (hw_config_info->config_max_size == mapped_size_align)) {
  104. mapped_size_align += PAGE_SIZE;
  105. }
  106. /*
  107. * map dynamically HW config region with its aligned base address and
  108. * size
  109. */
  110. rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
  111. hw_config_base_align,
  112. mapped_size_align,
  113. MT_RO_DATA);
  114. if (rc != 0) {
  115. ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
  116. panic();
  117. }
  118. /* Populate HW_CONFIG device tree with the mapped address */
  119. fconf_populate("HW_CONFIG", hw_config_info->config_addr);
  120. /* unmap the HW_CONFIG memory region */
  121. rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
  122. if (rc != 0) {
  123. ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
  124. rc);
  125. panic();
  126. }
  127. #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1 */
  128. }
  129. #endif /* TRANSFER_LIST */
  130. unsigned int plat_get_syscnt_freq2(void)
  131. {
  132. unsigned int counter_base_frequency;
  133. #if !RESET_TO_BL31 && !RESET_TO_BL2
  134. /* Get the frequency through FCONF API for HW_CONFIG */
  135. counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq);
  136. if (counter_base_frequency > 0U) {
  137. return counter_base_frequency;
  138. }
  139. #endif
  140. /* Read the frequency from Frequency modes table */
  141. counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF);
  142. /* The first entry of the frequency modes table must not be 0 */
  143. if (counter_base_frequency == 0U) {
  144. panic();
  145. }
  146. return counter_base_frequency;
  147. }