1/* 2 * Copyright (c) 2016-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 <lib/cpus/cpu_ops.h> 10#include <lib/cpus/errata.h> 11 12 /* 13 * Write given expressions as words 14 * 15 * _count: 16 * Write at least _count words. If the given number of expressions 17 * is less than _count, repeat the last expression to fill _count 18 * words in total 19 * _rest: 20 * Optional list of expressions. _this is for parameter extraction 21 * only, and has no significance to the caller 22 * 23 * Invoked as: 24 * fill_constants 2, foo, bar, blah, ... 25 */ 26 .macro fill_constants _count:req, _this, _rest:vararg 27 .ifgt \_count 28 /* Write the current expression */ 29 .ifb \_this 30 .error "Nothing to fill" 31 .endif 32 .word \_this 33 34 /* Invoke recursively for remaining expressions */ 35 .ifnb \_rest 36 fill_constants \_count-1, \_rest 37 .else 38 fill_constants \_count-1, \_this 39 .endif 40 .endif 41 .endm 42 43 /* 44 * Declare CPU operations 45 * 46 * _name: 47 * Name of the CPU for which operations are being specified 48 * _midr: 49 * Numeric value expected to read from CPU's MIDR 50 * _resetfunc: 51 * Reset function for the CPU. If there's no CPU reset function, 52 * specify CPU_NO_RESET_FUNC 53 * _power_down_ops: 54 * Comma-separated list of functions to perform power-down 55 * operatios on the CPU. At least one, and up to 56 * CPU_MAX_PWR_DWN_OPS number of functions may be specified. 57 * Starting at power level 0, these functions shall handle power 58 * down at subsequent power levels. If there aren't exactly 59 * CPU_MAX_PWR_DWN_OPS functions, the last specified one will be 60 * used to handle power down at subsequent levels 61 */ 62 .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \ 63 _power_down_ops:vararg 64 .section .cpu_ops, "a" 65 .align 2 66 .type cpu_ops_\_name, %object 67 .word \_midr 68#if defined(IMAGE_AT_EL3) 69 .word \_resetfunc 70#endif 71#ifdef IMAGE_BL32 72 /* Insert list of functions */ 73 fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops 74#endif 75 76 /* 77 * It is possible (although unlikely) that a cpu may have no errata in 78 * code. In that case the start label will not be defined. The list is 79 * inteded to be used in a loop, so define it as zero-length for 80 * predictable behaviour. Since this macro is always called at the end 81 * of the cpu file (after all errata have been parsed) we can be sure 82 * that we are at the end of the list. Some cpus call the macro twice, 83 * so only do this once. 84 */ 85 .pushsection .rodata.errata_entries 86 .ifndef \_name\()_errata_list_start 87 \_name\()_errata_list_start: 88 .endif 89 /* some call this multiple times, so only do this once */ 90 .ifndef \_name\()_errata_list_end 91 \_name\()_errata_list_end: 92 .endif 93 .popsection 94 95 /* and now put them in cpu_ops */ 96 .word \_name\()_errata_list_start 97 .word \_name\()_errata_list_end 98 99#if REPORT_ERRATA 100 .ifndef \_name\()_cpu_str 101 /* 102 * Place errata reported flag, and the spinlock to arbitrate access to 103 * it in the data section. 104 */ 105 .pushsection .data 106 define_asm_spinlock \_name\()_errata_lock 107 \_name\()_errata_reported: 108 .word 0 109 .popsection 110 111 /* Place CPU string in rodata */ 112 .pushsection .rodata 113 \_name\()_cpu_str: 114 .asciz "\_name" 115 .popsection 116 .endif 117 118 /* 119 * Mandatory errata status printing function for CPUs of 120 * this class. 121 */ 122 .word \_name\()_errata_report 123 .word \_name\()_cpu_str 124 125#ifdef IMAGE_BL32 126 /* Pointers to errata lock and reported flag */ 127 .word \_name\()_errata_lock 128 .word \_name\()_errata_reported 129#endif 130#endif 131 .endm 132 133#if REPORT_ERRATA 134 /* 135 * Print status of a CPU errata 136 * 137 * _chosen: 138 * Identifier indicating whether or not a CPU errata has been 139 * compiled in. 140 * _cpu: 141 * Name of the CPU 142 * _id: 143 * Errata identifier 144 * _rev_var: 145 * Register containing the combined value CPU revision and variant 146 * - typically the return value of cpu_get_rev_var 147 */ 148 .macro report_errata _chosen, _cpu, _id, _rev_var=r4 149 /* Stash a string with errata ID */ 150 .pushsection .rodata 151 \_cpu\()_errata_\_id\()_str: 152 .asciz "\_id" 153 .popsection 154 155 /* Check whether errata applies */ 156 mov r0, \_rev_var 157 bl check_errata_\_id 158 159 .ifeq \_chosen 160 /* 161 * Errata workaround has not been compiled in. If the errata would have 162 * applied had it been compiled in, print its status as missing. 163 */ 164 cmp r0, #0 165 movne r0, #ERRATA_MISSING 166 .endif 167 ldr r1, =\_cpu\()_cpu_str 168 ldr r2, =\_cpu\()_errata_\_id\()_str 169 bl errata_print_msg 170 .endm 171#endif 172 /* 173 * Helper macro that reads the part number of the current CPU and jumps 174 * to the given label if it matches the CPU MIDR provided. 175 * 176 * Clobbers: r0-r1 177 */ 178 .macro jump_if_cpu_midr _cpu_midr, _label 179 ldcopr r0, MIDR 180 ubfx r0, r0, #MIDR_PN_SHIFT, #12 181 ldr r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) 182 cmp r0, r1 183 beq \_label 184 .endm 185 186/* 187 * NOTE an erratum and CVE id could clash. However, both numbers are very large 188 * and the probablity is minuscule. Working around this makes code very 189 * complicated and extremely difficult to read so it is not considered. In the 190 * unlikely event that this does happen, prepending the CVE id with a 0 should 191 * resolve the conflict 192 */ 193 194/* 195 * Add an entry for this erratum to the errata framework 196 * 197 * _cpu: 198 * Name of cpu as given to declare_cpu_ops 199 * 200 * _cve: 201 * Whether erratum is a CVE. CVE year if yes, 0 otherwise 202 * 203 * _id: 204 * Erratum or CVE number. Please combine with the previous field with the 205 * ERRATUM or CVE macros 206 * 207 * _chosen: 208 * Compile time flag on whether the erratum is included 209 * 210 * _special: 211 * The special non-standard name of an erratum 212 */ 213.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _special 214 .pushsection .rodata.errata_entries 215 .align 2 216 .ifndef \_cpu\()_errata_list_start 217 \_cpu\()_errata_list_start: 218 .endif 219 220 /* unused on AArch32, maintain for portability */ 221 .word 0 222 /* TODO(errata ABI): this prevents all checker functions from 223 * being optimised away. Can be done away with unless the ABI 224 * needs them */ 225 .ifnb \_special 226 .word check_errata_\_special 227 .elseif \_cve 228 .word check_errata_cve_\_cve\()_\_id 229 .else 230 .word check_errata_\_id 231 .endif 232 /* Will fit CVEs with up to 10 character in the ID field */ 233 .word \_id 234 .hword \_cve 235 .byte \_chosen 236 /* TODO(errata ABI): mitigated field for known but unmitigated 237 * errata*/ 238 .byte 0x1 239 .popsection 240.endm 241 242/* 243 * Maintain compatibility with the old scheme of "each cpu has its own reporter". 244 * TODO remove entirely once all cpus have been converted. This includes the 245 * cpu_ops entry, as print_errata_status can call this directly for all cpus 246 */ 247.macro errata_report_shim _cpu:req 248 #if REPORT_ERRATA 249 func \_cpu\()_errata_report 250 push {r12, lr} 251 252 bl generic_errata_report 253 254 pop {r12, lr} 255 bx lr 256 endfunc \_cpu\()_errata_report 257 #endif 258.endm 259#endif /* CPU_MACROS_S */ 260