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