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