9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit ef1f6e02acac83f1c32800a25739183bdeb2bed7
parent 5360a03924e8be5e9b17ec750fa442fc93eb0161
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Wed, 10 Oct 2018 15:17:52 +0100

Add scripts for rscb code generation from json files

Diffstat:
Ainclude/.gitignore | 1+
Dinclude/types.h | 10----------
Ascripts/gencode.sh | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ascripts/genheaders.sh | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ascripts/genrscb.sh | 28++++++++++++++++++++++++++++
Mscripts/gentbl.sh | 1-
Ascripts/jinc.sh | 46++++++++++++++++++++++++++++++++++++++++++++++
Ascripts/rscb.sh | 23+++++++++++++++++++++++
Mscripts/rules.mk | 1+
Asrc/libtypes/.gitignore | 1+
Msrc/libtypes/Makefile | 11+++++++++++
Asrc/libtypes/gendep.sh | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 368 insertions(+), 11 deletions(-)

diff --git a/include/.gitignore b/include/.gitignore @@ -0,0 +1 @@ +types.h diff --git a/include/types.h b/include/types.h @@ -1,10 +0,0 @@ -#if __GNUC__ || __clang__ -#define UNPACKFMT __attribute__ ((format (scanf, 2, 3))) -#define PACKFMT __attribute__ ((format (printf, 2, 3))) -#else -#define UNPACKFMT -#define PACKFMT -#endif - -extern int unpack(uint64_t buf[], const char *fmt, ...) UNPACKFMT; -extern int pack(uint64_t buf[], const char *fmt, ...) PACKFMT; diff --git a/scripts/gencode.sh b/scripts/gencode.sh @@ -0,0 +1,113 @@ +#/bin/sh + +sed '/prototypes/q' "$@" | +awk ' +BEGIN {RS=""; FS="\n"} +/^struct/ {split($1, w, " "); parse(w[2])} +END {for (tag in structs) { + gen("pack", tag) + gen("unpack", tag)}} + +function parse(tag, fldnam,nfields,i,j,v,typ) +{ + nfields = 0 + for (i = 2; i < NF; i++) { + split($i, v, "#") + nbits = int(v[2]) + + sub(/^[ \t]*/, "", $i) + sub(/;.*/, "", $i) + n = split($i, v, /[ \t]*/) + + fldnam = v[n] + typ = "" + for (j = 1; j < n; j++) { + if (typ != "") + typ = typ " " + typ = typ v[j] + } + fields[tag, nfields++] = typ SUBSEP fldnam SUBSEP nbits + } + structs[tag] = nfields +} + +function buildfmt(tag, i,v,typ,nbits,fmt) +{ + for (i = 0; i < structs[tag]; i++) { + split(fields[tag, i], v, SUBSEP) + typ = v[1] + nbits = v[3] + if (typ ~ "struct") + fmt = fmt buildfmt(substr(typ, 8)) + else if (typ ~ /unsigned char/) + fmt = fmt "%" nbits "c " + else if (typ ~ /unsigned short/) + fmt = fmt "%" nbits "hu " + else if (typ ~ /unsigned long long/) + fmt = fmt "%" nbits "llu " + else if (typ ~ /unsigned long/) + fmt = fmt "%" nbits "lu " + } + return fmt +} + +function printfmt(tag,file, fmt,n,i,j,v) +{ + fmt = buildfmt(tag) + sub(/ *$/, "", fmt) + n = split(fmt, v, / /) + + for (i = 1; i <= n; i += 7) { + fmt = "" + for (j = 0; j < 7 && i + j <= n; j++) { + if (fmt != "") + fmt = fmt " " + fmt = fmt v[i+j] + } + printf("\t \"%s\"%s", + fmt, (i+7 < n) ? "\n" : ",\n") >> file + } +} + +function gen(fun, tag, file) +{ + file = fun "_" tag ".c" + + printf("#include <assert.h>\n"\ + "#include <stdint.h>\n\n"\ + "#include <types.h>\n"\ + "#include <arch/machine.h>\n\n"\ + "int\n"\ + "%s_%s(uint64_t buf[], struct %s *sp)\n"\ + "{\n"\ + "\tint n;\n\n"\ + "\tn = %s(buf,\n", fun, tag, tag, fun) > file + + printfmt(tag, file) + printargs(fun, tag, "", file) + + print ");\n\n\tassert(n == sizeof(*sp));\n\n"\ + "\treturn n;\n"\ + "}" >> file + + close(file) +} + +function printargs(fun,tag,prefix,file, i,v,typ,fldnam) +{ + for (i = 0; i < structs[tag]; i++) { + split(fields[tag, i], v, SUBSEP) + fldnam = v[2] + typ = v[1] + if (typ ~ "struct") { + printargs(fun, substr(typ, 8), prefix fldnam ".", file) + } else { + printf("\t %ssp->%s%s", + (fun == "unpack") ? "&" : "", + prefix, fldnam) >> file + } + if (i != structs[tag]-1) + print "," >> file + } +} +' diff --git a/scripts/genheaders.sh b/scripts/genheaders.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +awk ' +/^[^\t]/ {struct = $1; nbits = 1} + +/^\t[^\t]/ {if (fldname != "") + fldname = fldname "#" + fldname = fldname $1 + fldsize[$1] = $2 + fldbegin[$1] = nbits + last = $1 + next} + +/^\t\t/ {bitnam[nbits] = $1 + bitset[nbits] = $2 + fldcnt[last]++ + nbits++} + +END {split(fldname, names, "#") + gentypes() + genstruct() + genprotos()} + +function genprotos( t) +{ + print "/* prototypes */" + for (t in list) { + printf("extern int pack_%s(uint64_t buf[], struct %s *sp);\n"\ + "extern int unpack_%s(uint64_t buf[], struct %s *sp);\n\n", + t, t, t, t); + } +} + +function gentypes( f,bs,n,fld,off,res,i,name) +{ + for (f in names) { + fld = names[f] + if (fldcnt[fld] == 1) + continue + off = fldbegin[fld] + res = 0 + + print "struct " struct "_" fld " {" + for (i = 0; i < fldcnt[fld]; i++) { + n = off + i + name = bitnam[n] + if (name == "res0") + name = "res0_" res++ + bs = bitset[n] + printf("\t%s %s;\t\t//#%d\n", type(bs), name, getbits(bs)) + } + print "};\n" + list[struct "_" fld] = 1 + } +} + +function genstruct( f,fld,t,s,bs) +{ + printf("struct %s {\n", struct) + for (f in names) { + fld = names[f] + s = fldsize[fld] + t = (fldcnt[fld] == 1) ? type(s) : "struct rscb_" fld + printf("\t%s %s;\t\t//#%d\n", t, fld, s) + } + print "};\n" +} + + +function getbits(desc, arr,n) +{ + n = split(desc, arr, ":") + if (n == 1) + return 1 + return arr[1] - arr[2] +} + +function type(desc, siz) +{ + siz = getbits(desc) + + if (siz <= 8) + return "unsigned char" + if (siz <= 16) + return "unsigned short" + if (siz <= 32) + return "unsigned long" + if (siz <= 64) + return "unsigned long long" + print "error" +} +' "$@" diff --git a/scripts/genrscb.sh b/scripts/genrscb.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +set -e +trap 'rm -f pack_*.c unpack_*.c rscb.h;exit 1' HUP INT QUIT + +for i +do + case $i in + -j) + jsondir="-I $2" + shift 2 + ;; + --) + shift + ;; + -*) + echo usage: genrscb.sh [-j jsondir] [file] >&2 + exit 1 + ;; + esac +done + +jinc.sh $jsondir "$@" | +rscb.sh | +tr 'A-Z' 'a-z' | +genheaders.sh | +tee rscb.h | +gencode.sh diff --git a/scripts/gentbl.sh b/scripts/gentbl.sh @@ -19,7 +19,6 @@ do shift ;; -*) - echo i=$i echo usage: gentbl.sh [-o file] >&2 exit 1 ;; diff --git a/scripts/jinc.sh b/scripts/jinc.sh @@ -0,0 +1,46 @@ +#!/bin/sh + + +include="." + +for i +do + case $i in + -I) + include=$2 + shift 2 + ;; + --) + shift + ;; + -*) + echo usage: jinc.sh [-I dir] [file] >&2 + exit 1 + ;; + esac +done + +awk -v inc=$include ' +match($0, /"_include" *: *"[^"]*"/) { + pre = substr($0, 1, RSTART-1) + post = substr($0, RSTART+RLENGTH) + incl = substr($0, RSTART, RLENGTH) + + + split(incl, v, /:/) + incl = v[2] + gsub(/ *" */, "", incl) + nf = split(incl, v, /\//) + + file = v[nf] + dir = inc + for (i = 1; i < nf; i++) + dir = dir "/" v[i] + + print pre, "\"_include\":" + system("cd " dir " && jinc.sh " file) + print post + + next +} + {print}' "$@" diff --git a/scripts/rscb.sh b/scripts/rscb.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +jq -r ' +.register_blocks[0]._include | +{name, + registers: .registers | + map(._include) | + map({name, fieldsets: .fieldsets | + map({width, + values: .values | + map({name, value, rangeset})})})} | +.name, +(.registers | + map("\t" + + (.name | ltrimstr("RSCB_")) + + "\t" + (.fieldsets[0].width | tostring), + (.fieldsets | + map(.values | + map("\t\t\t" + + .name + + .value + + "\t" + + .rangeset)[])[])))[]' diff --git a/scripts/rules.mk b/scripts/rules.mk @@ -7,6 +7,7 @@ BINDIR = $(PROJECTDIR)/bin ARCHDIR = $(PROJECTDIR)/arch/$(ARCH) SRCDIR = $(PROJECTDIR)/src SCRIPTDIR= $(PROJECTDIR)/scripts +JSONDIR = $(PROJECTDIR)/json INCLUDES = -I$(INCDIR) -I$(INCDIR)/bits/$(ARCH)/ -I$(INCDIR)/bits/$(SYS) RCODE_CFLAGS = $(MORECFLAGS) \ diff --git a/src/libtypes/.gitignore b/src/libtypes/.gitignore @@ -0,0 +1 @@ +rscb.h diff --git a/src/libtypes/Makefile b/src/libtypes/Makefile @@ -2,12 +2,23 @@ PROJECTDIR=../.. include $(PROJECTDIR)/scripts/rules.mk OBJS = pack.o unpack.o + +RMSA = $(JSONDIR)/RMSA.json TARGET = $(LIBDIR)/libtypes.a $(TARGET): $(OBJS) all: $(TARGET) +gen: rscb.h FORCE + ./gendep.sh -I $(INCDIR) rscb.h + +rscb.h: $(JSONDIR)/version + PATH=$(SCRIPTDIR):$$PATH genrscb.sh -j $(JSONDIR) $(RMSA) + $(TARGET): $(OBJS) $(AR) $(ARFLAGS) $@ $? ranlib $@ + +clean: + rm -f rscb.h diff --git a/src/libtypes/gendep.sh b/src/libtypes/gendep.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +set -e + +for i +do + case $i in + -I) + inc=$2/ + shift 2 + ;; + --) + shift + ;; + -*) + echo usage: gendep.sh [-I dir] files ... >&2 + exit 1 + esac +done + +tmp=tmp1.$$ +trap 'rm -f $tmp1 $tmp2;exit $?' EXIT HUP INT QUIT + + +(cat <<'EOF' +#if __GNUC__ || __clang__ +#define UNPACKFMT __attribute__ ((format (scanf, 2, 3))) +#define PACKFMT __attribute__ ((format (printf, 2, 3))) +#else +#define UNPACKFMT +#define PACKFMT +#endif + +extern int unpack(uint64_t buf[], const char *fmt, ...) UNPACKFMT; +extern int pack(uint64_t buf[], const char *fmt, ...) PACKFMT; +EOF + +cat "$@") > $tmp && mv $tmp ${inc}types.h + +(echo H +echo '/^OBJS/;/^$/c' +printf 'OBJS = pack.o unpack.o \\\n' +for i +do + sed -n '/prototypes/,$ { + /prototypes/d + /^$/d + s/extern int \(.*\)(.*/ \1.o \\/p + }' $i +done +printf "\n.\nw\n" +) | ed -s Makefile