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