1 /* 2 * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <arch.h> 11 #include <arch_helpers.h> 12 #include <common/debug.h> 13 #include <drivers/arm/cci.h> 14 #include <drivers/arm/ccn.h> 15 #include <drivers/arm/gicv2.h> 16 #include <drivers/arm/sp804_delay_timer.h> 17 #include <drivers/arm/smmu_v3.h> 18 #include <drivers/generic_delay_timer.h> 19 #include <fconf_hw_config_getter.h> 20 #include <lib/mmio.h> 21 #include <lib/smccc.h> 22 #include <lib/xlat_tables/xlat_tables_compat.h> 23 #include <platform_def.h> 24 #include <services/arm_arch_svc.h> 25 #include <services/rmm_core_manifest.h> 26 #if SPM_MM 27 #include <services/spm_mm_partition.h> 28 #endif 29 30 #include <plat/arm/common/arm_config.h> 31 #include <plat/arm/common/plat_arm.h> 32 #include <plat/common/platform.h> 33 34 #include "fvp_private.h" 35 36 /* Defines for GIC Driver build time selection */ 37 #define FVP_GICV2 1 38 #define FVP_GICV3 2 39 40 /* Defines for RMM Console */ 41 #define FVP_RMM_CONSOLE_BASE UL(0x1c0c0000) 42 #define FVP_RMM_CONSOLE_BAUD UL(115200) 43 #define FVP_RMM_CONSOLE_CLK_IN_HZ UL(14745600) 44 #define FVP_RMM_CONSOLE_NAME "pl011" 45 #define FVP_RMM_CONSOLE_COUNT UL(1) 46 47 /* Defines for RMM PCIe ECAM */ 48 #define FVP_RMM_ECAM_BASE PCIE_EXP_BASE 49 #define FVP_RMM_ECAM_SEGMENT UL(0x0) 50 #define FVP_RMM_ECAM_BDF UL(0x0) 51 52 /* Defines for RMM SMMUv3 */ 53 #define FVP_RMM_SMMU_BASE PLAT_FVP_SMMUV3_BASE 54 #define FVP_RMM_SMMU_COUNT UL(1) 55 56 /******************************************************************************* 57 * arm_config holds the characteristics of the differences between the three FVP 58 * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot 59 * at each boot stage by the primary before enabling the MMU (to allow 60 * interconnect configuration) & used thereafter. Each BL will have its own copy 61 * to allow independent operation. 62 ******************************************************************************/ 63 arm_config_t arm_config; 64 65 #define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ 66 DEVICE0_SIZE, \ 67 MT_DEVICE | MT_RW | EL3_PAS) 68 69 #define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \ 70 DEVICE1_SIZE, \ 71 MT_DEVICE | MT_RW | MT_SECURE) 72 73 #if FVP_GICR_REGION_PROTECTION 74 #define MAP_GICD_MEM MAP_REGION_FLAT(BASE_GICD_BASE, \ 75 BASE_GICD_SIZE, \ 76 MT_DEVICE | MT_RW | MT_SECURE) 77 78 /* Map all core's redistributor memory as read-only. After boots up, 79 * per-core map its redistributor memory as read-write */ 80 #define MAP_GICR_MEM MAP_REGION_FLAT(BASE_GICR_BASE, \ 81 (BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\ 82 MT_DEVICE | MT_RO | MT_SECURE) 83 #endif /* FVP_GICR_REGION_PROTECTION */ 84 85 /* 86 * Need to be mapped with write permissions in order to set a new non-volatile 87 * counter value. 88 */ 89 #define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ 90 DEVICE2_SIZE, \ 91 MT_DEVICE | MT_RW | MT_SECURE) 92 93 #if TRANSFER_LIST 94 #ifdef FW_NS_HANDOFF_BASE 95 #define MAP_FW_NS_HANDOFF \ 96 MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \ 97 MT_MEMORY | MT_RW | MT_NS) 98 #endif 99 #ifdef PLAT_ARM_EL3_FW_HANDOFF_BASE 100 #define MAP_EL3_FW_HANDOFF \ 101 MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \ 102 PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS) 103 #endif 104 #endif 105 106 /* 107 * Table of memory regions for various BL stages to map using the MMU. 108 * This doesn't include Trusted SRAM as setup_page_tables() already takes care 109 * of mapping it. 110 */ 111 #ifdef IMAGE_BL1 112 const mmap_region_t plat_arm_mmap[] = { 113 ARM_MAP_SHARED_RAM, 114 V2M_MAP_FLASH0_RO, 115 V2M_MAP_IOFPGA, 116 MAP_DEVICE0, 117 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 118 MAP_DEVICE1, 119 #endif 120 #if TRUSTED_BOARD_BOOT 121 /* To access the Root of Trust Public Key registers. */ 122 MAP_DEVICE2, 123 /* Map DRAM to authenticate NS_BL2U image. */ 124 ARM_MAP_NS_DRAM1, 125 #endif 126 {0} 127 }; 128 #endif 129 #ifdef IMAGE_BL2 130 const mmap_region_t plat_arm_mmap[] = { 131 ARM_MAP_SHARED_RAM, 132 V2M_MAP_FLASH0_RW, 133 V2M_MAP_IOFPGA, 134 MAP_DEVICE0, 135 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 136 MAP_DEVICE1, 137 #endif 138 ARM_MAP_NS_DRAM1, 139 #ifdef __aarch64__ 140 ARM_MAP_DRAM2, 141 #endif 142 /* 143 * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM. 144 */ 145 ARM_MAP_TRUSTED_DRAM, 146 147 /* 148 * Required to load Event Log in TZC secured memory 149 */ 150 #if MEASURED_BOOT && (defined(SPD_tspd) || defined(SPD_opteed) || \ 151 defined(SPD_spmd)) 152 ARM_MAP_EVENT_LOG_DRAM1, 153 #endif /* MEASURED_BOOT && (SPD_tspd || SPD_opteed || SPD_spmd) */ 154 155 #if ENABLE_RME 156 ARM_MAP_RMM_DRAM, 157 ARM_MAP_GPT_L1_DRAM, 158 #endif /* ENABLE_RME */ 159 #ifdef SPD_tspd 160 ARM_MAP_TSP_SEC_MEM, 161 #endif 162 #if TRUSTED_BOARD_BOOT 163 /* To access the Root of Trust Public Key registers. */ 164 MAP_DEVICE2, 165 #endif /* TRUSTED_BOARD_BOOT */ 166 167 #if CRYPTO_SUPPORT && !RESET_TO_BL2 168 /* 169 * To access shared the Mbed TLS heap while booting the 170 * system with Crypto support 171 */ 172 ARM_MAP_BL1_RW, 173 #endif /* CRYPTO_SUPPORT && !RESET_TO_BL2 */ 174 #if SPM_MM || SPMC_AT_EL3 175 ARM_SP_IMAGE_MMAP, 176 #endif 177 #if ARM_BL31_IN_DRAM 178 ARM_MAP_BL31_SEC_DRAM, 179 #endif 180 #ifdef SPD_opteed 181 ARM_MAP_OPTEE_CORE_MEM, 182 ARM_OPTEE_PAGEABLE_LOAD_MEM, 183 #endif 184 #ifdef MAP_EL3_FW_HANDOFF 185 MAP_EL3_FW_HANDOFF, 186 #endif 187 { 0 } 188 }; 189 #endif 190 #ifdef IMAGE_BL2U 191 const mmap_region_t plat_arm_mmap[] = { 192 MAP_DEVICE0, 193 V2M_MAP_IOFPGA, 194 {0} 195 }; 196 #endif 197 #ifdef IMAGE_BL31 198 const mmap_region_t plat_arm_mmap[] = { 199 ARM_MAP_SHARED_RAM, 200 #if USE_DEBUGFS 201 /* Required by devfip, can be removed if devfip is not used */ 202 V2M_MAP_FLASH0_RW, 203 #endif /* USE_DEBUGFS */ 204 ARM_MAP_EL3_TZC_DRAM, 205 V2M_MAP_IOFPGA, 206 MAP_DEVICE0, 207 #if FVP_GICR_REGION_PROTECTION 208 MAP_GICD_MEM, 209 MAP_GICR_MEM, 210 #else 211 MAP_DEVICE1, 212 #endif /* FVP_GICR_REGION_PROTECTION */ 213 ARM_V2M_MAP_MEM_PROTECT, 214 #if SPM_MM 215 ARM_SPM_BUF_EL3_MMAP, 216 #endif 217 #if ENABLE_RME 218 ARM_MAP_GPT_L1_DRAM, 219 ARM_MAP_EL3_RMM_SHARED_MEM, 220 #endif 221 #ifdef MAP_FW_NS_HANDOFF 222 MAP_FW_NS_HANDOFF, 223 #endif 224 #if defined(MAP_EL3_FW_HANDOFF) && !RESET_TO_BL31 225 MAP_EL3_FW_HANDOFF, 226 #endif 227 { 0 } 228 }; 229 230 #if defined(IMAGE_BL31) && SPM_MM 231 const mmap_region_t plat_arm_secure_partition_mmap[] = { 232 V2M_MAP_IOFPGA_EL0, /* for the UART */ 233 V2M_MAP_SECURE_SYSTEMREG_EL0, /* for initializing flash */ 234 #if PSA_FWU_SUPPORT 235 V2M_MAP_FLASH0_RW_EL0, /* for firmware update service in standalone mm */ 236 #endif 237 V2M_MAP_FLASH1_RW_EL0, /* for secure variable service in standalone mm */ 238 MAP_REGION_FLAT(DEVICE0_BASE, 239 DEVICE0_SIZE, 240 MT_DEVICE | MT_RO | MT_SECURE | MT_USER), 241 ARM_SP_IMAGE_MMAP, 242 ARM_SP_IMAGE_NS_BUF_MMAP, 243 ARM_SP_IMAGE_RW_MMAP, 244 ARM_SPM_BUF_EL0_MMAP, 245 {0} 246 }; 247 #endif 248 #endif 249 #ifdef IMAGE_BL32 250 const mmap_region_t plat_arm_mmap[] = { 251 #ifndef __aarch64__ 252 ARM_MAP_SHARED_RAM, 253 ARM_V2M_MAP_MEM_PROTECT, 254 #endif 255 V2M_MAP_IOFPGA, 256 MAP_DEVICE0, 257 MAP_DEVICE1, 258 {0} 259 }; 260 #endif 261 262 #ifdef IMAGE_RMM 263 const mmap_region_t plat_arm_mmap[] = { 264 V2M_MAP_IOFPGA, 265 MAP_DEVICE0, 266 MAP_DEVICE1, 267 {0} 268 }; 269 #endif 270 271 ARM_CASSERT_MMAP 272 273 #if FVP_INTERCONNECT_DRIVER != FVP_CCN 274 static const int fvp_cci400_map[] = { 275 PLAT_FVP_CCI400_CLUS0_SL_PORT, 276 PLAT_FVP_CCI400_CLUS1_SL_PORT, 277 }; 278 279 static const int fvp_cci5xx_map[] = { 280 PLAT_FVP_CCI5XX_CLUS0_SL_PORT, 281 PLAT_FVP_CCI5XX_CLUS1_SL_PORT, 282 }; 283 284 static unsigned int get_interconnect_master(void) 285 { 286 unsigned int master; 287 u_register_t mpidr; 288 289 mpidr = read_mpidr_el1(); 290 master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ? 291 MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr); 292 293 assert(master < FVP_CLUSTER_COUNT); 294 return master; 295 } 296 #endif 297 298 #if defined(IMAGE_BL31) && SPM_MM 299 /* 300 * Boot information passed to a secure partition during initialisation. Linear 301 * indices in MP information will be filled at runtime. 302 */ 303 static spm_mm_mp_info_t sp_mp_info[] = { 304 [0] = {0x80000000, 0}, 305 [1] = {0x80000001, 0}, 306 [2] = {0x80000002, 0}, 307 [3] = {0x80000003, 0}, 308 [4] = {0x80000100, 0}, 309 [5] = {0x80000101, 0}, 310 [6] = {0x80000102, 0}, 311 [7] = {0x80000103, 0}, 312 }; 313 314 const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = { 315 .h.type = PARAM_SP_IMAGE_BOOT_INFO, 316 .h.version = VERSION_1, 317 .h.size = sizeof(spm_mm_boot_info_t), 318 .h.attr = 0, 319 .sp_mem_base = ARM_SP_IMAGE_BASE, 320 .sp_mem_limit = ARM_SP_IMAGE_LIMIT, 321 .sp_image_base = ARM_SP_IMAGE_BASE, 322 .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, 323 .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE, 324 .sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE, 325 .sp_shared_buf_base = PLAT_SPM_BUF_BASE, 326 .sp_image_size = ARM_SP_IMAGE_SIZE, 327 .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, 328 .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE, 329 .sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE, 330 .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, 331 .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS, 332 .num_cpus = PLATFORM_CORE_COUNT, 333 .mp_info = &sp_mp_info[0], 334 }; 335 336 const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) 337 { 338 return plat_arm_secure_partition_mmap; 339 } 340 341 const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( 342 void *cookie) 343 { 344 return &plat_arm_secure_partition_boot_info; 345 } 346 #endif 347 348 /******************************************************************************* 349 * A single boot loader stack is expected to work on both the Foundation FVP 350 * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The 351 * SYS_ID register provides a mechanism for detecting the differences between 352 * these platforms. This information is stored in a per-BL array to allow the 353 * code to take the correct path.Per BL platform configuration. 354 ******************************************************************************/ 355 void __init fvp_config_setup(void) 356 { 357 unsigned int rev, hbi, bld, arch, sys_id; 358 359 sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); 360 rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK; 361 hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK; 362 bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK; 363 arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK; 364 365 if (arch != ARCH_MODEL) { 366 ERROR("This firmware is for FVP models\n"); 367 panic(); 368 } 369 370 /* 371 * The build field in the SYS_ID tells which variant of the GIC 372 * memory is implemented by the model. 373 */ 374 switch (bld) { 375 case BLD_GIC_VE_MMAP: 376 ERROR("Legacy Versatile Express memory map for GIC peripheral" 377 " is not supported\n"); 378 panic(); 379 break; 380 case BLD_GIC_A53A57_MMAP: 381 break; 382 default: 383 ERROR("Unsupported board build %x\n", bld); 384 panic(); 385 } 386 387 /* 388 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010 389 * for the Foundation FVP. 390 */ 391 switch (hbi) { 392 case HBI_FOUNDATION_FVP: 393 arm_config.flags = 0; 394 395 /* 396 * Check for supported revisions of Foundation FVP 397 * Allow future revisions to run but emit warning diagnostic 398 */ 399 switch (rev) { 400 case REV_FOUNDATION_FVP_V2_0: 401 case REV_FOUNDATION_FVP_V2_1: 402 case REV_FOUNDATION_FVP_v9_1: 403 case REV_FOUNDATION_FVP_v9_6: 404 break; 405 default: 406 WARN("Unrecognized Foundation FVP revision %x\n", rev); 407 break; 408 } 409 break; 410 case HBI_BASE_FVP: 411 arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC); 412 413 /* 414 * Check for supported revisions 415 * Allow future revisions to run but emit warning diagnostic 416 */ 417 switch (rev) { 418 case REV_BASE_FVP_V0: 419 arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400; 420 break; 421 case REV_BASE_FVP_REVC: 422 arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 | 423 ARM_CONFIG_FVP_HAS_CCI5XX); 424 break; 425 default: 426 WARN("Unrecognized Base FVP revision %x\n", rev); 427 break; 428 } 429 break; 430 default: 431 ERROR("Unsupported board HBI number 0x%x\n", hbi); 432 panic(); 433 } 434 435 /* 436 * We assume that the presence of MT bit, and therefore shifted 437 * affinities, is uniform across the platform: either all CPUs, or no 438 * CPUs implement it. 439 */ 440 if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U) 441 arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF; 442 } 443 444 445 void __init fvp_interconnect_init(void) 446 { 447 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 448 if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { 449 ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported"); 450 panic(); 451 } 452 453 plat_arm_interconnect_init(); 454 #else 455 uintptr_t cci_base = 0U; 456 const int *cci_map = NULL; 457 unsigned int map_size = 0U; 458 459 /* Initialize the right interconnect */ 460 if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) { 461 cci_base = PLAT_FVP_CCI5XX_BASE; 462 cci_map = fvp_cci5xx_map; 463 map_size = ARRAY_SIZE(fvp_cci5xx_map); 464 } else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) { 465 cci_base = PLAT_FVP_CCI400_BASE; 466 cci_map = fvp_cci400_map; 467 map_size = ARRAY_SIZE(fvp_cci400_map); 468 } else { 469 return; 470 } 471 472 assert(cci_base != 0U); 473 assert(cci_map != NULL); 474 cci_init(cci_base, cci_map, map_size); 475 #endif 476 } 477 478 void fvp_interconnect_enable(void) 479 { 480 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 481 plat_arm_interconnect_enter_coherency(); 482 #else 483 unsigned int master; 484 485 if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 486 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { 487 master = get_interconnect_master(); 488 cci_enable_snoop_dvm_reqs(master); 489 } 490 #endif 491 } 492 493 void fvp_interconnect_disable(void) 494 { 495 #if FVP_INTERCONNECT_DRIVER == FVP_CCN 496 plat_arm_interconnect_exit_coherency(); 497 #else 498 unsigned int master; 499 500 if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 501 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { 502 master = get_interconnect_master(); 503 cci_disable_snoop_dvm_reqs(master); 504 } 505 #endif 506 } 507 508 #if CRYPTO_SUPPORT 509 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) 510 { 511 assert(heap_addr != NULL); 512 assert(heap_size != NULL); 513 514 return arm_get_mbedtls_heap(heap_addr, heap_size); 515 } 516 #endif /* CRYPTO_SUPPORT */ 517 518 void fvp_timer_init(void) 519 { 520 #if USE_SP804_TIMER 521 /* Enable the clock override for SP804 timer 0, which means that no 522 * clock dividers are applied and the raw (35MHz) clock will be used. 523 */ 524 mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV); 525 526 /* Initialize delay timer driver using SP804 dual timer 0 */ 527 sp804_timer_init(V2M_SP804_TIMER0_BASE, 528 SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); 529 #else 530 generic_delay_timer_init(); 531 532 /* Enable System level generic timer */ 533 mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, 534 CNTCR_FCREQ(0U) | CNTCR_EN); 535 #endif /* USE_SP804_TIMER */ 536 } 537 538 /***************************************************************************** 539 * plat_is_smccc_feature_available() - This function checks whether SMCCC 540 * feature is availabile for platform. 541 * @fid: SMCCC function id 542 * 543 * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and 544 * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. 545 *****************************************************************************/ 546 int32_t plat_is_smccc_feature_available(u_register_t fid) 547 { 548 switch (fid) { 549 case SMCCC_ARCH_SOC_ID: 550 return SMC_ARCH_CALL_SUCCESS; 551 default: 552 return SMC_ARCH_CALL_NOT_SUPPORTED; 553 } 554 } 555 556 /* Get SOC version */ 557 int32_t plat_get_soc_version(void) 558 { 559 return (int32_t) 560 (SOC_ID_SET_JEP_106(ARM_SOC_CONTINUATION_CODE, 561 ARM_SOC_IDENTIFICATION_CODE) | 562 (FVP_SOC_ID & SOC_ID_IMPL_DEF_MASK)); 563 } 564 565 /* Get SOC revision */ 566 int32_t plat_get_soc_revision(void) 567 { 568 unsigned int sys_id; 569 570 sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); 571 return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) & 572 V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK); 573 } 574 575 #if ENABLE_RME 576 577 /* BDF mappings for RP0 RC0 */ 578 const struct bdf_mapping_info rc0rp0_bdf_data[] = { 579 /* BDF0 */ 580 {0U, /* mapping_base */ 581 0x8000U, /* mapping_top */ 582 0U, /* mapping_off */ 583 0U /* smmu_idx */ 584 } 585 }; 586 587 /* Root ports for RC0 */ 588 const struct root_port_info rc0rp_data[] = { 589 /* RP0 */ 590 {0U, /* root_port_id */ 591 0U, /* padding */ 592 ARRAY_SIZE(rc0rp0_bdf_data), /* num_bdf_mappings */ 593 (struct bdf_mapping_info *)rc0rp0_bdf_data /* bdf_mappings */ 594 } 595 }; 596 597 /* Root complexes */ 598 const struct root_complex_info rc_data[] = { 599 /* RC0 */ 600 {PCIE_EXP_BASE, /* ecam_base */ 601 0U, /* segment */ 602 {0U, 0U, 0U}, /* padding */ 603 ARRAY_SIZE(rc0rp_data), /* num_root_ports */ 604 (struct root_port_info *)rc0rp_data /* root_ports */ 605 } 606 }; 607 608 /* Number of PCIe Root Complexes */ 609 #define FVP_RMM_RC_COUNT ARRAY_SIZE(rc_data) 610 611 /* 612 * Get a pointer to the RMM-EL3 Shared buffer and return it 613 * through the pointer passed as parameter. 614 * 615 * This function returns the size of the shared buffer. 616 */ 617 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared) 618 { 619 *shared = (uintptr_t)RMM_SHARED_BASE; 620 621 return (size_t)RMM_SHARED_SIZE; 622 } 623 624 /* 625 * Calculate checksum of 64-bit words @buffer with @size length 626 */ 627 static uint64_t checksum_calc(uint64_t *buffer, size_t size) 628 { 629 uint64_t sum = 0UL; 630 631 assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL); 632 assert((size & (sizeof(uint64_t) - 1UL)) == 0UL); 633 634 for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) { 635 sum += buffer[i]; 636 } 637 638 return sum; 639 } 640 /* 641 * Boot Manifest v0.5 structure illustration, with two DRAM banks, 642 * a single console and one device memory with two PCIe device 643 * non-coherent address ranges. 644 * 645 * +--------------------------------------------------+ 646 * | offset | field | comment | 647 * +--------+--------------------+--------------------+ 648 * | 0 | version | 0x00000005 | 649 * +--------+--------------------+--------------------+ 650 * | 4 | padding | 0x00000000 | 651 * +--------+--------------------+--------------------+ 652 * | 8 | plat_data | NULL | 653 * +--------+--------------------+--------------------+ 654 * | 16 | num_banks | | 655 * +--------+--------------------+ | 656 * | 24 | banks | plat_dram +--+ 657 * +--------+--------------------+ | | 658 * | 32 | checksum | | | 659 * +--------+--------------------+--------------------+ | 660 * | 40 | num_consoles | | | 661 * +--------+--------------------+ | | 662 * | 48 | consoles | plat_console +--|--+ 663 * +--------+--------------------+ | | | 664 * | 56 | checksum | | | | 665 * +--------+--------------------+--------------------+ | | 666 * | 64 | num_banks | | | | 667 * +--------+--------------------+ | | | 668 * | 72 | banks | plat_ncoh_region +--|--|--+ 669 * +--------+--------------------+ | | | | 670 * | 80 | checksum | | | | | 671 * +--------+--------------------+--------------------+ | | | 672 * | 88 | num_banks | | | | | 673 * +--------+--------------------+ | | | | 674 * | 96 | banks | plat_coh_region | | | | 675 * +--------+--------------------+ | | | | 676 * | 104 | checksum | | | | | 677 * +--------+--------------------+--------------------+ | | | 678 * | 112 | num_smmus | | | | | 679 * +--------+--------------------+ | | | | 680 * | 120 | smmus | plat_smmu +--|--|--|--+ 681 * +--------+--------------------+ | | | | | 682 * | 128 | checksum | | | | | | 683 * +--------+--------------------+--------------------+ | | | | 684 * | 136 | num_root_complex | | | | | | 685 * +--------+--------------------+ | | | | | 686 * | 144 | rc_info_version | | | | | | 687 * +--------+--------------------+ | | | | | 688 * | 148 | padding | plat_root_complex +--|--|--|--|--+ 689 * +--------+--------------------+ | | | | | | 690 * | 152 | root_complex | | | | | | | 691 * +--------+--------------------+ | | | | | | 692 * | 160 | checksum | | | | | | | 693 * +--------+--------------------+--------------------+<-+ | | | | 694 * | 168 | base 0 | | | | | | 695 * +--------+--------------------+ mem_bank[0] | | | | | 696 * | 176 | size 0 | | | | | | 697 * +--------+--------------------+--------------------+ | | | | 698 * | 184 | base 1 | | | | | | 699 * +--------+--------------------+ mem_bank[1] | | | | | 700 * | 192 | size 1 | | | | | | 701 * +--------+--------------------+--------------------+<----+ | | | 702 * | 200 | base | | | | | 703 * +--------+--------------------+ | | | | 704 * | 208 | map_pages | | | | | 705 * +--------+--------------------+ | | | | 706 * | 216 | name | | | | | 707 * +--------+--------------------+ consoles[0] | | | | 708 * | 224 | clk_in_hz | | | | | 709 * +--------+--------------------+ | | | | 710 * | 232 | baud_rate | | | | | 711 * +--------+--------------------+ | | | | 712 * | 240 | flags | | | | | 713 * +--------+--------------------+--------------------+<-------+ | | 714 * | 248 | base 0 | | | | 715 * +--------+--------------------+ ncoh_region[0] | | | 716 * | 256 | size 0 | | | | 717 * +--------+--------------------+--------------------+ | | 718 * | 264 | base 1 | | | | 719 * +--------+--------------------+ ncoh_region[1] | | | 720 * | 272 | size 1 | | | | 721 * +--------+--------------------+--------------------+<----------+ | 722 * | 280 | smmu_base | | | 723 * +--------+--------------------+ smmus[0] | | 724 * | 288 | smmu_r_base | | | 725 * +--------+--------------------+--------------------+<-------------+ 726 * | 296 | ecam_base | | 727 * +--------+--------------------+ | 728 * | 304 | segment | | 729 * +--------+--------------------+ | 730 * | 305 | padding | root_complex[0] +--+ 731 * +--------+--------------------+ | | 732 * | 308 | num_root_ports | | | 733 * +--------+--------------------+ | | 734 * | 312 | root_ports | | | 735 * +--------+--------------------+--------------------+<-+ 736 * | 320 | root_port_id | | 737 * +--------+--------------------+ | 738 * | 322 | padding | | 739 * +--------+--------------------+ root_ports[0] +--+ 740 * | 324 | num_bdf_mappings | | | 741 * +--------+--------------------+ | | 742 * | 328 | bdf_mappings | | | 743 * +--------+--------------------+--------------------+<-+ 744 * | 336 | mapping_base | | 745 * +--------+--------------------+ | 746 * | 338 | mapping_top | | 747 * +--------+--------------------+ bdf_mappings[0] | 748 * | 340 | mapping_off | | 749 * +--------+--------------------+ | 750 * | 342 | smmu_idx | | 751 * +--------+--------------------+--------------------+ 752 */ 753 int plat_rmmd_load_manifest(struct rmm_manifest *manifest) 754 { 755 uint64_t checksum, num_banks, num_consoles; 756 uint64_t num_ncoh_regions, num_coh_regions; 757 uint64_t num_smmus, num_root_complex; 758 unsigned int num_root_ports, num_bdf_mappings; 759 uint32_t o_realm; 760 struct memory_bank *bank_ptr, *ncoh_region_ptr, *coh_region_ptr; 761 struct console_info *console_ptr; 762 struct smmu_info *smmu_ptr; 763 struct root_complex_info *root_complex_ptr, *rc_ptr; 764 struct root_port_info *root_port_ptr, *rp_ptr; 765 struct bdf_mapping_info *bdf_mapping_ptr, *bdf_ptr; 766 767 assert(manifest != NULL); 768 769 /* Get number of DRAM banks */ 770 num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks); 771 assert(num_banks <= ARM_DRAM_NUM_BANKS); 772 773 /* Set number of consoles */ 774 num_consoles = FVP_RMM_CONSOLE_COUNT; 775 776 /* Set number of device non-coherent address ranges based on DT */ 777 num_ncoh_regions = FCONF_GET_PROPERTY(hw_config, pci_props, num_ncoh_regions); 778 779 /* Set number of SMMUs */ 780 num_smmus = FVP_RMM_SMMU_COUNT; 781 782 /* Set number of PCIe root complexes */ 783 num_root_complex = FVP_RMM_RC_COUNT; 784 785 /* Calculate and set number of all PCIe root ports and BDF mappings */ 786 num_root_ports = 0U; 787 num_bdf_mappings = 0U; 788 789 /* Scan all root complex entries */ 790 for (unsigned long i = 0UL; i < num_root_complex; i++) { 791 num_root_ports += rc_data[i].num_root_ports; 792 793 /* Scan all root ports entries in root complex */ 794 for (unsigned int j = 0U; j < rc_data[i].num_root_ports; j++) { 795 num_bdf_mappings += rc_data[i].root_ports[j].num_bdf_mappings; 796 } 797 } 798 799 manifest->version = RMMD_MANIFEST_VERSION; 800 manifest->padding = 0U; /* RES0 */ 801 manifest->plat_data = 0UL; 802 manifest->plat_dram.num_banks = num_banks; 803 manifest->plat_console.num_consoles = num_consoles; 804 manifest->plat_ncoh_region.num_banks = num_ncoh_regions; 805 manifest->plat_smmu.num_smmus = num_smmus; 806 manifest->plat_root_complex.num_root_complex = num_root_complex; 807 manifest->plat_root_complex.rc_info_version = PCIE_RC_INFO_VERSION; 808 manifest->plat_root_complex.padding = 0U; /* RES0 */ 809 810 /* FVP does not support device coherent address ranges */ 811 num_coh_regions = 0UL; 812 manifest->plat_coh_region.num_banks = num_coh_regions; 813 manifest->plat_coh_region.banks = NULL; 814 manifest->plat_coh_region.checksum = 0UL; 815 816 bank_ptr = (struct memory_bank *) 817 (((uintptr_t)manifest) + sizeof(struct rmm_manifest)); 818 console_ptr = (struct console_info *) 819 ((uintptr_t)bank_ptr + (num_banks * 820 sizeof(struct memory_bank))); 821 ncoh_region_ptr = (struct memory_bank *) 822 ((uintptr_t)console_ptr + (num_consoles * 823 sizeof(struct console_info))); 824 coh_region_ptr = (struct memory_bank *) 825 ((uintptr_t)ncoh_region_ptr + (num_ncoh_regions * 826 sizeof(struct memory_bank))); 827 smmu_ptr = (struct smmu_info *) 828 ((uintptr_t)coh_region_ptr + (num_coh_regions * 829 sizeof(struct memory_bank))); 830 root_complex_ptr = (struct root_complex_info *) 831 ((uintptr_t)smmu_ptr + (num_smmus * 832 sizeof(struct smmu_info))); 833 root_port_ptr = (struct root_port_info *) 834 ((uintptr_t)root_complex_ptr + (num_root_complex * 835 sizeof(struct root_complex_info))); 836 bdf_mapping_ptr = (struct bdf_mapping_info *) 837 ((uintptr_t)root_port_ptr + (num_root_ports * 838 sizeof(struct root_port_info))); 839 840 manifest->plat_dram.banks = bank_ptr; 841 manifest->plat_console.consoles = console_ptr; 842 manifest->plat_ncoh_region.banks = ncoh_region_ptr; 843 manifest->plat_smmu.smmus = smmu_ptr; 844 manifest->plat_root_complex.root_complex = root_complex_ptr; 845 846 /* Ensure the manifest is not larger than the shared buffer */ 847 assert((sizeof(struct rmm_manifest) + 848 (sizeof(struct memory_bank) * 849 manifest->plat_dram.num_banks) + 850 (sizeof(struct console_info) * 851 manifest->plat_console.num_consoles) + 852 (sizeof(struct memory_bank) * 853 manifest->plat_ncoh_region.num_banks) + 854 (sizeof(struct memory_bank) * 855 manifest->plat_coh_region.num_banks) + 856 (sizeof(struct smmu_info) * 857 manifest->plat_smmu.num_smmus) + 858 (sizeof(struct root_complex_info) * 859 manifest->plat_root_complex.num_root_complex) + 860 (sizeof(struct root_port_info) * num_root_ports) + 861 (sizeof(struct bdf_mapping_info) * num_bdf_mappings)) 862 <= ARM_EL3_RMM_SHARED_SIZE); 863 864 /* Calculate checksum of plat_dram structure */ 865 checksum = num_banks + (uint64_t)bank_ptr; 866 867 /* Store FVP DRAM banks data in Boot Manifest */ 868 for (unsigned long i = 0UL; i < num_banks; i++) { 869 bank_ptr[i].base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base); 870 bank_ptr[i].size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size); 871 } 872 873 /* Update checksum */ 874 checksum += checksum_calc((uint64_t *)bank_ptr, sizeof(struct memory_bank) * num_banks); 875 876 /* Checksum must be 0 */ 877 manifest->plat_dram.checksum = ~checksum + 1UL; 878 879 /* Calculate the checksum of plat_consoles structure */ 880 checksum = num_consoles + (uint64_t)console_ptr; 881 882 /* Zero out the console info struct */ 883 (void)memset((void *)console_ptr, '\0', 884 sizeof(struct console_info) * num_consoles); 885 886 console_ptr[0].base = FVP_RMM_CONSOLE_BASE; 887 console_ptr[0].map_pages = 1UL; 888 console_ptr[0].clk_in_hz = FVP_RMM_CONSOLE_CLK_IN_HZ; 889 console_ptr[0].baud_rate = FVP_RMM_CONSOLE_BAUD; 890 891 (void)strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME, 892 RMM_CONSOLE_MAX_NAME_LEN - 1UL); 893 894 /* Update checksum */ 895 checksum += checksum_calc((uint64_t *)console_ptr, 896 sizeof(struct console_info) * num_consoles); 897 /* Checksum must be 0 */ 898 manifest->plat_console.checksum = ~checksum + 1UL; 899 900 /* 901 * Calculate the checksum of device non-coherent address ranges 902 * info structure 903 */ 904 checksum = num_ncoh_regions + (uint64_t)ncoh_region_ptr; 905 906 /* Zero out the PCIe region info struct */ 907 (void)memset((void *)ncoh_region_ptr, 0, 908 sizeof(struct memory_bank) * num_ncoh_regions); 909 910 for (unsigned long i = 0UL; i < num_ncoh_regions; i++) { 911 ncoh_region_ptr[i].base = 912 FCONF_GET_PROPERTY(hw_config, pci_props, ncoh_regions[i].base); 913 ncoh_region_ptr[i].size = 914 FCONF_GET_PROPERTY(hw_config, pci_props, ncoh_regions[i].size); 915 } 916 917 /* Update checksum */ 918 checksum += checksum_calc((uint64_t *)ncoh_region_ptr, 919 sizeof(struct memory_bank) * num_ncoh_regions); 920 921 /* Checksum must be 0 */ 922 manifest->plat_ncoh_region.checksum = ~checksum + 1UL; 923 924 /* Calculate the checksum of the plat_smmu structure */ 925 checksum = num_smmus + (uint64_t)smmu_ptr; 926 927 smmu_ptr[0].smmu_base = FVP_RMM_SMMU_BASE; 928 929 /* Read SMMU_ROOT_IDR0.BA_REALM[31:22] register field */ 930 o_realm = mmio_read_32(FVP_RMM_SMMU_BASE + SMMU_ROOT_IDR0) & 931 SMMU_ROOT_IDR0_BA_REALM_MASK; 932 /* 933 * Calculate the base address offset of Realm Register Page 0. 934 * O_REALM = 0x20000 + (BA_REALM * 0x10000) 935 * SMMU_REALM_BASE = SMMU_PAGE_0_BASE + O_REALM 936 */ 937 o_realm = 0x20000 + (o_realm >> (SMMU_ROOT_IDR0_BA_REALM_SHIFT - 16U)); 938 939 smmu_ptr[0].smmu_r_base = FVP_RMM_SMMU_BASE + o_realm; 940 941 /* Update checksum */ 942 checksum += checksum_calc((uint64_t *)smmu_ptr, 943 sizeof(struct smmu_info) * num_smmus); 944 /* Checksum must be 0 */ 945 manifest->plat_smmu.checksum = ~checksum + 1UL; 946 947 /* Calculate the checksum of the plat_root_complex structure */ 948 checksum = num_root_complex + (uint64_t)root_complex_ptr; 949 950 /* Zero out PCIe root complex info structures */ 951 (void)memset((void *)root_complex_ptr, 0, 952 sizeof(struct root_complex_info) * num_root_complex); 953 954 /* Set pointers for data in manifest */ 955 rc_ptr = root_complex_ptr; 956 rp_ptr = root_port_ptr; 957 bdf_ptr = bdf_mapping_ptr; 958 959 /* Fill PCIe root complex info structures */ 960 for (unsigned long i = 0U; i < num_root_complex; i++) { 961 const struct root_complex_info *rc_info = &rc_data[i]; 962 const struct root_port_info *rp_info = rc_info->root_ports; 963 964 /* Copy root complex data, except root_ports pointer */ 965 (void)memcpy((void *)rc_ptr, (void *)rc_info, 966 sizeof(struct root_complex_info) - sizeof(struct root_port_info *)); 967 968 /* Set root_ports for root complex */ 969 rc_ptr->root_ports = rp_ptr; 970 971 /* Scan root ports */ 972 for (unsigned int j = 0U; j < rc_ptr->num_root_ports; j++) { 973 const struct bdf_mapping_info *bdf_info = rp_info->bdf_mappings; 974 975 /* Copy root port data, except bdf_mappings pointer */ 976 (void)memcpy((void *)rp_ptr, (void *)rp_info, 977 sizeof(struct root_port_info) - sizeof(struct bdf_mapping_info *)); 978 979 /* Set bdf_mappings for root port */ 980 rp_ptr->bdf_mappings = bdf_ptr; 981 982 /* Copy all BDF mappings for root port */ 983 (void)memcpy((void *)bdf_ptr, (void *)bdf_info, 984 sizeof(struct bdf_mapping_info) * rp_ptr->num_bdf_mappings); 985 986 bdf_ptr += rp_ptr->num_bdf_mappings; 987 rp_ptr++; 988 rp_info++; 989 } 990 rc_ptr++; 991 } 992 993 /* Check that all data are written in manifest */ 994 assert(rc_ptr == (root_complex_ptr + num_root_complex)); 995 assert(rp_ptr == (root_port_ptr + num_root_ports)); 996 assert(bdf_ptr == (bdf_mapping_ptr + num_bdf_mappings)); 997 998 /* Update checksum for all PCIe data */ 999 checksum += checksum_calc((uint64_t *)root_complex_ptr, 1000 (uintptr_t)bdf_ptr - (uintptr_t)root_complex_ptr); 1001 1002 /* Checksum must be 0 */ 1003 manifest->plat_root_complex.checksum = ~checksum + 1UL; 1004 1005 return 0; 1006 } 1007 1008 /* 1009 * Update encryption key associated with @mecid. 1010 */ 1011 int plat_rmmd_mecid_key_update(uint16_t mecid) 1012 { 1013 /* 1014 * FVP does not provide an interface to change the encryption key associated 1015 * with MECID. Hence always return success. 1016 */ 1017 return 0; 1018 } 1019 #endif /* ENABLE_RME */ 1020