cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gen-sysreg.awk (5184B)


      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# Log an error and terminate
      8function fatal(msg) {
      9	print "Error at " NR ": " msg > "/dev/stderr"
     10	exit 1
     11}
     12
     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
     19function change_block(this, prev, new) {
     20	if (block != prev)
     21		fatal("unexpected " this " (inside " block ")")
     22
     23	block = new
     24}
     25
     26# Sanity check the number of records for a field makes sense. If not, produce
     27# an error and terminate.
     28function expect_fields(nf) {
     29	if (NF != nf)
     30		fatal(NF " fields found where " nf " expected")
     31}
     32
     33# Print a CPP macro definition, padded with spaces so that the macro bodies
     34# line up in a column
     35function define(name, val) {
     36	printf "%-48s%s\n", "#define " name, val
     37}
     38
     39# Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field
     40function define_field(reg, field, msb, lsb) {
     41	define(reg "_" field, "GENMASK(" msb ", " lsb ")")
     42	define(reg "_" field "_MASK", "GENMASK(" msb ", " lsb ")")
     43	define(reg "_" field "_SHIFT", lsb)
     44	define(reg "_" field "_WIDTH", msb - lsb + 1)
     45}
     46
     47# Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb
     48function parse_bitdef(reg, field, bitdef, _bits)
     49{
     50	if (bitdef ~ /^[0-9]+$/) {
     51		msb = bitdef
     52		lsb = bitdef
     53	} else if (split(bitdef, _bits, ":") == 2) {
     54		msb = _bits[1]
     55		lsb = _bits[2]
     56	} else {
     57		fatal("invalid bit-range definition '" bitdef "'")
     58	}
     59
     60
     61	if (msb != next_bit)
     62		fatal(reg "." field " starts at " msb " not " next_bit)
     63	if (63 < msb || msb < 0)
     64		fatal(reg "." field " invalid high bit in '" bitdef "'")
     65	if (63 < lsb || lsb < 0)
     66		fatal(reg "." field " invalid low bit in '" bitdef "'")
     67	if (msb < lsb)
     68		fatal(reg "." field " invalid bit-range '" bitdef "'")
     69	if (low > high)
     70		fatal(reg "." field " has invalid range " high "-" low)
     71
     72	next_bit = lsb - 1
     73}
     74
     75BEGIN {
     76	print "#ifndef __ASM_SYSREG_DEFS_H"
     77	print "#define __ASM_SYSREG_DEFS_H"
     78	print ""
     79	print "/* Generated file - do not edit */"
     80	print ""
     81
     82	block = "None"
     83}
     84
     85END {
     86	print "#endif /* __ASM_SYSREG_DEFS_H */"
     87}
     88
     89# skip blank lines and comment lines
     90/^$/ { next }
     91/^#/ { next }
     92
     93/^SysregFields/ {
     94	change_block("SysregFields", "None", "SysregFields")
     95	expect_fields(2)
     96
     97	reg = $2
     98
     99	res0 = "UL(0)"
    100	res1 = "UL(0)"
    101
    102	next_bit = 63
    103
    104	next
    105}
    106
    107/^EndSysregFields/ {
    108	if (next_bit > 0)
    109		fatal("Unspecified bits in " reg)
    110
    111	change_block("EndSysregFields", "SysregFields", "None")
    112
    113	define(reg "_RES0", "(" res0 ")")
    114	define(reg "_RES1", "(" res1 ")")
    115	print ""
    116
    117	reg = null
    118	res0 = null
    119	res1 = null
    120
    121	next
    122}
    123
    124/^Sysreg/ {
    125	change_block("Sysreg", "None", "Sysreg")
    126	expect_fields(7)
    127
    128	reg = $2
    129	op0 = $3
    130	op1 = $4
    131	crn = $5
    132	crm = $6
    133	op2 = $7
    134
    135	res0 = "UL(0)"
    136	res1 = "UL(0)"
    137
    138	define("REG_" reg, "S" op0 "_" op1 "_C" crn "_C" crm "_" op2)
    139	define("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
    140
    141	define("SYS_" reg "_Op0", op0)
    142	define("SYS_" reg "_Op1", op1)
    143	define("SYS_" reg "_CRn", crn)
    144	define("SYS_" reg "_CRm", crm)
    145	define("SYS_" reg "_Op2", op2)
    146
    147	print ""
    148
    149	next_bit = 63
    150
    151	next
    152}
    153
    154/^EndSysreg/ {
    155	if (next_bit > 0)
    156		fatal("Unspecified bits in " reg)
    157
    158	change_block("EndSysreg", "Sysreg", "None")
    159
    160	if (res0 != null)
    161		define(reg "_RES0", "(" res0 ")")
    162	if (res1 != null)
    163		define(reg "_RES1", "(" res1 ")")
    164	if (res0 != null || res1 != null)
    165		print ""
    166
    167	reg = null
    168	op0 = null
    169	op1 = null
    170	crn = null
    171	crm = null
    172	op2 = null
    173	res0 = null
    174	res1 = null
    175
    176	next
    177}
    178
    179# Currently this is effectivey a comment, in future we may want to emit
    180# defines for the fields.
    181/^Fields/ && (block == "Sysreg") {
    182	expect_fields(2)
    183
    184	if (next_bit != 63)
    185		fatal("Some fields already defined for " reg)
    186
    187	print "/* For " reg " fields see " $2 " */"
    188	print ""
    189
    190        next_bit = 0
    191	res0 = null
    192	res1 = null
    193
    194	next
    195}
    196
    197
    198/^Res0/ && (block == "Sysreg" || block == "SysregFields") {
    199	expect_fields(2)
    200	parse_bitdef(reg, "RES0", $2)
    201	field = "RES0_" msb "_" lsb
    202
    203	res0 = res0 " | GENMASK_ULL(" msb ", " lsb ")"
    204
    205	next
    206}
    207
    208/^Res1/ && (block == "Sysreg" || block == "SysregFields") {
    209	expect_fields(2)
    210	parse_bitdef(reg, "RES1", $2)
    211	field = "RES1_" msb "_" lsb
    212
    213	res1 = res1 " | GENMASK_ULL(" msb ", " lsb ")"
    214
    215	next
    216}
    217
    218/^Field/ && (block == "Sysreg" || block == "SysregFields") {
    219	expect_fields(3)
    220	field = $3
    221	parse_bitdef(reg, field, $2)
    222
    223	define_field(reg, field, msb, lsb)
    224	print ""
    225
    226	next
    227}
    228
    229/^Raz/ && (block == "Sysreg" || block == "SysregFields") {
    230	expect_fields(2)
    231	parse_bitdef(reg, field, $2)
    232
    233	next
    234}
    235
    236/^Enum/ {
    237	change_block("Enum", "Sysreg", "Enum")
    238	expect_fields(3)
    239	field = $3
    240	parse_bitdef(reg, field, $2)
    241
    242	define_field(reg, field, msb, lsb)
    243
    244	next
    245}
    246
    247/^EndEnum/ {
    248	change_block("EndEnum", "Enum", "Sysreg")
    249	field = null
    250	msb = null
    251	lsb = null
    252	print ""
    253	next
    254}
    255
    256/0b[01]+/ && block == "Enum" {
    257	expect_fields(2)
    258	val = $1
    259	name = $2
    260
    261	define(reg "_" field "_" name, "UL(" val ")")
    262	next
    263}
    264
    265# Any lines not handled by previous rules are unexpected
    266{
    267	fatal("unhandled statement")
    268}