Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/awk -f
0002 # SPDX-License-Identifier: GPL-2.0
0003 # gen-sysreg.awk: arm64 sysreg header generator
0004 #
0005 # Usage: awk -f gen-sysreg.awk sysregs.txt
0006 
0007 # Log an error and terminate
0008 function fatal(msg) {
0009   print "Error at " NR ": " msg > "/dev/stderr"
0010   exit 1
0011 }
0012 
0013 # Sanity check that the start or end of a block makes sense at this point in
0014 # the file. If not, produce an error and terminate.
0015 #
0016 # @this - the $Block or $EndBlock
0017 # @prev - the only valid block to already be in (value of @block)
0018 # @new - the new value of @block
0019 function change_block(this, prev, new) {
0020   if (block != prev)
0021     fatal("unexpected " this " (inside " block ")")
0022 
0023   block = new
0024 }
0025 
0026 # Sanity check the number of records for a field makes sense. If not, produce
0027 # an error and terminate.
0028 function expect_fields(nf) {
0029   if (NF != nf)
0030     fatal(NF " fields found where " nf " expected")
0031 }
0032 
0033 # Print a CPP macro definition, padded with spaces so that the macro bodies
0034 # line up in a column
0035 function define(name, val) {
0036   printf "%-48s%s\n", "#define " name, val
0037 }
0038 
0039 # Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field
0040 function define_field(reg, field, msb, lsb) {
0041   define(reg "_" field, "GENMASK(" msb ", " lsb ")")
0042   define(reg "_" field "_MASK", "GENMASK(" msb ", " lsb ")")
0043   define(reg "_" field "_SHIFT", lsb)
0044   define(reg "_" field "_WIDTH", msb - lsb + 1)
0045 }
0046 
0047 # Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb
0048 function parse_bitdef(reg, field, bitdef, _bits)
0049 {
0050   if (bitdef ~ /^[0-9]+$/) {
0051     msb = bitdef
0052     lsb = bitdef
0053   } else if (split(bitdef, _bits, ":") == 2) {
0054     msb = _bits[1]
0055     lsb = _bits[2]
0056   } else {
0057     fatal("invalid bit-range definition '" bitdef "'")
0058   }
0059 
0060 
0061   if (msb != next_bit)
0062     fatal(reg "." field " starts at " msb " not " next_bit)
0063   if (63 < msb || msb < 0)
0064     fatal(reg "." field " invalid high bit in '" bitdef "'")
0065   if (63 < lsb || lsb < 0)
0066     fatal(reg "." field " invalid low bit in '" bitdef "'")
0067   if (msb < lsb)
0068     fatal(reg "." field " invalid bit-range '" bitdef "'")
0069   if (low > high)
0070     fatal(reg "." field " has invalid range " high "-" low)
0071 
0072   next_bit = lsb - 1
0073 }
0074 
0075 BEGIN {
0076   print "#ifndef __ASM_SYSREG_DEFS_H"
0077   print "#define __ASM_SYSREG_DEFS_H"
0078   print ""
0079   print "/* Generated file - do not edit */"
0080   print ""
0081 
0082   block = "None"
0083 }
0084 
0085 END {
0086   print "#endif /* __ASM_SYSREG_DEFS_H */"
0087 }
0088 
0089 # skip blank lines and comment lines
0090 /^$/ { next }
0091 /^[\t ]*#/ { next }
0092 
0093 /^SysregFields/ {
0094   change_block("SysregFields", "None", "SysregFields")
0095   expect_fields(2)
0096 
0097   reg = $2
0098 
0099   res0 = "UL(0)"
0100   res1 = "UL(0)"
0101 
0102   next_bit = 63
0103 
0104   next
0105 }
0106 
0107 /^EndSysregFields/ {
0108   if (next_bit > 0)
0109     fatal("Unspecified bits in " reg)
0110 
0111   change_block("EndSysregFields", "SysregFields", "None")
0112 
0113   define(reg "_RES0", "(" res0 ")")
0114   define(reg "_RES1", "(" res1 ")")
0115   print ""
0116 
0117   reg = null
0118   res0 = null
0119   res1 = null
0120 
0121   next
0122 }
0123 
0124 /^Sysreg/ {
0125   change_block("Sysreg", "None", "Sysreg")
0126   expect_fields(7)
0127 
0128   reg = $2
0129   op0 = $3
0130   op1 = $4
0131   crn = $5
0132   crm = $6
0133   op2 = $7
0134 
0135   res0 = "UL(0)"
0136   res1 = "UL(0)"
0137 
0138   define("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
0139   define("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
0140 
0141   define("SYS_" reg "_Op0", op0)
0142   define("SYS_" reg "_Op1", op1)
0143   define("SYS_" reg "_CRn", crn)
0144   define("SYS_" reg "_CRm", crm)
0145   define("SYS_" reg "_Op2", op2)
0146 
0147   print ""
0148 
0149   next_bit = 63
0150 
0151   next
0152 }
0153 
0154 /^EndSysreg/ {
0155   if (next_bit > 0)
0156     fatal("Unspecified bits in " reg)
0157 
0158   change_block("EndSysreg", "Sysreg", "None")
0159 
0160   if (res0 != null)
0161     define(reg "_RES0", "(" res0 ")")
0162   if (res1 != null)
0163     define(reg "_RES1", "(" res1 ")")
0164   if (res0 != null || res1 != null)
0165     print ""
0166 
0167   reg = null
0168   op0 = null
0169   op1 = null
0170   crn = null
0171   crm = null
0172   op2 = null
0173   res0 = null
0174   res1 = null
0175 
0176   next
0177 }
0178 
0179 # Currently this is effectivey a comment, in future we may want to emit
0180 # defines for the fields.
0181 /^Fields/ && (block == "Sysreg") {
0182   expect_fields(2)
0183 
0184   if (next_bit != 63)
0185     fatal("Some fields already defined for " reg)
0186 
0187   print "/* For " reg " fields see " $2 " */"
0188   print ""
0189 
0190         next_bit = 0
0191   res0 = null
0192   res1 = null
0193 
0194   next
0195 }
0196 
0197 
0198 /^Res0/ && (block == "Sysreg" || block == "SysregFields") {
0199   expect_fields(2)
0200   parse_bitdef(reg, "RES0", $2)
0201   field = "RES0_" msb "_" lsb
0202 
0203   res0 = res0 " | GENMASK_ULL(" msb ", " lsb ")"
0204 
0205   next
0206 }
0207 
0208 /^Res1/ && (block == "Sysreg" || block == "SysregFields") {
0209   expect_fields(2)
0210   parse_bitdef(reg, "RES1", $2)
0211   field = "RES1_" msb "_" lsb
0212 
0213   res1 = res1 " | GENMASK_ULL(" msb ", " lsb ")"
0214 
0215   next
0216 }
0217 
0218 /^Field/ && (block == "Sysreg" || block == "SysregFields") {
0219   expect_fields(3)
0220   field = $3
0221   parse_bitdef(reg, field, $2)
0222 
0223   define_field(reg, field, msb, lsb)
0224   print ""
0225 
0226   next
0227 }
0228 
0229 /^Raz/ && (block == "Sysreg" || block == "SysregFields") {
0230   expect_fields(2)
0231   parse_bitdef(reg, field, $2)
0232 
0233   next
0234 }
0235 
0236 /^Enum/ {
0237   change_block("Enum", "Sysreg", "Enum")
0238   expect_fields(3)
0239   field = $3
0240   parse_bitdef(reg, field, $2)
0241 
0242   define_field(reg, field, msb, lsb)
0243 
0244   next
0245 }
0246 
0247 /^EndEnum/ {
0248   change_block("EndEnum", "Enum", "Sysreg")
0249   field = null
0250   msb = null
0251   lsb = null
0252   print ""
0253   next
0254 }
0255 
0256 /0b[01]+/ && block == "Enum" {
0257   expect_fields(2)
0258   val = $1
0259   name = $2
0260 
0261   define(reg "_" field "_" name, "UL(" val ")")
0262   next
0263 }
0264 
0265 # Any lines not handled by previous rules are unexpected
0266 {
0267   fatal("unhandled statement")
0268 }