fvp_r_common.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. /* This uses xlat_mpu, but tables are set up using V2 mmap_region_t */
  7. #define XLAT_TABLES_LIB_V2 1
  8. #include <assert.h>
  9. #include <common/debug.h>
  10. #include <drivers/arm/cci.h>
  11. #include <drivers/arm/gicv2.h>
  12. #include <drivers/arm/sp804_delay_timer.h>
  13. #include <drivers/generic_delay_timer.h>
  14. #include <lib/mmio.h>
  15. #include <lib/smccc.h>
  16. #include <lib/xlat_tables/xlat_tables_compat.h>
  17. #include <services/arm_arch_svc.h>
  18. #include "fvp_r_private.h"
  19. #include <plat/arm/common/arm_config.h>
  20. #include <plat/arm/common/plat_arm.h>
  21. #include <plat/common/platform.h>
  22. #include <platform_def.h>
  23. /* Defines for GIC Driver build time selection */
  24. #define FVP_R_GICV3 2
  25. /*******************************************************************************
  26. * arm_config holds the characteristics of the differences between the FVP_R
  27. * platforms. It will be populated during cold boot at each boot stage by the
  28. * primary before enabling the MPU (to allow interconnect configuration) &
  29. * used thereafter. Each BL will have its own copy to allow independent
  30. * operation.
  31. ******************************************************************************/
  32. arm_config_t arm_config;
  33. #define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
  34. DEVICE0_SIZE, \
  35. MT_DEVICE | MT_RW | MT_SECURE)
  36. #define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \
  37. DEVICE1_SIZE, \
  38. MT_DEVICE | MT_RW | MT_SECURE)
  39. /*
  40. * Need to be mapped with write permissions in order to set a new non-volatile
  41. * counter value.
  42. */
  43. #define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \
  44. DEVICE2_SIZE, \
  45. MT_DEVICE | MT_RW | MT_SECURE)
  46. /*
  47. * Table of memory regions for various BL stages to map using the MPU.
  48. * This doesn't include Trusted SRAM as setup_page_tables() already takes care
  49. * of mapping it.
  50. *
  51. * The flash needs to be mapped as writable in order to erase the FIP's Table of
  52. * Contents in case of unrecoverable error (see plat_error_handler()).
  53. */
  54. #ifdef IMAGE_BL1
  55. const mmap_region_t plat_arm_mmap[] = {
  56. ARM_MAP_SHARED_RAM,
  57. V2M_MAP_FLASH0_RW,
  58. V2M_MAP_IOFPGA,
  59. MAP_DEVICE0,
  60. MAP_DEVICE1,
  61. #if TRUSTED_BOARD_BOOT
  62. /* To access the Root of Trust Public Key registers. */
  63. MAP_DEVICE2,
  64. #endif
  65. {0}
  66. };
  67. #endif
  68. ARM_CASSERT_MMAP
  69. static const int fvp_cci400_map[] = {
  70. PLAT_FVP_R_CCI400_CLUS0_SL_PORT,
  71. PLAT_FVP_R_CCI400_CLUS1_SL_PORT,
  72. };
  73. static const int fvp_cci5xx_map[] = {
  74. PLAT_FVP_R_CCI5XX_CLUS0_SL_PORT,
  75. PLAT_FVP_R_CCI5XX_CLUS1_SL_PORT,
  76. };
  77. static unsigned int get_interconnect_master(void)
  78. {
  79. unsigned int master;
  80. u_register_t mpidr;
  81. mpidr = read_mpidr_el1();
  82. master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
  83. MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);
  84. assert(master < FVP_R_CLUSTER_COUNT);
  85. return master;
  86. }
  87. /*******************************************************************************
  88. * Initialize the platform config for future decision making
  89. ******************************************************************************/
  90. void __init fvp_config_setup(void)
  91. {
  92. unsigned int rev, hbi, bld, arch, sys_id;
  93. arm_config.flags |= ARM_CONFIG_BASE_MMAP;
  94. sys_id = mmio_read_32(V2M_FVP_R_SYSREGS_BASE + V2M_SYS_ID);
  95. rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK;
  96. hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK;
  97. bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK;
  98. arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK;
  99. if (arch != ARCH_MODEL) {
  100. ERROR("This firmware is for FVP_R models\n");
  101. panic();
  102. }
  103. /*
  104. * The build field in the SYS_ID tells which variant of the GIC
  105. * memory is implemented by the model.
  106. */
  107. switch (bld) {
  108. case BLD_GIC_VE_MMAP:
  109. ERROR("Legacy Versatile Express memory map for GIC %s",
  110. "peripheral is not supported\n");
  111. panic();
  112. break;
  113. case BLD_GIC_A53A57_MMAP:
  114. break;
  115. default:
  116. ERROR("Unsupported board build %x\n", bld);
  117. panic();
  118. }
  119. /*
  120. * The hbi field in the SYS_ID is 0x020 for the Base FVP_R & 0x010
  121. * for the Foundation FVP_R.
  122. */
  123. switch (hbi) {
  124. case HBI_FOUNDATION_FVP_R:
  125. arm_config.flags = 0;
  126. /*
  127. * Check for supported revisions of Foundation FVP_R
  128. * Allow future revisions to run but emit warning diagnostic
  129. */
  130. switch (rev) {
  131. case REV_FOUNDATION_FVP_R_V2_0:
  132. case REV_FOUNDATION_FVP_R_V2_1:
  133. case REV_FOUNDATION_FVP_R_v9_1:
  134. case REV_FOUNDATION_FVP_R_v9_6:
  135. break;
  136. default:
  137. WARN("Unrecognized Foundation FVP_R revision %x\n", rev);
  138. break;
  139. }
  140. break;
  141. case HBI_BASE_FVP_R:
  142. arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
  143. /*
  144. * Check for supported revisions
  145. * Allow future revisions to run but emit warning diagnostic
  146. */
  147. switch (rev) {
  148. case REV_BASE_FVP_R_V0:
  149. arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
  150. break;
  151. default:
  152. WARN("Unrecognized Base FVP_R revision %x\n", rev);
  153. break;
  154. }
  155. break;
  156. default:
  157. ERROR("Unsupported board HBI number 0x%x\n", hbi);
  158. panic();
  159. }
  160. /*
  161. * We assume that the presence of MT bit, and therefore shifted
  162. * affinities, is uniform across the platform: either all CPUs, or no
  163. * CPUs implement it.
  164. */
  165. if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U) {
  166. arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
  167. }
  168. }
  169. void __init fvp_interconnect_init(void)
  170. {
  171. uintptr_t cci_base = 0U;
  172. const int *cci_map = NULL;
  173. unsigned int map_size = 0U;
  174. /* Initialize the right interconnect */
  175. if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
  176. cci_base = PLAT_FVP_R_CCI5XX_BASE;
  177. cci_map = fvp_cci5xx_map;
  178. map_size = ARRAY_SIZE(fvp_cci5xx_map);
  179. } else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
  180. cci_base = PLAT_FVP_R_CCI400_BASE;
  181. cci_map = fvp_cci400_map;
  182. map_size = ARRAY_SIZE(fvp_cci400_map);
  183. } else {
  184. return;
  185. }
  186. assert(cci_base != 0U);
  187. assert(cci_map != NULL);
  188. cci_init(cci_base, cci_map, map_size);
  189. }
  190. void fvp_interconnect_enable(void)
  191. {
  192. unsigned int master;
  193. if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
  194. ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
  195. master = get_interconnect_master();
  196. cci_enable_snoop_dvm_reqs(master);
  197. }
  198. }
  199. void fvp_interconnect_disable(void)
  200. {
  201. unsigned int master;
  202. if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
  203. ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
  204. master = get_interconnect_master();
  205. cci_disable_snoop_dvm_reqs(master);
  206. }
  207. }
  208. #if TRUSTED_BOARD_BOOT
  209. int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
  210. {
  211. assert(heap_addr != NULL);
  212. assert(heap_size != NULL);
  213. return arm_get_mbedtls_heap(heap_addr, heap_size);
  214. }
  215. #endif
  216. void fvp_timer_init(void)
  217. {
  218. #if USE_SP804_TIMER
  219. /* Enable the clock override for SP804 timer 0, which means that no
  220. * clock dividers are applied and the raw (35MHz) clock will be used.
  221. */
  222. mmio_write_32(V2M_SP810_BASE, FVP_R_SP810_CTRL_TIM0_OV);
  223. /* Initialize delay timer driver using SP804 dual timer 0 */
  224. sp804_timer_init(V2M_SP804_TIMER0_BASE,
  225. SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
  226. #else
  227. generic_delay_timer_init();
  228. /* Enable System level generic timer */
  229. mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
  230. CNTCR_FCREQ(0U) | CNTCR_EN);
  231. #endif /* USE_SP804_TIMER */
  232. }
  233. /* Get SOC version */
  234. int32_t plat_get_soc_version(void)
  235. {
  236. return (int32_t)
  237. ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
  238. | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
  239. | FVP_R_SOC_ID);
  240. }
  241. /* Get SOC revision */
  242. int32_t plat_get_soc_revision(void)
  243. {
  244. unsigned int sys_id;
  245. sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
  246. return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) &
  247. V2M_SYS_ID_REV_MASK);
  248. }