blob: 02999ae6c091b9f8653890b6b654d1b111e9b600 [file] [log] [blame]
Soby Mathew748be1d2016-05-05 14:10:46 +01001/*
Arvind Ram Prakash11b9b492022-11-22 14:41:00 -06002 * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
Soby Mathew748be1d2016-05-05 14:10:46 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathew748be1d2016-05-05 14:10:46 +01005 */
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +00006#ifndef CPU_MACROS_S
7#define CPU_MACROS_S
Soby Mathew748be1d2016-05-05 14:10:46 +01008
9#include <arch.h>
Boyan Karatoteve7d7c272023-01-25 16:55:18 +000010#include <lib/cpus/cpu_ops.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011#include <lib/cpus/errata_report.h>
Soby Mathew748be1d2016-05-05 14:10:46 +010012
Soby Mathew748be1d2016-05-05 14:10:46 +010013 /*
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000014 * Write given expressions as words
15 *
16 * _count:
17 * Write at least _count words. If the given number of expressions
18 * is less than _count, repeat the last expression to fill _count
19 * words in total
20 * _rest:
21 * Optional list of expressions. _this is for parameter extraction
22 * only, and has no significance to the caller
23 *
24 * Invoked as:
25 * fill_constants 2, foo, bar, blah, ...
Soby Mathew748be1d2016-05-05 14:10:46 +010026 */
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000027 .macro fill_constants _count:req, _this, _rest:vararg
28 .ifgt \_count
29 /* Write the current expression */
30 .ifb \_this
31 .error "Nothing to fill"
32 .endif
33 .word \_this
34
35 /* Invoke recursively for remaining expressions */
36 .ifnb \_rest
37 fill_constants \_count-1, \_rest
38 .else
39 fill_constants \_count-1, \_this
40 .endif
41 .endif
42 .endm
43
44 /*
45 * Declare CPU operations
46 *
47 * _name:
48 * Name of the CPU for which operations are being specified
49 * _midr:
50 * Numeric value expected to read from CPU's MIDR
51 * _resetfunc:
52 * Reset function for the CPU. If there's no CPU reset function,
53 * specify CPU_NO_RESET_FUNC
54 * _power_down_ops:
55 * Comma-separated list of functions to perform power-down
56 * operatios on the CPU. At least one, and up to
57 * CPU_MAX_PWR_DWN_OPS number of functions may be specified.
58 * Starting at power level 0, these functions shall handle power
59 * down at subsequent power levels. If there aren't exactly
60 * CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
61 * used to handle power down at subsequent levels
62 */
63 .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
64 _power_down_ops:vararg
Chris Kay33bfc5e2023-02-14 11:30:04 +000065 .section .cpu_ops, "a"
Soby Mathew748be1d2016-05-05 14:10:46 +010066 .align 2
67 .type cpu_ops_\_name, %object
68 .word \_midr
Roberto Vargase0e99462017-10-30 14:43:43 +000069#if defined(IMAGE_AT_EL3)
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000070 .word \_resetfunc
Yatharth Kocharf528faf2016-06-28 16:58:26 +010071#endif
Masahiro Yamada441bfdd2016-12-25 23:36:24 +090072#ifdef IMAGE_BL32
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000073 /* Insert list of functions */
74 fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
Yatharth Kocharf528faf2016-06-28 16:58:26 +010075#endif
Jeenu Viswambharand5ec3672017-01-03 11:01:51 +000076
77#if REPORT_ERRATA
78 .ifndef \_name\()_cpu_str
79 /*
80 * Place errata reported flag, and the spinlock to arbitrate access to
81 * it in the data section.
82 */
83 .pushsection .data
84 define_asm_spinlock \_name\()_errata_lock
85 \_name\()_errata_reported:
86 .word 0
87 .popsection
88
89 /* Place CPU string in rodata */
90 .pushsection .rodata
91 \_name\()_cpu_str:
92 .asciz "\_name"
93 .popsection
94 .endif
95
96 /*
Soby Mathew0980dce2018-09-17 04:34:35 +010097 * Mandatory errata status printing function for CPUs of
Jeenu Viswambharand5ec3672017-01-03 11:01:51 +000098 * this class.
99 */
Jeenu Viswambharand5ec3672017-01-03 11:01:51 +0000100 .word \_name\()_errata_report
101
102#ifdef IMAGE_BL32
103 /* Pointers to errata lock and reported flag */
104 .word \_name\()_errata_lock
105 .word \_name\()_errata_reported
106#endif
107#endif
Soby Mathew748be1d2016-05-05 14:10:46 +0100108 .endm
109
Jeenu Viswambharand5ec3672017-01-03 11:01:51 +0000110#if REPORT_ERRATA
111 /*
112 * Print status of a CPU errata
113 *
114 * _chosen:
115 * Identifier indicating whether or not a CPU errata has been
116 * compiled in.
117 * _cpu:
118 * Name of the CPU
119 * _id:
120 * Errata identifier
121 * _rev_var:
122 * Register containing the combined value CPU revision and variant
123 * - typically the return value of cpu_get_rev_var
124 */
125 .macro report_errata _chosen, _cpu, _id, _rev_var=r4
126 /* Stash a string with errata ID */
127 .pushsection .rodata
128 \_cpu\()_errata_\_id\()_str:
129 .asciz "\_id"
130 .popsection
131
132 /* Check whether errata applies */
133 mov r0, \_rev_var
134 bl check_errata_\_id
135
136 .ifeq \_chosen
137 /*
138 * Errata workaround has not been compiled in. If the errata would have
139 * applied had it been compiled in, print its status as missing.
140 */
141 cmp r0, #0
142 movne r0, #ERRATA_MISSING
143 .endif
144 ldr r1, =\_cpu\()_cpu_str
145 ldr r2, =\_cpu\()_errata_\_id\()_str
146 bl errata_print_msg
147 .endm
148#endif
Deepak Pandeyb5615362018-10-11 13:44:43 +0530149 /*
150 * Helper macro that reads the part number of the current CPU and jumps
151 * to the given label if it matches the CPU MIDR provided.
152 *
153 * Clobbers: r0-r1
154 */
155 .macro jump_if_cpu_midr _cpu_midr, _label
156 ldcopr r0, MIDR
157 ubfx r0, r0, #MIDR_PN_SHIFT, #12
158 ldr r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
159 cmp r0, r1
160 beq \_label
161 .endm
Jeenu Viswambharand5ec3672017-01-03 11:01:51 +0000162
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +0000163#endif /* CPU_MACROS_S */