xref: /rk3399_ARM-atf/include/lib/cpus/aarch64/cpu_macros.S (revision 36eeb59f9eb0c2e966bd41b02c0dc588faffce35)
1add40351SSoby Mathew/*
2bb801857SBoyan Karatotev * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
3add40351SSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5add40351SSoby Mathew */
6c3cf06f1SAntonio Nino Diaz#ifndef CPU_MACROS_S
7c3cf06f1SAntonio Nino Diaz#define CPU_MACROS_S
8add40351SSoby Mathew
9ff6f62e1SAntonio Nino Diaz#include <assert_macros.S>
10007433d8SBoyan Karatotev#include <lib/cpus/cpu_ops.h>
116bb96fa6SBoyan Karatotev#include <lib/cpus/errata.h>
12add40351SSoby Mathew
13add40351SSoby Mathew	/*
145dd9dbb5SJeenu Viswambharan	 * Write given expressions as quad words
155dd9dbb5SJeenu Viswambharan	 *
165dd9dbb5SJeenu Viswambharan	 * _count:
175dd9dbb5SJeenu Viswambharan	 *	Write at least _count quad words. If the given number of
185dd9dbb5SJeenu Viswambharan	 *	expressions is less than _count, repeat the last expression to
195dd9dbb5SJeenu Viswambharan	 *	fill _count quad words in total
205dd9dbb5SJeenu Viswambharan	 * _rest:
215dd9dbb5SJeenu Viswambharan	 *	Optional list of expressions. _this is for parameter extraction
225dd9dbb5SJeenu Viswambharan	 *	only, and has no significance to the caller
235dd9dbb5SJeenu Viswambharan	 *
245dd9dbb5SJeenu Viswambharan	 * Invoked as:
255dd9dbb5SJeenu Viswambharan	 *	fill_constants 2, foo, bar, blah, ...
26add40351SSoby Mathew	 */
275dd9dbb5SJeenu Viswambharan	.macro fill_constants _count:req, _this, _rest:vararg
285dd9dbb5SJeenu Viswambharan	  .ifgt \_count
295dd9dbb5SJeenu Viswambharan	    /* Write the current expression */
305dd9dbb5SJeenu Viswambharan	    .ifb \_this
315dd9dbb5SJeenu Viswambharan	      .error "Nothing to fill"
325dd9dbb5SJeenu Viswambharan	    .endif
335dd9dbb5SJeenu Viswambharan	    .quad \_this
345dd9dbb5SJeenu Viswambharan
355dd9dbb5SJeenu Viswambharan	    /* Invoke recursively for remaining expressions */
365dd9dbb5SJeenu Viswambharan	    .ifnb \_rest
375dd9dbb5SJeenu Viswambharan	      fill_constants \_count-1, \_rest
385dd9dbb5SJeenu Viswambharan	    .else
395dd9dbb5SJeenu Viswambharan	      fill_constants \_count-1, \_this
405dd9dbb5SJeenu Viswambharan	    .endif
415dd9dbb5SJeenu Viswambharan	  .endif
425dd9dbb5SJeenu Viswambharan	.endm
435dd9dbb5SJeenu Viswambharan
445dd9dbb5SJeenu Viswambharan	/*
455dd9dbb5SJeenu Viswambharan	 * Declare CPU operations
465dd9dbb5SJeenu Viswambharan	 *
475dd9dbb5SJeenu Viswambharan	 * _name:
485dd9dbb5SJeenu Viswambharan	 *	Name of the CPU for which operations are being specified
495dd9dbb5SJeenu Viswambharan	 * _midr:
505dd9dbb5SJeenu Viswambharan	 *	Numeric value expected to read from CPU's MIDR
515dd9dbb5SJeenu Viswambharan	 * _resetfunc:
525dd9dbb5SJeenu Viswambharan	 *	Reset function for the CPU. If there's no CPU reset function,
535dd9dbb5SJeenu Viswambharan	 *	specify CPU_NO_RESET_FUNC
54a205a56eSDimitris Papastamos	 * _extra1:
55a205a56eSDimitris Papastamos	 *	This is a placeholder for future per CPU operations.  Currently,
56a205a56eSDimitris Papastamos	 *	some CPUs use this entry to set a test function to determine if
57a205a56eSDimitris Papastamos	 *	the workaround for CVE-2017-5715 needs to be applied or not.
58fe007b2eSDimitris Papastamos	 * _extra2:
59fe007b2eSDimitris Papastamos	 *	This is a placeholder for future per CPU operations. Currently
60fe007b2eSDimitris Papastamos	 *	some CPUs use this entry to set a function to disable the
61fe007b2eSDimitris Papastamos	 *	workaround for CVE-2018-3639.
629b2510b6SBipin Ravi	 * _extra3:
639b2510b6SBipin Ravi	 *	This is a placeholder for future per CPU operations. Currently,
649b2510b6SBipin Ravi	 *	some CPUs use this entry to set a test function to determine if
659b2510b6SBipin Ravi	 *	the workaround for CVE-2022-23960 needs to be applied or not.
664caef42aSArvind Ram Prakash	 * _extra4:
674caef42aSArvind Ram Prakash	 *	This is a placeholder for future per CPU operations. Currently,
684caef42aSArvind Ram Prakash	 *	some CPUs use this entry to set a test function to determine if
694caef42aSArvind Ram Prakash	 *	the workaround for CVE-2024-7881 needs to be applied or not.
7080942622Slaurenw-arm	 * _e_handler:
7180942622Slaurenw-arm	 *	This is a placeholder for future per CPU exception handlers.
725dd9dbb5SJeenu Viswambharan	 * _power_down_ops:
735dd9dbb5SJeenu Viswambharan	 *	Comma-separated list of functions to perform power-down
745dd9dbb5SJeenu Viswambharan	 *	operatios on the CPU. At least one, and up to
755dd9dbb5SJeenu Viswambharan	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
765dd9dbb5SJeenu Viswambharan	 *	Starting at power level 0, these functions shall handle power
775dd9dbb5SJeenu Viswambharan	 *	down at subsequent power levels. If there aren't exactly
785dd9dbb5SJeenu Viswambharan	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
795dd9dbb5SJeenu Viswambharan	 *	used to handle power down at subsequent levels
805dd9dbb5SJeenu Viswambharan	 */
81a205a56eSDimitris Papastamos	.macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
824caef42aSArvind Ram Prakash		_extra1:req, _extra2:req, _extra3:req, _extra4:req, \
834caef42aSArvind Ram Prakash		_e_handler:req, _power_down_ops:vararg
84da04341eSChris Kay	.section .cpu_ops, "a"
855dd9dbb5SJeenu Viswambharan	.align 3
86add40351SSoby Mathew	.type cpu_ops_\_name, %object
87add40351SSoby Mathew	.quad \_midr
88b1d27b48SRoberto Vargas#if defined(IMAGE_AT_EL3)
895dd9dbb5SJeenu Viswambharan	.quad \_resetfunc
90add40351SSoby Mathew#endif
91a205a56eSDimitris Papastamos	.quad \_extra1
92fe007b2eSDimitris Papastamos	.quad \_extra2
939b2510b6SBipin Ravi	.quad \_extra3
944caef42aSArvind Ram Prakash	.quad \_extra4
9580942622Slaurenw-arm	.quad \_e_handler
963d8256b2SMasahiro Yamada#ifdef IMAGE_BL31
975dd9dbb5SJeenu Viswambharan	/* Insert list of functions */
985dd9dbb5SJeenu Viswambharan	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
99add40351SSoby Mathew#endif
1003f4c1e1eSBoyan Karatotev	/*
1013f4c1e1eSBoyan Karatotev	 * It is possible (although unlikely) that a cpu may have no errata in
1023f4c1e1eSBoyan Karatotev	 * code. In that case the start label will not be defined. The list is
1033f4c1e1eSBoyan Karatotev	 * intended to be used in a loop, so define it as zero-length for
1043f4c1e1eSBoyan Karatotev	 * predictable behaviour. Since this macro is always called at the end
1053f4c1e1eSBoyan Karatotev	 * of the cpu file (after all errata have been parsed) we can be sure
1063f4c1e1eSBoyan Karatotev	 * that we are at the end of the list. Some cpus call declare_cpu_ops
1073f4c1e1eSBoyan Karatotev	 * twice, so only do this once.
1083f4c1e1eSBoyan Karatotev	 */
1093f4c1e1eSBoyan Karatotev	.pushsection .rodata.errata_entries
1103f4c1e1eSBoyan Karatotev	.ifndef \_name\()_errata_list_start
1113f4c1e1eSBoyan Karatotev		\_name\()_errata_list_start:
1123f4c1e1eSBoyan Karatotev	.endif
1133f4c1e1eSBoyan Karatotev	.ifndef \_name\()_errata_list_end
1143f4c1e1eSBoyan Karatotev		\_name\()_errata_list_end:
1153f4c1e1eSBoyan Karatotev	.endif
1163f4c1e1eSBoyan Karatotev	.popsection
1173f4c1e1eSBoyan Karatotev
1183f4c1e1eSBoyan Karatotev	/* and now put them in cpu_ops */
1193f4c1e1eSBoyan Karatotev	.quad \_name\()_errata_list_start
1203f4c1e1eSBoyan Karatotev	.quad \_name\()_errata_list_end
12110bcd761SJeenu Viswambharan
12210bcd761SJeenu Viswambharan#if REPORT_ERRATA
12310bcd761SJeenu Viswambharan	.ifndef \_name\()_cpu_str
12410bcd761SJeenu Viswambharan	  /*
12510bcd761SJeenu Viswambharan	   * Place errata reported flag, and the spinlock to arbitrate access to
12610bcd761SJeenu Viswambharan	   * it in the data section.
12710bcd761SJeenu Viswambharan	   */
12810bcd761SJeenu Viswambharan	  .pushsection .data
12910bcd761SJeenu Viswambharan	  define_asm_spinlock \_name\()_errata_lock
13010bcd761SJeenu Viswambharan	  \_name\()_errata_reported:
13110bcd761SJeenu Viswambharan	  .word	0
13210bcd761SJeenu Viswambharan	  .popsection
13310bcd761SJeenu Viswambharan
13410bcd761SJeenu Viswambharan	  /* Place CPU string in rodata */
13510bcd761SJeenu Viswambharan	  .pushsection .rodata
13610bcd761SJeenu Viswambharan	  \_name\()_cpu_str:
13710bcd761SJeenu Viswambharan	  .asciz "\_name"
13810bcd761SJeenu Viswambharan	  .popsection
13910bcd761SJeenu Viswambharan	.endif
14010bcd761SJeenu Viswambharan
1413f4c1e1eSBoyan Karatotev	.quad \_name\()_cpu_str
14210bcd761SJeenu Viswambharan
14310bcd761SJeenu Viswambharan#ifdef IMAGE_BL31
14410bcd761SJeenu Viswambharan	/* Pointers to errata lock and reported flag */
14510bcd761SJeenu Viswambharan	.quad \_name\()_errata_lock
14610bcd761SJeenu Viswambharan	.quad \_name\()_errata_reported
1473f4c1e1eSBoyan Karatotev#endif /* IMAGE_BL31 */
1483f4c1e1eSBoyan Karatotev#endif /* REPORT_ERRATA */
14910bcd761SJeenu Viswambharan
1503d8256b2SMasahiro Yamada#if defined(IMAGE_BL31) && CRASH_REPORTING
151d3f70af6SSoby Mathew	.quad \_name\()_cpu_reg_dump
152d3f70af6SSoby Mathew#endif
153add40351SSoby Mathew	.endm
154e2bf57f8SDan Handley
155a205a56eSDimitris Papastamos	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
156a205a56eSDimitris Papastamos		_power_down_ops:vararg
1574caef42aSArvind Ram Prakash		declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, 0, 0, 0, 0, \
158a205a56eSDimitris Papastamos			\_power_down_ops
159a205a56eSDimitris Papastamos	.endm
160a205a56eSDimitris Papastamos
16180942622Slaurenw-arm	.macro declare_cpu_ops_eh _name:req, _midr:req, _resetfunc:req, \
16280942622Slaurenw-arm		_e_handler:req, _power_down_ops:vararg
16380942622Slaurenw-arm		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
1644caef42aSArvind Ram Prakash			0, 0, 0, 0, \_e_handler, \_power_down_ops
16580942622Slaurenw-arm	.endm
16680942622Slaurenw-arm
167fe007b2eSDimitris Papastamos	.macro declare_cpu_ops_wa _name:req, _midr:req, \
168fe007b2eSDimitris Papastamos		_resetfunc:req, _extra1:req, _extra2:req, \
1699b2510b6SBipin Ravi		_extra3:req, _power_down_ops:vararg
170a205a56eSDimitris Papastamos		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
1714caef42aSArvind Ram Prakash			\_extra1, \_extra2, \_extra3, 0, 0, \_power_down_ops
1724caef42aSArvind Ram Prakash	.endm
1734caef42aSArvind Ram Prakash
1744caef42aSArvind Ram Prakash	.macro declare_cpu_ops_wa_4 _name:req, _midr:req, \
1754caef42aSArvind Ram Prakash		_resetfunc:req, _extra1:req, _extra2:req, \
1764caef42aSArvind Ram Prakash		_extra3:req, _extra4:req, _power_down_ops:vararg
1774caef42aSArvind Ram Prakash		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
1784caef42aSArvind Ram Prakash			\_extra1, \_extra2, \_extra3, \_extra4, 0, \_power_down_ops
179a205a56eSDimitris Papastamos	.endm
180a205a56eSDimitris Papastamos
1813991a6a4SDimitris Papastamos	/*
1823991a6a4SDimitris Papastamos	 * This macro is used on some CPUs to detect if they are vulnerable
1833991a6a4SDimitris Papastamos	 * to CVE-2017-5715.
1843991a6a4SDimitris Papastamos	 */
1853991a6a4SDimitris Papastamos	.macro	cpu_check_csv2 _reg _label
1863991a6a4SDimitris Papastamos	mrs	\_reg, id_aa64pfr0_el1
1873991a6a4SDimitris Papastamos	ubfx	\_reg, \_reg, #ID_AA64PFR0_CSV2_SHIFT, #ID_AA64PFR0_CSV2_LENGTH
1883991a6a4SDimitris Papastamos	/*
189ff6f62e1SAntonio Nino Diaz	 * If the field equals 1, branch targets trained in one context cannot
190ff6f62e1SAntonio Nino Diaz	 * affect speculative execution in a different context.
191ff6f62e1SAntonio Nino Diaz	 *
192ff6f62e1SAntonio Nino Diaz	 * If the field equals 2, it means that the system is also aware of
193ff6f62e1SAntonio Nino Diaz	 * SCXTNUM_ELx register contexts. We aren't using them in the TF, so we
194ff6f62e1SAntonio Nino Diaz	 * expect users of the registers to do the right thing.
195ff6f62e1SAntonio Nino Diaz	 *
196ff6f62e1SAntonio Nino Diaz	 * Only apply mitigations if the value of this field is 0.
1973991a6a4SDimitris Papastamos	 */
198ff6f62e1SAntonio Nino Diaz#if ENABLE_ASSERTIONS
199ff6f62e1SAntonio Nino Diaz	cmp	\_reg, #3 /* Only values 0 to 2 are expected */
200ff6f62e1SAntonio Nino Diaz	ASM_ASSERT(lo)
201ff6f62e1SAntonio Nino Diaz#endif
202ff6f62e1SAntonio Nino Diaz
203ff6f62e1SAntonio Nino Diaz	cmp	\_reg, #0
204ff6f62e1SAntonio Nino Diaz	bne	\_label
2053991a6a4SDimitris Papastamos	.endm
206da3b038fSDeepak Pandey
207da3b038fSDeepak Pandey	/*
208da3b038fSDeepak Pandey	 * Helper macro that reads the part number of the current
209da3b038fSDeepak Pandey	 * CPU and jumps to the given label if it matches the CPU
210da3b038fSDeepak Pandey	 * MIDR provided.
211da3b038fSDeepak Pandey	 *
212da3b038fSDeepak Pandey	 * Clobbers x0.
213da3b038fSDeepak Pandey	 */
214da3b038fSDeepak Pandey	.macro  jump_if_cpu_midr _cpu_midr, _label
215da3b038fSDeepak Pandey	mrs	x0, midr_el1
216da3b038fSDeepak Pandey	ubfx	x0, x0, MIDR_PN_SHIFT, #12
217da3b038fSDeepak Pandey	cmp	w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
218da3b038fSDeepak Pandey	b.eq	\_label
219da3b038fSDeepak Pandey	.endm
220c3cf06f1SAntonio Nino Diaz
2213f4c1e1eSBoyan Karatotev
2223f4c1e1eSBoyan Karatotev/*
2233f4c1e1eSBoyan Karatotev * Workaround wrappers for errata that apply at reset or runtime. Reset errata
2243f4c1e1eSBoyan Karatotev * will be applied automatically
2253f4c1e1eSBoyan Karatotev *
2263f4c1e1eSBoyan Karatotev * _cpu:
2273f4c1e1eSBoyan Karatotev *	Name of cpu as given to declare_cpu_ops
2283f4c1e1eSBoyan Karatotev *
2293f4c1e1eSBoyan Karatotev * _cve:
2303f4c1e1eSBoyan Karatotev *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
2313f4c1e1eSBoyan Karatotev *
2323f4c1e1eSBoyan Karatotev * _id:
2333f4c1e1eSBoyan Karatotev *	Erratum or CVE number. Please combine with previous field with ERRATUM
2343f4c1e1eSBoyan Karatotev *	or CVE macros
2353f4c1e1eSBoyan Karatotev *
2363f4c1e1eSBoyan Karatotev * _chosen:
2373f4c1e1eSBoyan Karatotev *	Compile time flag on whether the erratum is included
2383f4c1e1eSBoyan Karatotev *
2393f4c1e1eSBoyan Karatotev * _apply_at_reset:
2403f4c1e1eSBoyan Karatotev *	Whether the erratum should be automatically applied at reset
2413f4c1e1eSBoyan Karatotev */
2423f4c1e1eSBoyan Karatotev.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _apply_at_reset:req
2433f4c1e1eSBoyan Karatotev	.pushsection .rodata.errata_entries
2443f4c1e1eSBoyan Karatotev		.align	3
2453f4c1e1eSBoyan Karatotev		.ifndef \_cpu\()_errata_list_start
2463f4c1e1eSBoyan Karatotev		\_cpu\()_errata_list_start:
2473f4c1e1eSBoyan Karatotev		.endif
2483f4c1e1eSBoyan Karatotev
2493f4c1e1eSBoyan Karatotev		/* check if unused and compile out if no references */
2503f4c1e1eSBoyan Karatotev		.if \_apply_at_reset && \_chosen
2513f4c1e1eSBoyan Karatotev			.quad	erratum_\_cpu\()_\_id\()_wa
2523f4c1e1eSBoyan Karatotev		.else
2533f4c1e1eSBoyan Karatotev			.quad	0
2543f4c1e1eSBoyan Karatotev		.endif
2553f4c1e1eSBoyan Karatotev		/* TODO(errata ABI): this prevents all checker functions from
2563f4c1e1eSBoyan Karatotev		 * being optimised away. Can be done away with unless the ABI
2573f4c1e1eSBoyan Karatotev		 * needs them */
2583f4c1e1eSBoyan Karatotev		.quad	check_erratum_\_cpu\()_\_id
2593f4c1e1eSBoyan Karatotev		/* Will fit CVEs with up to 10 character in the ID field */
2603f4c1e1eSBoyan Karatotev		.word	\_id
2613f4c1e1eSBoyan Karatotev		.hword	\_cve
2623f4c1e1eSBoyan Karatotev		.byte	\_chosen
2633f4c1e1eSBoyan Karatotev		/* TODO(errata ABI): mitigated field for known but unmitigated
2643f4c1e1eSBoyan Karatotev		 * errata */
2653f4c1e1eSBoyan Karatotev		.byte	0x1
2663f4c1e1eSBoyan Karatotev	.popsection
2673f4c1e1eSBoyan Karatotev.endm
2683f4c1e1eSBoyan Karatotev
2693f4c1e1eSBoyan Karatotev.macro _workaround_start _cpu:req, _cve:req, _id:req, _chosen:req, _apply_at_reset:req
2703f4c1e1eSBoyan Karatotev	add_erratum_entry \_cpu, \_cve, \_id, \_chosen, \_apply_at_reset
2713f4c1e1eSBoyan Karatotev
2723f4c1e1eSBoyan Karatotev	func erratum_\_cpu\()_\_id\()_wa
2733f4c1e1eSBoyan Karatotev		mov	x8, x30
2743f4c1e1eSBoyan Karatotev
2753f4c1e1eSBoyan Karatotev		/* save rev_var for workarounds that might need it but don't
2763f4c1e1eSBoyan Karatotev		 * restore to x0 because few will care */
2773f4c1e1eSBoyan Karatotev		mov	x7, x0
2783f4c1e1eSBoyan Karatotev		bl	check_erratum_\_cpu\()_\_id
2793f4c1e1eSBoyan Karatotev		cbz	x0, erratum_\_cpu\()_\_id\()_skip
2803f4c1e1eSBoyan Karatotev.endm
2813f4c1e1eSBoyan Karatotev
2823f4c1e1eSBoyan Karatotev.macro _workaround_end _cpu:req, _id:req
2833f4c1e1eSBoyan Karatotev	erratum_\_cpu\()_\_id\()_skip:
2843f4c1e1eSBoyan Karatotev		ret	x8
2853f4c1e1eSBoyan Karatotev	endfunc erratum_\_cpu\()_\_id\()_wa
2863f4c1e1eSBoyan Karatotev.endm
2873f4c1e1eSBoyan Karatotev
2883f4c1e1eSBoyan Karatotev/*******************************************************************************
2893f4c1e1eSBoyan Karatotev * Errata workaround wrappers
2903f4c1e1eSBoyan Karatotev ******************************************************************************/
2913f4c1e1eSBoyan Karatotev/*
2923f4c1e1eSBoyan Karatotev * Workaround wrappers for errata that apply at reset or runtime. Reset errata
2933f4c1e1eSBoyan Karatotev * will be applied automatically
2943f4c1e1eSBoyan Karatotev *
2953f4c1e1eSBoyan Karatotev * _cpu:
2963f4c1e1eSBoyan Karatotev *	Name of cpu as given to declare_cpu_ops
2973f4c1e1eSBoyan Karatotev *
2983f4c1e1eSBoyan Karatotev * _cve:
2993f4c1e1eSBoyan Karatotev *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
3003f4c1e1eSBoyan Karatotev *
3013f4c1e1eSBoyan Karatotev * _id:
3023f4c1e1eSBoyan Karatotev *	Erratum or CVE number. Please combine with previous field with ERRATUM
3033f4c1e1eSBoyan Karatotev *	or CVE macros
3043f4c1e1eSBoyan Karatotev *
3053f4c1e1eSBoyan Karatotev * _chosen:
3063f4c1e1eSBoyan Karatotev *	Compile time flag on whether the erratum is included
3073f4c1e1eSBoyan Karatotev *
3083f4c1e1eSBoyan Karatotev * in body:
3093f4c1e1eSBoyan Karatotev *	clobber x0 to x7 (please only use those)
3103f4c1e1eSBoyan Karatotev *	argument x7 - cpu_rev_var
3113f4c1e1eSBoyan Karatotev *
3123f4c1e1eSBoyan Karatotev * _wa clobbers: x0-x8 (PCS compliant)
3133f4c1e1eSBoyan Karatotev */
3143f4c1e1eSBoyan Karatotev.macro workaround_reset_start _cpu:req, _cve:req, _id:req, _chosen:req
3153f4c1e1eSBoyan Karatotev	_workaround_start \_cpu, \_cve, \_id, \_chosen, 1
3163f4c1e1eSBoyan Karatotev.endm
3173f4c1e1eSBoyan Karatotev
3183f4c1e1eSBoyan Karatotev/*
3193f4c1e1eSBoyan Karatotev * See `workaround_reset_start` for usage info. Additional arguments:
3203f4c1e1eSBoyan Karatotev *
3213f4c1e1eSBoyan Karatotev * _midr:
3223f4c1e1eSBoyan Karatotev *	Check if CPU's MIDR matches the CPU it's meant for. Must be specified
3233f4c1e1eSBoyan Karatotev *	for errata applied in generic code
3243f4c1e1eSBoyan Karatotev */
3253f4c1e1eSBoyan Karatotev.macro workaround_runtime_start _cpu:req, _cve:req, _id:req, _chosen:req, _midr
3263f4c1e1eSBoyan Karatotev	/*
3273f4c1e1eSBoyan Karatotev	 * Let errata specify if they need MIDR checking. Sadly, storing the
3283f4c1e1eSBoyan Karatotev	 * MIDR in an .equ to retrieve automatically blows up as it stores some
3293f4c1e1eSBoyan Karatotev	 * brackets in the symbol
3303f4c1e1eSBoyan Karatotev	 */
3313f4c1e1eSBoyan Karatotev	.ifnb \_midr
3323f4c1e1eSBoyan Karatotev		jump_if_cpu_midr \_midr, 1f
3333f4c1e1eSBoyan Karatotev		b	erratum_\_cpu\()_\_id\()_skip
3343f4c1e1eSBoyan Karatotev
3353f4c1e1eSBoyan Karatotev		1:
3363f4c1e1eSBoyan Karatotev	.endif
3373f4c1e1eSBoyan Karatotev	_workaround_start \_cpu, \_cve, \_id, \_chosen, 0
3383f4c1e1eSBoyan Karatotev.endm
3393f4c1e1eSBoyan Karatotev
3403f4c1e1eSBoyan Karatotev/*
3413f4c1e1eSBoyan Karatotev * Usage and arguments identical to `workaround_reset_start`. The _cve argument
3423f4c1e1eSBoyan Karatotev * is kept here so the same #define can be used as that macro
3433f4c1e1eSBoyan Karatotev */
3443f4c1e1eSBoyan Karatotev.macro workaround_reset_end _cpu:req, _cve:req, _id:req
3453f4c1e1eSBoyan Karatotev	_workaround_end \_cpu, \_id
3463f4c1e1eSBoyan Karatotev.endm
3473f4c1e1eSBoyan Karatotev
3483f4c1e1eSBoyan Karatotev/*
3493f4c1e1eSBoyan Karatotev * See `workaround_reset_start` for usage info. The _cve argument is kept here
3503f4c1e1eSBoyan Karatotev * so the same #define can be used as that macro. Additional arguments:
3513f4c1e1eSBoyan Karatotev *
3523f4c1e1eSBoyan Karatotev * _no_isb:
3533f4c1e1eSBoyan Karatotev *	Optionally do not include the trailing isb. Please disable with the
3543f4c1e1eSBoyan Karatotev *	NO_ISB macro
3553f4c1e1eSBoyan Karatotev */
3563f4c1e1eSBoyan Karatotev.macro workaround_runtime_end _cpu:req, _cve:req, _id:req, _no_isb
3573f4c1e1eSBoyan Karatotev	/*
3583f4c1e1eSBoyan Karatotev	 * Runtime errata do not have a reset function to call the isb for them
3593f4c1e1eSBoyan Karatotev	 * and missing the isb could be very problematic. It is also likely as
3603f4c1e1eSBoyan Karatotev	 * they tend to be scattered in generic code.
3613f4c1e1eSBoyan Karatotev	 */
3623f4c1e1eSBoyan Karatotev	.ifb \_no_isb
3633f4c1e1eSBoyan Karatotev		isb
3643f4c1e1eSBoyan Karatotev	.endif
3653f4c1e1eSBoyan Karatotev	_workaround_end \_cpu, \_id
3663f4c1e1eSBoyan Karatotev.endm
3673f4c1e1eSBoyan Karatotev
3683f4c1e1eSBoyan Karatotev/*******************************************************************************
3693f4c1e1eSBoyan Karatotev * Errata workaround helpers
3703f4c1e1eSBoyan Karatotev ******************************************************************************/
3713f4c1e1eSBoyan Karatotev/*
3723f4c1e1eSBoyan Karatotev * Set a bit in a system register. Can set multiple bits but is limited by the
3733f4c1e1eSBoyan Karatotev *  way the ORR instruction encodes them.
3743f4c1e1eSBoyan Karatotev *
3753f4c1e1eSBoyan Karatotev * _reg:
3763f4c1e1eSBoyan Karatotev *	Register to write to
3773f4c1e1eSBoyan Karatotev *
3783f4c1e1eSBoyan Karatotev * _bit:
3793f4c1e1eSBoyan Karatotev *	Bit to set. Please use a descriptive #define
3803f4c1e1eSBoyan Karatotev *
3813f4c1e1eSBoyan Karatotev * _assert:
3823f4c1e1eSBoyan Karatotev *	Optionally whether to read back and assert that the bit has been
3833f4c1e1eSBoyan Karatotev *	written. Please disable with NO_ASSERT macro
3843f4c1e1eSBoyan Karatotev *
3853f4c1e1eSBoyan Karatotev * clobbers: x1
3863f4c1e1eSBoyan Karatotev */
3873f4c1e1eSBoyan Karatotev.macro sysreg_bit_set _reg:req, _bit:req, _assert=1
3883f4c1e1eSBoyan Karatotev	mrs	x1, \_reg
3893f4c1e1eSBoyan Karatotev	orr	x1, x1, #\_bit
3903f4c1e1eSBoyan Karatotev	msr	\_reg, x1
3913f4c1e1eSBoyan Karatotev.endm
3923f4c1e1eSBoyan Karatotev
3933f4c1e1eSBoyan Karatotev/*
39494a75ad4SBoyan Karatotev * Clear a bit in a system register. Can clear multiple bits but is limited by
39594a75ad4SBoyan Karatotev *  the way the BIC instrucion encodes them.
39694a75ad4SBoyan Karatotev *
39794a75ad4SBoyan Karatotev * see sysreg_bit_set for usage
39894a75ad4SBoyan Karatotev */
39994a75ad4SBoyan Karatotev.macro sysreg_bit_clear _reg:req, _bit:req
40094a75ad4SBoyan Karatotev	mrs	x1, \_reg
40194a75ad4SBoyan Karatotev	bic	x1, x1, #\_bit
40294a75ad4SBoyan Karatotev	msr	\_reg, x1
40394a75ad4SBoyan Karatotev.endm
40494a75ad4SBoyan Karatotev
405bb801857SBoyan Karatotev/*
406bb801857SBoyan Karatotev * Toggle a bit in a system register. Can toggle multiple bits but is limited by
407bb801857SBoyan Karatotev *  the way the EOR instrucion encodes them.
408bb801857SBoyan Karatotev *
409bb801857SBoyan Karatotev * see sysreg_bit_set for usage
410bb801857SBoyan Karatotev */
411bb801857SBoyan Karatotev.macro sysreg_bit_toggle _reg:req, _bit:req, _assert=1
412bb801857SBoyan Karatotev	mrs	x1, \_reg
413bb801857SBoyan Karatotev	eor	x1, x1, #\_bit
414bb801857SBoyan Karatotev	msr	\_reg, x1
415bb801857SBoyan Karatotev.endm
416bb801857SBoyan Karatotev
41794a75ad4SBoyan Karatotev.macro override_vector_table _table:req
41894a75ad4SBoyan Karatotev	adr	x1, \_table
41994a75ad4SBoyan Karatotev	msr	vbar_el3, x1
42094a75ad4SBoyan Karatotev.endm
42194a75ad4SBoyan Karatotev
42294a75ad4SBoyan Karatotev/*
423445f7b51SJayanth Dodderi Chidanand * BFI : Inserts bitfield into a system register.
424445f7b51SJayanth Dodderi Chidanand *
425445f7b51SJayanth Dodderi Chidanand * BFI{cond} Rd, Rn, #lsb, #width
426445f7b51SJayanth Dodderi Chidanand */
427445f7b51SJayanth Dodderi Chidanand.macro sysreg_bitfield_insert _reg:req, _src:req, _lsb:req, _width:req
428445f7b51SJayanth Dodderi Chidanand	/* Source value for BFI */
429445f7b51SJayanth Dodderi Chidanand	mov	x1, #\_src
430445f7b51SJayanth Dodderi Chidanand	mrs	x0, \_reg
431445f7b51SJayanth Dodderi Chidanand	bfi	x0, x1, #\_lsb, #\_width
432445f7b51SJayanth Dodderi Chidanand	msr	\_reg, x0
433445f7b51SJayanth Dodderi Chidanand.endm
434445f7b51SJayanth Dodderi Chidanand
435ad8b5141SJagdish Gediya.macro sysreg_bitfield_insert_from_gpr _reg:req, _gpr:req, _lsb:req, _width:req
436ad8b5141SJagdish Gediya	/* Source value in register for BFI */
437ad8b5141SJagdish Gediya	mov	x1, \_gpr
438ad8b5141SJagdish Gediya	mrs	x0, \_reg
439ad8b5141SJagdish Gediya	bfi	x0, x1, #\_lsb, #\_width
440ad8b5141SJagdish Gediya	msr	\_reg, x0
441ad8b5141SJagdish Gediya.endm
442ad8b5141SJagdish Gediya
443445f7b51SJayanth Dodderi Chidanand/*
444*36eeb59fSBoyan Karatotev * Extract CPU revision and variant, and combine them into a single numeric for
445*36eeb59fSBoyan Karatotev * easier comparison.
446*36eeb59fSBoyan Karatotev *
447*36eeb59fSBoyan Karatotev * _res:
448*36eeb59fSBoyan Karatotev *	register where the result will be placed
449*36eeb59fSBoyan Karatotev * _tmp:
450*36eeb59fSBoyan Karatotev *	register to clobber for temporaries
451*36eeb59fSBoyan Karatotev */
452*36eeb59fSBoyan Karatotev.macro get_rev_var _res:req, _tmp:req
453*36eeb59fSBoyan Karatotev	mrs	\_tmp, midr_el1
454*36eeb59fSBoyan Karatotev
455*36eeb59fSBoyan Karatotev	/*
456*36eeb59fSBoyan Karatotev	 * Extract the variant[23:20] and revision[3:0] from MIDR, and pack them
457*36eeb59fSBoyan Karatotev	 * as variant[7:4] and revision[3:0] of x0.
458*36eeb59fSBoyan Karatotev	 *
459*36eeb59fSBoyan Karatotev	 * First extract x1[23:16] to x0[7:0] and zero fill the rest. Then
460*36eeb59fSBoyan Karatotev	 * extract x1[3:0] into x0[3:0] retaining other bits.
461*36eeb59fSBoyan Karatotev	 */
462*36eeb59fSBoyan Karatotev	ubfx	\_res, \_tmp, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS)
463*36eeb59fSBoyan Karatotev	bfxil	\_res, \_tmp, #MIDR_REV_SHIFT, #MIDR_REV_BITS
464*36eeb59fSBoyan Karatotev.endm
465*36eeb59fSBoyan Karatotev
466*36eeb59fSBoyan Karatotev/*
4673f4c1e1eSBoyan Karatotev * Apply erratum
4683f4c1e1eSBoyan Karatotev *
4693f4c1e1eSBoyan Karatotev * _cpu:
4703f4c1e1eSBoyan Karatotev *	Name of cpu as given to declare_cpu_ops
4713f4c1e1eSBoyan Karatotev *
4723f4c1e1eSBoyan Karatotev * _cve:
4733f4c1e1eSBoyan Karatotev *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
4743f4c1e1eSBoyan Karatotev *
4753f4c1e1eSBoyan Karatotev * _id:
4763f4c1e1eSBoyan Karatotev *	Erratum or CVE number. Please combine with previous field with ERRATUM
4773f4c1e1eSBoyan Karatotev *	or CVE macros
4783f4c1e1eSBoyan Karatotev *
4793f4c1e1eSBoyan Karatotev * _chosen:
4803f4c1e1eSBoyan Karatotev *	Compile time flag on whether the erratum is included
4813f4c1e1eSBoyan Karatotev *
4824d22b0e5SHarrison Mutai * _get_rev:
4834d22b0e5SHarrison Mutai *	Optional parameter that determines whether to insert a call to the CPU revision fetching
484db9ee834SBoyan Karatotev *	procedure. Stores the result of this in the temporary register x10 to allow for chaining
4854d22b0e5SHarrison Mutai *
4864d22b0e5SHarrison Mutai * clobbers: x0-x10 (PCS compliant)
4873f4c1e1eSBoyan Karatotev */
4884d22b0e5SHarrison Mutai.macro apply_erratum _cpu:req, _cve:req, _id:req, _chosen:req, _get_rev=GET_CPU_REV
489cc94e71bSBoyan Karatotev	.if (\_chosen && \_get_rev)
4903f4c1e1eSBoyan Karatotev		mov	x9, x30
4913f4c1e1eSBoyan Karatotev		bl	cpu_get_rev_var
4924d22b0e5SHarrison Mutai		mov	x10, x0
4934d22b0e5SHarrison Mutai	.elseif (\_chosen)
4944d22b0e5SHarrison Mutai		mov	x9, x30
4954d22b0e5SHarrison Mutai		mov	x0, x10
4964d22b0e5SHarrison Mutai	.endif
4974d22b0e5SHarrison Mutai
4984d22b0e5SHarrison Mutai	.if \_chosen
4993f4c1e1eSBoyan Karatotev		bl	erratum_\_cpu\()_\_id\()_wa
5003f4c1e1eSBoyan Karatotev		mov	x30, x9
5013f4c1e1eSBoyan Karatotev	.endif
5023f4c1e1eSBoyan Karatotev.endm
5033f4c1e1eSBoyan Karatotev
5043f4c1e1eSBoyan Karatotev/*
5057791ce21SBoyan Karatotev * Helpers to report if an erratum applies. Compares the given revision variant
5067791ce21SBoyan Karatotev * to the given value. Return ERRATA_APPLIES or ERRATA_NOT_APPLIES accordingly.
5077791ce21SBoyan Karatotev *
5087791ce21SBoyan Karatotev * _rev_num: the given revision variant. Or
5097791ce21SBoyan Karatotev * _rev_num_lo,_rev_num_hi: the lower and upper bounds of the revision variant
5107791ce21SBoyan Karatotev *
5117791ce21SBoyan Karatotev * in body:
5127791ce21SBoyan Karatotev *	clobber: x0
5137791ce21SBoyan Karatotev *	argument: x0 - cpu_rev_var
5147791ce21SBoyan Karatotev */
5157791ce21SBoyan Karatotev.macro cpu_rev_var_ls _rev_num:req
5167791ce21SBoyan Karatotev	cmp	x0, #\_rev_num
5177791ce21SBoyan Karatotev	cset	x0, ls
5187791ce21SBoyan Karatotev.endm
5197791ce21SBoyan Karatotev
5207791ce21SBoyan Karatotev.macro cpu_rev_var_hs _rev_num:req
5217791ce21SBoyan Karatotev	cmp	x0, #\_rev_num
5227791ce21SBoyan Karatotev	cset	x0, hs
5237791ce21SBoyan Karatotev.endm
5247791ce21SBoyan Karatotev
5257791ce21SBoyan Karatotev.macro cpu_rev_var_range _rev_num_lo:req, _rev_num_hi:req
5267791ce21SBoyan Karatotev	cmp	x0, #\_rev_num_lo
5277791ce21SBoyan Karatotev	mov	x1, #\_rev_num_hi
5287791ce21SBoyan Karatotev	ccmp	x0, x1, #2, hs
5297791ce21SBoyan Karatotev	cset	x0, ls
5307791ce21SBoyan Karatotev.endm
5317791ce21SBoyan Karatotev
5327791ce21SBoyan Karatotev/*
5337791ce21SBoyan Karatotev * Helpers to select which revisions errata apply to.
5343f4c1e1eSBoyan Karatotev *
5353f4c1e1eSBoyan Karatotev * _cpu:
5363f4c1e1eSBoyan Karatotev *	Name of cpu as given to declare_cpu_ops
5373f4c1e1eSBoyan Karatotev *
5383f4c1e1eSBoyan Karatotev * _cve:
5393f4c1e1eSBoyan Karatotev *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
5403f4c1e1eSBoyan Karatotev *
5413f4c1e1eSBoyan Karatotev * _id:
5423f4c1e1eSBoyan Karatotev *	Erratum or CVE number. Please combine with previous field with ERRATUM
5433f4c1e1eSBoyan Karatotev *	or CVE macros
5443f4c1e1eSBoyan Karatotev *
5453f4c1e1eSBoyan Karatotev * _rev_num:
5463f4c1e1eSBoyan Karatotev *	Revision to apply to
5473f4c1e1eSBoyan Karatotev *
5483f4c1e1eSBoyan Karatotev * in body:
5497791ce21SBoyan Karatotev *	clobber: x0 to x1
5503f4c1e1eSBoyan Karatotev *	argument: x0 - cpu_rev_var
5513f4c1e1eSBoyan Karatotev */
5523f4c1e1eSBoyan Karatotev.macro check_erratum_ls _cpu:req, _cve:req, _id:req, _rev_num:req
5533f4c1e1eSBoyan Karatotev	func check_erratum_\_cpu\()_\_id
5547791ce21SBoyan Karatotev		cpu_rev_var_ls \_rev_num
5557791ce21SBoyan Karatotev		ret
5563f4c1e1eSBoyan Karatotev	endfunc check_erratum_\_cpu\()_\_id
5573f4c1e1eSBoyan Karatotev.endm
5583f4c1e1eSBoyan Karatotev
5593f4c1e1eSBoyan Karatotev.macro check_erratum_hs _cpu:req, _cve:req, _id:req, _rev_num:req
5603f4c1e1eSBoyan Karatotev	func check_erratum_\_cpu\()_\_id
5617791ce21SBoyan Karatotev		cpu_rev_var_hs \_rev_num
5627791ce21SBoyan Karatotev		ret
5633f4c1e1eSBoyan Karatotev	endfunc check_erratum_\_cpu\()_\_id
5643f4c1e1eSBoyan Karatotev.endm
5653f4c1e1eSBoyan Karatotev
5663f4c1e1eSBoyan Karatotev.macro check_erratum_range _cpu:req, _cve:req, _id:req, _rev_num_lo:req, _rev_num_hi:req
5673f4c1e1eSBoyan Karatotev	func check_erratum_\_cpu\()_\_id
5687791ce21SBoyan Karatotev		cpu_rev_var_range \_rev_num_lo, \_rev_num_hi
5697791ce21SBoyan Karatotev		ret
5703f4c1e1eSBoyan Karatotev	endfunc check_erratum_\_cpu\()_\_id
5713f4c1e1eSBoyan Karatotev.endm
5723f4c1e1eSBoyan Karatotev
57394a75ad4SBoyan Karatotev.macro check_erratum_chosen _cpu:req, _cve:req, _id:req, _chosen:req
57494a75ad4SBoyan Karatotev	func check_erratum_\_cpu\()_\_id
57594a75ad4SBoyan Karatotev		.if \_chosen
57694a75ad4SBoyan Karatotev			mov	x0, #ERRATA_APPLIES
57794a75ad4SBoyan Karatotev		.else
57894a75ad4SBoyan Karatotev			mov	x0, #ERRATA_MISSING
57994a75ad4SBoyan Karatotev		.endif
58094a75ad4SBoyan Karatotev		ret
58194a75ad4SBoyan Karatotev	endfunc check_erratum_\_cpu\()_\_id
58294a75ad4SBoyan Karatotev.endm
58394a75ad4SBoyan Karatotev
5847791ce21SBoyan Karatotev/*
5857791ce21SBoyan Karatotev * provide a shorthand for the name format for annoying errata
586*36eeb59fSBoyan Karatotev * body: clobber x0 to x4
5877791ce21SBoyan Karatotev */
58894a75ad4SBoyan Karatotev.macro check_erratum_custom_start _cpu:req, _cve:req, _id:req
58994a75ad4SBoyan Karatotev	func check_erratum_\_cpu\()_\_id
59094a75ad4SBoyan Karatotev.endm
59194a75ad4SBoyan Karatotev
59294a75ad4SBoyan Karatotev.macro check_erratum_custom_end _cpu:req, _cve:req, _id:req
59394a75ad4SBoyan Karatotev	endfunc check_erratum_\_cpu\()_\_id
59494a75ad4SBoyan Karatotev.endm
59594a75ad4SBoyan Karatotev
59694a75ad4SBoyan Karatotev
5973f4c1e1eSBoyan Karatotev/*******************************************************************************
5983f4c1e1eSBoyan Karatotev * CPU reset function wrapper
5993f4c1e1eSBoyan Karatotev ******************************************************************************/
6003f4c1e1eSBoyan Karatotev
6013f4c1e1eSBoyan Karatotev/*
6023f4c1e1eSBoyan Karatotev * Wrapper to automatically apply all reset-time errata. Will end with an isb.
6033f4c1e1eSBoyan Karatotev *
6043f4c1e1eSBoyan Karatotev * _cpu:
6053f4c1e1eSBoyan Karatotev *	Name of cpu as given to declare_cpu_ops
6063f4c1e1eSBoyan Karatotev *
6073f4c1e1eSBoyan Karatotev * in body:
6083f4c1e1eSBoyan Karatotev *	clobber x8 to x14
6093f4c1e1eSBoyan Karatotev *	argument x14 - cpu_rev_var
6103f4c1e1eSBoyan Karatotev */
6113f4c1e1eSBoyan Karatotev.macro cpu_reset_func_start _cpu:req
6123f4c1e1eSBoyan Karatotev	func \_cpu\()_reset_func
6133f4c1e1eSBoyan Karatotev		mov	x15, x30
614*36eeb59fSBoyan Karatotev		get_rev_var x14, x0
6153f4c1e1eSBoyan Karatotev
6163f4c1e1eSBoyan Karatotev		/* short circuit the location to avoid searching the list */
6173f4c1e1eSBoyan Karatotev		adrp	x12, \_cpu\()_errata_list_start
6183f4c1e1eSBoyan Karatotev		add	x12, x12, :lo12:\_cpu\()_errata_list_start
6193f4c1e1eSBoyan Karatotev		adrp	x13, \_cpu\()_errata_list_end
6203f4c1e1eSBoyan Karatotev		add	x13, x13, :lo12:\_cpu\()_errata_list_end
6213f4c1e1eSBoyan Karatotev
6223f4c1e1eSBoyan Karatotev	errata_begin:
6233f4c1e1eSBoyan Karatotev		/* if head catches up with end of list, exit */
6243f4c1e1eSBoyan Karatotev		cmp	x12, x13
6253f4c1e1eSBoyan Karatotev		b.eq	errata_end
6263f4c1e1eSBoyan Karatotev
6273f4c1e1eSBoyan Karatotev		ldr	x10, [x12, #ERRATUM_WA_FUNC]
6283f4c1e1eSBoyan Karatotev		/* TODO(errata ABI): check mitigated and checker function fields
6293f4c1e1eSBoyan Karatotev		 * for 0 */
6303f4c1e1eSBoyan Karatotev		ldrb	w11, [x12, #ERRATUM_CHOSEN]
6313f4c1e1eSBoyan Karatotev
6323f4c1e1eSBoyan Karatotev		/* skip if not chosen */
6333f4c1e1eSBoyan Karatotev		cbz	x11, 1f
6343f4c1e1eSBoyan Karatotev		/* skip if runtime erratum */
6353f4c1e1eSBoyan Karatotev		cbz	x10, 1f
6363f4c1e1eSBoyan Karatotev
6373f4c1e1eSBoyan Karatotev		/* put cpu revision in x0 and call workaround */
6383f4c1e1eSBoyan Karatotev		mov	x0, x14
6393f4c1e1eSBoyan Karatotev		blr	x10
6403f4c1e1eSBoyan Karatotev	1:
6413f4c1e1eSBoyan Karatotev		add	x12, x12, #ERRATUM_ENTRY_SIZE
6423f4c1e1eSBoyan Karatotev		b	errata_begin
6433f4c1e1eSBoyan Karatotev	errata_end:
6443f4c1e1eSBoyan Karatotev.endm
6453f4c1e1eSBoyan Karatotev
6463f4c1e1eSBoyan Karatotev.macro cpu_reset_func_end _cpu:req
6473f4c1e1eSBoyan Karatotev		isb
6483f4c1e1eSBoyan Karatotev		ret	x15
6493f4c1e1eSBoyan Karatotev	endfunc \_cpu\()_reset_func
6503f4c1e1eSBoyan Karatotev.endm
6514f748cc4SBoyan Karatotev
652c3cf06f1SAntonio Nino Diaz#endif /* CPU_MACROS_S */
653