13a8c55f6SVarun Wadekar/* 2b0301467SVarun 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> 10b0301467SVarun Wadekar#include <context.h> 113a8c55f6SVarun Wadekar#include <denver.h> 123a8c55f6SVarun Wadekar#include <cpu_macros.S> 133a8c55f6SVarun Wadekar#include <plat_macros.S> 143a8c55f6SVarun Wadekar 15b0301467SVarun Wadekar /* ------------------------------------------------- 16b0301467SVarun Wadekar * CVE-2017-5715 mitigation 17b0301467SVarun Wadekar * 18b0301467SVarun Wadekar * Flush the indirect branch predictor and RSB on 19b0301467SVarun Wadekar * entry to EL3 by issuing a newly added instruction 20b0301467SVarun Wadekar * for Denver CPUs. 21b0301467SVarun Wadekar * 22b0301467SVarun Wadekar * To achieve this without performing any branch 23b0301467SVarun Wadekar * instruction, a per-cpu vbar is installed which 24b0301467SVarun Wadekar * executes the workaround and then branches off to 25b0301467SVarun Wadekar * the corresponding vector entry in the main vector 26b0301467SVarun Wadekar * table. 27b0301467SVarun Wadekar * ------------------------------------------------- 28b0301467SVarun Wadekar */ 29b0301467SVarun Wadekar .globl workaround_bpflush_runtime_exceptions 30b0301467SVarun Wadekar 31b0301467SVarun Wadekarvector_base workaround_bpflush_runtime_exceptions 32b0301467SVarun Wadekar 33b0301467SVarun Wadekar .macro apply_workaround 34b0301467SVarun Wadekar stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 35b0301467SVarun Wadekar 36b0301467SVarun Wadekar /* ------------------------------------------------- 37b0301467SVarun Wadekar * A new write-only system register where a write of 38b0301467SVarun Wadekar * 1 to bit 0 will cause the indirect branch predictor 39b0301467SVarun Wadekar * and RSB to be flushed. 40b0301467SVarun Wadekar * 41b0301467SVarun Wadekar * A write of 0 to bit 0 will be ignored. A write of 42b0301467SVarun Wadekar * 1 to any other bit will cause an MCA. 43b0301467SVarun Wadekar * ------------------------------------------------- 44b0301467SVarun Wadekar */ 45b0301467SVarun Wadekar mov x0, #1 46b0301467SVarun Wadekar msr s3_0_c15_c0_6, x0 47b0301467SVarun Wadekar isb 48b0301467SVarun Wadekar 49b0301467SVarun Wadekar ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 50b0301467SVarun Wadekar .endm 51b0301467SVarun Wadekar 52b0301467SVarun Wadekar /* --------------------------------------------------------------------- 53b0301467SVarun Wadekar * Current EL with SP_EL0 : 0x0 - 0x200 54b0301467SVarun Wadekar * --------------------------------------------------------------------- 55b0301467SVarun Wadekar */ 56b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_el0 57b0301467SVarun Wadekar b sync_exception_sp_el0 58a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_sp_el0 59b0301467SVarun Wadekar 60b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_el0 61b0301467SVarun Wadekar b irq_sp_el0 62a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_sp_el0 63b0301467SVarun Wadekar 64b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_el0 65b0301467SVarun Wadekar b fiq_sp_el0 66a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_sp_el0 67b0301467SVarun Wadekar 68b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_el0 69b0301467SVarun Wadekar b serror_sp_el0 70a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_sp_el0 71b0301467SVarun Wadekar 72b0301467SVarun Wadekar /* --------------------------------------------------------------------- 73b0301467SVarun Wadekar * Current EL with SP_ELx: 0x200 - 0x400 74b0301467SVarun Wadekar * --------------------------------------------------------------------- 75b0301467SVarun Wadekar */ 76b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_elx 77b0301467SVarun Wadekar b sync_exception_sp_elx 78a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_sp_elx 79b0301467SVarun Wadekar 80b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_elx 81b0301467SVarun Wadekar b irq_sp_elx 82a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_sp_elx 83b0301467SVarun Wadekar 84b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_elx 85b0301467SVarun Wadekar b fiq_sp_elx 86a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_sp_elx 87b0301467SVarun Wadekar 88b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_elx 89b0301467SVarun Wadekar b serror_sp_elx 90a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_sp_elx 91b0301467SVarun Wadekar 92b0301467SVarun Wadekar /* --------------------------------------------------------------------- 93b0301467SVarun Wadekar * Lower EL using AArch64 : 0x400 - 0x600 94b0301467SVarun Wadekar * --------------------------------------------------------------------- 95b0301467SVarun Wadekar */ 96b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch64 97b0301467SVarun Wadekar apply_workaround 98b0301467SVarun Wadekar b sync_exception_aarch64 99a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_aarch64 100b0301467SVarun Wadekar 101b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch64 102b0301467SVarun Wadekar apply_workaround 103b0301467SVarun Wadekar b irq_aarch64 104a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_aarch64 105b0301467SVarun Wadekar 106b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch64 107b0301467SVarun Wadekar apply_workaround 108b0301467SVarun Wadekar b fiq_aarch64 109a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_aarch64 110b0301467SVarun Wadekar 111b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch64 112b0301467SVarun Wadekar apply_workaround 113b0301467SVarun Wadekar b serror_aarch64 114a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_aarch64 115b0301467SVarun Wadekar 116b0301467SVarun Wadekar /* --------------------------------------------------------------------- 117b0301467SVarun Wadekar * Lower EL using AArch32 : 0x600 - 0x800 118b0301467SVarun Wadekar * --------------------------------------------------------------------- 119b0301467SVarun Wadekar */ 120b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch32 121b0301467SVarun Wadekar apply_workaround 122b0301467SVarun Wadekar b sync_exception_aarch32 123a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_aarch32 124b0301467SVarun Wadekar 125b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch32 126b0301467SVarun Wadekar apply_workaround 127b0301467SVarun Wadekar b irq_aarch32 128a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_aarch32 129b0301467SVarun Wadekar 130b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch32 131b0301467SVarun Wadekar apply_workaround 132b0301467SVarun Wadekar b fiq_aarch32 133a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_aarch32 134b0301467SVarun Wadekar 135b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch32 136b0301467SVarun Wadekar apply_workaround 137b0301467SVarun Wadekar b serror_aarch32 138a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_aarch32 139b0301467SVarun 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 1591593cae4SVarun Wadekar mov x3, x30 1601593cae4SVarun Wadekar bl plat_my_core_pos 1613a8c55f6SVarun Wadekar mov x1, #1 1623a8c55f6SVarun Wadekar lsl x1, x1, x0 1633a8c55f6SVarun Wadekar msr s3_0_c15_c0_2, x1 1641593cae4SVarun Wadekar mov x30, x3 1653a8c55f6SVarun Wadekar ret 1663a8c55f6SVarun Wadekarendfunc denver_enable_dco 1673a8c55f6SVarun Wadekar 1683a8c55f6SVarun Wadekar /* ---------------------------------------------------- 1693a8c55f6SVarun Wadekar * Disable dynamic code optimizer (DCO) 1703a8c55f6SVarun Wadekar * ---------------------------------------------------- 1713a8c55f6SVarun Wadekar */ 1723a8c55f6SVarun Wadekarfunc denver_disable_dco 1733a8c55f6SVarun Wadekar 1741593cae4SVarun Wadekar mov x3, x30 1751593cae4SVarun Wadekar 1763a8c55f6SVarun Wadekar /* turn off background work */ 1771593cae4SVarun Wadekar bl plat_my_core_pos 1783a8c55f6SVarun Wadekar mov x1, #1 1793a8c55f6SVarun Wadekar lsl x1, x1, x0 1803a8c55f6SVarun Wadekar lsl x2, x1, #16 1813a8c55f6SVarun Wadekar msr s3_0_c15_c0_2, x2 1823a8c55f6SVarun Wadekar isb 1833a8c55f6SVarun Wadekar 1843a8c55f6SVarun Wadekar /* wait till the background work turns off */ 1853a8c55f6SVarun Wadekar1: mrs x2, s3_0_c15_c0_2 1863a8c55f6SVarun Wadekar lsr x2, x2, #32 1873a8c55f6SVarun Wadekar and w2, w2, 0xFFFF 1883a8c55f6SVarun Wadekar and x2, x2, x1 1893a8c55f6SVarun Wadekar cbnz x2, 1b 1903a8c55f6SVarun Wadekar 1911593cae4SVarun Wadekar mov x30, x3 1923a8c55f6SVarun Wadekar ret 1933a8c55f6SVarun Wadekarendfunc denver_disable_dco 1943a8c55f6SVarun Wadekar 19583353962SVarun Wadekarfunc check_errata_cve_2017_5715 19683353962SVarun Wadekar mov x0, #ERRATA_MISSING 19783353962SVarun Wadekar#if WORKAROUND_CVE_2017_5715 19883353962SVarun Wadekar /* 19983353962SVarun Wadekar * Check if the CPU supports the special instruction 20083353962SVarun Wadekar * required to flush the indirect branch predictor and 20183353962SVarun Wadekar * RSB. Support for this operation can be determined by 20283353962SVarun Wadekar * comparing bits 19:16 of ID_AFR0_EL1 with 0b0001. 20383353962SVarun Wadekar */ 20483353962SVarun Wadekar mrs x1, id_afr0_el1 20583353962SVarun Wadekar mov x2, #0x10000 20683353962SVarun Wadekar and x1, x1, x2 20783353962SVarun Wadekar cbz x1, 1f 20883353962SVarun Wadekar mov x0, #ERRATA_APPLIES 20983353962SVarun Wadekar1: 21083353962SVarun Wadekar#endif 21183353962SVarun Wadekar ret 21283353962SVarun Wadekarendfunc check_errata_cve_2017_5715 21383353962SVarun Wadekar 2143a8c55f6SVarun Wadekar /* ------------------------------------------------- 2153a8c55f6SVarun Wadekar * The CPU Ops reset function for Denver. 2163a8c55f6SVarun Wadekar * ------------------------------------------------- 2173a8c55f6SVarun Wadekar */ 2183a8c55f6SVarun Wadekarfunc denver_reset_func 2193a8c55f6SVarun Wadekar 2203a8c55f6SVarun Wadekar mov x19, x30 2213a8c55f6SVarun Wadekar 222b0301467SVarun Wadekar#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715 223b0301467SVarun Wadekar /* 224b0301467SVarun Wadekar * Check if the CPU supports the special instruction 225b0301467SVarun Wadekar * required to flush the indirect branch predictor and 226b0301467SVarun Wadekar * RSB. Support for this operation can be determined by 227b0301467SVarun Wadekar * comparing bits 19:16 of ID_AFR0_EL1 with 0b0001. 228b0301467SVarun Wadekar */ 229b0301467SVarun Wadekar mrs x0, id_afr0_el1 230b0301467SVarun Wadekar mov x1, #0x10000 231b0301467SVarun Wadekar and x0, x0, x1 232b0301467SVarun Wadekar cmp x0, #0 233b0301467SVarun Wadekar adr x1, workaround_bpflush_runtime_exceptions 234b0301467SVarun Wadekar mrs x2, vbar_el3 235b0301467SVarun Wadekar csel x0, x1, x2, ne 236b0301467SVarun Wadekar msr vbar_el3, x0 237b0301467SVarun Wadekar#endif 238b0301467SVarun Wadekar 2393a8c55f6SVarun Wadekar /* ---------------------------------------------------- 240*cf3ed0dcSVarun Wadekar * Reset ACTLR.PMSTATE to C1 state 241*cf3ed0dcSVarun Wadekar * ---------------------------------------------------- 242*cf3ed0dcSVarun Wadekar */ 243*cf3ed0dcSVarun Wadekar mrs x0, actlr_el1 244*cf3ed0dcSVarun Wadekar bic x0, x0, #DENVER_CPU_PMSTATE_MASK 245*cf3ed0dcSVarun Wadekar orr x0, x0, #DENVER_CPU_PMSTATE_C1 246*cf3ed0dcSVarun Wadekar msr actlr_el1, x0 247*cf3ed0dcSVarun Wadekar 248*cf3ed0dcSVarun Wadekar /* ---------------------------------------------------- 2493a8c55f6SVarun Wadekar * Enable dynamic code optimizer (DCO) 2503a8c55f6SVarun Wadekar * ---------------------------------------------------- 2513a8c55f6SVarun Wadekar */ 2523a8c55f6SVarun Wadekar bl denver_enable_dco 2533a8c55f6SVarun Wadekar 2543a8c55f6SVarun Wadekar ret x19 2553a8c55f6SVarun Wadekarendfunc denver_reset_func 2563a8c55f6SVarun Wadekar 2573a8c55f6SVarun Wadekar /* ---------------------------------------------------- 2583a8c55f6SVarun Wadekar * The CPU Ops core power down function for Denver. 2593a8c55f6SVarun Wadekar * ---------------------------------------------------- 2603a8c55f6SVarun Wadekar */ 2613a8c55f6SVarun Wadekarfunc denver_core_pwr_dwn 2623a8c55f6SVarun Wadekar 2633a8c55f6SVarun Wadekar mov x19, x30 2643a8c55f6SVarun Wadekar 2653a8c55f6SVarun Wadekar /* --------------------------------------------- 2663a8c55f6SVarun Wadekar * Force the debug interfaces to be quiescent 2673a8c55f6SVarun Wadekar * --------------------------------------------- 2683a8c55f6SVarun Wadekar */ 2693a8c55f6SVarun Wadekar bl denver_disable_ext_debug 2703a8c55f6SVarun Wadekar 2713a8c55f6SVarun Wadekar ret x19 2723a8c55f6SVarun Wadekarendfunc denver_core_pwr_dwn 2733a8c55f6SVarun Wadekar 2743a8c55f6SVarun Wadekar /* ------------------------------------------------------- 2753a8c55f6SVarun Wadekar * The CPU Ops cluster power down function for Denver. 2763a8c55f6SVarun Wadekar * ------------------------------------------------------- 2773a8c55f6SVarun Wadekar */ 2783a8c55f6SVarun Wadekarfunc denver_cluster_pwr_dwn 2793a8c55f6SVarun Wadekar ret 2803a8c55f6SVarun Wadekarendfunc denver_cluster_pwr_dwn 2813a8c55f6SVarun Wadekar 28283353962SVarun Wadekar#if REPORT_ERRATA 28383353962SVarun Wadekar /* 28483353962SVarun Wadekar * Errata printing function for Denver. Must follow AAPCS. 28583353962SVarun Wadekar */ 28683353962SVarun Wadekarfunc denver_errata_report 28783353962SVarun Wadekar stp x8, x30, [sp, #-16]! 28883353962SVarun Wadekar 28983353962SVarun Wadekar bl cpu_get_rev_var 29083353962SVarun Wadekar mov x8, x0 29183353962SVarun Wadekar 29283353962SVarun Wadekar /* 29383353962SVarun Wadekar * Report all errata. The revision-variant information is passed to 29483353962SVarun Wadekar * checking functions of each errata. 29583353962SVarun Wadekar */ 29683353962SVarun Wadekar report_errata WORKAROUND_CVE_2017_5715, denver, cve_2017_5715 29783353962SVarun Wadekar 29883353962SVarun Wadekar ldp x8, x30, [sp], #16 29983353962SVarun Wadekar ret 30083353962SVarun Wadekarendfunc denver_errata_report 30183353962SVarun Wadekar#endif 30283353962SVarun Wadekar 3033a8c55f6SVarun Wadekar /* --------------------------------------------- 3043a8c55f6SVarun Wadekar * This function provides Denver specific 3053a8c55f6SVarun Wadekar * register information for crash reporting. 3063a8c55f6SVarun Wadekar * It needs to return with x6 pointing to 3073a8c55f6SVarun Wadekar * a list of register names in ascii and 3083a8c55f6SVarun Wadekar * x8 - x15 having values of registers to be 3093a8c55f6SVarun Wadekar * reported. 3103a8c55f6SVarun Wadekar * --------------------------------------------- 3113a8c55f6SVarun Wadekar */ 3123a8c55f6SVarun Wadekar.section .rodata.denver_regs, "aS" 3133a8c55f6SVarun Wadekardenver_regs: /* The ascii list of register names to be reported */ 3143a8c55f6SVarun Wadekar .asciz "actlr_el1", "" 3153a8c55f6SVarun Wadekar 3163a8c55f6SVarun Wadekarfunc denver_cpu_reg_dump 3173a8c55f6SVarun Wadekar adr x6, denver_regs 3183a8c55f6SVarun Wadekar mrs x8, ACTLR_EL1 3193a8c55f6SVarun Wadekar ret 3203a8c55f6SVarun Wadekarendfunc denver_cpu_reg_dump 3213a8c55f6SVarun Wadekar 32283353962SVarun Wadekardeclare_cpu_ops_wa denver, DENVER_MIDR_PN0, \ 323e956e228SVarun Wadekar denver_reset_func, \ 32483353962SVarun Wadekar check_errata_cve_2017_5715, \ 32583353962SVarun Wadekar CPU_NO_EXTRA2_FUNC, \ 326e956e228SVarun Wadekar denver_core_pwr_dwn, \ 327e956e228SVarun Wadekar denver_cluster_pwr_dwn 328e956e228SVarun Wadekar 32983353962SVarun Wadekardeclare_cpu_ops_wa denver, DENVER_MIDR_PN1, \ 330e956e228SVarun Wadekar denver_reset_func, \ 33183353962SVarun Wadekar check_errata_cve_2017_5715, \ 33283353962SVarun Wadekar CPU_NO_EXTRA2_FUNC, \ 333e956e228SVarun Wadekar denver_core_pwr_dwn, \ 334e956e228SVarun Wadekar denver_cluster_pwr_dwn 335e956e228SVarun Wadekar 33683353962SVarun Wadekardeclare_cpu_ops_wa denver, DENVER_MIDR_PN2, \ 337e956e228SVarun Wadekar denver_reset_func, \ 33883353962SVarun Wadekar check_errata_cve_2017_5715, \ 33983353962SVarun Wadekar CPU_NO_EXTRA2_FUNC, \ 340e956e228SVarun Wadekar denver_core_pwr_dwn, \ 341e956e228SVarun Wadekar denver_cluster_pwr_dwn 342e956e228SVarun Wadekar 34383353962SVarun Wadekardeclare_cpu_ops_wa denver, DENVER_MIDR_PN3, \ 344e956e228SVarun Wadekar denver_reset_func, \ 34583353962SVarun Wadekar check_errata_cve_2017_5715, \ 34683353962SVarun Wadekar CPU_NO_EXTRA2_FUNC, \ 347e956e228SVarun Wadekar denver_core_pwr_dwn, \ 348e956e228SVarun Wadekar denver_cluster_pwr_dwn 349e956e228SVarun Wadekar 35083353962SVarun Wadekardeclare_cpu_ops_wa denver, DENVER_MIDR_PN4, \ 3515dd9dbb5SJeenu Viswambharan denver_reset_func, \ 35283353962SVarun Wadekar check_errata_cve_2017_5715, \ 35383353962SVarun Wadekar CPU_NO_EXTRA2_FUNC, \ 3545dd9dbb5SJeenu Viswambharan denver_core_pwr_dwn, \ 3555dd9dbb5SJeenu Viswambharan denver_cluster_pwr_dwn 356