1e33b78a6SSoby Mathew/* 2*34c51f32SBoyan Karatotev * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved. 3e33b78a6SSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5e33b78a6SSoby Mathew */ 6c3cf06f1SAntonio Nino Diaz#ifndef CPU_MACROS_S 7c3cf06f1SAntonio Nino Diaz#define CPU_MACROS_S 8e33b78a6SSoby Mathew 9007433d8SBoyan Karatotev#include <lib/cpus/cpu_ops.h> 106bb96fa6SBoyan Karatotev#include <lib/cpus/errata.h> 11e33b78a6SSoby Mathew 12e33b78a6SSoby Mathew /* 135dd9dbb5SJeenu Viswambharan * Write given expressions as words 145dd9dbb5SJeenu Viswambharan * 155dd9dbb5SJeenu Viswambharan * _count: 165dd9dbb5SJeenu Viswambharan * Write at least _count words. If the given number of expressions 175dd9dbb5SJeenu Viswambharan * is less than _count, repeat the last expression to fill _count 185dd9dbb5SJeenu Viswambharan * words in total 195dd9dbb5SJeenu Viswambharan * _rest: 205dd9dbb5SJeenu Viswambharan * Optional list of expressions. _this is for parameter extraction 215dd9dbb5SJeenu Viswambharan * only, and has no significance to the caller 225dd9dbb5SJeenu Viswambharan * 235dd9dbb5SJeenu Viswambharan * Invoked as: 245dd9dbb5SJeenu Viswambharan * fill_constants 2, foo, bar, blah, ... 25e33b78a6SSoby Mathew */ 265dd9dbb5SJeenu Viswambharan .macro fill_constants _count:req, _this, _rest:vararg 275dd9dbb5SJeenu Viswambharan .ifgt \_count 285dd9dbb5SJeenu Viswambharan /* Write the current expression */ 295dd9dbb5SJeenu Viswambharan .ifb \_this 305dd9dbb5SJeenu Viswambharan .error "Nothing to fill" 315dd9dbb5SJeenu Viswambharan .endif 325dd9dbb5SJeenu Viswambharan .word \_this 335dd9dbb5SJeenu Viswambharan 345dd9dbb5SJeenu Viswambharan /* Invoke recursively for remaining expressions */ 355dd9dbb5SJeenu Viswambharan .ifnb \_rest 365dd9dbb5SJeenu Viswambharan fill_constants \_count-1, \_rest 375dd9dbb5SJeenu Viswambharan .else 385dd9dbb5SJeenu Viswambharan fill_constants \_count-1, \_this 395dd9dbb5SJeenu Viswambharan .endif 405dd9dbb5SJeenu Viswambharan .endif 415dd9dbb5SJeenu Viswambharan .endm 425dd9dbb5SJeenu Viswambharan 435dd9dbb5SJeenu Viswambharan /* 445dd9dbb5SJeenu Viswambharan * Declare CPU operations 455dd9dbb5SJeenu Viswambharan * 465dd9dbb5SJeenu Viswambharan * _name: 475dd9dbb5SJeenu Viswambharan * Name of the CPU for which operations are being specified 485dd9dbb5SJeenu Viswambharan * _midr: 495dd9dbb5SJeenu Viswambharan * Numeric value expected to read from CPU's MIDR 505dd9dbb5SJeenu Viswambharan * _resetfunc: 515dd9dbb5SJeenu Viswambharan * Reset function for the CPU. If there's no CPU reset function, 525dd9dbb5SJeenu Viswambharan * specify CPU_NO_RESET_FUNC 535dd9dbb5SJeenu Viswambharan * _power_down_ops: 545dd9dbb5SJeenu Viswambharan * Comma-separated list of functions to perform power-down 555dd9dbb5SJeenu Viswambharan * operatios on the CPU. At least one, and up to 565dd9dbb5SJeenu Viswambharan * CPU_MAX_PWR_DWN_OPS number of functions may be specified. 575dd9dbb5SJeenu Viswambharan * Starting at power level 0, these functions shall handle power 585dd9dbb5SJeenu Viswambharan * down at subsequent power levels. If there aren't exactly 595dd9dbb5SJeenu Viswambharan * CPU_MAX_PWR_DWN_OPS functions, the last specified one will be 605dd9dbb5SJeenu Viswambharan * used to handle power down at subsequent levels 615dd9dbb5SJeenu Viswambharan */ 625dd9dbb5SJeenu Viswambharan .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \ 635dd9dbb5SJeenu Viswambharan _power_down_ops:vararg 64da04341eSChris Kay .section .cpu_ops, "a" 65e33b78a6SSoby Mathew .align 2 66e33b78a6SSoby Mathew .type cpu_ops_\_name, %object 67e33b78a6SSoby Mathew .word \_midr 68b1d27b48SRoberto Vargas#if defined(IMAGE_AT_EL3) 695dd9dbb5SJeenu Viswambharan .word \_resetfunc 701a0a3f06SYatharth Kochar#endif 713d8256b2SMasahiro Yamada#ifdef IMAGE_BL32 725dd9dbb5SJeenu Viswambharan /* Insert list of functions */ 735dd9dbb5SJeenu Viswambharan fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops 741a0a3f06SYatharth Kochar#endif 7510bcd761SJeenu Viswambharan 76*34c51f32SBoyan Karatotev /* 77*34c51f32SBoyan Karatotev * It is possible (although unlikely) that a cpu may have no errata in 78*34c51f32SBoyan Karatotev * code. In that case the start label will not be defined. The list is 79*34c51f32SBoyan Karatotev * inteded to be used in a loop, so define it as zero-length for 80*34c51f32SBoyan Karatotev * predictable behaviour. Since this macro is always called at the end 81*34c51f32SBoyan Karatotev * of the cpu file (after all errata have been parsed) we can be sure 82*34c51f32SBoyan Karatotev * that we are at the end of the list. Some cpus call the macro twice, 83*34c51f32SBoyan Karatotev * so only do this once. 84*34c51f32SBoyan Karatotev */ 85*34c51f32SBoyan Karatotev .pushsection .rodata.errata_entries 86*34c51f32SBoyan Karatotev .ifndef \_name\()_errata_list_start 87*34c51f32SBoyan Karatotev \_name\()_errata_list_start: 88*34c51f32SBoyan Karatotev .endif 89*34c51f32SBoyan Karatotev /* some call this multiple times, so only do this once */ 90*34c51f32SBoyan Karatotev .ifndef \_name\()_errata_list_end 91*34c51f32SBoyan Karatotev \_name\()_errata_list_end: 92*34c51f32SBoyan Karatotev .endif 93*34c51f32SBoyan Karatotev .popsection 94*34c51f32SBoyan Karatotev 95*34c51f32SBoyan Karatotev /* and now put them in cpu_ops */ 96*34c51f32SBoyan Karatotev .word \_name\()_errata_list_start 97*34c51f32SBoyan Karatotev .word \_name\()_errata_list_end 98*34c51f32SBoyan Karatotev 9910bcd761SJeenu Viswambharan#if REPORT_ERRATA 10010bcd761SJeenu Viswambharan .ifndef \_name\()_cpu_str 10110bcd761SJeenu Viswambharan /* 10210bcd761SJeenu Viswambharan * Place errata reported flag, and the spinlock to arbitrate access to 10310bcd761SJeenu Viswambharan * it in the data section. 10410bcd761SJeenu Viswambharan */ 10510bcd761SJeenu Viswambharan .pushsection .data 10610bcd761SJeenu Viswambharan define_asm_spinlock \_name\()_errata_lock 10710bcd761SJeenu Viswambharan \_name\()_errata_reported: 10810bcd761SJeenu Viswambharan .word 0 10910bcd761SJeenu Viswambharan .popsection 11010bcd761SJeenu Viswambharan 11110bcd761SJeenu Viswambharan /* Place CPU string in rodata */ 11210bcd761SJeenu Viswambharan .pushsection .rodata 11310bcd761SJeenu Viswambharan \_name\()_cpu_str: 11410bcd761SJeenu Viswambharan .asciz "\_name" 11510bcd761SJeenu Viswambharan .popsection 11610bcd761SJeenu Viswambharan .endif 11710bcd761SJeenu Viswambharan 11810bcd761SJeenu Viswambharan /* 11912af5ed4SSoby Mathew * Mandatory errata status printing function for CPUs of 12010bcd761SJeenu Viswambharan * this class. 12110bcd761SJeenu Viswambharan */ 12210bcd761SJeenu Viswambharan .word \_name\()_errata_report 123*34c51f32SBoyan Karatotev .word \_name\()_cpu_str 12410bcd761SJeenu Viswambharan 12510bcd761SJeenu Viswambharan#ifdef IMAGE_BL32 12610bcd761SJeenu Viswambharan /* Pointers to errata lock and reported flag */ 12710bcd761SJeenu Viswambharan .word \_name\()_errata_lock 12810bcd761SJeenu Viswambharan .word \_name\()_errata_reported 12910bcd761SJeenu Viswambharan#endif 13010bcd761SJeenu Viswambharan#endif 131e33b78a6SSoby Mathew .endm 132e33b78a6SSoby Mathew 13310bcd761SJeenu Viswambharan#if REPORT_ERRATA 13410bcd761SJeenu Viswambharan /* 13510bcd761SJeenu Viswambharan * Print status of a CPU errata 13610bcd761SJeenu Viswambharan * 13710bcd761SJeenu Viswambharan * _chosen: 13810bcd761SJeenu Viswambharan * Identifier indicating whether or not a CPU errata has been 13910bcd761SJeenu Viswambharan * compiled in. 14010bcd761SJeenu Viswambharan * _cpu: 14110bcd761SJeenu Viswambharan * Name of the CPU 14210bcd761SJeenu Viswambharan * _id: 14310bcd761SJeenu Viswambharan * Errata identifier 14410bcd761SJeenu Viswambharan * _rev_var: 14510bcd761SJeenu Viswambharan * Register containing the combined value CPU revision and variant 14610bcd761SJeenu Viswambharan * - typically the return value of cpu_get_rev_var 14710bcd761SJeenu Viswambharan */ 14810bcd761SJeenu Viswambharan .macro report_errata _chosen, _cpu, _id, _rev_var=r4 14910bcd761SJeenu Viswambharan /* Stash a string with errata ID */ 15010bcd761SJeenu Viswambharan .pushsection .rodata 15110bcd761SJeenu Viswambharan \_cpu\()_errata_\_id\()_str: 15210bcd761SJeenu Viswambharan .asciz "\_id" 15310bcd761SJeenu Viswambharan .popsection 15410bcd761SJeenu Viswambharan 15510bcd761SJeenu Viswambharan /* Check whether errata applies */ 15610bcd761SJeenu Viswambharan mov r0, \_rev_var 15710bcd761SJeenu Viswambharan bl check_errata_\_id 15810bcd761SJeenu Viswambharan 15910bcd761SJeenu Viswambharan .ifeq \_chosen 16010bcd761SJeenu Viswambharan /* 16110bcd761SJeenu Viswambharan * Errata workaround has not been compiled in. If the errata would have 16210bcd761SJeenu Viswambharan * applied had it been compiled in, print its status as missing. 16310bcd761SJeenu Viswambharan */ 16410bcd761SJeenu Viswambharan cmp r0, #0 16510bcd761SJeenu Viswambharan movne r0, #ERRATA_MISSING 16610bcd761SJeenu Viswambharan .endif 16710bcd761SJeenu Viswambharan ldr r1, =\_cpu\()_cpu_str 16810bcd761SJeenu Viswambharan ldr r2, =\_cpu\()_errata_\_id\()_str 16910bcd761SJeenu Viswambharan bl errata_print_msg 17010bcd761SJeenu Viswambharan .endm 17110bcd761SJeenu Viswambharan#endif 172da3b038fSDeepak Pandey /* 173da3b038fSDeepak Pandey * Helper macro that reads the part number of the current CPU and jumps 174da3b038fSDeepak Pandey * to the given label if it matches the CPU MIDR provided. 175da3b038fSDeepak Pandey * 176da3b038fSDeepak Pandey * Clobbers: r0-r1 177da3b038fSDeepak Pandey */ 178da3b038fSDeepak Pandey .macro jump_if_cpu_midr _cpu_midr, _label 179da3b038fSDeepak Pandey ldcopr r0, MIDR 180da3b038fSDeepak Pandey ubfx r0, r0, #MIDR_PN_SHIFT, #12 181da3b038fSDeepak Pandey ldr r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) 182da3b038fSDeepak Pandey cmp r0, r1 183da3b038fSDeepak Pandey beq \_label 184da3b038fSDeepak Pandey .endm 18510bcd761SJeenu Viswambharan 186*34c51f32SBoyan Karatotev/* 187*34c51f32SBoyan Karatotev * NOTE an erratum and CVE id could clash. However, both numbers are very large 188*34c51f32SBoyan Karatotev * and the probablity is minuscule. Working around this makes code very 189*34c51f32SBoyan Karatotev * complicated and extremely difficult to read so it is not considered. In the 190*34c51f32SBoyan Karatotev * unlikely event that this does happen, prepending the CVE id with a 0 should 191*34c51f32SBoyan Karatotev * resolve the conflict 192*34c51f32SBoyan Karatotev */ 193*34c51f32SBoyan Karatotev 194*34c51f32SBoyan Karatotev/* 195*34c51f32SBoyan Karatotev * Add an entry for this erratum to the errata framework 196*34c51f32SBoyan Karatotev * 197*34c51f32SBoyan Karatotev * _cpu: 198*34c51f32SBoyan Karatotev * Name of cpu as given to declare_cpu_ops 199*34c51f32SBoyan Karatotev * 200*34c51f32SBoyan Karatotev * _cve: 201*34c51f32SBoyan Karatotev * Whether erratum is a CVE. CVE year if yes, 0 otherwise 202*34c51f32SBoyan Karatotev * 203*34c51f32SBoyan Karatotev * _id: 204*34c51f32SBoyan Karatotev * Erratum or CVE number. Please combine with the previous field with the 205*34c51f32SBoyan Karatotev * ERRATUM or CVE macros 206*34c51f32SBoyan Karatotev * 207*34c51f32SBoyan Karatotev * _chosen: 208*34c51f32SBoyan Karatotev * Compile time flag on whether the erratum is included 209*34c51f32SBoyan Karatotev * 210*34c51f32SBoyan Karatotev * _special: 211*34c51f32SBoyan Karatotev * The special non-standard name of an erratum 212*34c51f32SBoyan Karatotev */ 213*34c51f32SBoyan Karatotev.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _special 214*34c51f32SBoyan Karatotev .pushsection .rodata.errata_entries 215*34c51f32SBoyan Karatotev .align 2 216*34c51f32SBoyan Karatotev .ifndef \_cpu\()_errata_list_start 217*34c51f32SBoyan Karatotev \_cpu\()_errata_list_start: 218*34c51f32SBoyan Karatotev .endif 219*34c51f32SBoyan Karatotev 220*34c51f32SBoyan Karatotev /* unused on AArch32, maintain for portability */ 221*34c51f32SBoyan Karatotev .word 0 222*34c51f32SBoyan Karatotev /* TODO(errata ABI): this prevents all checker functions from 223*34c51f32SBoyan Karatotev * being optimised away. Can be done away with unless the ABI 224*34c51f32SBoyan Karatotev * needs them */ 225*34c51f32SBoyan Karatotev .ifnb \_special 226*34c51f32SBoyan Karatotev .word check_errata_\_special 227*34c51f32SBoyan Karatotev .elseif \_cve 228*34c51f32SBoyan Karatotev .word check_errata_cve_\_cve\()_\_id 229*34c51f32SBoyan Karatotev .else 230*34c51f32SBoyan Karatotev .word check_errata_\_id 231*34c51f32SBoyan Karatotev .endif 232*34c51f32SBoyan Karatotev /* Will fit CVEs with up to 10 character in the ID field */ 233*34c51f32SBoyan Karatotev .word \_id 234*34c51f32SBoyan Karatotev .hword \_cve 235*34c51f32SBoyan Karatotev .byte \_chosen 236*34c51f32SBoyan Karatotev /* TODO(errata ABI): mitigated field for known but unmitigated 237*34c51f32SBoyan Karatotev * errata*/ 238*34c51f32SBoyan Karatotev .byte 0x1 239*34c51f32SBoyan Karatotev .popsection 240*34c51f32SBoyan Karatotev.endm 241*34c51f32SBoyan Karatotev 242*34c51f32SBoyan Karatotev/* 243*34c51f32SBoyan Karatotev * Maintain compatibility with the old scheme of "each cpu has its own reporter". 244*34c51f32SBoyan Karatotev * TODO remove entirely once all cpus have been converted. This includes the 245*34c51f32SBoyan Karatotev * cpu_ops entry, as print_errata_status can call this directly for all cpus 246*34c51f32SBoyan Karatotev */ 247*34c51f32SBoyan Karatotev.macro errata_report_shim _cpu:req 248*34c51f32SBoyan Karatotev #if REPORT_ERRATA 249*34c51f32SBoyan Karatotev func \_cpu\()_errata_report 250*34c51f32SBoyan Karatotev push {r12, lr} 251*34c51f32SBoyan Karatotev 252*34c51f32SBoyan Karatotev bl generic_errata_report 253*34c51f32SBoyan Karatotev 254*34c51f32SBoyan Karatotev pop {r12, lr} 255*34c51f32SBoyan Karatotev bx lr 256*34c51f32SBoyan Karatotev endfunc \_cpu\()_errata_report 257*34c51f32SBoyan Karatotev #endif 258*34c51f32SBoyan Karatotev.endm 259c3cf06f1SAntonio Nino Diaz#endif /* CPU_MACROS_S */ 260