Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
7function block_current() {
8 return __current_block[__current_block_depth];
9}
10
11# Log an error and terminate
12function 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
26function block_push(block) {
27 __current_block[++__current_block_depth] = block
28}
29
30# Exit a block, setting the active block to the parent block
31function 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.
40function 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
47function define(name, val) {
48 printf "%-56s%s\n", "#define " name, val
49}
50
51# Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field
52function 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
60function 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
65function 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
92BEGIN {
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
103END {
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$1 == "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 if (reg in defined_fields)
126 fatal("Duplicate SysregFields definition for " reg)
127 defined_fields[reg] = 1
128
129 next_bit = 63
130
131 next
132}
133
134$1 == "EndSysregFields" && block_current() == "SysregFields" {
135 expect_fields(1)
136 if (next_bit > 0)
137 fatal("Unspecified bits in " reg)
138
139 define(reg "_RES0", "(" res0 ")")
140 define(reg "_RES1", "(" res1 ")")
141 define(reg "_UNKN", "(" unkn ")")
142 print ""
143
144 reg = null
145 res0 = null
146 res1 = null
147 unkn = null
148
149 block_pop()
150 next
151}
152
153$1 == "Sysreg" && block_current() == "Root" {
154 block_push("Sysreg")
155
156 expect_fields(7)
157
158 reg = $2
159 op0 = $3
160 op1 = $4
161 crn = $5
162 crm = $6
163 op2 = $7
164
165 res0 = "UL(0)"
166 res1 = "UL(0)"
167 unkn = "UL(0)"
168
169 if (reg in defined_regs)
170 fatal("Duplicate Sysreg definition for " reg)
171 defined_regs[reg] = 1
172
173 define("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
174 define("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
175
176 define("SYS_" reg "_Op0", op0)
177 define("SYS_" reg "_Op1", op1)
178 define("SYS_" reg "_CRn", crn)
179 define("SYS_" reg "_CRm", crm)
180 define("SYS_" reg "_Op2", op2)
181
182 print ""
183
184 next_bit = 63
185
186 next
187}
188
189$1 == "EndSysreg" && block_current() == "Sysreg" {
190 expect_fields(1)
191 if (next_bit > 0)
192 fatal("Unspecified bits in " reg)
193
194 if (res0 != null)
195 define(reg "_RES0", "(" res0 ")")
196 if (res1 != null)
197 define(reg "_RES1", "(" res1 ")")
198 if (unkn != null)
199 define(reg "_UNKN", "(" unkn ")")
200 if (res0 != null || res1 != null || unkn != null)
201 print ""
202
203 reg = null
204 op0 = null
205 op1 = null
206 crn = null
207 crm = null
208 op2 = null
209 res0 = null
210 res1 = null
211 unkn = null
212
213 block_pop()
214 next
215}
216
217# Currently this is effectivey a comment, in future we may want to emit
218# defines for the fields.
219($1 == "Fields" || $1 == "Mapping") && block_current() == "Sysreg" {
220 expect_fields(2)
221
222 if (next_bit != 63)
223 fatal("Some fields already defined for " reg)
224
225 print "/* For " reg " fields see " $2 " */"
226 print ""
227
228 next_bit = 0
229 res0 = null
230 res1 = null
231 unkn = null
232
233 next
234}
235
236
237$1 == "Res0" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
238 expect_fields(2)
239 parse_bitdef(reg, "RES0", $2)
240 field = "RES0_" msb "_" lsb
241
242 res0 = res0 " | GENMASK_ULL(" msb ", " lsb ")"
243
244 next
245}
246
247$1 == "Res1" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
248 expect_fields(2)
249 parse_bitdef(reg, "RES1", $2)
250 field = "RES1_" msb "_" lsb
251
252 res1 = res1 " | GENMASK_ULL(" msb ", " lsb ")"
253
254 next
255}
256
257$1 == "Unkn" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
258 expect_fields(2)
259 parse_bitdef(reg, "UNKN", $2)
260 field = "UNKN_" msb "_" lsb
261
262 unkn = unkn " | GENMASK_ULL(" msb ", " lsb ")"
263
264 next
265}
266
267$1 == "Field" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
268 expect_fields(3)
269 field = $3
270 parse_bitdef(reg, field, $2)
271
272 define_field(reg, field, msb, lsb)
273 print ""
274
275 next
276}
277
278$1 == "Raz" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
279 expect_fields(2)
280 parse_bitdef(reg, field, $2)
281
282 next
283}
284
285$1 == "SignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
286 block_push("Enum")
287
288 expect_fields(3)
289 field = $3
290 parse_bitdef(reg, field, $2)
291
292 define_field(reg, field, msb, lsb)
293 define_field_sign(reg, field, "true")
294
295 delete seen_enum_vals
296
297 next
298}
299
300$1 == "UnsignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
301 block_push("Enum")
302
303 expect_fields(3)
304 field = $3
305 parse_bitdef(reg, field, $2)
306
307 define_field(reg, field, msb, lsb)
308 define_field_sign(reg, field, "false")
309
310 delete seen_enum_vals
311
312 next
313}
314
315$1 == "Enum" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
316 block_push("Enum")
317
318 expect_fields(3)
319 field = $3
320 parse_bitdef(reg, field, $2)
321
322 define_field(reg, field, msb, lsb)
323
324 delete seen_enum_vals
325
326 next
327}
328
329$1 == "EndEnum" && block_current() == "Enum" {
330 expect_fields(1)
331
332 field = null
333 msb = null
334 lsb = null
335 print ""
336
337 delete seen_enum_vals
338
339 block_pop()
340 next
341}
342
343/0b[01]+/ && block_current() == "Enum" {
344 expect_fields(2)
345 val = $1
346 name = $2
347
348 if (val in seen_enum_vals)
349 fatal("Duplicate Enum value " val " for " name)
350 seen_enum_vals[val] = 1
351
352 define(reg "_" field "_" name, "UL(" val ")")
353 next
354}
355
356# Any lines not handled by previous rules are unexpected
357{
358 fatal("unhandled statement")
359}