/*
 * Copyright (c) 2017, Intel Corporation
 *
 * SPDX-License-Identifier: Apache 2.0
 */


#ifndef _ZEPHYR_SYSCALL_H_
#define _ZEPHYR_SYSCALL_H_

#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
#include <syscall_list.h>
#include <syscall_macros.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * System Call Declaration macros
 *
 * These macros are used in public header files to declare system calls.
 * They generate inline functions which have different implementations
 * depending on the current compilation context:
 *
 * - Kernel-only code, or CONFIG_USERSPACE disabled, these inlines will
 *   directly call the implementation
 * - User-only code, these inlines will marshal parameters and elevate
 *   privileges
 * - Mixed or indeterminate code, these inlines will do a runtime check
 *   to determine what course of action is needed.
 *
 * All system calls require a handler function and an implementation function.
 * These must follow a naming convention. For a system call named k_foo():
 *
 * - The handler function will be named _handler_k_foo(). Handler functions
 *   are always of type _k_syscall_handler_t, verify arguments passed up
 *   from userspace, and call the implementation function. See
 *   documentation for that typedef for more information.
 * - The implementation function will be named _impl_k_foo(). This is the
 *   actual implementation of the system call.
 *
 * The basic declartion macros are as follows. System calls with 0 to 10
 * parameters are supported. For a system call with N parameters, that returns
 * a value and is* not implemented inline, the macro is as follows (N noted
 * as {N} for clarity):
 *
 * K_SYSCALL_DECLARE{N}(id, name, ret, t0, p0, ... , t{N-1}, p{N-1})

 * @param id System call ID, one of K_SYSCALL_* defines
 * @param name Symbol name of the system call used to invoke it
 * @param ret Data type of return value
 * @param tX Data type of parameter X
 * @param pX Name of parameter x
 *
 * For system calls that return no value:
 *
 * K_SYSCALL_DECLARE{n}_VOID(id, name, t0, p0, .... , t{N-1}, p{N-1})
 *
 * This is identical to above except there is no 'ret' parameter.
 *
 * For system calls where the implementation is an inline function, we have
 *
 * K_SYSCALL_DECLARE{n}_INLINE(id, name, ret, t0, p0, ... , t{N-1}, p{N-1})
 * K_SYSCALL_DECLARE{n}_VOID_INLINE(id, name, t0, p0, ... , t{N-1}, p{N-1})
 *
 * These are used in the same way as their non-INLINE counterparts.
 *
 * These macros are generated by scripts/gen_syscall_header.py and can be
 * found in $OUTDIR/include/generated/syscall_macros.h
 */

/**
 * @typedef _k_syscall_handler_t
 * @brief System call handler function type
 *
 * These are kernel-side skeleton functions for system calls. They are
 * necessary to sanitize the arguments passed into the system call:
 *
 * - Any kernel object or device pointers are validated with _SYSCALL_IS_OBJ()
 * - Any memory buffers passed in are checked to ensure that the calling thread
 *   actually has access to them
 * - Many kernel calls do no sanity checking of parameters other than
 *   assertions. The handler must check all of these conditions using
 *   _SYSCALL_ASSERT()
 * - If the system call has more than 6 arguments, then arg6 will be a pointer
 *   to some struct containing arguments 6+. The struct itself needs to be
 *   validated like any other buffer passed in from userspace, and its members
 *   individually validated (if necessary) and then passed to the real
 *   implementation like normal arguments
 *
 * Even if the system call implementation has no return value, these always
 * return something, even 0, to prevent register leakage to userspace.
 *
 * Once everything has been validated, the real implementation will be executed.
 *
 * @param arg1 system call argument 1
 * @param arg2 system call argument 2
 * @param arg3 system call argument 3
 * @param arg4 system call argument 4
 * @param arg5 system call argument 5
 * @param arg6 system call argument 6
 * @param ssf System call stack frame pointer. Used to generate kernel oops
 *            via _arch_syscall_oops_at(). Contents are arch-specific.
 * @return system call return value, or 0 if the system call implementation
 *         return void
 *
 */
typedef u32_t (*_k_syscall_handler_t)(u32_t arg1, u32_t arg2, u32_t arg3,
				      u32_t arg4, u32_t arg5, u32_t arg6,
				      void *ssf);
#ifdef CONFIG_USERSPACE

/**
 * Indicate whether we are currently running in user mode
 *
 * @return nonzero if the CPU is currently running with user permissions
 */
static inline int _arch_is_user_context(void);

/**
 * Indicate whether the CPU is currently in user mode
 *
 * @return nonzero if the CPU is currently running with user permissions
 */
static inline int _is_user_context(void)
{
	return _arch_is_user_context();
}

/*
 * Helper data structures for system calls with large argument lists
 */

struct _syscall_7_args {
	u32_t arg6;
	u32_t arg7;
};

struct _syscall_8_args {
	u32_t arg6;
	u32_t arg7;
	u32_t arg8;
};

struct _syscall_9_args {
	u32_t arg6;
	u32_t arg7;
	u32_t arg8;
	u32_t arg9;
};

struct _syscall_10_args {
	u32_t arg6;
	u32_t arg7;
	u32_t arg8;
	u32_t arg9;
	u32_t arg10;
};

/*
 * Interfaces for invoking system calls
 */

static inline u32_t _arch_syscall_invoke0(u32_t call_id);

static inline u32_t _arch_syscall_invoke1(u32_t arg1, u32_t call_id);

static inline u32_t _arch_syscall_invoke2(u32_t arg1, u32_t arg2,
					  u32_t call_id);

static inline u32_t _arch_syscall_invoke3(u32_t arg1, u32_t arg2, u32_t arg3,
					  u32_t call_id);

static inline u32_t _arch_syscall_invoke4(u32_t arg1, u32_t arg2, u32_t arg3,
					  u32_t arg4, u32_t call_id);

static inline u32_t _arch_syscall_invoke5(u32_t arg1, u32_t arg2, u32_t arg3,
					  u32_t arg4, u32_t arg5,
					  u32_t call_id);

static inline u32_t _arch_syscall_invoke6(u32_t arg1, u32_t arg2, u32_t arg3,
					  u32_t arg4, u32_t arg5, u32_t arg6,
					  u32_t call_id);

static inline u32_t _syscall_invoke7(u32_t arg1, u32_t arg2, u32_t arg3,
				    u32_t arg4, u32_t arg5, u32_t arg6,
				    u32_t arg7, u32_t call_id) {
	struct _syscall_7_args args = {
		.arg6 = arg6,
		.arg7 = arg7,
	};

	return _arch_syscall_invoke6(arg1, arg2, arg3, arg4, arg5, (u32_t)&args,
				     call_id);
}

static inline u32_t _syscall_invoke8(u32_t arg1, u32_t arg2, u32_t arg3,
				    u32_t arg4, u32_t arg5, u32_t arg6,
				    u32_t arg7, u32_t arg8, u32_t call_id)
{
	struct _syscall_8_args args = {
		.arg6 = arg6,
		.arg7 = arg7,
		.arg8 = arg8,
	};

	return _arch_syscall_invoke6(arg1, arg2, arg3, arg4, arg5, (u32_t)&args,
				     call_id);
}

static inline u32_t _syscall_invoke9(u32_t arg1, u32_t arg2, u32_t arg3,
				    u32_t arg4, u32_t arg5, u32_t arg6,
				    u32_t arg7, u32_t arg8, u32_t arg9,
				    u32_t call_id)
{
	struct _syscall_9_args args = {
		.arg6 = arg6,
		.arg7 = arg7,
		.arg8 = arg8,
		.arg9 = arg9,
	};

	return _arch_syscall_invoke6(arg1, arg2, arg3, arg4, arg5, (u32_t)&args,
				     call_id);
}

static inline u32_t _syscall_invoke10(u32_t arg1, u32_t arg2, u32_t arg3,
				     u32_t arg4, u32_t arg5, u32_t arg6,
				     u32_t arg7, u32_t arg8, u32_t arg9,
				     u32_t arg10, u32_t call_id)
{
	struct _syscall_10_args args = {
		.arg6 = arg6,
		.arg7 = arg7,
		.arg8 = arg8,
		.arg9 = arg9,
		.arg10 = arg10
	};

	return _arch_syscall_invoke6(arg1, arg2, arg3, arg4, arg5, (u32_t)&args,
				     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
}
#endif

#endif /* _ASMLANGUAGE */

#endif

