gen_syscall_header.py: script to generate macros

This header could be maintained by hand since there are no inputs
and it only changes if the generating script is modified, but given
the choice to maintain 800-ish lines of extremely repetitive C
preprocessor code, or 100-ish lines of Python, the choice is pretty
clear.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-09-22 13:52:21 -07:00 committed by Andrew Boie
commit 1d3731f1e5
2 changed files with 133 additions and 1 deletions

View file

@ -1017,6 +1017,14 @@ endif
dts: include/generated/generated_dts_board.h
GEN_SYSCALL_HEADER := $(srctree)/scripts/gen_syscall_header.py
include/generated/syscall_macros.h: $(GEN_SYSCALL_HEADER)
$(Q)mkdir -p $(dir $@)
$(Q)$(GEN_SYSCALL_HEADER) > $@
syscall_macros: include/generated/syscall_macros.h
define filechk_.config-sanitycheck
(cat .config; \
grep -e '^CONFIG' include/generated/generated_dts_board.conf | cat; \
@ -1085,7 +1093,7 @@ archprepare = $(strip \
)
# All the preparing..
prepare: $(archprepare) dts FORCE
prepare: $(archprepare) dts syscall_macros FORCE
$(Q)$(MAKE) $(build)=.
# Generate some files

124
scripts/gen_syscall_header.py Executable file
View file

@ -0,0 +1,124 @@
#!/usr/bin/env python3
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
import sys
def gen_macro(ret, argc, inline=False):
sys.stdout.write("K_SYSCALL_DECLARE%d%s%s(id, name" % (argc,
("" if ret else "_VOID"), ("_INLINE" if inline else "")))
if (ret):
sys.stdout.write(", ret")
for i in range(argc):
sys.stdout.write(", t%d, p%d" % (i, i))
sys.stdout.write(")")
def gen_fn(ret, argc, name, extern=False):
sys.stdout.write("\t%s %s %s(" %
(("extern" if extern else "static inline"),
("ret" if ret else "void"), name))
if argc == 0:
sys.stdout.write("void");
else:
for i in range(argc):
sys.stdout.write("t%d p%d" % (i, i))
if i != (argc - 1):
sys.stdout.write(", ")
sys.stdout.write(")")
def gen_make_syscall(ret, argc):
if (ret):
sys.stdout.write("return (ret)")
if (argc <= 6):
sys.stdout.write("_arch")
sys.stdout.write("_syscall_invoke%d(" % (argc))
for i in range(argc):
sys.stdout.write("(u32_t)p%d, " % (i))
sys.stdout.write("id); \\\n")
def gen_call_impl(ret, argc):
if (ret):
sys.stdout.write("return ")
sys.stdout.write("_impl_##name(")
for i in range(argc):
sys.stdout.write("p%d" % (i))
if i != (argc - 1):
sys.stdout.write(", ")
sys.stdout.write("); \\\n")
def newline():
sys.stdout.write(" \\\n")
def gen_defines_inner(ret, argc, kernel_only=False, user_only=False):
sys.stdout.write("#define ")
gen_macro(ret, argc, inline=True)
newline()
if not user_only:
sys.stdout.write("\textern u32_t _handler_##name(u32_t, u32_t, u32_t, u32_t, u32_t, u32_t, void *); \\\n")
gen_fn(ret, argc, "name");
newline()
sys.stdout.write("\t{")
newline()
if kernel_only:
sys.stdout.write("\t\t")
gen_call_impl(ret, argc)
elif user_only:
sys.stdout.write("\t\t")
gen_make_syscall(ret, argc)
else:
sys.stdout.write("\t\tif (_is_user_context()) {")
newline()
sys.stdout.write("\t\t\t")
gen_make_syscall(ret, argc)
sys.stdout.write("\t\t} else {")
newline()
sys.stdout.write("\t\t\t")
gen_call_impl(ret, argc)
sys.stdout.write("\t\t}")
newline()
sys.stdout.write("\t}\n\n")
sys.stdout.write("#define ")
gen_macro(ret, argc)
newline()
if not user_only:
gen_fn(ret, argc, "_impl_##name", extern=True)
sys.stdout.write(";")
newline()
sys.stdout.write("\t")
gen_macro(ret, argc, inline=True)
sys.stdout.write(";\n\n")
def gen_defines(argc, kernel_only=False, user_only=False):
gen_defines_inner(False, argc, kernel_only, user_only)
gen_defines_inner(True, argc, kernel_only, user_only)
sys.stdout.write("/* Auto-generated by gen_syscall_header.py, do not edit! */\n\n")
sys.stdout.write("#ifndef GEN_SYSCALL_H\n#define GEN_SYSCALL_H\n\n")
for i in range(11):
sys.stdout.write("#if !defined(CONFIG_USERSPACE) || defined(__ZEPHYR_KERNEL__)\n")
gen_defines(i, kernel_only=True)
sys.stdout.write("#elif defined(__ZEPHYR_USER__)\n")
gen_defines(i, user_only=True)
sys.stdout.write("#else /* mixed kernel/user macros */\n")
gen_defines(i)
sys.stdout.write("#endif /* mixed kernel/user macros */\n\n")
sys.stdout.write("#endif /* GEN_SYSCALL_H */\n")