Merge tag 'spi-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
[linux-2.6-microblaze.git] / arch / arm64 / tools / gen-sysreg.awk
1 #!/bin/awk -f
2 # SPDX-License-Identifier: GPL-2.0
3 # gen-sysreg.awk: arm64 sysreg header generator
4 #
5 # Usage: awk -f gen-sysreg.awk sysregs.txt
6
7 function block_current() {
8         return __current_block[__current_block_depth];
9 }
10
11 # Log an error and terminate
12 function fatal(msg) {
13         print "Error at " NR ": " msg > "/dev/stderr"
14
15         printf "Current block nesting:"
16
17         for (i = 0; i <= __current_block_depth; i++) {
18                 printf " " __current_block[i]
19         }
20         printf "\n"
21
22         exit 1
23 }
24
25 # Enter a new block, setting the active block to @block
26 function block_push(block) {
27         __current_block[++__current_block_depth] = block
28 }
29
30 # Exit a block, setting the active block to the parent block
31 function block_pop() {
32         if (__current_block_depth == 0)
33                 fatal("error: block_pop() in root block")
34
35         __current_block_depth--;
36 }
37
38 # Sanity check the number of records for a field makes sense. If not, produce
39 # an error and terminate.
40 function expect_fields(nf) {
41         if (NF != nf)
42                 fatal(NF " fields found where " nf " expected")
43 }
44
45 # Print a CPP macro definition, padded with spaces so that the macro bodies
46 # line up in a column
47 function define(name, val) {
48         printf "%-56s%s\n", "#define " name, val
49 }
50
51 # Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field
52 function define_field(reg, field, msb, lsb) {
53         define(reg "_" field, "GENMASK(" msb ", " lsb ")")
54         define(reg "_" field "_MASK", "GENMASK(" msb ", " lsb ")")
55         define(reg "_" field "_SHIFT", lsb)
56         define(reg "_" field "_WIDTH", msb - lsb + 1)
57 }
58
59 # Print a field _SIGNED definition for a field
60 function define_field_sign(reg, field, sign) {
61         define(reg "_" field "_SIGNED", sign)
62 }
63
64 # Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb
65 function parse_bitdef(reg, field, bitdef, _bits)
66 {
67         if (bitdef ~ /^[0-9]+$/) {
68                 msb = bitdef
69                 lsb = bitdef
70         } else if (split(bitdef, _bits, ":") == 2) {
71                 msb = _bits[1]
72                 lsb = _bits[2]
73         } else {
74                 fatal("invalid bit-range definition '" bitdef "'")
75         }
76
77
78         if (msb != next_bit)
79                 fatal(reg "." field " starts at " msb " not " next_bit)
80         if (63 < msb || msb < 0)
81                 fatal(reg "." field " invalid high bit in '" bitdef "'")
82         if (63 < lsb || lsb < 0)
83                 fatal(reg "." field " invalid low bit in '" bitdef "'")
84         if (msb < lsb)
85                 fatal(reg "." field " invalid bit-range '" bitdef "'")
86         if (low > high)
87                 fatal(reg "." field " has invalid range " high "-" low)
88
89         next_bit = lsb - 1
90 }
91
92 BEGIN {
93         print "#ifndef __ASM_SYSREG_DEFS_H"
94         print "#define __ASM_SYSREG_DEFS_H"
95         print ""
96         print "/* Generated file - do not edit */"
97         print ""
98
99         __current_block_depth = 0
100         __current_block[__current_block_depth] = "Root"
101 }
102
103 END {
104         if (__current_block_depth != 0)
105                 fatal("Missing terminator for " block_current() " block")
106
107         print "#endif /* __ASM_SYSREG_DEFS_H */"
108 }
109
110 # skip blank lines and comment lines
111 /^$/ { next }
112 /^[\t ]*#/ { next }
113
114 /^SysregFields/ && block_current() == "Root" {
115         block_push("SysregFields")
116
117         expect_fields(2)
118
119         reg = $2
120
121         res0 = "UL(0)"
122         res1 = "UL(0)"
123         unkn = "UL(0)"
124
125         next_bit = 63
126
127         next
128 }
129
130 /^EndSysregFields/ && block_current() == "SysregFields" {
131         if (next_bit > 0)
132                 fatal("Unspecified bits in " reg)
133
134         define(reg "_RES0", "(" res0 ")")
135         define(reg "_RES1", "(" res1 ")")
136         define(reg "_UNKN", "(" unkn ")")
137         print ""
138
139         reg = null
140         res0 = null
141         res1 = null
142         unkn = null
143
144         block_pop()
145         next
146 }
147
148 /^Sysreg/ && block_current() == "Root" {
149         block_push("Sysreg")
150
151         expect_fields(7)
152
153         reg = $2
154         op0 = $3
155         op1 = $4
156         crn = $5
157         crm = $6
158         op2 = $7
159
160         res0 = "UL(0)"
161         res1 = "UL(0)"
162         unkn = "UL(0)"
163
164         define("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
165         define("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
166
167         define("SYS_" reg "_Op0", op0)
168         define("SYS_" reg "_Op1", op1)
169         define("SYS_" reg "_CRn", crn)
170         define("SYS_" reg "_CRm", crm)
171         define("SYS_" reg "_Op2", op2)
172
173         print ""
174
175         next_bit = 63
176
177         next
178 }
179
180 /^EndSysreg/ && block_current() == "Sysreg" {
181         if (next_bit > 0)
182                 fatal("Unspecified bits in " reg)
183
184         if (res0 != null)
185                 define(reg "_RES0", "(" res0 ")")
186         if (res1 != null)
187                 define(reg "_RES1", "(" res1 ")")
188         if (unkn != null)
189                 define(reg "_UNKN", "(" unkn ")")
190         if (res0 != null || res1 != null || unkn != null)
191                 print ""
192
193         reg = null
194         op0 = null
195         op1 = null
196         crn = null
197         crm = null
198         op2 = null
199         res0 = null
200         res1 = null
201         unkn = null
202
203         block_pop()
204         next
205 }
206
207 # Currently this is effectivey a comment, in future we may want to emit
208 # defines for the fields.
209 /^Fields/ && block_current() == "Sysreg" {
210         expect_fields(2)
211
212         if (next_bit != 63)
213                 fatal("Some fields already defined for " reg)
214
215         print "/* For " reg " fields see " $2 " */"
216         print ""
217
218         next_bit = 0
219         res0 = null
220         res1 = null
221         unkn = null
222
223         next
224 }
225
226
227 /^Res0/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
228         expect_fields(2)
229         parse_bitdef(reg, "RES0", $2)
230         field = "RES0_" msb "_" lsb
231
232         res0 = res0 " | GENMASK_ULL(" msb ", " lsb ")"
233
234         next
235 }
236
237 /^Res1/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
238         expect_fields(2)
239         parse_bitdef(reg, "RES1", $2)
240         field = "RES1_" msb "_" lsb
241
242         res1 = res1 " | GENMASK_ULL(" msb ", " lsb ")"
243
244         next
245 }
246
247 /^Unkn/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
248         expect_fields(2)
249         parse_bitdef(reg, "UNKN", $2)
250         field = "UNKN_" msb "_" lsb
251
252         unkn = unkn " | GENMASK_ULL(" msb ", " lsb ")"
253
254         next
255 }
256
257 /^Field/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
258         expect_fields(3)
259         field = $3
260         parse_bitdef(reg, field, $2)
261
262         define_field(reg, field, msb, lsb)
263         print ""
264
265         next
266 }
267
268 /^Raz/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
269         expect_fields(2)
270         parse_bitdef(reg, field, $2)
271
272         next
273 }
274
275 /^SignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
276         block_push("Enum")
277
278         expect_fields(3)
279         field = $3
280         parse_bitdef(reg, field, $2)
281
282         define_field(reg, field, msb, lsb)
283         define_field_sign(reg, field, "true")
284
285         next
286 }
287
288 /^UnsignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
289         block_push("Enum")
290
291         expect_fields(3)
292         field = $3
293         parse_bitdef(reg, field, $2)
294
295         define_field(reg, field, msb, lsb)
296         define_field_sign(reg, field, "false")
297
298         next
299 }
300
301 /^Enum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
302         block_push("Enum")
303
304         expect_fields(3)
305         field = $3
306         parse_bitdef(reg, field, $2)
307
308         define_field(reg, field, msb, lsb)
309
310         next
311 }
312
313 /^EndEnum/ && block_current() == "Enum" {
314
315         field = null
316         msb = null
317         lsb = null
318         print ""
319
320         block_pop()
321         next
322 }
323
324 /0b[01]+/ && block_current() == "Enum" {
325         expect_fields(2)
326         val = $1
327         name = $2
328
329         define(reg "_" field "_" name, "UL(" val ")")
330         next
331 }
332
333 # Any lines not handled by previous rules are unexpected
334 {
335         fatal("unhandled statement")
336 }