1 /* 2 * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <common/debug.h> 10 #include <drivers/arm/cci.h> 11 #include <drivers/arm/ccn.h> 12 #include <drivers/arm/gicv2.h> 13 #include <drivers/arm/sp804_delay_timer.h> 14 #include <drivers/generic_delay_timer.h> 15 #include <fconf_hw_config_getter.h> 16 #include <lib/mmio.h> 17 #include <lib/smccc.h> 18 #include <lib/xlat_tables/xlat_tables_compat.h> 19 #include <platform_def.h> 20 #include <services/arm_arch_svc.h> 21 #include <services/rmm_core_manifest.h> 22 #if SPM_MM 23 #include <services/spm_mm_partition.h> 24 #endif 25 26 #include <plat/arm/common/arm_config.h> 27 #include <plat/arm/common/arm_pas_def.h> 28 #include <plat/arm/common/plat_arm.h> 29 #include <plat/common/platform.h> 30 31 #include "fvp_private.h" 32 33 /* Defines for GIC Driver build time selection */ 34 #define FVP_GICV2 1 35 #define FVP_GICV3 2 36 37 /******************************************************************************* 38 * arm_config holds the characteristics of the differences between the three FVP 39 * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot 40 * at each boot stage by the primary before enabling the MMU (to allow 41 * interconnect configuration) & used thereafter. Each BL will have its own copy 42 * to allow independent operation. 43 ******************************************************************************/ 44 arm_config_t arm_config; 45 46 #define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ 47 DEVICE0_SIZE, \ 48 MT_DEVICE | MT_RW | MT_SECURE) 49 50 #define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \ 51 DEVICE1_SIZE, \ 52 MT_DEVICE | MT_RW | MT_SECURE) 53 54 #if FVP_GICR_REGION_PROTECTION 55 #define MAP_GICD_MEM MAP_REGION_FLAT(BASE_GICD_BASE, \ 56 BASE_GICD_SIZE, \ 57 MT_DEVICE | MT_RW | MT_SECURE) 58 59 /* Map all core's redistributor memory as read-only. After boots up, 60 * per-core map its redistributor memory as read-write */ 61 #define MAP_GICR_MEM MAP_REGION_FLAT(BASE_GICR_BASE, \ 62 (BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\ 63 MT_DEVICE | MT_RO | MT_SECURE) 64 #endif /* FVP_GICR_REGION_PROTECTION */ 65 66 /* 67 * Need to be mapped with write permissions in order to set a new non-volatile 68 * counter value. 69 */ 70 #define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ 71 DEVICE2_SIZE, \ 72 MT_DEVICE | MT_RW | MT_SECURE) 73 74 /* 75 * Table of memory regions for various BL stages to map using the MMU. 76 * This doesn't include Trusted SRAM as setup_page_tables() already takes care 77 * of mapping it. 78 */ 79 #ifdef IMAGE_BL1 80 const mmap_region_t plat_arm_mmap[] = { 81 ARM_MAP_SHARED_RAM, 82 V2M_MAP_FLASH0_RO, 83 V2M_MAP_IOFPGA, 84 MAP_DEVICE0, 85 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 86 MAP_DEVICE1, 87 #endif 88 #if TRUSTED_BOARD_BOOT 89 /* To access the Root of Trust Public Key registers. */ 90 MAP_DEVICE2, 91 /* Map DRAM to authenticate NS_BL2U image. */ 92 ARM_MAP_NS_DRAM1, 93 #endif 94 {0} 95 }; 96 #endif 97 #ifdef IMAGE_BL2 98 const mmap_region_t plat_arm_mmap[] = { 99 ARM_MAP_SHARED_RAM, 100 V2M_MAP_FLASH0_RW, 101 V2M_MAP_IOFPGA, 102 MAP_DEVICE0, 103 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 104 MAP_DEVICE1, 105 #endif 106 ARM_MAP_NS_DRAM1, 107 #ifdef __aarch64__ 108 ARM_MAP_DRAM2, 109 #endif 110 /* 111 * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM. 112 */ 113 ARM_MAP_TRUSTED_DRAM, 114 #if ENABLE_RME 115 ARM_MAP_RMM_DRAM, 116 ARM_MAP_GPT_L1_DRAM, 117 #endif /* ENABLE_RME */ 118 #ifdef SPD_tspd 119 ARM_MAP_TSP_SEC_MEM, 120 #endif 121 #if TRUSTED_BOARD_BOOT 122 /* To access the Root of Trust Public Key registers. */ 123 MAP_DEVICE2, 124 #endif /* TRUSTED_BOARD_BOOT */ 125 126 #if CRYPTO_SUPPORT && !BL2_AT_EL3 127 /* 128 * To access shared the Mbed TLS heap while booting the 129 * system with Crypto support 130 */ 131 ARM_MAP_BL1_RW, 132 #endif /* CRYPTO_SUPPORT && !BL2_AT_EL3 */ 133 #if SPM_MM || SPMC_AT_EL3 134 ARM_SP_IMAGE_MMAP, 135 #endif 136 #if ARM_BL31_IN_DRAM 137 ARM_MAP_BL31_SEC_DRAM, 138 #endif 139 #ifdef SPD_opteed 140 ARM_MAP_OPTEE_CORE_MEM, 141 ARM_OPTEE_PAGEABLE_LOAD_MEM, 142 #endif 143 {0} 144 }; 145 #endif 146 #ifdef IMAGE_BL2U 147 const mmap_region_t plat_arm_mmap[] = { 148 MAP_DEVICE0, 149 V2M_MAP_IOFPGA, 150 {0} 151 }; 152 #endif 153 #ifdef IMAGE_BL31 154 const mmap_region_t plat_arm_mmap[] = { 155 ARM_MAP_SHARED_RAM, 156 #if USE_DEBUGFS 157 /* Required by devfip, can be removed if devfip is not used */ 158 V2M_MAP_FLASH0_RW, 159 #endif /* USE_DEBUGFS */ 160 ARM_MAP_EL3_TZC_DRAM, 161 V2M_MAP_IOFPGA, 162 MAP_DEVICE0, 163 #if FVP_GICR_REGION_PROTECTION 164 MAP_GICD_MEM, 165 MAP_GICR_MEM, 166 #else 167 MAP_DEVICE1, 168 #endif /* FVP_GICR_REGION_PROTECTION */ 169 ARM_V2M_MAP_MEM_PROTECT, 170 #if SPM_MM 171 ARM_SPM_BUF_EL3_MMAP, 172 #endif 173 #if ENABLE_RME 174 ARM_MAP_GPT_L1_DRAM, 175 ARM_MAP_EL3_RMM_SHARED_MEM, 176 #endif 177 {0} 178 }; 179 180 #if defined(IMAGE_BL31) && SPM_MM 181 const mmap_region_t plat_arm_secure_partition_mmap[] = { 182 V2M_MAP_IOFPGA_EL0, /* for the UART */ 183 MAP_REGION_FLAT(DEVICE0_BASE, 184 DEVICE0_SIZE, 185 MT_DEVICE | MT_RO | MT_SECURE | MT_USER), 186 ARM_SP_IMAGE_MMAP, 187 ARM_SP_IMAGE_NS_BUF_MMAP, 188 ARM_SP_IMAGE_RW_MMAP, 189 ARM_SPM_BUF_EL0_MMAP, 190 {0} 191 }; 192 #endif 193 #endif 194 #ifdef IMAGE_BL32 195 const mmap_region_t plat_arm_mmap[] = { 196 #ifndef __aarch64__ 197 ARM_MAP_SHARED_RAM, 198 ARM_V2M_MAP_MEM_PROTECT, 199 #endif 200 V2M_MAP_IOFPGA, 201 MAP_DEVICE0, 202 MAP_DEVICE1, 203 {0} 204 }; 205 #endif 206 207 #ifdef IMAGE_RMM 208 const mmap_region_t plat_arm_mmap[] = { 209 V2M_MAP_IOFPGA, 210 MAP_DEVICE0, 211 MAP_DEVICE1, 212 {0} 213 }; 214 #endif 215 216 ARM_CASSERT_MMAP 217 218 #if FVP_INTERCONNECT_DRIVER != FVP_CCN 219 static const int fvp_cci400_map[] = { 220 PLAT_FVP_CCI400_CLUS0_SL_PORT, 221 PLAT_FVP_CCI400_CLUS1_SL_PORT, 222 }; 223 224 static const int fvp_cci5xx_map[] = { 225 PLAT_FVP_CCI5XX_CLUS0_SL_PORT, 226 PLAT_FVP_CCI5XX_CLUS1_SL_PORT, 227 }; 228 229 static unsigned int get_interconnect_master(void) 230 { 231 unsigned int master; 232 u_register_t mpidr; 233 234 mpidr = read_mpidr_el1(); 235 master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ? 236 MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr); 237 238 assert(master < FVP_CLUSTER_COUNT); 239 return master; 240 } 241 #endif 242 243 #if defined(IMAGE_BL31) && SPM_MM 244 /* 245 * Boot information passed to a secure partition during initialisation. Linear 246 * indices in MP information will be filled at runtime. 247 */ 248 static spm_mm_mp_info_t sp_mp_info[] = { 249 [0] = {0x80000000, 0}, 250 [1] = {0x80000001, 0}, 251 [2] = {0x80000002, 0}, 252 [3] = {0x80000003, 0}, 253 [4] = {0x80000100, 0}, 254 [5] = {0x80000101, 0}, 255 [6] = {0x80000102, 0}, 256 [7] = {0x80000103, 0}, 257 }; 258 259 const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = { 260 .h.type = PARAM_SP_IMAGE_BOOT_INFO, 261 .h.version = VERSION_1, 262 .h.size = sizeof(spm_mm_boot_info_t), 263 .h.attr = 0, 264 .sp_mem_base = ARM_SP_IMAGE_BASE, 265 .sp_mem_limit = ARM_SP_IMAGE_LIMIT, 266 .sp_image_base = ARM_SP_IMAGE_BASE, 267 .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, 268 .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE, 269 .sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE, 270 .sp_shared_buf_base = PLAT_SPM_BUF_BASE, 271 .sp_image_size = ARM_SP_IMAGE_SIZE, 272 .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, 273 .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE, 274 .sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE, 275 .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, 276 .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS, 277 .num_cpus = PLATFORM_CORE_COUNT, 278 .mp_info = &sp_mp_info[0], 279 }; 280 281 const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) 282 { 283 return plat_arm_secure_partition_mmap; 284 } 285 286 const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( 287 void *cookie) 288 { 289 return &plat_arm_secure_partition_boot_info; 290 } 291 #endif 292 293 /******************************************************************************* 294 * A single boot loader stack is expected to work on both the Foundation FVP 295 * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The 296 * SYS_ID register provides a mechanism for detecting the differences between 297 * these platforms. This information is stored in a per-BL array to allow the 298 * code to take the correct path.Per BL platform configuration. 299 ******************************************************************************/ 300 void __init fvp_config_setup(void) 301 { 302 unsigned int rev, hbi, bld, arch, sys_id; 303 304 sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); 305 rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK; 306 hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK; 307 bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK; 308 arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK; 309 310 if (arch != ARCH_MODEL) { 311 ERROR("This firmware is for FVP models\n"); 312 panic(); 313 } 314 315 /* 316 * The build field in the SYS_ID tells which variant of the GIC 317 * memory is implemented by the model. 318 */ 319 switch (bld) { 320 case BLD_GIC_VE_MMAP: 321 ERROR("Legacy Versatile Express memory map for GIC peripheral" 322 " is not supported\n"); 323 panic(); 324 break; 325 case BLD_GIC_A53A57_MMAP: 326 break; 327 default: 328 ERROR("Unsupported board build %x\n", bld); 329 panic(); 330 } 331 332 /* 333 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010 334 * for the Foundation FVP. 335 */ 336 switch (hbi) { 337 case HBI_FOUNDATION_FVP: 338 arm_config.flags = 0; 339 340 /* 341 * Check for supported revisions of Foundation FVP 342 * Allow future revisions to run but emit warning diagnostic 343 */ 344 switch (rev) { 345 case REV_FOUNDATION_FVP_V2_0: 346 case REV_FOUNDATION_FVP_V2_1: 347 case REV_FOUNDATION_FVP_v9_1: 348 case REV_FOUNDATION_FVP_v9_6: 349 break; 350 default: 351 WARN("Unrecognized Foundation FVP revision %x\n", rev); 352 break; 353 } 354 break; 355 case HBI_BASE_FVP: 356 arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC); 357 358 /* 359 * Check for supported revisions 360 * Allow future revisions to run but emit warning diagnostic 361 */ 362 switch (rev) { 363 case REV_BASE_FVP_V0: 364 arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400; 365 break; 366 case REV_BASE_FVP_REVC: 367 arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 | 368 ARM_CONFIG_FVP_HAS_CCI5XX); 369 break; 370 default: 371 WARN("Unrecognized Base FVP revision %x\n", rev); 372 break; 373 } 374 break; 375 default: 376 ERROR("Unsupported board HBI number 0x%x\n", hbi); 377 panic(); 378 } 379 380 /* 381 * We assume that the presence of MT bit, and therefore shifted 382 * affinities, is uniform across the platform: either all CPUs, or no 383 * CPUs implement it. 384 */ 385 if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U) 386 arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF; 387 } 388 389 390 void __init fvp_interconnect_init(void) 391 { 392 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 393 if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { 394 ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported"); 395 panic(); 396 } 397 398 plat_arm_interconnect_init(); 399 #else 400 uintptr_t cci_base = 0U; 401 const int *cci_map = NULL; 402 unsigned int map_size = 0U; 403 404 /* Initialize the right interconnect */ 405 if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) { 406 cci_base = PLAT_FVP_CCI5XX_BASE; 407 cci_map = fvp_cci5xx_map; 408 map_size = ARRAY_SIZE(fvp_cci5xx_map); 409 } else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) { 410 cci_base = PLAT_FVP_CCI400_BASE; 411 cci_map = fvp_cci400_map; 412 map_size = ARRAY_SIZE(fvp_cci400_map); 413 } else { 414 return; 415 } 416 417 assert(cci_base != 0U); 418 assert(cci_map != NULL); 419 cci_init(cci_base, cci_map, map_size); 420 #endif 421 } 422 423 void fvp_interconnect_enable(void) 424 { 425 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 426 plat_arm_interconnect_enter_coherency(); 427 #else 428 unsigned int master; 429 430 if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 431 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { 432 master = get_interconnect_master(); 433 cci_enable_snoop_dvm_reqs(master); 434 } 435 #endif 436 } 437 438 void fvp_interconnect_disable(void) 439 { 440 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 441 plat_arm_interconnect_exit_coherency(); 442 #else 443 unsigned int master; 444 445 if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 446 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { 447 master = get_interconnect_master(); 448 cci_disable_snoop_dvm_reqs(master); 449 } 450 #endif 451 } 452 453 #if CRYPTO_SUPPORT 454 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) 455 { 456 assert(heap_addr != NULL); 457 assert(heap_size != NULL); 458 459 return arm_get_mbedtls_heap(heap_addr, heap_size); 460 } 461 #endif /* CRYPTO_SUPPORT */ 462 463 void fvp_timer_init(void) 464 { 465 #if USE_SP804_TIMER 466 /* Enable the clock override for SP804 timer 0, which means that no 467 * clock dividers are applied and the raw (35MHz) clock will be used. 468 */ 469 mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV); 470 471 /* Initialize delay timer driver using SP804 dual timer 0 */ 472 sp804_timer_init(V2M_SP804_TIMER0_BASE, 473 SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); 474 #else 475 generic_delay_timer_init(); 476 477 /* Enable System level generic timer */ 478 mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, 479 CNTCR_FCREQ(0U) | CNTCR_EN); 480 #endif /* USE_SP804_TIMER */ 481 } 482 483 /***************************************************************************** 484 * plat_is_smccc_feature_available() - This function checks whether SMCCC 485 * feature is availabile for platform. 486 * @fid: SMCCC function id 487 * 488 * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and 489 * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. 490 *****************************************************************************/ 491 int32_t plat_is_smccc_feature_available(u_register_t fid) 492 { 493 switch (fid) { 494 case SMCCC_ARCH_SOC_ID: 495 return SMC_ARCH_CALL_SUCCESS; 496 default: 497 return SMC_ARCH_CALL_NOT_SUPPORTED; 498 } 499 } 500 501 /* Get SOC version */ 502 int32_t plat_get_soc_version(void) 503 { 504 return (int32_t) 505 (SOC_ID_SET_JEP_106(ARM_SOC_CONTINUATION_CODE, 506 ARM_SOC_IDENTIFICATION_CODE) | 507 (FVP_SOC_ID & SOC_ID_IMPL_DEF_MASK)); 508 } 509 510 /* Get SOC revision */ 511 int32_t plat_get_soc_revision(void) 512 { 513 unsigned int sys_id; 514 515 sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); 516 return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) & 517 V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK); 518 } 519 520 #if ENABLE_RME 521 /* 522 * Get a pointer to the RMM-EL3 Shared buffer and return it 523 * through the pointer passed as parameter. 524 * 525 * This function returns the size of the shared buffer. 526 */ 527 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared) 528 { 529 *shared = (uintptr_t)RMM_SHARED_BASE; 530 531 return (size_t)RMM_SHARED_SIZE; 532 } 533 534 int plat_rmmd_load_manifest(struct rmm_manifest *manifest) 535 { 536 uint64_t checksum, num_banks; 537 struct ns_dram_bank *bank_ptr; 538 539 assert(manifest != NULL); 540 541 /* Get number of DRAM banks */ 542 num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks); 543 assert(num_banks <= ARM_DRAM_NUM_BANKS); 544 545 manifest->version = RMMD_MANIFEST_VERSION; 546 manifest->padding = 0U; /* RES0 */ 547 manifest->plat_data = (uintptr_t)NULL; 548 manifest->plat_dram.num_banks = num_banks; 549 550 /* 551 * Array ns_dram_banks[] follows ns_dram_info structure: 552 * 553 * +-----------------------------------+ 554 * | offset | field | comment | 555 * +----------+-----------+------------+ 556 * | 0 | version | 0x00000002 | 557 * +----------+-----------+------------+ 558 * | 4 | padding | 0x00000000 | 559 * +----------+-----------+------------+ 560 * | 8 | plat_data | NULL | 561 * +----------+-----------+------------+ 562 * | 16 | num_banks | | 563 * +----------+-----------+ | 564 * | 24 | banks | plat_dram | 565 * +----------+-----------+ | 566 * | 32 | checksum | | 567 * +----------+-----------+------------+ 568 * | 40 | base 0 | | 569 * +----------+-----------+ bank[0] | 570 * | 48 | size 0 | | 571 * +----------+-----------+------------+ 572 * | 56 | base 1 | | 573 * +----------+-----------+ bank[1] | 574 * | 64 | size 1 | | 575 * +----------+-----------+------------+ 576 */ 577 bank_ptr = (struct ns_dram_bank *) 578 ((uintptr_t)&manifest->plat_dram.checksum + 579 sizeof(manifest->plat_dram.checksum)); 580 581 manifest->plat_dram.banks = bank_ptr; 582 583 /* Calculate checksum of plat_dram structure */ 584 checksum = num_banks + (uint64_t)bank_ptr; 585 586 /* Store FVP DRAM banks data in Boot Manifest */ 587 for (unsigned long i = 0UL; i < num_banks; i++) { 588 uintptr_t base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base); 589 uint64_t size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size); 590 591 bank_ptr[i].base = base; 592 bank_ptr[i].size = size; 593 594 /* Update checksum */ 595 checksum += base + size; 596 } 597 598 /* Checksum must be 0 */ 599 manifest->plat_dram.checksum = ~checksum + 1UL; 600 601 return 0; 602 } 603 #endif /* ENABLE_RME */ 604