Skip to content

Commit 013ecd4

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64/sysreg: allow *Enum blocks in SysregFields blocks
We'd like to support Enum/SignedEnum/UnsignedEnum blocks within SysregFields blocks, so that we can define enumerations for sets of registers. This isn't currently supported by gen-sysreg.awk due to the way we track the active block, which can't handle more than a single layer of nesting, which imposes an awkward requirement that when ending a block we know what the parent block is when calling change_block() Make this nicer by using a stack of active blocks, with block_push() to start a block, and block_pop() to end a block. Doing so means that we only need to check the active block at the start of parsing a line: for the start of a block we can check the parent is valid, and for the end of a block we check that the active block is valid. This structure makes the block parsing simpler and makes it easy to permit a block to live under several potential parents (e.g. by permitting Enum to start when the active block is Sysreg or SysregFields). It also permits further nesting, if we need that in future. To aid debugging, the stack of active blocks is reported for fatal errors, and an error is raised if the file is terminated without ending the active block. For clarity I've renamed the top-level element from "None" to "Root". The Fields element it intended only for use within Sysreg blocks, and does not make sense within SysregFields blocks, and so remains forbidden within a SysregFields block. I've verified using sha1sum that this patch does not change the current generated contents of <asm/sysreg-defs.h>. Signed-off-by: Mark Rutland <[email protected]> Cc: Anshuman Khandual <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: Mark Brown <[email protected]> Cc: Will Deacon <[email protected]> Reviewed-by: Anshuman Khandual <[email protected]> Reviewed-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent e8d018d commit 013ecd4

File tree

1 file changed

+58
-37
lines changed

1 file changed

+58
-37
lines changed

arch/arm64/tools/gen-sysreg.awk

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,35 @@
44
#
55
# Usage: awk -f gen-sysreg.awk sysregs.txt
66

7+
function block_current() {
8+
return __current_block[__current_block_depth];
9+
}
10+
711
# Log an error and terminate
812
function fatal(msg) {
913
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+
1022
exit 1
1123
}
1224

13-
# Sanity check that the start or end of a block makes sense at this point in
14-
# the file. If not, produce an error and terminate.
15-
#
16-
# @this - the $Block or $EndBlock
17-
# @prev - the only valid block to already be in (value of @block)
18-
# @new - the new value of @block
19-
function change_block(this, prev, new) {
20-
if (block != prev)
21-
fatal("unexpected " this " (inside " block ")")
22-
23-
block = new
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--;
2436
}
2537

2638
# Sanity check the number of records for a field makes sense. If not, produce
@@ -84,19 +96,24 @@ BEGIN {
8496
print "/* Generated file - do not edit */"
8597
print ""
8698

87-
block = "None"
99+
__current_block_depth = 0
100+
__current_block[__current_block_depth] = "Root"
88101
}
89102

90103
END {
104+
if (__current_block_depth != 0)
105+
fatal("Missing terminator for " block_current() " block")
106+
91107
print "#endif /* __ASM_SYSREG_DEFS_H */"
92108
}
93109

94110
# skip blank lines and comment lines
95111
/^$/ { next }
96112
/^[\t ]*#/ { next }
97113

98-
/^SysregFields/ {
99-
change_block("SysregFields", "None", "SysregFields")
114+
/^SysregFields/ && block_current() == "Root" {
115+
block_push("SysregFields")
116+
100117
expect_fields(2)
101118

102119
reg = $2
@@ -110,12 +127,10 @@ END {
110127
next
111128
}
112129

113-
/^EndSysregFields/ {
130+
/^EndSysregFields/ && block_current() == "SysregFields" {
114131
if (next_bit > 0)
115132
fatal("Unspecified bits in " reg)
116133

117-
change_block("EndSysregFields", "SysregFields", "None")
118-
119134
define(reg "_RES0", "(" res0 ")")
120135
define(reg "_RES1", "(" res1 ")")
121136
define(reg "_UNKN", "(" unkn ")")
@@ -126,11 +141,13 @@ END {
126141
res1 = null
127142
unkn = null
128143

144+
block_pop()
129145
next
130146
}
131147

132-
/^Sysreg/ {
133-
change_block("Sysreg", "None", "Sysreg")
148+
/^Sysreg/ && block_current() == "Root" {
149+
block_push("Sysreg")
150+
134151
expect_fields(7)
135152

136153
reg = $2
@@ -160,12 +177,10 @@ END {
160177
next
161178
}
162179

163-
/^EndSysreg/ {
180+
/^EndSysreg/ && block_current() == "Sysreg" {
164181
if (next_bit > 0)
165182
fatal("Unspecified bits in " reg)
166183

167-
change_block("EndSysreg", "Sysreg", "None")
168-
169184
if (res0 != null)
170185
define(reg "_RES0", "(" res0 ")")
171186
if (res1 != null)
@@ -185,12 +200,13 @@ END {
185200
res1 = null
186201
unkn = null
187202

203+
block_pop()
188204
next
189205
}
190206

191207
# Currently this is effectivey a comment, in future we may want to emit
192208
# defines for the fields.
193-
/^Fields/ && (block == "Sysreg") {
209+
/^Fields/ && block_current() == "Sysreg" {
194210
expect_fields(2)
195211

196212
if (next_bit != 63)
@@ -208,7 +224,7 @@ END {
208224
}
209225

210226

211-
/^Res0/ && (block == "Sysreg" || block == "SysregFields") {
227+
/^Res0/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
212228
expect_fields(2)
213229
parse_bitdef(reg, "RES0", $2)
214230
field = "RES0_" msb "_" lsb
@@ -218,7 +234,7 @@ END {
218234
next
219235
}
220236

221-
/^Res1/ && (block == "Sysreg" || block == "SysregFields") {
237+
/^Res1/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
222238
expect_fields(2)
223239
parse_bitdef(reg, "RES1", $2)
224240
field = "RES1_" msb "_" lsb
@@ -228,7 +244,7 @@ END {
228244
next
229245
}
230246

231-
/^Unkn/ && (block == "Sysreg" || block == "SysregFields") {
247+
/^Unkn/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
232248
expect_fields(2)
233249
parse_bitdef(reg, "UNKN", $2)
234250
field = "UNKN_" msb "_" lsb
@@ -238,7 +254,7 @@ END {
238254
next
239255
}
240256

241-
/^Field/ && (block == "Sysreg" || block == "SysregFields") {
257+
/^Field/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
242258
expect_fields(3)
243259
field = $3
244260
parse_bitdef(reg, field, $2)
@@ -249,15 +265,16 @@ END {
249265
next
250266
}
251267

252-
/^Raz/ && (block == "Sysreg" || block == "SysregFields") {
268+
/^Raz/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
253269
expect_fields(2)
254270
parse_bitdef(reg, field, $2)
255271

256272
next
257273
}
258274

259-
/^SignedEnum/ {
260-
change_block("Enum<", "Sysreg", "Enum")
275+
/^SignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
276+
block_push("Enum")
277+
261278
expect_fields(3)
262279
field = $3
263280
parse_bitdef(reg, field, $2)
@@ -268,8 +285,9 @@ END {
268285
next
269286
}
270287

271-
/^UnsignedEnum/ {
272-
change_block("Enum<", "Sysreg", "Enum")
288+
/^UnsignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
289+
block_push("Enum")
290+
273291
expect_fields(3)
274292
field = $3
275293
parse_bitdef(reg, field, $2)
@@ -280,8 +298,9 @@ END {
280298
next
281299
}
282300

283-
/^Enum/ {
284-
change_block("Enum", "Sysreg", "Enum")
301+
/^Enum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
302+
block_push("Enum")
303+
285304
expect_fields(3)
286305
field = $3
287306
parse_bitdef(reg, field, $2)
@@ -291,16 +310,18 @@ END {
291310
next
292311
}
293312

294-
/^EndEnum/ {
295-
change_block("EndEnum", "Enum", "Sysreg")
313+
/^EndEnum/ && block_current() == "Enum" {
314+
296315
field = null
297316
msb = null
298317
lsb = null
299318
print ""
319+
320+
block_pop()
300321
next
301322
}
302323

303-
/0b[01]+/ && block == "Enum" {
324+
/0b[01]+/ && block_current() == "Enum" {
304325
expect_fields(2)
305326
val = $1
306327
name = $2

0 commit comments

Comments
 (0)