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