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