1/* 2 * Copyright (c) 2020, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9#include <context.h> 10#include <cpu_macros.S> 11#include <cpuamu.h> 12#include <rainier.h> 13 14/* Hardware handled coherency */ 15#if HW_ASSISTED_COHERENCY == 0 16#error "Rainier CPU must be compiled with HW_ASSISTED_COHERENCY enabled" 17#endif 18 19/* 64-bit only core */ 20#if CTX_INCLUDE_AARCH32_REGS == 1 21#error "Rainier CPU supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" 22#endif 23 24#if ERRATA_RAINIER_IC_TRAP 25 .global rainier_errata_ic_trap_handler 26#endif 27 28/* -------------------------------------------------- 29 * Disable speculative loads if Rainier supports 30 * SSBS. 31 * 32 * Shall clobber: x0. 33 * -------------------------------------------------- 34 */ 35func rainier_disable_speculative_loads 36 /* Check if the PE implements SSBS */ 37 mrs x0, id_aa64pfr1_el1 38 tst x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT) 39 b.eq 1f 40 41 /* Disable speculative loads */ 42 msr SSBS, xzr 43 441: 45 ret 46endfunc rainier_disable_speculative_loads 47 48/* -------------------------------------------------- 49 * Errata Workaround for Neoverse N1 Erratum 1542419. 50 * This applies to revisions r3p0 - r4p0 of Neoverse N1 51 * Since Rainier core is based on Neoverse N1 r4p0, this 52 * errata applies to Rainier core r0p0 53 * Inputs: 54 * x0: variant[4:7] and revision[0:3] of current cpu. 55 * Shall clobber: x0-x17 56 * -------------------------------------------------- 57 */ 58func errata_n1_1542419_wa 59 /* Compare x0 against revision r3p0 and r4p0 */ 60 mov x17, x30 61 bl check_errata_1542419 62 cbz x0, 1f 63 64 /* Apply instruction patching sequence */ 65 mov x0, xzr 66 msr CPUPSELR_EL3, x0 67 ldr x0, =0xEE670D35 68 msr CPUPOR_EL3, x0 69 ldr x0, =0xFFFF0FFF 70 msr CPUPMR_EL3, x0 71 ldr x0, =0x08000020007D 72 msr CPUPCR_EL3, x0 73 isb 741: 75 ret x17 76endfunc errata_n1_1542419_wa 77 78func check_errata_1542419 79 /* Applies to Rainier core r0p0. */ 80 mov x1, #0x00 81 b cpu_rev_var_ls 82endfunc check_errata_1542419 83 84func rainier_reset_func 85 mov x19, x30 86 87 bl rainier_disable_speculative_loads 88 89 /* Forces all cacheable atomic instructions to be near */ 90 mrs x0, RAINIER_CPUACTLR2_EL1 91 orr x0, x0, #RAINIER_CPUACTLR2_EL1_BIT_2 92 msr RAINIER_CPUACTLR2_EL1, x0 93 isb 94 95 bl cpu_get_rev_var 96 mov x18, x0 97 98#if ERRATA_N1_1542419 99 mov x0, x18 100 bl errata_n1_1542419_wa 101#endif 102 103#if ENABLE_AMU 104 /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ 105 mrs x0, actlr_el3 106 orr x0, x0, #RAINIER_ACTLR_AMEN_BIT 107 msr actlr_el3, x0 108 109 /* Make sure accesses from EL0/EL1 are not trapped to EL2 */ 110 mrs x0, actlr_el2 111 orr x0, x0, #RAINIER_ACTLR_AMEN_BIT 112 msr actlr_el2, x0 113 114 /* Enable group0 counters */ 115 mov x0, #RAINIER_AMU_GROUP0_MASK 116 msr CPUAMCNTENSET_EL0, x0 117#endif 118 119 isb 120 ret x19 121endfunc rainier_reset_func 122 123 /* --------------------------------------------- 124 * HW will do the cache maintenance while powering down 125 * --------------------------------------------- 126 */ 127func rainier_core_pwr_dwn 128 /* --------------------------------------------- 129 * Enable CPU power down bit in power control register 130 * --------------------------------------------- 131 */ 132 mrs x0, RAINIER_CPUPWRCTLR_EL1 133 orr x0, x0, #RAINIER_CORE_PWRDN_EN_MASK 134 msr RAINIER_CPUPWRCTLR_EL1, x0 135 isb 136 ret 137endfunc rainier_core_pwr_dwn 138 139#if REPORT_ERRATA 140/* 141 * Errata printing function for Rainier. Must follow AAPCS. 142 */ 143func rainier_errata_report 144 stp x8, x30, [sp, #-16]! 145 146 bl cpu_get_rev_var 147 mov x8, x0 148 149 /* 150 * Report all errata. The revision-variant information is passed to 151 * checking functions of each errata. 152 */ 153 report_errata ERRATA_N1_1542419, rainier, 1542419 154 155 ldp x8, x30, [sp], #16 156 ret 157endfunc rainier_errata_report 158#endif 159 160/* 161 * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB 162 * inner-shareable invalidation to an arbitrary address followed by a DSB. 163 * 164 * x1: Exception Syndrome 165 */ 166func rainier_errata_ic_trap_handler 167 cmp x1, #RAINIER_EC_IC_TRAP 168 b.ne 1f 169 tlbi vae3is, xzr 170 dsb sy 171 172 # Skip the IC instruction itself 173 mrs x3, elr_el3 174 add x3, x3, #4 175 msr elr_el3, x3 176 177 ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 178 ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 179 ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] 180 ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 181 182#if IMAGE_BL31 && RAS_EXTENSION 183 /* 184 * Issue Error Synchronization Barrier to synchronize SErrors before 185 * exiting EL3. We're running with EAs unmasked, so any synchronized 186 * errors would be taken immediately; therefore no need to inspect 187 * DISR_EL1 register. 188 */ 189 esb 190#endif 191 eret 1921: 193 ret 194endfunc rainier_errata_ic_trap_handler 195 196 /* --------------------------------------------- 197 * This function provides Rainier specific 198 * register information for crash reporting. 199 * It needs to return with x6 pointing to 200 * a list of register names in ascii and 201 * x8 - x15 having values of registers to be 202 * reported. 203 * --------------------------------------------- 204 */ 205.section .rodata.rainier_regs, "aS" 206rainier_regs: /* The ascii list of register names to be reported */ 207 .asciz "cpuectlr_el1", "" 208 209func rainier_cpu_reg_dump 210 adr x6, rainier_regs 211 mrs x8, RAINIER_CPUECTLR_EL1 212 ret 213endfunc rainier_cpu_reg_dump 214 215declare_cpu_ops_eh rainier, RAINIER_MIDR, \ 216 rainier_reset_func, \ 217 rainier_errata_ic_trap_handler, \ 218 rainier_core_pwr_dwn 219