1e33b78a6SSoby Mathew/* 20d020822SBoyan Karatotev * Copyright (c) 2016-2025, 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: 510d020822SBoyan Karatotev * Reset function for the CPU 525dd9dbb5SJeenu Viswambharan * _power_down_ops: 535dd9dbb5SJeenu Viswambharan * Comma-separated list of functions to perform power-down 545dd9dbb5SJeenu Viswambharan * operatios on the CPU. At least one, and up to 555dd9dbb5SJeenu Viswambharan * CPU_MAX_PWR_DWN_OPS number of functions may be specified. 565dd9dbb5SJeenu Viswambharan * Starting at power level 0, these functions shall handle power 575dd9dbb5SJeenu Viswambharan * down at subsequent power levels. If there aren't exactly 585dd9dbb5SJeenu Viswambharan * CPU_MAX_PWR_DWN_OPS functions, the last specified one will be 595dd9dbb5SJeenu Viswambharan * used to handle power down at subsequent levels 605dd9dbb5SJeenu Viswambharan */ 615dd9dbb5SJeenu Viswambharan .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \ 625dd9dbb5SJeenu Viswambharan _power_down_ops:vararg 63da04341eSChris Kay .section .cpu_ops, "a" 64e33b78a6SSoby Mathew .align 2 65e33b78a6SSoby Mathew .type cpu_ops_\_name, %object 66e33b78a6SSoby Mathew .word \_midr 67b1d27b48SRoberto Vargas#if defined(IMAGE_AT_EL3) 685dd9dbb5SJeenu Viswambharan .word \_resetfunc 691a0a3f06SYatharth Kochar#endif 703d8256b2SMasahiro Yamada#ifdef IMAGE_BL32 715dd9dbb5SJeenu Viswambharan /* Insert list of functions */ 725dd9dbb5SJeenu Viswambharan fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops 731a0a3f06SYatharth Kochar#endif 7410bcd761SJeenu Viswambharan 7534c51f32SBoyan Karatotev /* 7634c51f32SBoyan Karatotev * It is possible (although unlikely) that a cpu may have no errata in 7734c51f32SBoyan Karatotev * code. In that case the start label will not be defined. The list is 7834c51f32SBoyan Karatotev * inteded to be used in a loop, so define it as zero-length for 7934c51f32SBoyan Karatotev * predictable behaviour. Since this macro is always called at the end 8034c51f32SBoyan Karatotev * of the cpu file (after all errata have been parsed) we can be sure 8134c51f32SBoyan Karatotev * that we are at the end of the list. Some cpus call the macro twice, 8234c51f32SBoyan Karatotev * so only do this once. 8334c51f32SBoyan Karatotev */ 8434c51f32SBoyan Karatotev .pushsection .rodata.errata_entries 8534c51f32SBoyan Karatotev .ifndef \_name\()_errata_list_start 8634c51f32SBoyan Karatotev \_name\()_errata_list_start: 8734c51f32SBoyan Karatotev .endif 8834c51f32SBoyan Karatotev /* some call this multiple times, so only do this once */ 8934c51f32SBoyan Karatotev .ifndef \_name\()_errata_list_end 9034c51f32SBoyan Karatotev \_name\()_errata_list_end: 9134c51f32SBoyan Karatotev .endif 9234c51f32SBoyan Karatotev .popsection 9334c51f32SBoyan Karatotev 9434c51f32SBoyan Karatotev /* and now put them in cpu_ops */ 9534c51f32SBoyan Karatotev .word \_name\()_errata_list_start 9634c51f32SBoyan Karatotev .word \_name\()_errata_list_end 9734c51f32SBoyan Karatotev 9810bcd761SJeenu Viswambharan#if REPORT_ERRATA 9910bcd761SJeenu Viswambharan .ifndef \_name\()_cpu_str 10010bcd761SJeenu Viswambharan /* 10110bcd761SJeenu Viswambharan * Place errata reported flag, and the spinlock to arbitrate access to 10210bcd761SJeenu Viswambharan * it in the data section. 10310bcd761SJeenu Viswambharan */ 10410bcd761SJeenu Viswambharan .pushsection .data 10510bcd761SJeenu Viswambharan define_asm_spinlock \_name\()_errata_lock 10610bcd761SJeenu Viswambharan \_name\()_errata_reported: 10710bcd761SJeenu Viswambharan .word 0 10810bcd761SJeenu Viswambharan .popsection 10910bcd761SJeenu Viswambharan 11010bcd761SJeenu Viswambharan /* Place CPU string in rodata */ 11110bcd761SJeenu Viswambharan .pushsection .rodata 11210bcd761SJeenu Viswambharan \_name\()_cpu_str: 11310bcd761SJeenu Viswambharan .asciz "\_name" 11410bcd761SJeenu Viswambharan .popsection 11510bcd761SJeenu Viswambharan .endif 11610bcd761SJeenu Viswambharan 11734c51f32SBoyan Karatotev .word \_name\()_cpu_str 11810bcd761SJeenu Viswambharan 11910bcd761SJeenu Viswambharan#ifdef IMAGE_BL32 12010bcd761SJeenu Viswambharan /* Pointers to errata lock and reported flag */ 12110bcd761SJeenu Viswambharan .word \_name\()_errata_lock 12210bcd761SJeenu Viswambharan .word \_name\()_errata_reported 12310bcd761SJeenu Viswambharan#endif 12410bcd761SJeenu Viswambharan#endif 125e33b78a6SSoby Mathew .endm 126e33b78a6SSoby Mathew 127da3b038fSDeepak Pandey /* 128da3b038fSDeepak Pandey * Helper macro that reads the part number of the current CPU and jumps 129da3b038fSDeepak Pandey * to the given label if it matches the CPU MIDR provided. 130da3b038fSDeepak Pandey * 131da3b038fSDeepak Pandey * Clobbers: r0-r1 132da3b038fSDeepak Pandey */ 133da3b038fSDeepak Pandey .macro jump_if_cpu_midr _cpu_midr, _label 134da3b038fSDeepak Pandey ldcopr r0, MIDR 135da3b038fSDeepak Pandey ubfx r0, r0, #MIDR_PN_SHIFT, #12 136da3b038fSDeepak Pandey ldr r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) 137da3b038fSDeepak Pandey cmp r0, r1 138da3b038fSDeepak Pandey beq \_label 139da3b038fSDeepak Pandey .endm 14010bcd761SJeenu Viswambharan 14134c51f32SBoyan Karatotev/* 14234c51f32SBoyan Karatotev * NOTE an erratum and CVE id could clash. However, both numbers are very large 14334c51f32SBoyan Karatotev * and the probablity is minuscule. Working around this makes code very 14434c51f32SBoyan Karatotev * complicated and extremely difficult to read so it is not considered. In the 14534c51f32SBoyan Karatotev * unlikely event that this does happen, prepending the CVE id with a 0 should 14634c51f32SBoyan Karatotev * resolve the conflict 14734c51f32SBoyan Karatotev */ 14834c51f32SBoyan Karatotev 14934c51f32SBoyan Karatotev/* 15034c51f32SBoyan Karatotev * Add an entry for this erratum to the errata framework 15134c51f32SBoyan Karatotev * 15234c51f32SBoyan Karatotev * _cpu: 15334c51f32SBoyan Karatotev * Name of cpu as given to declare_cpu_ops 15434c51f32SBoyan Karatotev * 15534c51f32SBoyan Karatotev * _cve: 15634c51f32SBoyan Karatotev * Whether erratum is a CVE. CVE year if yes, 0 otherwise 15734c51f32SBoyan Karatotev * 15834c51f32SBoyan Karatotev * _id: 15934c51f32SBoyan Karatotev * Erratum or CVE number. Please combine with the previous field with the 16034c51f32SBoyan Karatotev * ERRATUM or CVE macros 16134c51f32SBoyan Karatotev * 16234c51f32SBoyan Karatotev * _chosen: 16334c51f32SBoyan Karatotev * Compile time flag on whether the erratum is included 16434c51f32SBoyan Karatotev * 16534c51f32SBoyan Karatotev * _special: 16634c51f32SBoyan Karatotev * The special non-standard name of an erratum 16734c51f32SBoyan Karatotev */ 16834c51f32SBoyan Karatotev.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _special 16934c51f32SBoyan Karatotev .pushsection .rodata.errata_entries 17034c51f32SBoyan Karatotev .align 2 17134c51f32SBoyan Karatotev .ifndef \_cpu\()_errata_list_start 17234c51f32SBoyan Karatotev \_cpu\()_errata_list_start: 17334c51f32SBoyan Karatotev .endif 17434c51f32SBoyan Karatotev 17534c51f32SBoyan Karatotev .ifnb \_special 17634c51f32SBoyan Karatotev .word check_errata_\_special 17734c51f32SBoyan Karatotev .elseif \_cve 17834c51f32SBoyan Karatotev .word check_errata_cve_\_cve\()_\_id 17934c51f32SBoyan Karatotev .else 18034c51f32SBoyan Karatotev .word check_errata_\_id 18134c51f32SBoyan Karatotev .endif 18234c51f32SBoyan Karatotev /* Will fit CVEs with up to 10 character in the ID field */ 18334c51f32SBoyan Karatotev .word \_id 18434c51f32SBoyan Karatotev .hword \_cve 18534c51f32SBoyan Karatotev .byte \_chosen 186*89dba82dSBoyan Karatotev .byte 0x0 /* alignment */ 18734c51f32SBoyan Karatotev .popsection 18834c51f32SBoyan Karatotev.endm 18934c51f32SBoyan Karatotev 190c3cf06f1SAntonio Nino Diaz#endif /* CPU_MACROS_S */ 191