1 /* 2 * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arm_config.h> 8 #include <arm_def.h> 9 #include <arm_spm_def.h> 10 #include <assert.h> 11 #include <cci.h> 12 #include <ccn.h> 13 #include <debug.h> 14 #include <gicv2.h> 15 #include <mmio.h> 16 #include <plat_arm.h> 17 #include <secure_partition.h> 18 #include <v2m_def.h> 19 #include "../fvp_def.h" 20 21 /* Defines for GIC Driver build time selection */ 22 #define FVP_GICV2 1 23 #define FVP_GICV3 2 24 #define FVP_GICV3_LEGACY 3 25 26 /******************************************************************************* 27 * arm_config holds the characteristics of the differences between the three FVP 28 * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot 29 * at each boot stage by the primary before enabling the MMU (to allow 30 * interconnect configuration) & used thereafter. Each BL will have its own copy 31 * to allow independent operation. 32 ******************************************************************************/ 33 arm_config_t arm_config; 34 35 #define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ 36 DEVICE0_SIZE, \ 37 MT_DEVICE | MT_RW | MT_SECURE) 38 39 #define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \ 40 DEVICE1_SIZE, \ 41 MT_DEVICE | MT_RW | MT_SECURE) 42 43 /* 44 * Need to be mapped with write permissions in order to set a new non-volatile 45 * counter value. 46 */ 47 #define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ 48 DEVICE2_SIZE, \ 49 MT_DEVICE | MT_RW | MT_SECURE) 50 51 52 /* 53 * Table of memory regions for various BL stages to map using the MMU. 54 * This doesn't include Trusted SRAM as arm_setup_page_tables() already 55 * takes care of mapping it. 56 * 57 * The flash needs to be mapped as writable in order to erase the FIP's Table of 58 * Contents in case of unrecoverable error (see plat_error_handler()). 59 */ 60 #ifdef IMAGE_BL1 61 const mmap_region_t plat_arm_mmap[] = { 62 ARM_MAP_SHARED_RAM, 63 V2M_MAP_FLASH0_RW, 64 V2M_MAP_IOFPGA, 65 MAP_DEVICE0, 66 MAP_DEVICE1, 67 #if TRUSTED_BOARD_BOOT 68 /* To access the Root of Trust Public Key registers. */ 69 MAP_DEVICE2, 70 /* Map DRAM to authenticate NS_BL2U image. */ 71 ARM_MAP_NS_DRAM1, 72 #endif 73 {0} 74 }; 75 #endif 76 #ifdef IMAGE_BL2 77 const mmap_region_t plat_arm_mmap[] = { 78 ARM_MAP_SHARED_RAM, 79 V2M_MAP_FLASH0_RW, 80 V2M_MAP_IOFPGA, 81 MAP_DEVICE0, 82 MAP_DEVICE1, 83 ARM_MAP_NS_DRAM1, 84 #ifdef AARCH64 85 ARM_MAP_DRAM2, 86 #endif 87 #ifdef SPD_tspd 88 ARM_MAP_TSP_SEC_MEM, 89 #endif 90 #if TRUSTED_BOARD_BOOT 91 /* To access the Root of Trust Public Key registers. */ 92 MAP_DEVICE2, 93 #endif 94 #if ENABLE_SPM 95 ARM_SP_IMAGE_MMAP, 96 #endif 97 #if ARM_BL31_IN_DRAM 98 ARM_MAP_BL31_SEC_DRAM, 99 #endif 100 #ifdef SPD_opteed 101 ARM_MAP_OPTEE_CORE_MEM, 102 ARM_OPTEE_PAGEABLE_LOAD_MEM, 103 #endif 104 {0} 105 }; 106 #endif 107 #ifdef IMAGE_BL2U 108 const mmap_region_t plat_arm_mmap[] = { 109 MAP_DEVICE0, 110 V2M_MAP_IOFPGA, 111 {0} 112 }; 113 #endif 114 #ifdef IMAGE_BL31 115 const mmap_region_t plat_arm_mmap[] = { 116 ARM_MAP_SHARED_RAM, 117 ARM_MAP_EL3_TZC_DRAM, 118 V2M_MAP_IOFPGA, 119 MAP_DEVICE0, 120 MAP_DEVICE1, 121 ARM_V2M_MAP_MEM_PROTECT, 122 #if ENABLE_SPM 123 ARM_SPM_BUF_EL3_MMAP, 124 #endif 125 {0} 126 }; 127 128 #if ENABLE_SPM && defined(IMAGE_BL31) 129 const mmap_region_t plat_arm_secure_partition_mmap[] = { 130 V2M_MAP_IOFPGA_EL0, /* for the UART */ 131 ARM_SP_IMAGE_MMAP, 132 ARM_SP_IMAGE_NS_BUF_MMAP, 133 ARM_SP_IMAGE_RW_MMAP, 134 ARM_SPM_BUF_EL0_MMAP, 135 {0} 136 }; 137 #endif 138 #endif 139 #ifdef IMAGE_BL32 140 const mmap_region_t plat_arm_mmap[] = { 141 #ifdef AARCH32 142 ARM_MAP_SHARED_RAM, 143 #endif 144 V2M_MAP_IOFPGA, 145 MAP_DEVICE0, 146 MAP_DEVICE1, 147 {0} 148 }; 149 #endif 150 151 ARM_CASSERT_MMAP 152 153 #if FVP_INTERCONNECT_DRIVER != FVP_CCN 154 static const int fvp_cci400_map[] = { 155 PLAT_FVP_CCI400_CLUS0_SL_PORT, 156 PLAT_FVP_CCI400_CLUS1_SL_PORT, 157 }; 158 159 static const int fvp_cci5xx_map[] = { 160 PLAT_FVP_CCI5XX_CLUS0_SL_PORT, 161 PLAT_FVP_CCI5XX_CLUS1_SL_PORT, 162 }; 163 164 static unsigned int get_interconnect_master(void) 165 { 166 unsigned int master; 167 u_register_t mpidr; 168 169 mpidr = read_mpidr_el1(); 170 master = (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) ? 171 MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr); 172 173 assert(master < FVP_CLUSTER_COUNT); 174 return master; 175 } 176 #endif 177 178 #if ENABLE_SPM && defined(IMAGE_BL31) 179 /* 180 * Boot information passed to a secure partition during initialisation. Linear 181 * indices in MP information will be filled at runtime. 182 */ 183 static secure_partition_mp_info_t sp_mp_info[] = { 184 [0] = {0x80000000, 0}, 185 [1] = {0x80000001, 0}, 186 [2] = {0x80000002, 0}, 187 [3] = {0x80000003, 0}, 188 [4] = {0x80000100, 0}, 189 [5] = {0x80000101, 0}, 190 [6] = {0x80000102, 0}, 191 [7] = {0x80000103, 0}, 192 }; 193 194 const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = { 195 .h.type = PARAM_SP_IMAGE_BOOT_INFO, 196 .h.version = VERSION_1, 197 .h.size = sizeof(secure_partition_boot_info_t), 198 .h.attr = 0, 199 .sp_mem_base = ARM_SP_IMAGE_BASE, 200 .sp_mem_limit = ARM_SP_IMAGE_LIMIT, 201 .sp_image_base = ARM_SP_IMAGE_BASE, 202 .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, 203 .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE, 204 .sp_ns_comm_buf_base = ARM_SP_IMAGE_NS_BUF_BASE, 205 .sp_shared_buf_base = PLAT_SPM_BUF_BASE, 206 .sp_image_size = ARM_SP_IMAGE_SIZE, 207 .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, 208 .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE, 209 .sp_ns_comm_buf_size = ARM_SP_IMAGE_NS_BUF_SIZE, 210 .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, 211 .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS, 212 .num_cpus = PLATFORM_CORE_COUNT, 213 .mp_info = &sp_mp_info[0], 214 }; 215 216 const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) 217 { 218 return plat_arm_secure_partition_mmap; 219 } 220 221 const struct secure_partition_boot_info *plat_get_secure_partition_boot_info( 222 void *cookie) 223 { 224 return &plat_arm_secure_partition_boot_info; 225 } 226 227 #endif 228 229 /******************************************************************************* 230 * A single boot loader stack is expected to work on both the Foundation FVP 231 * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The 232 * SYS_ID register provides a mechanism for detecting the differences between 233 * these platforms. This information is stored in a per-BL array to allow the 234 * code to take the correct path.Per BL platform configuration. 235 ******************************************************************************/ 236 void fvp_config_setup(void) 237 { 238 unsigned int rev, hbi, bld, arch, sys_id; 239 240 sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); 241 rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK; 242 hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK; 243 bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK; 244 arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK; 245 246 if (arch != ARCH_MODEL) { 247 ERROR("This firmware is for FVP models\n"); 248 panic(); 249 } 250 251 /* 252 * The build field in the SYS_ID tells which variant of the GIC 253 * memory is implemented by the model. 254 */ 255 switch (bld) { 256 case BLD_GIC_VE_MMAP: 257 ERROR("Legacy Versatile Express memory map for GIC peripheral" 258 " is not supported\n"); 259 panic(); 260 break; 261 case BLD_GIC_A53A57_MMAP: 262 break; 263 default: 264 ERROR("Unsupported board build %x\n", bld); 265 panic(); 266 } 267 268 /* 269 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010 270 * for the Foundation FVP. 271 */ 272 switch (hbi) { 273 case HBI_FOUNDATION_FVP: 274 arm_config.flags = 0; 275 276 /* 277 * Check for supported revisions of Foundation FVP 278 * Allow future revisions to run but emit warning diagnostic 279 */ 280 switch (rev) { 281 case REV_FOUNDATION_FVP_V2_0: 282 case REV_FOUNDATION_FVP_V2_1: 283 case REV_FOUNDATION_FVP_v9_1: 284 case REV_FOUNDATION_FVP_v9_6: 285 break; 286 default: 287 WARN("Unrecognized Foundation FVP revision %x\n", rev); 288 break; 289 } 290 break; 291 case HBI_BASE_FVP: 292 arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC); 293 294 /* 295 * Check for supported revisions 296 * Allow future revisions to run but emit warning diagnostic 297 */ 298 switch (rev) { 299 case REV_BASE_FVP_V0: 300 arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400; 301 break; 302 case REV_BASE_FVP_REVC: 303 arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 | 304 ARM_CONFIG_FVP_HAS_CCI5XX); 305 break; 306 default: 307 WARN("Unrecognized Base FVP revision %x\n", rev); 308 break; 309 } 310 break; 311 default: 312 ERROR("Unsupported board HBI number 0x%x\n", hbi); 313 panic(); 314 } 315 316 /* 317 * We assume that the presence of MT bit, and therefore shifted 318 * affinities, is uniform across the platform: either all CPUs, or no 319 * CPUs implement it. 320 */ 321 if (read_mpidr_el1() & MPIDR_MT_MASK) 322 arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF; 323 } 324 325 326 void fvp_interconnect_init(void) 327 { 328 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 329 if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { 330 ERROR("Unrecognized CCN variant detected. Only CCN-502" 331 " is supported"); 332 panic(); 333 } 334 335 plat_arm_interconnect_init(); 336 #else 337 uintptr_t cci_base = 0; 338 const int *cci_map = 0; 339 unsigned int map_size = 0; 340 341 if (!(arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 342 ARM_CONFIG_FVP_HAS_CCI5XX))) { 343 return; 344 } 345 346 /* Initialize the right interconnect */ 347 if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) { 348 cci_base = PLAT_FVP_CCI5XX_BASE; 349 cci_map = fvp_cci5xx_map; 350 map_size = ARRAY_SIZE(fvp_cci5xx_map); 351 } else if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) { 352 cci_base = PLAT_FVP_CCI400_BASE; 353 cci_map = fvp_cci400_map; 354 map_size = ARRAY_SIZE(fvp_cci400_map); 355 } 356 357 assert(cci_base); 358 assert(cci_map); 359 cci_init(cci_base, cci_map, map_size); 360 #endif 361 } 362 363 void fvp_interconnect_enable(void) 364 { 365 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 366 plat_arm_interconnect_enter_coherency(); 367 #else 368 unsigned int master; 369 370 if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 371 ARM_CONFIG_FVP_HAS_CCI5XX)) { 372 master = get_interconnect_master(); 373 cci_enable_snoop_dvm_reqs(master); 374 } 375 #endif 376 } 377 378 void fvp_interconnect_disable(void) 379 { 380 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 381 plat_arm_interconnect_exit_coherency(); 382 #else 383 unsigned int master; 384 385 if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 386 ARM_CONFIG_FVP_HAS_CCI5XX)) { 387 master = get_interconnect_master(); 388 cci_disable_snoop_dvm_reqs(master); 389 } 390 #endif 391 } 392