Home | History | Annotate | Download | only in aarch64
      1 /*
      2  * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are met:
      6  *
      7  * Redistributions of source code must retain the above copyright notice, this
      8  * list of conditions and the following disclaimer.
      9  *
     10  * Redistributions in binary form must reproduce the above copyright notice,
     11  * this list of conditions and the following disclaimer in the documentation
     12  * and/or other materials provided with the distribution.
     13  *
     14  * Neither the name of ARM nor the names of its contributors may be used
     15  * to endorse or promote products derived from this software without specific
     16  * prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     28  * POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include <arch.h>
     32 #include <arch_helpers.h>
     33 #include <arm_gic.h>
     34 #include <bl_common.h>
     35 #include <cci400.h>
     36 #include <debug.h>
     37 #include <mmio.h>
     38 #include <platform.h>
     39 #include <platform_def.h>
     40 #include <plat_config.h>
     41 #include <xlat_tables.h>
     42 #include "../fvp_def.h"
     43 
     44 /*******************************************************************************
     45  * plat_config holds the characteristics of the differences between the three
     46  * FVP platforms (Base, A53_A57 & Foundation). It will be populated during cold
     47  * boot at each boot stage by the primary before enabling the MMU (to allow cci
     48  * configuration) & used thereafter. Each BL will have its own copy to allow
     49  * independent operation.
     50  ******************************************************************************/
     51 plat_config_t plat_config;
     52 
     53 #define MAP_SHARED_RAM	MAP_REGION_FLAT(FVP_SHARED_MEM_BASE,		\
     54 					FVP_SHARED_MEM_SIZE,		\
     55 					MT_MEMORY | MT_RW | MT_SECURE)
     56 
     57 #define MAP_FLASH0	MAP_REGION_FLAT(FLASH0_BASE,			\
     58 					FLASH0_SIZE,			\
     59 					MT_MEMORY | MT_RO | MT_SECURE)
     60 
     61 #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
     62 					DEVICE0_SIZE,			\
     63 					MT_DEVICE | MT_RW | MT_SECURE)
     64 
     65 #define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
     66 					DEVICE1_SIZE,			\
     67 					MT_DEVICE | MT_RW | MT_SECURE)
     68 
     69 #define MAP_DRAM1_NS	MAP_REGION_FLAT(DRAM1_NS_BASE,			\
     70 					DRAM1_NS_SIZE,			\
     71 					MT_MEMORY | MT_RW | MT_NS)
     72 
     73 #define MAP_TSP_SEC_MEM	MAP_REGION_FLAT(TSP_SEC_MEM_BASE,		\
     74 					TSP_SEC_MEM_SIZE,		\
     75 					MT_MEMORY | MT_RW | MT_SECURE)
     76 
     77 /*
     78  * Table of regions for various BL stages to map using the MMU.
     79  * This doesn't include TZRAM as the 'mem_layout' argument passed to
     80  * configure_mmu_elx() will give the available subset of that,
     81  */
     82 #if IMAGE_BL1
     83 const mmap_region_t fvp_mmap[] = {
     84 	MAP_SHARED_RAM,
     85 	MAP_FLASH0,
     86 	MAP_DEVICE0,
     87 	MAP_DEVICE1,
     88 	{0}
     89 };
     90 #endif
     91 #if IMAGE_BL2
     92 const mmap_region_t fvp_mmap[] = {
     93 	MAP_SHARED_RAM,
     94 	MAP_FLASH0,
     95 	MAP_DEVICE0,
     96 	MAP_DEVICE1,
     97 	MAP_DRAM1_NS,
     98 	MAP_TSP_SEC_MEM,
     99 	{0}
    100 };
    101 #endif
    102 #if IMAGE_BL31
    103 const mmap_region_t fvp_mmap[] = {
    104 	MAP_SHARED_RAM,
    105 	MAP_DEVICE0,
    106 	MAP_DEVICE1,
    107 	MAP_TSP_SEC_MEM,
    108 	{0}
    109 };
    110 #endif
    111 #if IMAGE_BL32
    112 const mmap_region_t fvp_mmap[] = {
    113 	MAP_DEVICE0,
    114 	MAP_DEVICE1,
    115 	{0}
    116 };
    117 #endif
    118 
    119 /* Array of secure interrupts to be configured by the gic driver */
    120 const unsigned int irq_sec_array[] = {
    121 	IRQ_TZ_WDOG,
    122 	IRQ_SEC_PHY_TIMER,
    123 	IRQ_SEC_SGI_0,
    124 	IRQ_SEC_SGI_1,
    125 	IRQ_SEC_SGI_2,
    126 	IRQ_SEC_SGI_3,
    127 	IRQ_SEC_SGI_4,
    128 	IRQ_SEC_SGI_5,
    129 	IRQ_SEC_SGI_6,
    130 	IRQ_SEC_SGI_7
    131 };
    132 
    133 const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
    134 	sizeof(irq_sec_array[0]);
    135 
    136 /*******************************************************************************
    137  * Macro generating the code for the function setting up the pagetables as per
    138  * the platform memory map & initialize the mmu, for the given exception level
    139  ******************************************************************************/
    140 #if USE_COHERENT_MEM
    141 #define DEFINE_CONFIGURE_MMU_EL(_el)				\
    142 	void fvp_configure_mmu_el##_el(unsigned long total_base,	\
    143 				   unsigned long total_size,		\
    144 				   unsigned long ro_start,		\
    145 				   unsigned long ro_limit,		\
    146 				   unsigned long coh_start,		\
    147 				   unsigned long coh_limit)		\
    148 	{								\
    149 		mmap_add_region(total_base, total_base,			\
    150 				total_size,				\
    151 				MT_MEMORY | MT_RW | MT_SECURE);		\
    152 		mmap_add_region(ro_start, ro_start,			\
    153 				ro_limit - ro_start,			\
    154 				MT_MEMORY | MT_RO | MT_SECURE);		\
    155 		mmap_add_region(coh_start, coh_start,			\
    156 				coh_limit - coh_start,			\
    157 				MT_DEVICE | MT_RW | MT_SECURE);		\
    158 		mmap_add(fvp_mmap);					\
    159 		init_xlat_tables();					\
    160 									\
    161 		enable_mmu_el##_el(0);					\
    162 	}
    163 #else
    164 #define DEFINE_CONFIGURE_MMU_EL(_el)				\
    165 	void fvp_configure_mmu_el##_el(unsigned long total_base,	\
    166 				   unsigned long total_size,		\
    167 				   unsigned long ro_start,		\
    168 				   unsigned long ro_limit)		\
    169 	{								\
    170 		mmap_add_region(total_base, total_base,			\
    171 				total_size,				\
    172 				MT_MEMORY | MT_RW | MT_SECURE);		\
    173 		mmap_add_region(ro_start, ro_start,			\
    174 				ro_limit - ro_start,			\
    175 				MT_MEMORY | MT_RO | MT_SECURE);		\
    176 		mmap_add(fvp_mmap);					\
    177 		init_xlat_tables();					\
    178 									\
    179 		enable_mmu_el##_el(0);					\
    180 	}
    181 #endif
    182 
    183 /* Define EL1 and EL3 variants of the function initialising the MMU */
    184 DEFINE_CONFIGURE_MMU_EL(1)
    185 DEFINE_CONFIGURE_MMU_EL(3)
    186 
    187 /*******************************************************************************
    188  * A single boot loader stack is expected to work on both the Foundation FVP
    189  * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
    190  * SYS_ID register provides a mechanism for detecting the differences between
    191  * these platforms. This information is stored in a per-BL array to allow the
    192  * code to take the correct path.Per BL platform configuration.
    193  ******************************************************************************/
    194 int fvp_config_setup(void)
    195 {
    196 	unsigned int rev, hbi, bld, arch, sys_id;
    197 
    198 	sys_id = mmio_read_32(VE_SYSREGS_BASE + V2M_SYS_ID);
    199 	rev = (sys_id >> SYS_ID_REV_SHIFT) & SYS_ID_REV_MASK;
    200 	hbi = (sys_id >> SYS_ID_HBI_SHIFT) & SYS_ID_HBI_MASK;
    201 	bld = (sys_id >> SYS_ID_BLD_SHIFT) & SYS_ID_BLD_MASK;
    202 	arch = (sys_id >> SYS_ID_ARCH_SHIFT) & SYS_ID_ARCH_MASK;
    203 
    204 	if (arch != ARCH_MODEL) {
    205 		ERROR("This firmware is for FVP models\n");
    206 		panic();
    207 	}
    208 
    209 	/*
    210 	 * The build field in the SYS_ID tells which variant of the GIC
    211 	 * memory is implemented by the model.
    212 	 */
    213 	switch (bld) {
    214 	case BLD_GIC_VE_MMAP:
    215 		plat_config.gicd_base = VE_GICD_BASE;
    216 		plat_config.gicc_base = VE_GICC_BASE;
    217 		plat_config.gich_base = VE_GICH_BASE;
    218 		plat_config.gicv_base = VE_GICV_BASE;
    219 		break;
    220 	case BLD_GIC_A53A57_MMAP:
    221 		plat_config.gicd_base = BASE_GICD_BASE;
    222 		plat_config.gicc_base = BASE_GICC_BASE;
    223 		plat_config.gich_base = BASE_GICH_BASE;
    224 		plat_config.gicv_base = BASE_GICV_BASE;
    225 		break;
    226 	default:
    227 		ERROR("Unsupported board build %x\n", bld);
    228 		panic();
    229 	}
    230 
    231 	/*
    232 	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
    233 	 * for the Foundation FVP.
    234 	 */
    235 	switch (hbi) {
    236 	case HBI_FOUNDATION:
    237 		plat_config.max_aff0 = 4;
    238 		plat_config.max_aff1 = 1;
    239 		plat_config.flags = 0;
    240 
    241 		/*
    242 		 * Check for supported revisions of Foundation FVP
    243 		 * Allow future revisions to run but emit warning diagnostic
    244 		 */
    245 		switch (rev) {
    246 		case REV_FOUNDATION_V2_0:
    247 		case REV_FOUNDATION_V2_1:
    248 			break;
    249 		default:
    250 			WARN("Unrecognized Foundation FVP revision %x\n", rev);
    251 			break;
    252 		}
    253 		break;
    254 	case HBI_FVP_BASE:
    255 		plat_config.max_aff0 = 4;
    256 		plat_config.max_aff1 = 2;
    257 		plat_config.flags |= CONFIG_BASE_MMAP | CONFIG_HAS_CCI |
    258 			CONFIG_HAS_TZC;
    259 
    260 		/*
    261 		 * Check for supported revisions
    262 		 * Allow future revisions to run but emit warning diagnostic
    263 		 */
    264 		switch (rev) {
    265 		case REV_FVP_BASE_V0:
    266 			break;
    267 		default:
    268 			WARN("Unrecognized Base FVP revision %x\n", rev);
    269 			break;
    270 		}
    271 		break;
    272 	default:
    273 		ERROR("Unsupported board HBI number 0x%x\n", hbi);
    274 		panic();
    275 	}
    276 
    277 	return 0;
    278 }
    279 
    280 unsigned long plat_get_ns_image_entrypoint(void)
    281 {
    282 	return NS_IMAGE_OFFSET;
    283 }
    284 
    285 uint64_t plat_get_syscnt_freq(void)
    286 {
    287 	uint64_t counter_base_frequency;
    288 
    289 	/* Read the frequency from Frequency modes table */
    290 	counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
    291 
    292 	/* The first entry of the frequency modes table must not be 0 */
    293 	if (counter_base_frequency == 0)
    294 		panic();
    295 
    296 	return counter_base_frequency;
    297 }
    298 
    299 void fvp_cci_init(void)
    300 {
    301 	/*
    302 	 * Initialize CCI-400 driver
    303 	 */
    304 	if (plat_config.flags & CONFIG_HAS_CCI)
    305 		cci_init(CCI400_BASE,
    306 			CCI400_SL_IFACE3_CLUSTER_IX,
    307 			CCI400_SL_IFACE4_CLUSTER_IX);
    308 }
    309 
    310 void fvp_cci_enable(void)
    311 {
    312 	/*
    313 	 * Enable CCI-400 coherency for this cluster. No need
    314 	 * for locks as no other cpu is active at the
    315 	 * moment
    316 	 */
    317 	if (plat_config.flags & CONFIG_HAS_CCI)
    318 		cci_enable_cluster_coherency(read_mpidr());
    319 }
    320 
    321 void fvp_gic_init(void)
    322 {
    323 	arm_gic_init(plat_config.gicc_base,
    324 		plat_config.gicd_base,
    325 		BASE_GICR_BASE,
    326 		irq_sec_array,
    327 		num_sec_irqs);
    328 }
    329 
    330 
    331 /*******************************************************************************
    332  * Gets SPSR for BL32 entry
    333  ******************************************************************************/
    334 uint32_t fvp_get_spsr_for_bl32_entry(void)
    335 {
    336 	/*
    337 	 * The Secure Payload Dispatcher service is responsible for
    338 	 * setting the SPSR prior to entry into the BL32 image.
    339 	 */
    340 	return 0;
    341 }
    342 
    343 /*******************************************************************************
    344  * Gets SPSR for BL33 entry
    345  ******************************************************************************/
    346 uint32_t fvp_get_spsr_for_bl33_entry(void)
    347 {
    348 	unsigned long el_status;
    349 	unsigned int mode;
    350 	uint32_t spsr;
    351 
    352 	/* Figure out what mode we enter the non-secure world in */
    353 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
    354 	el_status &= ID_AA64PFR0_ELX_MASK;
    355 
    356 	if (el_status)
    357 		mode = MODE_EL2;
    358 	else
    359 		mode = MODE_EL1;
    360 
    361 	/*
    362 	 * TODO: Consider the possibility of specifying the SPSR in
    363 	 * the FIP ToC and allowing the platform to have a say as
    364 	 * well.
    365 	 */
    366 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
    367 	return spsr;
    368 }
    369