blob: fcda2a87820802d41c436b7f8a26620fb9ec6e1c [file] [log] [blame]
Achin Gupta4f6ad662013-10-25 09:08:21 +01001/*
Dan Handleye83b0ca2014-01-14 18:17:09 +00002 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
Achin Gupta4f6ad662013-10-25 09:08:21 +01003 *
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
Dan Handley2bd4ef22014-04-09 13:14:54 +010031#include <arch.h>
Achin Gupta4f6ad662013-10-25 09:08:21 +010032#include <arch_helpers.h>
Dan Handleyfb42b122014-06-20 09:43:15 +010033#include <arm_gic.h>
Dan Handley2bd4ef22014-04-09 13:14:54 +010034#include <bl_common.h>
Vikram Kanigiri96377452014-04-24 11:02:16 +010035#include <cci400.h>
Dan Handley714a0d22014-04-09 13:13:04 +010036#include <debug.h>
Dan Handley2bd4ef22014-04-09 13:14:54 +010037#include <mmio.h>
Jon Medhurstb1eb0932014-02-26 16:27:53 +000038#include <platform.h>
Soby Mathewb08bc042014-09-03 17:48:44 +010039#include <platform_def.h>
Dan Handley1c54d972014-06-20 12:02:01 +010040#include <plat_config.h>
Jon Medhurstb1eb0932014-02-26 16:27:53 +000041#include <xlat_tables.h>
Dan Handleyed6ff952014-05-14 17:44:19 +010042#include "../fvp_def.h"
Achin Gupta4f6ad662013-10-25 09:08:21 +010043
Achin Gupta4f6ad662013-10-25 09:08:21 +010044/*******************************************************************************
Dan Handley1c54d972014-06-20 12:02:01 +010045 * plat_config holds the characteristics of the differences between the three
Achin Gupta4f6ad662013-10-25 09:08:21 +010046 * 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 ******************************************************************************/
Dan Handley1c54d972014-06-20 12:02:01 +010051plat_config_t plat_config;
Achin Gupta4f6ad662013-10-25 09:08:21 +010052
Juan Castillo42a617d2014-09-24 10:00:06 +010053#define MAP_SHARED_RAM MAP_REGION_FLAT(FVP_SHARED_MEM_BASE, \
54 FVP_SHARED_MEM_SIZE, \
Soby Mathewb08bc042014-09-03 17:48:44 +010055 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
Juan Castillof3e02182014-12-19 09:28:30 +000069#define MAP_DRAM1_NS MAP_REGION_FLAT(DRAM1_NS_BASE, \
70 DRAM1_NS_SIZE, \
Soby Mathewb08bc042014-09-03 17:48:44 +010071 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
Jon Medhurstb1eb0932014-02-26 16:27:53 +000077/*
Soby Mathewb08bc042014-09-03 17:48:44 +010078 * Table of regions for various BL stages to map using the MMU.
Sandrine Bailleux74a62b32014-05-09 11:35:36 +010079 * This doesn't include TZRAM as the 'mem_layout' argument passed to
80 * configure_mmu_elx() will give the available subset of that,
Jon Medhurstb1eb0932014-02-26 16:27:53 +000081 */
Soby Mathewb08bc042014-09-03 17:48:44 +010082#if IMAGE_BL1
83const 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
92const mmap_region_t fvp_mmap[] = {
93 MAP_SHARED_RAM,
94 MAP_FLASH0,
95 MAP_DEVICE0,
96 MAP_DEVICE1,
Juan Castillof3e02182014-12-19 09:28:30 +000097 MAP_DRAM1_NS,
Soby Mathewb08bc042014-09-03 17:48:44 +010098 MAP_TSP_SEC_MEM,
99 {0}
100};
101#endif
102#if IMAGE_BL31
103const mmap_region_t fvp_mmap[] = {
104 MAP_SHARED_RAM,
105 MAP_DEVICE0,
106 MAP_DEVICE1,
107 {0}
108};
109#endif
110#if IMAGE_BL32
Dan Handleye2712bc2014-04-10 15:37:22 +0100111const mmap_region_t fvp_mmap[] = {
Soby Mathewb08bc042014-09-03 17:48:44 +0100112 MAP_DEVICE0,
113 MAP_DEVICE1,
Jon Medhurstb1eb0932014-02-26 16:27:53 +0000114 {0}
115};
Soby Mathewb08bc042014-09-03 17:48:44 +0100116#endif
Jon Medhurstb1eb0932014-02-26 16:27:53 +0000117
Soby Mathew13ee9682015-01-22 11:22:22 +0000118CASSERT((sizeof(fvp_mmap)/sizeof(fvp_mmap[0])) + FVP_BL_REGIONS \
119 <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
120
Dan Handleyfb42b122014-06-20 09:43:15 +0100121/* Array of secure interrupts to be configured by the gic driver */
122const unsigned int irq_sec_array[] = {
123 IRQ_TZ_WDOG,
124 IRQ_SEC_PHY_TIMER,
125 IRQ_SEC_SGI_0,
126 IRQ_SEC_SGI_1,
127 IRQ_SEC_SGI_2,
128 IRQ_SEC_SGI_3,
129 IRQ_SEC_SGI_4,
130 IRQ_SEC_SGI_5,
131 IRQ_SEC_SGI_6,
132 IRQ_SEC_SGI_7
133};
134
135const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
136 sizeof(irq_sec_array[0]);
137
Achin Gupta4f6ad662013-10-25 09:08:21 +0100138/*******************************************************************************
Sandrine Bailleux74a62b32014-05-09 11:35:36 +0100139 * Macro generating the code for the function setting up the pagetables as per
140 * the platform memory map & initialize the mmu, for the given exception level
141 ******************************************************************************/
Soby Mathew2ae20432015-01-08 18:02:44 +0000142#if USE_COHERENT_MEM
143#define DEFINE_CONFIGURE_MMU_EL(_el) \
Lin Ma13592362014-06-02 11:45:36 -0700144 void fvp_configure_mmu_el##_el(unsigned long total_base, \
Vikram Kanigirid8c9d262014-05-16 18:48:12 +0100145 unsigned long total_size, \
Sandrine Bailleux74a62b32014-05-09 11:35:36 +0100146 unsigned long ro_start, \
147 unsigned long ro_limit, \
148 unsigned long coh_start, \
149 unsigned long coh_limit) \
150 { \
Lin Ma13592362014-06-02 11:45:36 -0700151 mmap_add_region(total_base, total_base, \
Vikram Kanigirid8c9d262014-05-16 18:48:12 +0100152 total_size, \
Sandrine Bailleux74a62b32014-05-09 11:35:36 +0100153 MT_MEMORY | MT_RW | MT_SECURE); \
Lin Ma13592362014-06-02 11:45:36 -0700154 mmap_add_region(ro_start, ro_start, \
155 ro_limit - ro_start, \
Sandrine Bailleux74a62b32014-05-09 11:35:36 +0100156 MT_MEMORY | MT_RO | MT_SECURE); \
Lin Ma13592362014-06-02 11:45:36 -0700157 mmap_add_region(coh_start, coh_start, \
158 coh_limit - coh_start, \
Sandrine Bailleux74a62b32014-05-09 11:35:36 +0100159 MT_DEVICE | MT_RW | MT_SECURE); \
160 mmap_add(fvp_mmap); \
161 init_xlat_tables(); \
162 \
Achin Guptae9982542014-06-26 08:59:07 +0100163 enable_mmu_el##_el(0); \
Sandrine Bailleux74a62b32014-05-09 11:35:36 +0100164 }
Soby Mathew2ae20432015-01-08 18:02:44 +0000165#else
166#define DEFINE_CONFIGURE_MMU_EL(_el) \
167 void fvp_configure_mmu_el##_el(unsigned long total_base, \
168 unsigned long total_size, \
169 unsigned long ro_start, \
170 unsigned long ro_limit) \
171 { \
172 mmap_add_region(total_base, total_base, \
173 total_size, \
174 MT_MEMORY | MT_RW | MT_SECURE); \
175 mmap_add_region(ro_start, ro_start, \
176 ro_limit - ro_start, \
177 MT_MEMORY | MT_RO | MT_SECURE); \
178 mmap_add(fvp_mmap); \
179 init_xlat_tables(); \
180 \
181 enable_mmu_el##_el(0); \
182 }
183#endif
Sandrine Bailleux8d69a032013-11-27 09:38:52 +0000184
Sandrine Bailleux74a62b32014-05-09 11:35:36 +0100185/* Define EL1 and EL3 variants of the function initialising the MMU */
186DEFINE_CONFIGURE_MMU_EL(1)
187DEFINE_CONFIGURE_MMU_EL(3)
Achin Gupta4f6ad662013-10-25 09:08:21 +0100188
Achin Gupta4f6ad662013-10-25 09:08:21 +0100189/*******************************************************************************
190 * A single boot loader stack is expected to work on both the Foundation FVP
191 * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
192 * SYS_ID register provides a mechanism for detecting the differences between
193 * these platforms. This information is stored in a per-BL array to allow the
194 * code to take the correct path.Per BL platform configuration.
195 ******************************************************************************/
Dan Handleyea451572014-05-15 14:53:30 +0100196int fvp_config_setup(void)
Achin Gupta4f6ad662013-10-25 09:08:21 +0100197{
Soby Mathew8e2f2872014-08-14 12:49:05 +0100198 unsigned int rev, hbi, bld, arch, sys_id;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100199
200 sys_id = mmio_read_32(VE_SYSREGS_BASE + V2M_SYS_ID);
201 rev = (sys_id >> SYS_ID_REV_SHIFT) & SYS_ID_REV_MASK;
202 hbi = (sys_id >> SYS_ID_HBI_SHIFT) & SYS_ID_HBI_MASK;
203 bld = (sys_id >> SYS_ID_BLD_SHIFT) & SYS_ID_BLD_MASK;
204 arch = (sys_id >> SYS_ID_ARCH_SHIFT) & SYS_ID_ARCH_MASK;
205
Andrew Thoelke960347d2014-06-26 14:27:26 +0100206 if (arch != ARCH_MODEL) {
207 ERROR("This firmware is for FVP models\n");
James Morrissey40a6f642014-02-10 14:24:36 +0000208 panic();
Andrew Thoelke960347d2014-06-26 14:27:26 +0100209 }
Achin Gupta4f6ad662013-10-25 09:08:21 +0100210
211 /*
212 * The build field in the SYS_ID tells which variant of the GIC
213 * memory is implemented by the model.
214 */
215 switch (bld) {
216 case BLD_GIC_VE_MMAP:
Dan Handley1c54d972014-06-20 12:02:01 +0100217 plat_config.gicd_base = VE_GICD_BASE;
218 plat_config.gicc_base = VE_GICC_BASE;
219 plat_config.gich_base = VE_GICH_BASE;
220 plat_config.gicv_base = VE_GICV_BASE;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100221 break;
222 case BLD_GIC_A53A57_MMAP:
Dan Handley1c54d972014-06-20 12:02:01 +0100223 plat_config.gicd_base = BASE_GICD_BASE;
224 plat_config.gicc_base = BASE_GICC_BASE;
225 plat_config.gich_base = BASE_GICH_BASE;
226 plat_config.gicv_base = BASE_GICV_BASE;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100227 break;
228 default:
Andrew Thoelke960347d2014-06-26 14:27:26 +0100229 ERROR("Unsupported board build %x\n", bld);
230 panic();
Achin Gupta4f6ad662013-10-25 09:08:21 +0100231 }
232
233 /*
234 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
235 * for the Foundation FVP.
236 */
237 switch (hbi) {
238 case HBI_FOUNDATION:
Dan Handley1c54d972014-06-20 12:02:01 +0100239 plat_config.max_aff0 = 4;
240 plat_config.max_aff1 = 1;
241 plat_config.flags = 0;
Andrew Thoelke960347d2014-06-26 14:27:26 +0100242
243 /*
244 * Check for supported revisions of Foundation FVP
245 * Allow future revisions to run but emit warning diagnostic
246 */
247 switch (rev) {
248 case REV_FOUNDATION_V2_0:
249 case REV_FOUNDATION_V2_1:
250 break;
251 default:
252 WARN("Unrecognized Foundation FVP revision %x\n", rev);
253 break;
254 }
Achin Gupta4f6ad662013-10-25 09:08:21 +0100255 break;
256 case HBI_FVP_BASE:
Dan Handley1c54d972014-06-20 12:02:01 +0100257 plat_config.max_aff0 = 4;
258 plat_config.max_aff1 = 2;
259 plat_config.flags |= CONFIG_BASE_MMAP | CONFIG_HAS_CCI |
260 CONFIG_HAS_TZC;
Andrew Thoelke960347d2014-06-26 14:27:26 +0100261
262 /*
263 * Check for supported revisions
264 * Allow future revisions to run but emit warning diagnostic
265 */
266 switch (rev) {
267 case REV_FVP_BASE_V0:
268 break;
269 default:
270 WARN("Unrecognized Base FVP revision %x\n", rev);
271 break;
272 }
Achin Gupta4f6ad662013-10-25 09:08:21 +0100273 break;
274 default:
Andrew Thoelke960347d2014-06-26 14:27:26 +0100275 ERROR("Unsupported board HBI number 0x%x\n", hbi);
276 panic();
Achin Gupta4f6ad662013-10-25 09:08:21 +0100277 }
278
279 return 0;
280}
281
Ian Spray84687392014-01-02 16:57:12 +0000282unsigned long plat_get_ns_image_entrypoint(void)
283{
Achin Gupta4f6ad662013-10-25 09:08:21 +0100284 return NS_IMAGE_OFFSET;
285}
Sandrine Bailleux3fa98472014-03-31 11:25:18 +0100286
287uint64_t plat_get_syscnt_freq(void)
288{
289 uint64_t counter_base_frequency;
290
291 /* Read the frequency from Frequency modes table */
292 counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
293
294 /* The first entry of the frequency modes table must not be 0 */
Juan Castillof558cac2014-06-05 09:45:36 +0100295 if (counter_base_frequency == 0)
296 panic();
Sandrine Bailleux3fa98472014-03-31 11:25:18 +0100297
298 return counter_base_frequency;
299}
Vikram Kanigiri96377452014-04-24 11:02:16 +0100300
Dan Handleybe234f92014-08-04 16:11:15 +0100301void fvp_cci_init(void)
Vikram Kanigiri96377452014-04-24 11:02:16 +0100302{
Vikram Kanigiri96377452014-04-24 11:02:16 +0100303 /*
Dan Handleybe234f92014-08-04 16:11:15 +0100304 * Initialize CCI-400 driver
305 */
306 if (plat_config.flags & CONFIG_HAS_CCI)
307 cci_init(CCI400_BASE,
308 CCI400_SL_IFACE3_CLUSTER_IX,
309 CCI400_SL_IFACE4_CLUSTER_IX);
310}
311
312void fvp_cci_enable(void)
313{
314 /*
315 * Enable CCI-400 coherency for this cluster. No need
Vikram Kanigiri96377452014-04-24 11:02:16 +0100316 * for locks as no other cpu is active at the
317 * moment
318 */
Dan Handley1c54d972014-06-20 12:02:01 +0100319 if (plat_config.flags & CONFIG_HAS_CCI)
Dan Handleybe234f92014-08-04 16:11:15 +0100320 cci_enable_cluster_coherency(read_mpidr());
Vikram Kanigiri96377452014-04-24 11:02:16 +0100321}
322
Dan Handleyfb42b122014-06-20 09:43:15 +0100323void fvp_gic_init(void)
324{
325 arm_gic_init(plat_config.gicc_base,
326 plat_config.gicd_base,
327 BASE_GICR_BASE,
328 irq_sec_array,
329 num_sec_irqs);
330}
331
Vikram Kanigiri96377452014-04-24 11:02:16 +0100332
333/*******************************************************************************
Vikram Kanigiricf79bf52014-06-02 14:59:00 +0100334 * Gets SPSR for BL32 entry
Vikram Kanigiri96377452014-04-24 11:02:16 +0100335 ******************************************************************************/
Vikram Kanigiricf79bf52014-06-02 14:59:00 +0100336uint32_t fvp_get_spsr_for_bl32_entry(void)
Vikram Kanigiri96377452014-04-24 11:02:16 +0100337{
Vikram Kanigiri96377452014-04-24 11:02:16 +0100338 /*
339 * The Secure Payload Dispatcher service is responsible for
340 * setting the SPSR prior to entry into the BL32 image.
341 */
Vikram Kanigiricf79bf52014-06-02 14:59:00 +0100342 return 0;
Vikram Kanigiri96377452014-04-24 11:02:16 +0100343}
344
345/*******************************************************************************
Vikram Kanigiricf79bf52014-06-02 14:59:00 +0100346 * Gets SPSR for BL33 entry
Vikram Kanigiri96377452014-04-24 11:02:16 +0100347 ******************************************************************************/
Vikram Kanigiricf79bf52014-06-02 14:59:00 +0100348uint32_t fvp_get_spsr_for_bl33_entry(void)
Vikram Kanigiri96377452014-04-24 11:02:16 +0100349{
350 unsigned long el_status;
351 unsigned int mode;
Vikram Kanigiricf79bf52014-06-02 14:59:00 +0100352 uint32_t spsr;
Vikram Kanigiri96377452014-04-24 11:02:16 +0100353
354 /* Figure out what mode we enter the non-secure world in */
355 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
356 el_status &= ID_AA64PFR0_ELX_MASK;
357
358 if (el_status)
359 mode = MODE_EL2;
360 else
361 mode = MODE_EL1;
362
363 /*
364 * TODO: Consider the possibility of specifying the SPSR in
365 * the FIP ToC and allowing the platform to have a say as
366 * well.
367 */
Vikram Kanigiricf79bf52014-06-02 14:59:00 +0100368 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
369 return spsr;
Vikram Kanigiri96377452014-04-24 11:02:16 +0100370}