Skip to content

Commit fe2ef46

Browse files
Sticklyman1936ctmarinas
authored andcommitted
arm64/sysreg: Support feature-specific fields with 'Prefix' descriptor
Some system register field encodings change based on, for example the in-use architecture features, or the context in which they are accessed. In order to support these different field encodings, introduce the Prefix descriptor (Prefix, EndPrefix) for describing such sysregs. The Prefix descriptor can be used in the following way: Sysreg EXAMPLE 0 1 2 3 4 Prefix FEAT_A Field 63:0 Foo EndPrefix Prefix FEAT_B Field 63:1 Bar Res0 0 EndPrefix Field 63:0 Baz EndSysreg This will generate a single set of system register encodings (REG_, SYS_, ...), and then generate three sets of field definitions for the system register called EXAMPLE. The first set is prefixed by FEAT_A, e.g. FEAT_A_EXAMPLE_Foo. The second set is prefixed by FEAT_B, e.g., FEAT_B_EXAMPLE_Bar. The third set is not given a prefix at all, e.g. EXAMPLE_BAZ. For each set, a corresponding set of defines for Res0, Res1, and Unkn is generated. The intent for the final prefix-less fields is to describe default or legacy field encodings. This ensure that prefixed encodings can be added to already-present sysregs without affecting existing legacy code. Prefixed fields must be defined before those without a prefix, and this is checked by the generator. This ensures consisnt ordering within the sysregs definitions. The Prefix descriptor can be used within Sysreg or SysregFields blocks. Field, Res0, Res1, Unkn, Rax, SignedEnum, Enum can all be used within a Prefix block. Fields and Mapping can not. Fields that vary with features must be described as part of a SysregFields block, instead. Mappings, which are just a code comment, make little sense in this context, and have hence not been included. There are no changes to the generated system register definitions as part of this change. Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 0aab577 commit fe2ef46

1 file changed

Lines changed: 88 additions & 38 deletions

File tree

arch/arm64/tools/gen-sysreg.awk

Lines changed: 88 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,26 @@ function expect_fields(nf) {
4444

4545
# Print a CPP macro definition, padded with spaces so that the macro bodies
4646
# line up in a column
47-
function define(name, val) {
48-
printf "%-56s%s\n", "#define " name, val
47+
function define(prefix, name, val) {
48+
printf "%-56s%s\n", "#define " prefix name, val
49+
}
50+
51+
# Same as above, but without a prefix
52+
function define_reg(name, val) {
53+
define(null, name, val)
4954
}
5055

5156
# 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+
function define_field(prefix, reg, field, msb, lsb) {
58+
define(prefix, reg "_" field, "GENMASK(" msb ", " lsb ")")
59+
define(prefix, reg "_" field "_MASK", "GENMASK(" msb ", " lsb ")")
60+
define(prefix, reg "_" field "_SHIFT", lsb)
61+
define(prefix, reg "_" field "_WIDTH", msb - lsb + 1)
5762
}
5863

5964
# Print a field _SIGNED definition for a field
60-
function define_field_sign(reg, field, sign) {
61-
define(reg "_" field "_SIGNED", sign)
65+
function define_field_sign(prefix, reg, field, sign) {
66+
define(prefix, reg "_" field "_SIGNED", sign)
6267
}
6368

6469
# Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb
@@ -128,6 +133,8 @@ $1 == "SysregFields" && block_current() == "Root" {
128133

129134
next_bit = 63
130135

136+
delete seen_prefixes
137+
131138
next
132139
}
133140

@@ -136,9 +143,9 @@ $1 == "EndSysregFields" && block_current() == "SysregFields" {
136143
if (next_bit >= 0)
137144
fatal("Unspecified bits in " reg)
138145

139-
define(reg "_RES0", "(" res0 ")")
140-
define(reg "_RES1", "(" res1 ")")
141-
define(reg "_UNKN", "(" unkn ")")
146+
define(prefix, reg "_RES0", "(" res0 ")")
147+
define(prefix, reg "_RES1", "(" res1 ")")
148+
define(prefix, reg "_UNKN", "(" unkn ")")
142149
print ""
143150

144151
reg = null
@@ -170,19 +177,22 @@ $1 == "Sysreg" && block_current() == "Root" {
170177
fatal("Duplicate Sysreg definition for " reg)
171178
defined_regs[reg] = 1
172179

173-
define("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
174-
define("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
180+
define_reg("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
181+
define_reg("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
175182

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)
183+
define_reg("SYS_" reg "_Op0", op0)
184+
define_reg("SYS_" reg "_Op1", op1)
185+
define_reg("SYS_" reg "_CRn", crn)
186+
define_reg("SYS_" reg "_CRm", crm)
187+
define_reg("SYS_" reg "_Op2", op2)
181188

182189
print ""
183190

191+
prefix = null
184192
next_bit = 63
185193

194+
delete seen_prefixes
195+
186196
next
187197
}
188198

@@ -192,11 +202,11 @@ $1 == "EndSysreg" && block_current() == "Sysreg" {
192202
fatal("Unspecified bits in " reg)
193203

194204
if (res0 != null)
195-
define(reg "_RES0", "(" res0 ")")
205+
define(prefix, reg "_RES0", "(" res0 ")")
196206
if (res1 != null)
197-
define(reg "_RES1", "(" res1 ")")
207+
define(prefix, reg "_RES1", "(" res1 ")")
198208
if (unkn != null)
199-
define(reg "_UNKN", "(" unkn ")")
209+
define(prefix, reg "_UNKN", "(" unkn ")")
200210
if (res0 != null || res1 != null || unkn != null)
201211
print ""
202212

@@ -209,6 +219,7 @@ $1 == "EndSysreg" && block_current() == "Sysreg" {
209219
res0 = null
210220
res1 = null
211221
unkn = null
222+
prefix = null
212223

213224
block_pop()
214225
next
@@ -233,8 +244,7 @@ $1 == "EndSysreg" && block_current() == "Sysreg" {
233244
next
234245
}
235246

236-
237-
$1 == "Res0" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
247+
$1 == "Res0" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
238248
expect_fields(2)
239249
parse_bitdef(reg, "RES0", $2)
240250
field = "RES0_" msb "_" lsb
@@ -244,7 +254,7 @@ $1 == "Res0" && (block_current() == "Sysreg" || block_current() == "SysregFields
244254
next
245255
}
246256

247-
$1 == "Res1" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
257+
$1 == "Res1" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
248258
expect_fields(2)
249259
parse_bitdef(reg, "RES1", $2)
250260
field = "RES1_" msb "_" lsb
@@ -254,7 +264,7 @@ $1 == "Res1" && (block_current() == "Sysreg" || block_current() == "SysregFields
254264
next
255265
}
256266

257-
$1 == "Unkn" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
267+
$1 == "Unkn" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
258268
expect_fields(2)
259269
parse_bitdef(reg, "UNKN", $2)
260270
field = "UNKN_" msb "_" lsb
@@ -264,62 +274,62 @@ $1 == "Unkn" && (block_current() == "Sysreg" || block_current() == "SysregFields
264274
next
265275
}
266276

267-
$1 == "Field" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
277+
$1 == "Field" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
268278
expect_fields(3)
269279
field = $3
270280
parse_bitdef(reg, field, $2)
271281

272-
define_field(reg, field, msb, lsb)
282+
define_field(prefix, reg, field, msb, lsb)
273283
print ""
274284

275285
next
276286
}
277287

278-
$1 == "Raz" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
288+
$1 == "Raz" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
279289
expect_fields(2)
280290
parse_bitdef(reg, field, $2)
281291

282292
next
283293
}
284294

285-
$1 == "SignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
295+
$1 == "SignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
286296
block_push("Enum")
287297

288298
expect_fields(3)
289299
field = $3
290300
parse_bitdef(reg, field, $2)
291301

292-
define_field(reg, field, msb, lsb)
293-
define_field_sign(reg, field, "true")
302+
define_field(prefix, reg, field, msb, lsb)
303+
define_field_sign(prefix, reg, field, "true")
294304

295305
delete seen_enum_vals
296306

297307
next
298308
}
299309

300-
$1 == "UnsignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
310+
$1 == "UnsignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
301311
block_push("Enum")
302312

303313
expect_fields(3)
304314
field = $3
305315
parse_bitdef(reg, field, $2)
306316

307-
define_field(reg, field, msb, lsb)
308-
define_field_sign(reg, field, "false")
317+
define_field(prefix, reg, field, msb, lsb)
318+
define_field_sign(prefix, reg, field, "false")
309319

310320
delete seen_enum_vals
311321

312322
next
313323
}
314324

315-
$1 == "Enum" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
325+
$1 == "Enum" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
316326
block_push("Enum")
317327

318328
expect_fields(3)
319329
field = $3
320330
parse_bitdef(reg, field, $2)
321331

322-
define_field(reg, field, msb, lsb)
332+
define_field(prefix, reg, field, msb, lsb)
323333

324334
delete seen_enum_vals
325335

@@ -349,7 +359,47 @@ $1 == "EndEnum" && block_current() == "Enum" {
349359
fatal("Duplicate Enum value " val " for " name)
350360
seen_enum_vals[val] = 1
351361

352-
define(reg "_" field "_" name, "UL(" val ")")
362+
define(prefix, reg "_" field "_" name, "UL(" val ")")
363+
next
364+
}
365+
366+
$1 == "Prefix" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
367+
block_push("Prefix")
368+
369+
expect_fields(2)
370+
371+
if (next_bit < 63)
372+
fatal("Prefixed fields must precede non-prefixed fields (" reg ")")
373+
374+
prefix = $2 "_"
375+
376+
if (prefix in seen_prefixes)
377+
fatal("Duplicate prefix " prefix " for " reg)
378+
seen_prefixes[prefix] = 1
379+
380+
res0 = "UL(0)"
381+
res1 = "UL(0)"
382+
unkn = "UL(0)"
383+
next_bit = 63
384+
385+
next
386+
}
387+
388+
$1 == "EndPrefix" && block_current() == "Prefix" {
389+
expect_fields(1)
390+
if (next_bit >= 0)
391+
fatal("Unspecified bits in prefix " prefix " for " reg)
392+
393+
define_resx_unkn(prefix, reg, res0, res1, unkn)
394+
395+
prefix = null
396+
res0 = "UL(0)"
397+
res1 = "UL(0)"
398+
unkn = "UL(0)"
399+
next_bit = 63
400+
401+
block_pop()
402+
353403
next
354404
}
355405

0 commit comments

Comments
 (0)