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:
parent
3b2120f500
commit
1d3731f1e5
2 changed files with 133 additions and 1 deletions
10
Makefile
10
Makefile
|
@ -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
124
scripts/gen_syscall_header.py
Executable 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")
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue