| /* SPDX-License-Identifier: GPL-2.0-only */ |
| |
| #include <arch/asm.h> |
| #include <cpu/cortex_a57.h> |
| |
| /* |
| * It is observed that BTB contains stale data after power on reset. This could |
| * lead to unexpected branching and crashes at random intervals during the boot |
| * flow. Thus, invalidate the BTB immediately after power on reset. |
| */ |
| .macro t210_a57_fixup |
| /* |
| * Invalidate BTB along with I$ to remove any stale entries |
| * from the branch predictor array. |
| */ |
| mrs x0, CPUACTLR_EL1 |
| orr x0, x0, #BTB_INVALIDATE |
| msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ |
| dsb sy |
| isb |
| ic iallu /* invalidate */ |
| dsb sy |
| isb |
| |
| bic x0, x0, #BTB_INVALIDATE |
| msr CPUACTLR_EL1, x0 /* restore original CPUACTLR_EL1 */ |
| dsb sy |
| isb |
| |
| .rept 7 |
| nop /* wait */ |
| .endr |
| |
| /* |
| * Extract OSLK bit and check if it is '1'. This bit remains '0' |
| * for A53. If '1', turn off regional clock gating and request |
| * warm reset. |
| */ |
| mrs x0, oslsr_el1 |
| and x0, x0, #2 /* extract oslk bit */ |
| mrs x1, mpidr_el1 |
| bics xzr, x0, x1, lsr #7 /* 0 if slow cluster */ |
| b.eq 1000f |
| mov x0, xzr |
| msr oslar_el1, x0 /* os lock stays 0 across warm reset */ |
| mov x3, #3 |
| movz x4, #0x8000, lsl #48 |
| msr CPUACTLR_EL1, x4 /* turn off RCG */ |
| isb |
| msr rmr_el3, x3 /* request warm reset */ |
| isb |
| dsb sy |
| wfi |
| |
| /* |
| * These nops are here so that speculative execution won't harm us |
| * before we are done warm reset. |
| */ |
| .rept 65 |
| nop |
| .endr |
| |
| 1000: |
| /* Restore os lock */ |
| mov x0, #1 |
| msr oslar_el1, x0 |
| .endm |
| |
| ENTRY(stage_entry) |
| t210_a57_fixup |
| |
| /* Initialize PSTATE, SCTLR and caches to clean state, set up stack. */ |
| bl arm64_init_cpu |
| |
| /* Jump to Tegra-specific C entry point. */ |
| bl ramstage_entry |
| ENDPROC(stage_entry) |