13a8c55f6SVarun Wadekar/* 2*b0301467SVarun Wadekar * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 33a8c55f6SVarun Wadekar * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 53a8c55f6SVarun Wadekar */ 63a8c55f6SVarun Wadekar 73a8c55f6SVarun Wadekar#include <arch.h> 83a8c55f6SVarun Wadekar#include <asm_macros.S> 93a8c55f6SVarun Wadekar#include <assert_macros.S> 10*b0301467SVarun Wadekar#include <context.h> 113a8c55f6SVarun Wadekar#include <denver.h> 123a8c55f6SVarun Wadekar#include <cpu_macros.S> 133a8c55f6SVarun Wadekar#include <plat_macros.S> 143a8c55f6SVarun Wadekar 15*b0301467SVarun Wadekar /* ------------------------------------------------- 16*b0301467SVarun Wadekar * CVE-2017-5715 mitigation 17*b0301467SVarun Wadekar * 18*b0301467SVarun Wadekar * Flush the indirect branch predictor and RSB on 19*b0301467SVarun Wadekar * entry to EL3 by issuing a newly added instruction 20*b0301467SVarun Wadekar * for Denver CPUs. 21*b0301467SVarun Wadekar * 22*b0301467SVarun Wadekar * To achieve this without performing any branch 23*b0301467SVarun Wadekar * instruction, a per-cpu vbar is installed which 24*b0301467SVarun Wadekar * executes the workaround and then branches off to 25*b0301467SVarun Wadekar * the corresponding vector entry in the main vector 26*b0301467SVarun Wadekar * table. 27*b0301467SVarun Wadekar * ------------------------------------------------- 28*b0301467SVarun Wadekar */ 29*b0301467SVarun Wadekar .globl workaround_bpflush_runtime_exceptions 30*b0301467SVarun Wadekar 31*b0301467SVarun Wadekarvector_base workaround_bpflush_runtime_exceptions 32*b0301467SVarun Wadekar 33*b0301467SVarun Wadekar .macro apply_workaround 34*b0301467SVarun Wadekar stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 35*b0301467SVarun Wadekar 36*b0301467SVarun Wadekar /* ------------------------------------------------- 37*b0301467SVarun Wadekar * A new write-only system register where a write of 38*b0301467SVarun Wadekar * 1 to bit 0 will cause the indirect branch predictor 39*b0301467SVarun Wadekar * and RSB to be flushed. 40*b0301467SVarun Wadekar * 41*b0301467SVarun Wadekar * A write of 0 to bit 0 will be ignored. A write of 42*b0301467SVarun Wadekar * 1 to any other bit will cause an MCA. 43*b0301467SVarun Wadekar * ------------------------------------------------- 44*b0301467SVarun Wadekar */ 45*b0301467SVarun Wadekar mov x0, #1 46*b0301467SVarun Wadekar msr s3_0_c15_c0_6, x0 47*b0301467SVarun Wadekar isb 48*b0301467SVarun Wadekar 49*b0301467SVarun Wadekar ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 50*b0301467SVarun Wadekar .endm 51*b0301467SVarun Wadekar 52*b0301467SVarun Wadekar /* --------------------------------------------------------------------- 53*b0301467SVarun Wadekar * Current EL with SP_EL0 : 0x0 - 0x200 54*b0301467SVarun Wadekar * --------------------------------------------------------------------- 55*b0301467SVarun Wadekar */ 56*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_el0 57*b0301467SVarun Wadekar b sync_exception_sp_el0 58*b0301467SVarun Wadekar check_vector_size workaround_bpflush_sync_exception_sp_el0 59*b0301467SVarun Wadekar 60*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_el0 61*b0301467SVarun Wadekar b irq_sp_el0 62*b0301467SVarun Wadekar check_vector_size workaround_bpflush_irq_sp_el0 63*b0301467SVarun Wadekar 64*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_el0 65*b0301467SVarun Wadekar b fiq_sp_el0 66*b0301467SVarun Wadekar check_vector_size workaround_bpflush_fiq_sp_el0 67*b0301467SVarun Wadekar 68*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_el0 69*b0301467SVarun Wadekar b serror_sp_el0 70*b0301467SVarun Wadekar check_vector_size workaround_bpflush_serror_sp_el0 71*b0301467SVarun Wadekar 72*b0301467SVarun Wadekar /* --------------------------------------------------------------------- 73*b0301467SVarun Wadekar * Current EL with SP_ELx: 0x200 - 0x400 74*b0301467SVarun Wadekar * --------------------------------------------------------------------- 75*b0301467SVarun Wadekar */ 76*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_elx 77*b0301467SVarun Wadekar b sync_exception_sp_elx 78*b0301467SVarun Wadekar check_vector_size workaround_bpflush_sync_exception_sp_elx 79*b0301467SVarun Wadekar 80*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_elx 81*b0301467SVarun Wadekar b irq_sp_elx 82*b0301467SVarun Wadekar check_vector_size workaround_bpflush_irq_sp_elx 83*b0301467SVarun Wadekar 84*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_elx 85*b0301467SVarun Wadekar b fiq_sp_elx 86*b0301467SVarun Wadekar check_vector_size workaround_bpflush_fiq_sp_elx 87*b0301467SVarun Wadekar 88*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_elx 89*b0301467SVarun Wadekar b serror_sp_elx 90*b0301467SVarun Wadekar check_vector_size workaround_bpflush_serror_sp_elx 91*b0301467SVarun Wadekar 92*b0301467SVarun Wadekar /* --------------------------------------------------------------------- 93*b0301467SVarun Wadekar * Lower EL using AArch64 : 0x400 - 0x600 94*b0301467SVarun Wadekar * --------------------------------------------------------------------- 95*b0301467SVarun Wadekar */ 96*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch64 97*b0301467SVarun Wadekar apply_workaround 98*b0301467SVarun Wadekar b sync_exception_aarch64 99*b0301467SVarun Wadekar check_vector_size workaround_bpflush_sync_exception_aarch64 100*b0301467SVarun Wadekar 101*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch64 102*b0301467SVarun Wadekar apply_workaround 103*b0301467SVarun Wadekar b irq_aarch64 104*b0301467SVarun Wadekar check_vector_size workaround_bpflush_irq_aarch64 105*b0301467SVarun Wadekar 106*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch64 107*b0301467SVarun Wadekar apply_workaround 108*b0301467SVarun Wadekar b fiq_aarch64 109*b0301467SVarun Wadekar check_vector_size workaround_bpflush_fiq_aarch64 110*b0301467SVarun Wadekar 111*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch64 112*b0301467SVarun Wadekar apply_workaround 113*b0301467SVarun Wadekar b serror_aarch64 114*b0301467SVarun Wadekar check_vector_size workaround_bpflush_serror_aarch64 115*b0301467SVarun Wadekar 116*b0301467SVarun Wadekar /* --------------------------------------------------------------------- 117*b0301467SVarun Wadekar * Lower EL using AArch32 : 0x600 - 0x800 118*b0301467SVarun Wadekar * --------------------------------------------------------------------- 119*b0301467SVarun Wadekar */ 120*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch32 121*b0301467SVarun Wadekar apply_workaround 122*b0301467SVarun Wadekar b sync_exception_aarch32 123*b0301467SVarun Wadekar check_vector_size workaround_bpflush_sync_exception_aarch32 124*b0301467SVarun Wadekar 125*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch32 126*b0301467SVarun Wadekar apply_workaround 127*b0301467SVarun Wadekar b irq_aarch32 128*b0301467SVarun Wadekar check_vector_size workaround_bpflush_irq_aarch32 129*b0301467SVarun Wadekar 130*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch32 131*b0301467SVarun Wadekar apply_workaround 132*b0301467SVarun Wadekar b fiq_aarch32 133*b0301467SVarun Wadekar check_vector_size workaround_bpflush_fiq_aarch32 134*b0301467SVarun Wadekar 135*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch32 136*b0301467SVarun Wadekar apply_workaround 137*b0301467SVarun Wadekar b serror_aarch32 138*b0301467SVarun Wadekar check_vector_size workaround_bpflush_serror_aarch32 139*b0301467SVarun Wadekar 1409f1c5dd1SVarun Wadekar .global denver_disable_dco 1419f1c5dd1SVarun Wadekar 1423a8c55f6SVarun Wadekar /* --------------------------------------------- 1433a8c55f6SVarun Wadekar * Disable debug interfaces 1443a8c55f6SVarun Wadekar * --------------------------------------------- 1453a8c55f6SVarun Wadekar */ 1463a8c55f6SVarun Wadekarfunc denver_disable_ext_debug 1473a8c55f6SVarun Wadekar mov x0, #1 1483a8c55f6SVarun Wadekar msr osdlr_el1, x0 1493a8c55f6SVarun Wadekar isb 1503a8c55f6SVarun Wadekar dsb sy 1513a8c55f6SVarun Wadekar ret 1523a8c55f6SVarun Wadekarendfunc denver_disable_ext_debug 1533a8c55f6SVarun Wadekar 1543a8c55f6SVarun Wadekar /* ---------------------------------------------------- 1553a8c55f6SVarun Wadekar * Enable dynamic code optimizer (DCO) 1563a8c55f6SVarun Wadekar * ---------------------------------------------------- 1573a8c55f6SVarun Wadekar */ 1583a8c55f6SVarun Wadekarfunc denver_enable_dco 1593a8c55f6SVarun Wadekar mrs x0, mpidr_el1 1603a8c55f6SVarun Wadekar and x0, x0, #0xF 1613a8c55f6SVarun Wadekar mov x1, #1 1623a8c55f6SVarun Wadekar lsl x1, x1, x0 1633a8c55f6SVarun Wadekar msr s3_0_c15_c0_2, x1 1643a8c55f6SVarun Wadekar ret 1653a8c55f6SVarun Wadekarendfunc denver_enable_dco 1663a8c55f6SVarun Wadekar 1673a8c55f6SVarun Wadekar /* ---------------------------------------------------- 1683a8c55f6SVarun Wadekar * Disable dynamic code optimizer (DCO) 1693a8c55f6SVarun Wadekar * ---------------------------------------------------- 1703a8c55f6SVarun Wadekar */ 1713a8c55f6SVarun Wadekarfunc denver_disable_dco 1723a8c55f6SVarun Wadekar 1733a8c55f6SVarun Wadekar /* turn off background work */ 1743a8c55f6SVarun Wadekar mrs x0, mpidr_el1 1753a8c55f6SVarun Wadekar and x0, x0, #0xF 1763a8c55f6SVarun Wadekar mov x1, #1 1773a8c55f6SVarun Wadekar lsl x1, x1, x0 1783a8c55f6SVarun Wadekar lsl x2, x1, #16 1793a8c55f6SVarun Wadekar msr s3_0_c15_c0_2, x2 1803a8c55f6SVarun Wadekar isb 1813a8c55f6SVarun Wadekar 1823a8c55f6SVarun Wadekar /* wait till the background work turns off */ 1833a8c55f6SVarun Wadekar1: mrs x2, s3_0_c15_c0_2 1843a8c55f6SVarun Wadekar lsr x2, x2, #32 1853a8c55f6SVarun Wadekar and w2, w2, 0xFFFF 1863a8c55f6SVarun Wadekar and x2, x2, x1 1873a8c55f6SVarun Wadekar cbnz x2, 1b 1883a8c55f6SVarun Wadekar 1893a8c55f6SVarun Wadekar ret 1903a8c55f6SVarun Wadekarendfunc denver_disable_dco 1913a8c55f6SVarun Wadekar 1923a8c55f6SVarun Wadekar /* ------------------------------------------------- 1933a8c55f6SVarun Wadekar * The CPU Ops reset function for Denver. 1943a8c55f6SVarun Wadekar * ------------------------------------------------- 1953a8c55f6SVarun Wadekar */ 1963a8c55f6SVarun Wadekarfunc denver_reset_func 1973a8c55f6SVarun Wadekar 1983a8c55f6SVarun Wadekar mov x19, x30 1993a8c55f6SVarun Wadekar 200*b0301467SVarun Wadekar#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715 201*b0301467SVarun Wadekar /* 202*b0301467SVarun Wadekar * Check if the CPU supports the special instruction 203*b0301467SVarun Wadekar * required to flush the indirect branch predictor and 204*b0301467SVarun Wadekar * RSB. Support for this operation can be determined by 205*b0301467SVarun Wadekar * comparing bits 19:16 of ID_AFR0_EL1 with 0b0001. 206*b0301467SVarun Wadekar */ 207*b0301467SVarun Wadekar mrs x0, id_afr0_el1 208*b0301467SVarun Wadekar mov x1, #0x10000 209*b0301467SVarun Wadekar and x0, x0, x1 210*b0301467SVarun Wadekar cmp x0, #0 211*b0301467SVarun Wadekar adr x1, workaround_bpflush_runtime_exceptions 212*b0301467SVarun Wadekar mrs x2, vbar_el3 213*b0301467SVarun Wadekar csel x0, x1, x2, ne 214*b0301467SVarun Wadekar msr vbar_el3, x0 215*b0301467SVarun Wadekar#endif 216*b0301467SVarun Wadekar 2173a8c55f6SVarun Wadekar /* ---------------------------------------------------- 2183a8c55f6SVarun Wadekar * Enable dynamic code optimizer (DCO) 2193a8c55f6SVarun Wadekar * ---------------------------------------------------- 2203a8c55f6SVarun Wadekar */ 2213a8c55f6SVarun Wadekar bl denver_enable_dco 2223a8c55f6SVarun Wadekar 2233a8c55f6SVarun Wadekar ret x19 2243a8c55f6SVarun Wadekarendfunc denver_reset_func 2253a8c55f6SVarun Wadekar 2263a8c55f6SVarun Wadekar /* ---------------------------------------------------- 2273a8c55f6SVarun Wadekar * The CPU Ops core power down function for Denver. 2283a8c55f6SVarun Wadekar * ---------------------------------------------------- 2293a8c55f6SVarun Wadekar */ 2303a8c55f6SVarun Wadekarfunc denver_core_pwr_dwn 2313a8c55f6SVarun Wadekar 2323a8c55f6SVarun Wadekar mov x19, x30 2333a8c55f6SVarun Wadekar 2343a8c55f6SVarun Wadekar /* --------------------------------------------- 2353a8c55f6SVarun Wadekar * Force the debug interfaces to be quiescent 2363a8c55f6SVarun Wadekar * --------------------------------------------- 2373a8c55f6SVarun Wadekar */ 2383a8c55f6SVarun Wadekar bl denver_disable_ext_debug 2393a8c55f6SVarun Wadekar 2403a8c55f6SVarun Wadekar ret x19 2413a8c55f6SVarun Wadekarendfunc denver_core_pwr_dwn 2423a8c55f6SVarun Wadekar 2433a8c55f6SVarun Wadekar /* ------------------------------------------------------- 2443a8c55f6SVarun Wadekar * The CPU Ops cluster power down function for Denver. 2453a8c55f6SVarun Wadekar * ------------------------------------------------------- 2463a8c55f6SVarun Wadekar */ 2473a8c55f6SVarun Wadekarfunc denver_cluster_pwr_dwn 2483a8c55f6SVarun Wadekar ret 2493a8c55f6SVarun Wadekarendfunc denver_cluster_pwr_dwn 2503a8c55f6SVarun Wadekar 2513a8c55f6SVarun Wadekar /* --------------------------------------------- 2523a8c55f6SVarun Wadekar * This function provides Denver specific 2533a8c55f6SVarun Wadekar * register information for crash reporting. 2543a8c55f6SVarun Wadekar * It needs to return with x6 pointing to 2553a8c55f6SVarun Wadekar * a list of register names in ascii and 2563a8c55f6SVarun Wadekar * x8 - x15 having values of registers to be 2573a8c55f6SVarun Wadekar * reported. 2583a8c55f6SVarun Wadekar * --------------------------------------------- 2593a8c55f6SVarun Wadekar */ 2603a8c55f6SVarun Wadekar.section .rodata.denver_regs, "aS" 2613a8c55f6SVarun Wadekardenver_regs: /* The ascii list of register names to be reported */ 2623a8c55f6SVarun Wadekar .asciz "actlr_el1", "" 2633a8c55f6SVarun Wadekar 2643a8c55f6SVarun Wadekarfunc denver_cpu_reg_dump 2653a8c55f6SVarun Wadekar adr x6, denver_regs 2663a8c55f6SVarun Wadekar mrs x8, ACTLR_EL1 2673a8c55f6SVarun Wadekar ret 2683a8c55f6SVarun Wadekarendfunc denver_cpu_reg_dump 2693a8c55f6SVarun Wadekar 270e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN0, \ 271e956e228SVarun Wadekar denver_reset_func, \ 272e956e228SVarun Wadekar denver_core_pwr_dwn, \ 273e956e228SVarun Wadekar denver_cluster_pwr_dwn 274e956e228SVarun Wadekar 275e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN1, \ 276e956e228SVarun Wadekar denver_reset_func, \ 277e956e228SVarun Wadekar denver_core_pwr_dwn, \ 278e956e228SVarun Wadekar denver_cluster_pwr_dwn 279e956e228SVarun Wadekar 280e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN2, \ 281e956e228SVarun Wadekar denver_reset_func, \ 282e956e228SVarun Wadekar denver_core_pwr_dwn, \ 283e956e228SVarun Wadekar denver_cluster_pwr_dwn 284e956e228SVarun Wadekar 285e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN3, \ 286e956e228SVarun Wadekar denver_reset_func, \ 287e956e228SVarun Wadekar denver_core_pwr_dwn, \ 288e956e228SVarun Wadekar denver_cluster_pwr_dwn 289e956e228SVarun Wadekar 290e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN4, \ 2915dd9dbb5SJeenu Viswambharan denver_reset_func, \ 2925dd9dbb5SJeenu Viswambharan denver_core_pwr_dwn, \ 2935dd9dbb5SJeenu Viswambharan denver_cluster_pwr_dwn 294