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:
parent
5008fedc92
commit
3ff41b9484
3 changed files with 52 additions and 11 deletions
|
@ -243,6 +243,21 @@ static inline u32_t _syscall_invoke10(u32_t arg1, u32_t arg2, u32_t arg3,
|
||||||
call_id);
|
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 */
|
#endif /* CONFIG_USERSPACE */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -5,11 +5,23 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class Retval(Enum):
|
||||||
|
VOID = 0
|
||||||
|
U32 = 1
|
||||||
|
U64 = 2
|
||||||
|
|
||||||
def gen_macro(ret, argc):
|
def gen_macro(ret, argc):
|
||||||
sys.stdout.write("K_SYSCALL_DECLARE%d%s(id, name" % (argc,
|
if ret == Retval.VOID:
|
||||||
("" if ret else "_VOID")))
|
suffix = "_VOID"
|
||||||
if (ret):
|
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")
|
sys.stdout.write(", ret")
|
||||||
for i in range(argc):
|
for i in range(argc):
|
||||||
sys.stdout.write(", t%d, p%d" % (i, i))
|
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):
|
def gen_fn(ret, argc, name, extern=False):
|
||||||
sys.stdout.write("\t%s %s %s(" %
|
sys.stdout.write("\t%s %s %s(" %
|
||||||
(("extern" if extern else "static inline"),
|
(("extern" if extern else "static inline"),
|
||||||
("ret" if ret else "void"), name))
|
("ret" if ret != Retval.VOID else "void"), name))
|
||||||
if argc == 0:
|
if argc == 0:
|
||||||
sys.stdout.write("void");
|
sys.stdout.write("void");
|
||||||
else:
|
else:
|
||||||
|
@ -29,17 +41,18 @@ def gen_fn(ret, argc, name, extern=False):
|
||||||
sys.stdout.write(")")
|
sys.stdout.write(")")
|
||||||
|
|
||||||
def gen_make_syscall(ret, argc):
|
def gen_make_syscall(ret, argc):
|
||||||
if (ret):
|
if (ret != Retval.VOID):
|
||||||
sys.stdout.write("return (ret)")
|
sys.stdout.write("return (ret)")
|
||||||
if (argc <= 6):
|
if (argc <= 6 and ret != Retval.U64):
|
||||||
sys.stdout.write("_arch")
|
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):
|
for i in range(argc):
|
||||||
sys.stdout.write("(u32_t)p%d, " % (i))
|
sys.stdout.write("(u32_t)p%d, " % (i))
|
||||||
sys.stdout.write("id); \\\n")
|
sys.stdout.write("id); \\\n")
|
||||||
|
|
||||||
def gen_call_impl(ret, argc):
|
def gen_call_impl(ret, argc):
|
||||||
if (ret):
|
if (ret != Retval.VOID):
|
||||||
sys.stdout.write("return ")
|
sys.stdout.write("return ")
|
||||||
sys.stdout.write("_impl_##name(")
|
sys.stdout.write("_impl_##name(")
|
||||||
for i in range(argc):
|
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")
|
sys.stdout.write("\t}\n\n")
|
||||||
|
|
||||||
|
|
||||||
def gen_defines(argc, kernel_only=False, user_only=False):
|
def gen_defines(argc, kernel_only=False, user_only=False):
|
||||||
gen_defines_inner(False, argc, kernel_only, user_only)
|
gen_defines_inner(Retval.VOID, argc, kernel_only, user_only)
|
||||||
gen_defines_inner(True, 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("/* Auto-generated by gen_syscall_header.py, do not edit! */\n\n")
|
||||||
|
|
|
@ -55,12 +55,23 @@ def analyze_fn(match_group, fn):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
sys_id = "K_SYSCALL_" + func_name.upper()
|
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")
|
is_void = (func_type == "void")
|
||||||
|
|
||||||
# Get the proper system call macro invocation, which depends on the
|
# Get the proper system call macro invocation, which depends on the
|
||||||
# number of arguments, the return type, and whether the implementation
|
# number of arguments, the return type, and whether the implementation
|
||||||
# is an inline function
|
# 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
|
# Flatten the argument lists and generate a comma separated list
|
||||||
# of t0, p0, t1, p1, ... tN, pN as expected by the macros
|
# of t0, p0, t1, p1, ... tN, pN as expected by the macros
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue