kernel: allow system call with 64-bit return val

This is subject to the constraint that such system calls must have a
return value which is "u64_t" or "s64_t".

So far all the relevant kernel calls just have zero or one arguments,
we can later add more _syscall_ret64_invokeN() APIs as needed.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-10-08 12:20:24 -07:00 committed by Andrew Boie
commit 3ff41b9484
3 changed files with 52 additions and 11 deletions

View file

@ -243,6 +243,21 @@ static inline u32_t _syscall_invoke10(u32_t arg1, u32_t arg2, u32_t arg3,
call_id);
}
static inline u64_t _syscall_ret64_invoke0(u32_t call_id)
{
u64_t ret;
_arch_syscall_invoke1((u32_t)&ret, call_id);
return ret;
}
static inline u64_t _syscall_ret64_invoke1(u32_t arg1, u32_t call_id)
{
u64_t ret;
_arch_syscall_invoke2(arg1, (u32_t)&ret, call_id);
return ret;
}
#endif /* CONFIG_USERSPACE */
#ifdef __cplusplus

View file

@ -5,11 +5,23 @@
# 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):
sys.stdout.write("K_SYSCALL_DECLARE%d%s(id, name" % (argc,
("" if ret else "_VOID")))
if (ret):
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))
@ -18,7 +30,7 @@ def gen_macro(ret, argc):
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))
("ret" if ret != Retval.VOID else "void"), name))
if argc == 0:
sys.stdout.write("void");
else:
@ -29,17 +41,18 @@ def gen_fn(ret, argc, name, extern=False):
sys.stdout.write(")")
def gen_make_syscall(ret, argc):
if (ret):
if (ret != Retval.VOID):
sys.stdout.write("return (ret)")
if (argc <= 6):
if (argc <= 6 and ret != Retval.U64):
sys.stdout.write("_arch")
sys.stdout.write("_syscall_invoke%d(" % (argc))
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):
if (ret != Retval.VOID):
sys.stdout.write("return ")
sys.stdout.write("_impl_##name(")
for i in range(argc):
@ -89,9 +102,11 @@ def gen_defines_inner(ret, argc, kernel_only=False, user_only=False):
sys.stdout.write("\t}\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)
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")

View file

@ -55,12 +55,23 @@ def analyze_fn(match_group, fn):
raise
sys_id = "K_SYSCALL_" + func_name.upper()
if func_type == "void":
suffix = "_VOID"
is_void = True
else:
is_void = False
if func_type in ["s64_t", "u64_t"]:
suffix = "_RET64"
else:
suffix = ""
is_void = (func_type == "void")
# Get the proper system call macro invocation, which depends on the
# number of arguments, the return type, and whether the implementation
# is an inline function
macro = "K_SYSCALL_DECLARE%d%s" % (len(args), "_VOID" if is_void else "")
macro = "K_SYSCALL_DECLARE%d%s" % (len(args), suffix)
# Flatten the argument lists and generate a comma separated list
# of t0, p0, t1, p1, ... tN, pN as expected by the macros