1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu /* This uses xlat_mpu, but tables are set up using V2 mmap_region_t */ 8*91f16700Schasinglulu #define XLAT_TABLES_LIB_V2 1 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <assert.h> 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu 13*91f16700Schasinglulu #include <drivers/arm/cci.h> 14*91f16700Schasinglulu #include <drivers/arm/gicv2.h> 15*91f16700Schasinglulu #include <drivers/arm/sp804_delay_timer.h> 16*91f16700Schasinglulu #include <drivers/generic_delay_timer.h> 17*91f16700Schasinglulu #include <lib/mmio.h> 18*91f16700Schasinglulu #include <lib/smccc.h> 19*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_compat.h> 20*91f16700Schasinglulu #include <services/arm_arch_svc.h> 21*91f16700Schasinglulu 22*91f16700Schasinglulu #include "fvp_r_private.h" 23*91f16700Schasinglulu #include <plat/arm/common/arm_config.h> 24*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h> 25*91f16700Schasinglulu #include <plat/common/platform.h> 26*91f16700Schasinglulu #include <platform_def.h> 27*91f16700Schasinglulu 28*91f16700Schasinglulu 29*91f16700Schasinglulu /* Defines for GIC Driver build time selection */ 30*91f16700Schasinglulu #define FVP_R_GICV3 2 31*91f16700Schasinglulu 32*91f16700Schasinglulu /******************************************************************************* 33*91f16700Schasinglulu * arm_config holds the characteristics of the differences between the FVP_R 34*91f16700Schasinglulu * platforms. It will be populated during cold boot at each boot stage by the 35*91f16700Schasinglulu * primary before enabling the MPU (to allow interconnect configuration) & 36*91f16700Schasinglulu * used thereafter. Each BL will have its own copy to allow independent 37*91f16700Schasinglulu * operation. 38*91f16700Schasinglulu ******************************************************************************/ 39*91f16700Schasinglulu arm_config_t arm_config; 40*91f16700Schasinglulu 41*91f16700Schasinglulu #define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ 42*91f16700Schasinglulu DEVICE0_SIZE, \ 43*91f16700Schasinglulu MT_DEVICE | MT_RW | MT_SECURE) 44*91f16700Schasinglulu 45*91f16700Schasinglulu #define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \ 46*91f16700Schasinglulu DEVICE1_SIZE, \ 47*91f16700Schasinglulu MT_DEVICE | MT_RW | MT_SECURE) 48*91f16700Schasinglulu 49*91f16700Schasinglulu /* 50*91f16700Schasinglulu * Need to be mapped with write permissions in order to set a new non-volatile 51*91f16700Schasinglulu * counter value. 52*91f16700Schasinglulu */ 53*91f16700Schasinglulu #define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ 54*91f16700Schasinglulu DEVICE2_SIZE, \ 55*91f16700Schasinglulu MT_DEVICE | MT_RW | MT_SECURE) 56*91f16700Schasinglulu 57*91f16700Schasinglulu /* 58*91f16700Schasinglulu * Table of memory regions for various BL stages to map using the MPU. 59*91f16700Schasinglulu * This doesn't include Trusted SRAM as setup_page_tables() already takes care 60*91f16700Schasinglulu * of mapping it. 61*91f16700Schasinglulu * 62*91f16700Schasinglulu * The flash needs to be mapped as writable in order to erase the FIP's Table of 63*91f16700Schasinglulu * Contents in case of unrecoverable error (see plat_error_handler()). 64*91f16700Schasinglulu */ 65*91f16700Schasinglulu #ifdef IMAGE_BL1 66*91f16700Schasinglulu const mmap_region_t plat_arm_mmap[] = { 67*91f16700Schasinglulu ARM_MAP_SHARED_RAM, 68*91f16700Schasinglulu V2M_MAP_FLASH0_RW, 69*91f16700Schasinglulu V2M_MAP_IOFPGA, 70*91f16700Schasinglulu MAP_DEVICE0, 71*91f16700Schasinglulu MAP_DEVICE1, 72*91f16700Schasinglulu #if TRUSTED_BOARD_BOOT 73*91f16700Schasinglulu /* To access the Root of Trust Public Key registers. */ 74*91f16700Schasinglulu MAP_DEVICE2, 75*91f16700Schasinglulu #endif 76*91f16700Schasinglulu {0} 77*91f16700Schasinglulu }; 78*91f16700Schasinglulu #endif 79*91f16700Schasinglulu 80*91f16700Schasinglulu ARM_CASSERT_MMAP 81*91f16700Schasinglulu 82*91f16700Schasinglulu static const int fvp_cci400_map[] = { 83*91f16700Schasinglulu PLAT_FVP_R_CCI400_CLUS0_SL_PORT, 84*91f16700Schasinglulu PLAT_FVP_R_CCI400_CLUS1_SL_PORT, 85*91f16700Schasinglulu }; 86*91f16700Schasinglulu 87*91f16700Schasinglulu static const int fvp_cci5xx_map[] = { 88*91f16700Schasinglulu PLAT_FVP_R_CCI5XX_CLUS0_SL_PORT, 89*91f16700Schasinglulu PLAT_FVP_R_CCI5XX_CLUS1_SL_PORT, 90*91f16700Schasinglulu }; 91*91f16700Schasinglulu 92*91f16700Schasinglulu static unsigned int get_interconnect_master(void) 93*91f16700Schasinglulu { 94*91f16700Schasinglulu unsigned int master; 95*91f16700Schasinglulu u_register_t mpidr; 96*91f16700Schasinglulu 97*91f16700Schasinglulu mpidr = read_mpidr_el1(); 98*91f16700Schasinglulu master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ? 99*91f16700Schasinglulu MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr); 100*91f16700Schasinglulu 101*91f16700Schasinglulu assert(master < FVP_R_CLUSTER_COUNT); 102*91f16700Schasinglulu return master; 103*91f16700Schasinglulu } 104*91f16700Schasinglulu 105*91f16700Schasinglulu /******************************************************************************* 106*91f16700Schasinglulu * Initialize the platform config for future decision making 107*91f16700Schasinglulu ******************************************************************************/ 108*91f16700Schasinglulu void __init fvp_config_setup(void) 109*91f16700Schasinglulu { 110*91f16700Schasinglulu unsigned int rev, hbi, bld, arch, sys_id; 111*91f16700Schasinglulu 112*91f16700Schasinglulu arm_config.flags |= ARM_CONFIG_BASE_MMAP; 113*91f16700Schasinglulu sys_id = mmio_read_32(V2M_FVP_R_SYSREGS_BASE + V2M_SYS_ID); 114*91f16700Schasinglulu rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK; 115*91f16700Schasinglulu hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK; 116*91f16700Schasinglulu bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK; 117*91f16700Schasinglulu arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK; 118*91f16700Schasinglulu 119*91f16700Schasinglulu if (arch != ARCH_MODEL) { 120*91f16700Schasinglulu ERROR("This firmware is for FVP_R models\n"); 121*91f16700Schasinglulu panic(); 122*91f16700Schasinglulu } 123*91f16700Schasinglulu 124*91f16700Schasinglulu /* 125*91f16700Schasinglulu * The build field in the SYS_ID tells which variant of the GIC 126*91f16700Schasinglulu * memory is implemented by the model. 127*91f16700Schasinglulu */ 128*91f16700Schasinglulu switch (bld) { 129*91f16700Schasinglulu case BLD_GIC_VE_MMAP: 130*91f16700Schasinglulu ERROR("Legacy Versatile Express memory map for GIC %s", 131*91f16700Schasinglulu "peripheral is not supported\n"); 132*91f16700Schasinglulu panic(); 133*91f16700Schasinglulu break; 134*91f16700Schasinglulu case BLD_GIC_A53A57_MMAP: 135*91f16700Schasinglulu break; 136*91f16700Schasinglulu default: 137*91f16700Schasinglulu ERROR("Unsupported board build %x\n", bld); 138*91f16700Schasinglulu panic(); 139*91f16700Schasinglulu } 140*91f16700Schasinglulu 141*91f16700Schasinglulu /* 142*91f16700Schasinglulu * The hbi field in the SYS_ID is 0x020 for the Base FVP_R & 0x010 143*91f16700Schasinglulu * for the Foundation FVP_R. 144*91f16700Schasinglulu */ 145*91f16700Schasinglulu switch (hbi) { 146*91f16700Schasinglulu case HBI_FOUNDATION_FVP_R: 147*91f16700Schasinglulu arm_config.flags = 0; 148*91f16700Schasinglulu 149*91f16700Schasinglulu /* 150*91f16700Schasinglulu * Check for supported revisions of Foundation FVP_R 151*91f16700Schasinglulu * Allow future revisions to run but emit warning diagnostic 152*91f16700Schasinglulu */ 153*91f16700Schasinglulu switch (rev) { 154*91f16700Schasinglulu case REV_FOUNDATION_FVP_R_V2_0: 155*91f16700Schasinglulu case REV_FOUNDATION_FVP_R_V2_1: 156*91f16700Schasinglulu case REV_FOUNDATION_FVP_R_v9_1: 157*91f16700Schasinglulu case REV_FOUNDATION_FVP_R_v9_6: 158*91f16700Schasinglulu break; 159*91f16700Schasinglulu default: 160*91f16700Schasinglulu WARN("Unrecognized Foundation FVP_R revision %x\n", rev); 161*91f16700Schasinglulu break; 162*91f16700Schasinglulu } 163*91f16700Schasinglulu break; 164*91f16700Schasinglulu case HBI_BASE_FVP_R: 165*91f16700Schasinglulu arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC); 166*91f16700Schasinglulu 167*91f16700Schasinglulu /* 168*91f16700Schasinglulu * Check for supported revisions 169*91f16700Schasinglulu * Allow future revisions to run but emit warning diagnostic 170*91f16700Schasinglulu */ 171*91f16700Schasinglulu switch (rev) { 172*91f16700Schasinglulu case REV_BASE_FVP_R_V0: 173*91f16700Schasinglulu arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400; 174*91f16700Schasinglulu break; 175*91f16700Schasinglulu default: 176*91f16700Schasinglulu WARN("Unrecognized Base FVP_R revision %x\n", rev); 177*91f16700Schasinglulu break; 178*91f16700Schasinglulu } 179*91f16700Schasinglulu break; 180*91f16700Schasinglulu default: 181*91f16700Schasinglulu ERROR("Unsupported board HBI number 0x%x\n", hbi); 182*91f16700Schasinglulu panic(); 183*91f16700Schasinglulu } 184*91f16700Schasinglulu 185*91f16700Schasinglulu /* 186*91f16700Schasinglulu * We assume that the presence of MT bit, and therefore shifted 187*91f16700Schasinglulu * affinities, is uniform across the platform: either all CPUs, or no 188*91f16700Schasinglulu * CPUs implement it. 189*91f16700Schasinglulu */ 190*91f16700Schasinglulu if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U) { 191*91f16700Schasinglulu arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF; 192*91f16700Schasinglulu } 193*91f16700Schasinglulu } 194*91f16700Schasinglulu 195*91f16700Schasinglulu 196*91f16700Schasinglulu void __init fvp_interconnect_init(void) 197*91f16700Schasinglulu { 198*91f16700Schasinglulu uintptr_t cci_base = 0U; 199*91f16700Schasinglulu const int *cci_map = NULL; 200*91f16700Schasinglulu unsigned int map_size = 0U; 201*91f16700Schasinglulu 202*91f16700Schasinglulu /* Initialize the right interconnect */ 203*91f16700Schasinglulu if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) { 204*91f16700Schasinglulu cci_base = PLAT_FVP_R_CCI5XX_BASE; 205*91f16700Schasinglulu cci_map = fvp_cci5xx_map; 206*91f16700Schasinglulu map_size = ARRAY_SIZE(fvp_cci5xx_map); 207*91f16700Schasinglulu } else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) { 208*91f16700Schasinglulu cci_base = PLAT_FVP_R_CCI400_BASE; 209*91f16700Schasinglulu cci_map = fvp_cci400_map; 210*91f16700Schasinglulu map_size = ARRAY_SIZE(fvp_cci400_map); 211*91f16700Schasinglulu } else { 212*91f16700Schasinglulu return; 213*91f16700Schasinglulu } 214*91f16700Schasinglulu 215*91f16700Schasinglulu assert(cci_base != 0U); 216*91f16700Schasinglulu assert(cci_map != NULL); 217*91f16700Schasinglulu cci_init(cci_base, cci_map, map_size); 218*91f16700Schasinglulu } 219*91f16700Schasinglulu 220*91f16700Schasinglulu void fvp_interconnect_enable(void) 221*91f16700Schasinglulu { 222*91f16700Schasinglulu unsigned int master; 223*91f16700Schasinglulu 224*91f16700Schasinglulu if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 225*91f16700Schasinglulu ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { 226*91f16700Schasinglulu master = get_interconnect_master(); 227*91f16700Schasinglulu cci_enable_snoop_dvm_reqs(master); 228*91f16700Schasinglulu } 229*91f16700Schasinglulu } 230*91f16700Schasinglulu 231*91f16700Schasinglulu void fvp_interconnect_disable(void) 232*91f16700Schasinglulu { 233*91f16700Schasinglulu unsigned int master; 234*91f16700Schasinglulu 235*91f16700Schasinglulu if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | 236*91f16700Schasinglulu ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { 237*91f16700Schasinglulu master = get_interconnect_master(); 238*91f16700Schasinglulu cci_disable_snoop_dvm_reqs(master); 239*91f16700Schasinglulu } 240*91f16700Schasinglulu } 241*91f16700Schasinglulu 242*91f16700Schasinglulu #if TRUSTED_BOARD_BOOT 243*91f16700Schasinglulu int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) 244*91f16700Schasinglulu { 245*91f16700Schasinglulu assert(heap_addr != NULL); 246*91f16700Schasinglulu assert(heap_size != NULL); 247*91f16700Schasinglulu 248*91f16700Schasinglulu return arm_get_mbedtls_heap(heap_addr, heap_size); 249*91f16700Schasinglulu } 250*91f16700Schasinglulu #endif 251*91f16700Schasinglulu 252*91f16700Schasinglulu void fvp_timer_init(void) 253*91f16700Schasinglulu { 254*91f16700Schasinglulu #if USE_SP804_TIMER 255*91f16700Schasinglulu /* Enable the clock override for SP804 timer 0, which means that no 256*91f16700Schasinglulu * clock dividers are applied and the raw (35MHz) clock will be used. 257*91f16700Schasinglulu */ 258*91f16700Schasinglulu mmio_write_32(V2M_SP810_BASE, FVP_R_SP810_CTRL_TIM0_OV); 259*91f16700Schasinglulu 260*91f16700Schasinglulu /* Initialize delay timer driver using SP804 dual timer 0 */ 261*91f16700Schasinglulu sp804_timer_init(V2M_SP804_TIMER0_BASE, 262*91f16700Schasinglulu SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); 263*91f16700Schasinglulu #else 264*91f16700Schasinglulu generic_delay_timer_init(); 265*91f16700Schasinglulu 266*91f16700Schasinglulu /* Enable System level generic timer */ 267*91f16700Schasinglulu mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, 268*91f16700Schasinglulu CNTCR_FCREQ(0U) | CNTCR_EN); 269*91f16700Schasinglulu #endif /* USE_SP804_TIMER */ 270*91f16700Schasinglulu } 271*91f16700Schasinglulu 272*91f16700Schasinglulu /* Get SOC version */ 273*91f16700Schasinglulu int32_t plat_get_soc_version(void) 274*91f16700Schasinglulu { 275*91f16700Schasinglulu return (int32_t) 276*91f16700Schasinglulu ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT) 277*91f16700Schasinglulu | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT) 278*91f16700Schasinglulu | FVP_R_SOC_ID); 279*91f16700Schasinglulu } 280*91f16700Schasinglulu 281*91f16700Schasinglulu /* Get SOC revision */ 282*91f16700Schasinglulu int32_t plat_get_soc_revision(void) 283*91f16700Schasinglulu { 284*91f16700Schasinglulu unsigned int sys_id; 285*91f16700Schasinglulu 286*91f16700Schasinglulu sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); 287*91f16700Schasinglulu return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) & 288*91f16700Schasinglulu V2M_SYS_ID_REV_MASK); 289*91f16700Schasinglulu } 290