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