1/* 2 * Copyright (c) 2014-2018, 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 <arch.h> 10#include <errata_report.h> 11 12#define CPU_IMPL_PN_MASK (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \ 13 (MIDR_PN_MASK << MIDR_PN_SHIFT) 14 15/* The number of CPU operations allowed */ 16#define CPU_MAX_PWR_DWN_OPS 2 17 18/* Special constant to specify that CPU has no reset function */ 19#define CPU_NO_RESET_FUNC 0 20 21/* Word size for 64-bit CPUs */ 22#define CPU_WORD_SIZE 8 23 24#if defined(IMAGE_BL1) || defined(IMAGE_BL31) ||(defined(IMAGE_BL2) && BL2_AT_EL3) 25#define IMAGE_AT_EL3 26#endif 27 28/* 29 * Whether errata status needs reporting. Errata status is printed in debug 30 * builds for both BL1 and BL31 images. 31 */ 32#if (defined(IMAGE_BL1) || defined(IMAGE_BL31)) && DEBUG 33# define REPORT_ERRATA 1 34#else 35# define REPORT_ERRATA 0 36#endif 37 38 /* 39 * Define the offsets to the fields in cpu_ops structure. 40 */ 41 .struct 0 42CPU_MIDR: /* cpu_ops midr */ 43 .space 8 44/* Reset fn is needed in BL at reset vector */ 45#if defined(IMAGE_AT_EL3) 46CPU_RESET_FUNC: /* cpu_ops reset_func */ 47 .space 8 48#endif 49CPU_EXTRA1_FUNC: 50 .space 8 51#ifdef IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */ 52CPU_PWR_DWN_OPS: /* cpu_ops power down functions */ 53 .space (8 * CPU_MAX_PWR_DWN_OPS) 54#endif 55 56/* 57 * Fields required to print errata status. Only in BL31 that the printing 58 * require mutual exclusion and printed flag. 59 */ 60#if REPORT_ERRATA 61CPU_ERRATA_FUNC: 62 .space 8 63#if defined(IMAGE_BL31) 64CPU_ERRATA_LOCK: 65 .space 8 66CPU_ERRATA_PRINTED: 67 .space 8 68#endif 69#endif 70 71#if defined(IMAGE_BL31) && CRASH_REPORTING 72CPU_REG_DUMP: /* cpu specific register dump for crash reporting */ 73 .space 8 74#endif 75CPU_OPS_SIZE = . 76 77 /* 78 * Write given expressions as quad words 79 * 80 * _count: 81 * Write at least _count quad words. If the given number of 82 * expressions is less than _count, repeat the last expression to 83 * fill _count quad words in total 84 * _rest: 85 * Optional list of expressions. _this is for parameter extraction 86 * only, and has no significance to the caller 87 * 88 * Invoked as: 89 * fill_constants 2, foo, bar, blah, ... 90 */ 91 .macro fill_constants _count:req, _this, _rest:vararg 92 .ifgt \_count 93 /* Write the current expression */ 94 .ifb \_this 95 .error "Nothing to fill" 96 .endif 97 .quad \_this 98 99 /* Invoke recursively for remaining expressions */ 100 .ifnb \_rest 101 fill_constants \_count-1, \_rest 102 .else 103 fill_constants \_count-1, \_this 104 .endif 105 .endif 106 .endm 107 108 /* 109 * Declare CPU operations 110 * 111 * _name: 112 * Name of the CPU for which operations are being specified 113 * _midr: 114 * Numeric value expected to read from CPU's MIDR 115 * _resetfunc: 116 * Reset function for the CPU. If there's no CPU reset function, 117 * specify CPU_NO_RESET_FUNC 118 * _extra1: 119 * This is a placeholder for future per CPU operations. Currently, 120 * some CPUs use this entry to set a test function to determine if 121 * the workaround for CVE-2017-5715 needs to be applied or not. 122 * _power_down_ops: 123 * Comma-separated list of functions to perform power-down 124 * operatios on the CPU. At least one, and up to 125 * CPU_MAX_PWR_DWN_OPS number of functions may be specified. 126 * Starting at power level 0, these functions shall handle power 127 * down at subsequent power levels. If there aren't exactly 128 * CPU_MAX_PWR_DWN_OPS functions, the last specified one will be 129 * used to handle power down at subsequent levels 130 */ 131 .macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \ 132 _extra1:req, _power_down_ops:vararg 133 .section cpu_ops, "a" 134 .align 3 135 .type cpu_ops_\_name, %object 136 .quad \_midr 137#if defined(IMAGE_AT_EL3) 138 .quad \_resetfunc 139#endif 140 .quad \_extra1 141#ifdef IMAGE_BL31 1421: 143 /* Insert list of functions */ 144 fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops 1452: 146 /* 147 * Error if no or more than CPU_MAX_PWR_DWN_OPS were specified in the 148 * list 149 */ 150 .ifeq 2b - 1b 151 .error "At least one power down function must be specified" 152 .else 153 .iflt 2b - 1b - (CPU_MAX_PWR_DWN_OPS * CPU_WORD_SIZE) 154 .error "More than CPU_MAX_PWR_DWN_OPS functions specified" 155 .endif 156 .endif 157#endif 158 159#if REPORT_ERRATA 160 .ifndef \_name\()_cpu_str 161 /* 162 * Place errata reported flag, and the spinlock to arbitrate access to 163 * it in the data section. 164 */ 165 .pushsection .data 166 define_asm_spinlock \_name\()_errata_lock 167 \_name\()_errata_reported: 168 .word 0 169 .popsection 170 171 /* Place CPU string in rodata */ 172 .pushsection .rodata 173 \_name\()_cpu_str: 174 .asciz "\_name" 175 .popsection 176 .endif 177 178 /* 179 * Weakly-bound, optional errata status printing function for CPUs of 180 * this class. 181 */ 182 .weak \_name\()_errata_report 183 .quad \_name\()_errata_report 184 185#ifdef IMAGE_BL31 186 /* Pointers to errata lock and reported flag */ 187 .quad \_name\()_errata_lock 188 .quad \_name\()_errata_reported 189#endif 190#endif 191 192#if defined(IMAGE_BL31) && CRASH_REPORTING 193 .quad \_name\()_cpu_reg_dump 194#endif 195 .endm 196 197 .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \ 198 _power_down_ops:vararg 199 declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, \ 200 \_power_down_ops 201 .endm 202 203 .macro declare_cpu_ops_workaround_cve_2017_5715 _name:req, _midr:req, \ 204 _resetfunc:req, _extra1:req, _power_down_ops:vararg 205 declare_cpu_ops_base \_name, \_midr, \_resetfunc, \ 206 \_extra1, \_power_down_ops 207 .endm 208 209#if REPORT_ERRATA 210 /* 211 * Print status of a CPU errata 212 * 213 * _chosen: 214 * Identifier indicating whether or not a CPU errata has been 215 * compiled in. 216 * _cpu: 217 * Name of the CPU 218 * _id: 219 * Errata identifier 220 * _rev_var: 221 * Register containing the combined value CPU revision and variant 222 * - typically the return value of cpu_get_rev_var 223 */ 224 .macro report_errata _chosen, _cpu, _id, _rev_var=x8 225 /* Stash a string with errata ID */ 226 .pushsection .rodata 227 \_cpu\()_errata_\_id\()_str: 228 .asciz "\_id" 229 .popsection 230 231 /* Check whether errata applies */ 232 mov x0, \_rev_var 233 bl check_errata_\_id 234 235 .ifeq \_chosen 236 /* 237 * Errata workaround has not been compiled in. If the errata would have 238 * applied had it been compiled in, print its status as missing. 239 */ 240 cbz x0, 900f 241 mov x0, #ERRATA_MISSING 242 .endif 243900: 244 adr x1, \_cpu\()_cpu_str 245 adr x2, \_cpu\()_errata_\_id\()_str 246 bl errata_print_msg 247 .endm 248#endif 249 250#endif /* __CPU_MACROS_S__ */ 251 252 /* 253 * This macro is used on some CPUs to detect if they are vulnerable 254 * to CVE-2017-5715. 255 */ 256 .macro cpu_check_csv2 _reg _label 257 mrs \_reg, id_aa64pfr0_el1 258 ubfx \_reg, \_reg, #ID_AA64PFR0_CSV2_SHIFT, #ID_AA64PFR0_CSV2_LENGTH 259 /* 260 * If the field equals to 1 then branch targets trained in one 261 * context cannot affect speculative execution in a different context. 262 */ 263 cmp \_reg, #1 264 beq \_label 265 .endm 266