1/* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28/* 29 * Entry points for the A9 inits, A9 revision specific or not. 30 * It is assume no stack is available when these routines are called. 31 * It is assume each routine is called with return address in LR 32 * and with ARM registers R0, R1, R2, R3 being scratchable. 33 */ 34#include <arm32.h> 35#include <arm32_macros.S> 36#include <asm.S> 37#include <kernel/tz_ssvce_def.h> 38#include <kernel/unwind.h> 39#include <platform_config.h> 40 41#define CPUID_A9_R3P0_H 0x413f 42#define CPUID_A9_R3P0_L 0xc090 43 44.section .text 45.balign 4 46.code 32 47 48/* 49 * void arm_cl2_config(vaddr_t pl310_base) - Memory Cache Level2 Configuration 50 * 51 * Use scratables registers R0-R3. 52 * No stack usage. 53 * LR store return address. 54 * Trap CPU in case of error. 55 */ 56FUNC arm_cl2_config , : 57UNWIND( .fnstart) 58 59 mrc p15, 0, r2, c0, c0, 0 /* read A9 ID */ 60 movw r1, #CPUID_A9_R3P0_L 61 movt r1, #CPUID_A9_R3P0_H 62 cmp r2, r1 63 beq _config_l2cc_r3p0 64 b . /* TODO: unknown id: reset? log? */ 65 66_config_l2cc_r3p0: 67 /* 68 * TAG RAM Control Register 69 * 70 * bit[10:8]:1 - 2 cycle of write accesses latency 71 * bit[6:4]:1 - 2 cycle of read accesses latency 72 * bit[2:0]:1 - 2 cycle of setup latency 73 */ 74 ldr r2, [r0, #PL310_TAG_RAM_CTRL] 75 movw r1, #0xf888 76 movt r1, #0xffff 77 and r2,r2,r1 78 movw r1, #0xf999 79 movt r1, #0xffff 80 orr r2,r2,r1 81 str r2, [r0, #PL310_TAG_RAM_CTRL] 82 83 /* 84 * DATA RAM Control Register 85 * 86 * bit[10:8]:2 - 3 cycle of write accesses latency 87 * bit[6:4]:2 - 3 cycle of read accesses latency 88 * bit[2:0]:2 - 3 cycle of setup latency 89 */ 90 ldr r2, [r0, #PL310_DATA_RAM_CTRL] 91 movw r1, #0xf888 92 movt r1, #0xffff 93 and r2,r2,r1 94 movw r1, #0xfaaa 95 movt r1, #0xffff 96 orr r2,r2,r1 97 str r2, [r0, #PL310_DATA_RAM_CTRL] 98 99 /* 100 * Auxiliary Control Register = 0x3C480800 101 * 102 * I/Dcache prefetch enabled (bit29:28=2b11) 103 * NS can access interrupts (bit27=1) 104 * NS can lockown cache lines (bit26=1) 105 * Pseudo-random replacement policy (bit25=0) 106 * Force write allocated (default) 107 * Shared attribute internally ignored (bit22=1, bit13=0) 108 * Parity disabled (bit21=0) 109 * Event monitor disabled (bit20=0) 110 * 128kB ways, 8-way associativity (bit19:17=3b100 bit16=0) 111 * Store buffer device limitation enabled (bit11=1) 112 * Cacheable accesses have high prio (bit10=0) 113 * Full Line Zero (FLZ) disabled (bit0=0) 114 */ 115 movw r1, #0x0800 116 movt r1, #0x3C48 117 str r1, [r0, #PL310_AUX_CTRL] 118 119 /* 120 * Prefetch Control Register = 0x31000007 121 * 122 * Double linefill disabled (bit30=0) 123 * I/D prefetch enabled (bit29:28=2b11) 124 * Prefetch drop enabled (bit24=1) 125 * Incr double linefill disable (bit23=0) 126 * Prefetch offset = 7 (bit4:0) 127 */ 128 movw r1, #0x0007 129 movt r1, #0x3100 130 str r1, [r0, #PL310_PREFETCH_CTRL] 131 132 /* 133 * Power Register = 0x00000003 134 * 135 * Dynamic clock gating enabled 136 * Standby mode enabled 137 */ 138 movw r1, #0x0003 139 movt r1, #0x0000 140 str r1, [r0, #PL310_POWER_CTRL] 141 142 /* invalidate all cache ways */ 143 movw r1, #0x00FF 144 movt r1, #0x0000 145 str r1, [r0, #PL310_INV_BY_WAY] 146 147 mov pc, lr 148UNWIND( .fnend) 149END_FUNC arm_cl2_config 150/* End of arm_cl2_config */ 151 152 153/* 154 * void arm_cl2_enable(vaddr_t pl310_base) - Memory Cache Level2 Enable Function 155 * 156 * If PL310 supports FZLW, enable also FZL in A9 core 157 * 158 * Use scratables registers R0-R3. 159 * No stack usage. 160 * LR store return address. 161 * Trap CPU in case of error. 162 * TODO: to be moved to PL310 code (tz_svce_pl310.S ?) 163 */ 164FUNC arm_cl2_enable , : 165UNWIND( .fnstart) 166 167 168 /* Enable PL310 ctrl -> only set lsb bit */ 169 mov r1, #0x1 170 str r1, [r0, #PL310_CTRL] 171 172 /* if L2 FLZW enable, enable in L1 */ 173 ldr r1, [r0, #PL310_AUX_CTRL] 174 tst r1, #(1 << 0) /* test AUX_CTRL[FLZ] */ 175 mrc p15, 0, r0, c1, c0, 1 176 orrne r0, r0, #(1 << 3) /* enable ACTLR[FLZW] */ 177 mcr p15, 0, r0, c1, c0, 1 178 179 mov pc, lr 180UNWIND( .fnend) 181END_FUNC arm_cl2_enable 182 183/* 184 * Cortex A9 configuration early configuration 185 * 186 * Use scratables registers R0-R3. 187 * No stack usage. 188 * LR store return address. 189 * Trap CPU in case of error. 190 */ 191FUNC plat_cpu_reset_early , : 192UNWIND( .fnstart) 193 194 /* only r3p0 is supported */ 195 mrc p15, 0, r0, c0, c0, 0 /* read A9 ID */ 196 movw r1, #CPUID_A9_R3P0_L 197 movt r1, #CPUID_A9_R3P0_H 198 cmp r0, r1 199 beq _early_a9_r3p0 200 b . /* TODO: unknown id: reset? log? */ 201 202_early_a9_r3p0: 203 /* 204 * Mandated HW config loaded 205 * 206 * SCTLR = 0x00004000 207 * - Round-Robin replac. for icache, btac, i/duTLB (bit14: RoundRobin) 208 * 209 * ACTRL = 0x00000041 210 * - core always in full SMP (FW bit0=1, SMP bit6=1) 211 * - L2 write full line of zero disabled (bit3=0) 212 * (keep WFLZ low. Will be set once outer L2 is ready) 213 * 214 * NSACR = 0x00020C00 215 * - NSec cannot change ACTRL.SMP (NS_SMP bit18=0) 216 * - Nsec can lockdown TLB (TL bit17=1) 217 * - NSec cannot access PLE (PLE bit16=0) 218 * - NSec can use SIMD/VFP (CP10/CP11) (bit15:14=2b00, bit11:10=2b11) 219 * 220 * PCR = 0x00000001 221 * - no change latency, enable clk gating 222 */ 223 movw r0, #0x4000 224 movt r0, #0x0000 225 write_sctlr r0 226 227 movw r0, #0x0041 228 movt r0, #0x0000 229 write_actlr r0 230 231 movw r0, #0x0C00 232 movt r0, #0x0002 233 write_nsacr r0 234 235 movw r0, #0x0000 236 movt r0, #0x0001 237 write_pcr r0 238 239 /* 240 * GIC configuration 241 * 242 * Register ICDISR0 = 0xFFFFFFFF 243 * - All local interrupts are NonSecure. 244 * 245 * Register ICCPMR = 0xFFFFFFFF 246 */ 247 248 ldr r0, =GIC_DIST_BASE 249 mov r1, #0xFFFFFFFF 250 str r1, [r0, #GIC_DIST_ISR0] 251 252 ldr r0, =GIC_CPU_BASE 253 mov r1, #0xFFFFFFFF 254 str r1, [r0, #CORE_ICC_ICCPMR] 255 256 mov pc, lr /* back to tzinit */ 257UNWIND( .fnend) 258END_FUNC plat_cpu_reset_early 259 260/* 261 * A9 secured config, needed only from a single core 262 * 263 * Use scratables registers R0-R3. 264 * No stack usage. 265 * LR store return address. 266 * Trap CPU in case of error. 267 * 268 * TODO: size optim in code 269 */ 270FUNC plat_cpu_reset_late , : 271UNWIND( .fnstart) 272 273 /* Allow NSec to manage FIQ/Imprecise abort (SCR[FW]=1, SCR[AW]=1) */ 274 read_scr r0 275 orr r0, r0, #SCR_AW 276 orr r0, r0, #SCR_FW 277 write_scr r0 278 279 mrc p15, 0, r0, c0, c0, 5 280 ands r0, #3 281 beq _boot_late_primary_cpu 282 283_boot_late_secondary_cpu: 284 mov pc, lr 285 286_boot_late_primary_cpu: 287 /* 288 * Snoop Control Unit configuration 289 * 290 * SCU is enabled with filtering off. 291 * Both Secure/Unsecure can access SCU and timers 292 * 293 * 0x00 SCUControl = 0x00000060 !!! should be 0x5 ! A NETTOYER !!!!!!!!!!!!!!!!!!!!!!!!! 294 * 0x04 SCUConfiguration = ??? A NETTOYER !!!!!!!!!!!!!!!!!!!!!!!!! 295 * 0x0C SCUInvalidateAll (Secure cfg) 296 * 0x40 FilteringStartAddress = 0x40000000 297 * 0x44 FilteeringEndAddress - 0x80000000 298 * 0x50 SCUAccessControl 299 * 0x54 SCUSecureAccessControl 300 */ 301 302 /* 303 * SCU Access Register : SAC = 0x00000003 304 * - both secure CPU access SCU 305 */ 306 ldr r0, =SCU_BASE 307 movw r1, #0x0003 308 movt r1, #0x0000 309 str r1, [r0, #SCU_SAC] 310 311 /* 312 * SCU NonSecure Access Register : SNSAC : 0x00000333 313 * - both nonsec cpu access SCU, private and global timer 314 */ 315 movw r1, #0x0333 316 movt r1, #0x0000 317 str r1, [r0, #SCU_NSAC] 318 319 /* 320 * SCU Filtering End Address register: SFEA 321 */ 322 movw r1, #(CPU_PORT_FILT_END & 0xFFFF) 323 movt r1, #(CPU_PORT_FILT_END >> 16) 324 str r1, [r0, #SCU_FILT_EA] 325 326 /* 327 * SCU Filtering Start Address register: SFSA 328 */ 329 movw r1, #(CPU_PORT_FILT_START & 0xFFFF) 330 movt r1, #(CPU_PORT_FILT_START >> 16) 331 str r1, [r0, #SCU_FILT_SA] 332 333 /* 334 * SCU Control Register : CTRL = 0x00000065 335 * - ic stanby enable=1 336 * - scu standby enable=1 337 * - scu enable=1 338 */ 339 movw r1, #0x0065 340 movt r1, #0x0000 341 str r1, [r0, #SCU_CTRL] 342 343 /*- GIC secure configuration ---*/ 344 345 /* 346 * Register ICDISR[1-31] = 0xFFFFFFFF 347 * - All external interrupts are NonSecure. 348 */ 349 ldr r0, =(GIC_DIST_BASE + GIC_DIST_ISR1) 350 mov r2, #0xFFFFFFFF 351 mov r1, #31 /* Nb of loop rounds */ 352loop_1: 353 str r2, [r0] 354 add r0, #4 355 sub r1, r1, #1 356 cmp r1, #0 357 bne loop_1 358 359 360 /*- PL310 Memory Controller (Note: should be done with NS=1) ---*/ 361 /* Note: we're in secure mode with mmu disabled => NS=0 */ 362 363 /* 364 * reg12_addr_filtering_end 365 */ 366 ldr r0, =PL310_BASE 367 movw r1, #(CPU_PORT_FILT_END & 0xFFFF) 368 movt r1, #(CPU_PORT_FILT_END >> 16) 369 str r1, [r0, #PL310_ADDR_FILT_END] 370 371 /* 372 * reg12_addr_filtering_start 373 */ 374 movw r1, #((CPU_PORT_FILT_START & 0xFFFF) | 1) 375 movt r1, #(CPU_PORT_FILT_START >> 16) 376 str r1, [r0, #PL310_ADDR_FILT_START] 377 378 mov pc, lr 379UNWIND( .fnend) 380END_FUNC plat_cpu_reset_late 381