summaryrefslogtreecommitdiff
path: root/arch/arm64/tools/gen-sysreg.awk
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/tools/gen-sysreg.awk')
-rwxr-xr-xarch/arm64/tools/gen-sysreg.awk181
1 files changed, 128 insertions, 53 deletions
diff --git a/arch/arm64/tools/gen-sysreg.awk b/arch/arm64/tools/gen-sysreg.awk
index d1254a056114..86860ab672dc 100755
--- a/arch/arm64/tools/gen-sysreg.awk
+++ b/arch/arm64/tools/gen-sysreg.awk
@@ -44,21 +44,38 @@ function expect_fields(nf) {
# Print a CPP macro definition, padded with spaces so that the macro bodies
# line up in a column
-function define(name, val) {
- printf "%-56s%s\n", "#define " name, val
+function define(prefix, name, val) {
+ printf "%-56s%s\n", "#define " prefix name, val
+}
+
+# Same as above, but without a prefix
+function define_reg(name, val) {
+ define(null, name, val)
}
# Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field
-function define_field(reg, field, msb, lsb) {
- define(reg "_" field, "GENMASK(" msb ", " lsb ")")
- define(reg "_" field "_MASK", "GENMASK(" msb ", " lsb ")")
- define(reg "_" field "_SHIFT", lsb)
- define(reg "_" field "_WIDTH", msb - lsb + 1)
+function define_field(prefix, reg, field, msb, lsb) {
+ define(prefix, reg "_" field, "GENMASK(" msb ", " lsb ")")
+ define(prefix, reg "_" field "_MASK", "GENMASK(" msb ", " lsb ")")
+ define(prefix, reg "_" field "_SHIFT", lsb)
+ define(prefix, reg "_" field "_WIDTH", msb - lsb + 1)
}
# Print a field _SIGNED definition for a field
-function define_field_sign(reg, field, sign) {
- define(reg "_" field "_SIGNED", sign)
+function define_field_sign(prefix, reg, field, sign) {
+ define(prefix, reg "_" field "_SIGNED", sign)
+}
+
+# Print the Res0, Res1, Unkn masks
+function define_resx_unkn(prefix, reg, res0, res1, unkn) {
+ if (res0 != null)
+ define(prefix, reg "_RES0", "(" res0 ")")
+ if (res1 != null)
+ define(prefix, reg "_RES1", "(" res1 ")")
+ if (unkn != null)
+ define(prefix, reg "_UNKN", "(" unkn ")")
+ if (res0 != null || res1 != null || unkn != null)
+ print ""
}
# Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb
@@ -111,7 +128,7 @@ END {
/^$/ { next }
/^[\t ]*#/ { next }
-/^SysregFields/ && block_current() == "Root" {
+$1 == "SysregFields" && block_current() == "Root" {
block_push("SysregFields")
expect_fields(2)
@@ -122,19 +139,23 @@ END {
res1 = "UL(0)"
unkn = "UL(0)"
+ if (reg in defined_fields)
+ fatal("Duplicate SysregFields definition for " reg)
+ defined_fields[reg] = 1
+
next_bit = 63
+ delete seen_prefixes
+
next
}
-/^EndSysregFields/ && block_current() == "SysregFields" {
- if (next_bit > 0)
+$1 == "EndSysregFields" && block_current() == "SysregFields" {
+ expect_fields(1)
+ if (next_bit >= 0)
fatal("Unspecified bits in " reg)
- define(reg "_RES0", "(" res0 ")")
- define(reg "_RES1", "(" res1 ")")
- define(reg "_UNKN", "(" unkn ")")
- print ""
+ define_resx_unkn(prefix, reg, res0, res1, unkn)
reg = null
res0 = null
@@ -145,7 +166,7 @@ END {
next
}
-/^Sysreg/ && block_current() == "Root" {
+$1 == "Sysreg" && block_current() == "Root" {
block_push("Sysreg")
expect_fields(7)
@@ -161,34 +182,35 @@ END {
res1 = "UL(0)"
unkn = "UL(0)"
- define("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
- define("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
+ if (reg in defined_regs)
+ fatal("Duplicate Sysreg definition for " reg)
+ defined_regs[reg] = 1
+
+ define_reg("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
+ define_reg("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
- define("SYS_" reg "_Op0", op0)
- define("SYS_" reg "_Op1", op1)
- define("SYS_" reg "_CRn", crn)
- define("SYS_" reg "_CRm", crm)
- define("SYS_" reg "_Op2", op2)
+ define_reg("SYS_" reg "_Op0", op0)
+ define_reg("SYS_" reg "_Op1", op1)
+ define_reg("SYS_" reg "_CRn", crn)
+ define_reg("SYS_" reg "_CRm", crm)
+ define_reg("SYS_" reg "_Op2", op2)
print ""
+ prefix = null
next_bit = 63
+ delete seen_prefixes
+
next
}
-/^EndSysreg/ && block_current() == "Sysreg" {
- if (next_bit > 0)
+$1 == "EndSysreg" && block_current() == "Sysreg" {
+ expect_fields(1)
+ if (next_bit >= 0)
fatal("Unspecified bits in " reg)
- if (res0 != null)
- define(reg "_RES0", "(" res0 ")")
- if (res1 != null)
- define(reg "_RES1", "(" res1 ")")
- if (unkn != null)
- define(reg "_UNKN", "(" unkn ")")
- if (res0 != null || res1 != null || unkn != null)
- print ""
+ define_resx_unkn(prefix, reg, res0, res1, unkn)
reg = null
op0 = null
@@ -199,6 +221,7 @@ END {
res0 = null
res1 = null
unkn = null
+ prefix = null
block_pop()
next
@@ -206,7 +229,7 @@ END {
# Currently this is effectivey a comment, in future we may want to emit
# defines for the fields.
-/^Fields/ && block_current() == "Sysreg" {
+($1 == "Fields" || $1 == "Mapping") && block_current() == "Sysreg" {
expect_fields(2)
if (next_bit != 63)
@@ -215,7 +238,7 @@ END {
print "/* For " reg " fields see " $2 " */"
print ""
- next_bit = 0
+ next_bit = -1
res0 = null
res1 = null
unkn = null
@@ -223,8 +246,7 @@ END {
next
}
-
-/^Res0/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "Res0" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
expect_fields(2)
parse_bitdef(reg, "RES0", $2)
field = "RES0_" msb "_" lsb
@@ -234,7 +256,7 @@ END {
next
}
-/^Res1/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "Res1" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
expect_fields(2)
parse_bitdef(reg, "RES1", $2)
field = "RES1_" msb "_" lsb
@@ -244,7 +266,7 @@ END {
next
}
-/^Unkn/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "Unkn" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
expect_fields(2)
parse_bitdef(reg, "UNKN", $2)
field = "UNKN_" msb "_" lsb
@@ -254,69 +276,78 @@ END {
next
}
-/^Field/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "Field" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
expect_fields(3)
field = $3
parse_bitdef(reg, field, $2)
- define_field(reg, field, msb, lsb)
+ define_field(prefix, reg, field, msb, lsb)
print ""
next
}
-/^Raz/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "Raz" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
expect_fields(2)
parse_bitdef(reg, field, $2)
next
}
-/^SignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "SignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
block_push("Enum")
expect_fields(3)
field = $3
parse_bitdef(reg, field, $2)
- define_field(reg, field, msb, lsb)
- define_field_sign(reg, field, "true")
+ define_field(prefix, reg, field, msb, lsb)
+ define_field_sign(prefix, reg, field, "true")
+
+ delete seen_enum_vals
next
}
-/^UnsignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "UnsignedEnum" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
block_push("Enum")
expect_fields(3)
field = $3
parse_bitdef(reg, field, $2)
- define_field(reg, field, msb, lsb)
- define_field_sign(reg, field, "false")
+ define_field(prefix, reg, field, msb, lsb)
+ define_field_sign(prefix, reg, field, "false")
+
+ delete seen_enum_vals
next
}
-/^Enum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+$1 == "Enum" && (block_current() == "Sysreg" || block_current() == "SysregFields" || block_current() == "Prefix") {
block_push("Enum")
expect_fields(3)
field = $3
parse_bitdef(reg, field, $2)
- define_field(reg, field, msb, lsb)
+ define_field(prefix, reg, field, msb, lsb)
+
+ delete seen_enum_vals
next
}
-/^EndEnum/ && block_current() == "Enum" {
+$1 == "EndEnum" && block_current() == "Enum" {
+ expect_fields(1)
field = null
msb = null
lsb = null
print ""
+ delete seen_enum_vals
+
block_pop()
next
}
@@ -326,7 +357,51 @@ END {
val = $1
name = $2
- define(reg "_" field "_" name, "UL(" val ")")
+ if (val in seen_enum_vals)
+ fatal("Duplicate Enum value " val " for " name)
+ seen_enum_vals[val] = 1
+
+ define(prefix, reg "_" field "_" name, "UL(" val ")")
+ next
+}
+
+$1 == "Prefix" && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ block_push("Prefix")
+
+ expect_fields(2)
+
+ if (next_bit < 63)
+ fatal("Prefixed fields must precede non-prefixed fields (" reg ")")
+
+ prefix = $2 "_"
+
+ if (prefix in seen_prefixes)
+ fatal("Duplicate prefix " prefix " for " reg)
+ seen_prefixes[prefix] = 1
+
+ res0 = "UL(0)"
+ res1 = "UL(0)"
+ unkn = "UL(0)"
+ next_bit = 63
+
+ next
+}
+
+$1 == "EndPrefix" && block_current() == "Prefix" {
+ expect_fields(1)
+ if (next_bit >= 0)
+ fatal("Unspecified bits in prefix " prefix " for " reg)
+
+ define_resx_unkn(prefix, reg, res0, res1, unkn)
+
+ prefix = null
+ res0 = "UL(0)"
+ res1 = "UL(0)"
+ unkn = "UL(0)"
+ next_bit = 63
+
+ block_pop()
+
next
}