1/* 2 * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#ifndef CPU_MACROS_S 7#define CPU_MACROS_S 8 9#include <assert_macros.S> 10#include <lib/cpus/cpu_ops.h> 11#include <lib/cpus/errata.h> 12 13 /* 14 * Write given expressions as quad words 15 * 16 * _count: 17 * Write at least _count quad words. If the given number of 18 * expressions is less than _count, repeat the last expression to 19 * fill _count quad words in total 20 * _rest: 21 * Optional list of expressions. _this is for parameter extraction 22 * only, and has no significance to the caller 23 * 24 * Invoked as: 25 * fill_constants 2, foo, bar, blah, ... 26 */ 27 .macro fill_constants _count:req, _this, _rest:vararg 28 .ifgt \_count 29 /* Write the current expression */ 30 .ifb \_this 31 .error "Nothing to fill" 32 .endif 33 .quad \_this 34 35 /* Invoke recursively for remaining expressions */ 36 .ifnb \_rest 37 fill_constants \_count-1, \_rest 38 .else 39 fill_constants \_count-1, \_this 40 .endif 41 .endif 42 .endm 43 44 /* 45 * Declare CPU operations 46 * 47 * _name: 48 * Name of the CPU for which operations are being specified 49 * _midr: 50 * Numeric value expected to read from CPU's MIDR 51 * _resetfunc: 52 * Reset function for the CPU. If there's no CPU reset function, 53 * specify CPU_NO_RESET_FUNC 54 * _extra1: 55 * This is a placeholder for future per CPU operations. Currently, 56 * some CPUs use this entry to set a test function to determine if 57 * the workaround for CVE-2017-5715 needs to be applied or not. 58 * _extra2: 59 * This is a placeholder for future per CPU operations. Currently 60 * some CPUs use this entry to set a function to disable the 61 * workaround for CVE-2018-3639. 62 * _extra3: 63 * This is a placeholder for future per CPU operations. Currently, 64 * some CPUs use this entry to set a test function to determine if 65 * the workaround for CVE-2022-23960 needs to be applied or not. 66 * _e_handler: 67 * This is a placeholder for future per CPU exception handlers. 68 * _power_down_ops: 69 * Comma-separated list of functions to perform power-down 70 * operatios on the CPU. At least one, and up to 71 * CPU_MAX_PWR_DWN_OPS number of functions may be specified. 72 * Starting at power level 0, these functions shall handle power 73 * down at subsequent power levels. If there aren't exactly 74 * CPU_MAX_PWR_DWN_OPS functions, the last specified one will be 75 * used to handle power down at subsequent levels 76 */ 77 .macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \ 78 _extra1:req, _extra2:req, _extra3:req, _e_handler:req, _power_down_ops:vararg 79 .section .cpu_ops, "a" 80 .align 3 81 .type cpu_ops_\_name, %object 82 .quad \_midr 83#if defined(IMAGE_AT_EL3) 84 .quad \_resetfunc 85#endif 86 .quad \_extra1 87 .quad \_extra2 88 .quad \_extra3 89 .quad \_e_handler 90#ifdef IMAGE_BL31 91 /* Insert list of functions */ 92 fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops 93#endif 94 95#if REPORT_ERRATA 96 .ifndef \_name\()_cpu_str 97 /* 98 * Place errata reported flag, and the spinlock to arbitrate access to 99 * it in the data section. 100 */ 101 .pushsection .data 102 define_asm_spinlock \_name\()_errata_lock 103 \_name\()_errata_reported: 104 .word 0 105 .popsection 106 107 /* Place CPU string in rodata */ 108 .pushsection .rodata 109 \_name\()_cpu_str: 110 .asciz "\_name" 111 .popsection 112 .endif 113 114 /* 115 * Mandatory errata status printing function for CPUs of 116 * this class. 117 */ 118 .quad \_name\()_errata_report 119 120#ifdef IMAGE_BL31 121 /* Pointers to errata lock and reported flag */ 122 .quad \_name\()_errata_lock 123 .quad \_name\()_errata_reported 124#endif 125#endif 126 127#if defined(IMAGE_BL31) && CRASH_REPORTING 128 .quad \_name\()_cpu_reg_dump 129#endif 130 .endm 131 132 .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \ 133 _power_down_ops:vararg 134 declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, 0, 0, 0, \ 135 \_power_down_ops 136 .endm 137 138 .macro declare_cpu_ops_eh _name:req, _midr:req, _resetfunc:req, \ 139 _e_handler:req, _power_down_ops:vararg 140 declare_cpu_ops_base \_name, \_midr, \_resetfunc, \ 141 0, 0, 0, \_e_handler, \_power_down_ops 142 .endm 143 144 .macro declare_cpu_ops_wa _name:req, _midr:req, \ 145 _resetfunc:req, _extra1:req, _extra2:req, \ 146 _extra3:req, _power_down_ops:vararg 147 declare_cpu_ops_base \_name, \_midr, \_resetfunc, \ 148 \_extra1, \_extra2, \_extra3, 0, \_power_down_ops 149 .endm 150 151#if REPORT_ERRATA 152 /* 153 * Print status of a CPU errata 154 * 155 * _chosen: 156 * Identifier indicating whether or not a CPU errata has been 157 * compiled in. 158 * _cpu: 159 * Name of the CPU 160 * _id: 161 * Errata identifier 162 * _rev_var: 163 * Register containing the combined value CPU revision and variant 164 * - typically the return value of cpu_get_rev_var 165 */ 166 .macro report_errata _chosen, _cpu, _id, _rev_var=x8 167 /* Stash a string with errata ID */ 168 .pushsection .rodata 169 \_cpu\()_errata_\_id\()_str: 170 .asciz "\_id" 171 .popsection 172 173 /* Check whether errata applies */ 174 mov x0, \_rev_var 175 /* Shall clobber: x0-x7 */ 176 bl check_errata_\_id 177 178 .ifeq \_chosen 179 /* 180 * Errata workaround has not been compiled in. If the errata would have 181 * applied had it been compiled in, print its status as missing. 182 */ 183 cbz x0, 900f 184 mov x0, #ERRATA_MISSING 185 .endif 186900: 187 adr x1, \_cpu\()_cpu_str 188 adr x2, \_cpu\()_errata_\_id\()_str 189 bl errata_print_msg 190 .endm 191#endif 192 193 /* 194 * This macro is used on some CPUs to detect if they are vulnerable 195 * to CVE-2017-5715. 196 */ 197 .macro cpu_check_csv2 _reg _label 198 mrs \_reg, id_aa64pfr0_el1 199 ubfx \_reg, \_reg, #ID_AA64PFR0_CSV2_SHIFT, #ID_AA64PFR0_CSV2_LENGTH 200 /* 201 * If the field equals 1, branch targets trained in one context cannot 202 * affect speculative execution in a different context. 203 * 204 * If the field equals 2, it means that the system is also aware of 205 * SCXTNUM_ELx register contexts. We aren't using them in the TF, so we 206 * expect users of the registers to do the right thing. 207 * 208 * Only apply mitigations if the value of this field is 0. 209 */ 210#if ENABLE_ASSERTIONS 211 cmp \_reg, #3 /* Only values 0 to 2 are expected */ 212 ASM_ASSERT(lo) 213#endif 214 215 cmp \_reg, #0 216 bne \_label 217 .endm 218 219 /* 220 * Helper macro that reads the part number of the current 221 * CPU and jumps to the given label if it matches the CPU 222 * MIDR provided. 223 * 224 * Clobbers x0. 225 */ 226 .macro jump_if_cpu_midr _cpu_midr, _label 227 mrs x0, midr_el1 228 ubfx x0, x0, MIDR_PN_SHIFT, #12 229 cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) 230 b.eq \_label 231 .endm 232 233#endif /* CPU_MACROS_S */ 234