You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.6 KiB
134 lines
3.6 KiB
#!/usr/bin/env python3 |
|
# |
|
# Copyright (c) 2017 Intel Corporation |
|
# |
|
# SPDX-License-Identifier: Apache-2.0 |
|
|
|
import sys |
|
from enum import Enum |
|
|
|
class Retval(Enum): |
|
VOID = 0 |
|
U32 = 1 |
|
U64 = 2 |
|
|
|
def gen_macro(ret, argc): |
|
if ret == Retval.VOID: |
|
suffix = "_VOID" |
|
elif ret == Retval.U64: |
|
suffix = "_RET64" |
|
else: |
|
suffix = "" |
|
|
|
sys.stdout.write("K_SYSCALL_DECLARE%d%s(id, name" % (argc, suffix)) |
|
if (ret != Retval.VOID): |
|
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 != Retval.VOID 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 != Retval.VOID): |
|
sys.stdout.write("return (ret)") |
|
if (argc <= 6 and ret != Retval.U64): |
|
sys.stdout.write("_arch") |
|
sys.stdout.write("_syscall%s_invoke%d(" % |
|
(("_ret64" if ret == Retval.U64 else ""), 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 != Retval.VOID): |
|
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) |
|
newline() |
|
|
|
if not user_only: |
|
gen_fn(ret, argc, "_impl_##name", extern=True) |
|
sys.stdout.write(";") |
|
newline() |
|
|
|
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() |
|
|
|
# Prevent memory access issues if the implementation function gets |
|
# inlined |
|
sys.stdout.write("\t\t\tcompiler_barrier();"); |
|
newline() |
|
|
|
sys.stdout.write("\t\t\t") |
|
gen_call_impl(ret, argc) |
|
sys.stdout.write("\t\t}") |
|
newline() |
|
|
|
sys.stdout.write("\t}\n\n") |
|
|
|
|
|
def gen_defines(argc, kernel_only=False, user_only=False): |
|
gen_defines_inner(Retval.VOID, argc, kernel_only, user_only) |
|
gen_defines_inner(Retval.U32, argc, kernel_only, user_only) |
|
gen_defines_inner(Retval.U64, 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_SUPERVISOR__)\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") |
|
|
|
|
|
|
|
|
|
|
|
|