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