~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm64/tools/gen-sysreg.awk

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 }

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php