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