kernel: Provide only one _SYSCALL_HANDLER() macro
Use some preprocessor trickery to automatically deduce the amount of arguments for the various _SYSCALL_HANDLERn() macros. Makes the grunt work of converting a bunch of kernel APIs to system calls slightly easier. Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
parent
a39ec5f72c
commit
6f99bdb02a
15 changed files with 56 additions and 42 deletions
|
@ -101,7 +101,7 @@ int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER2(k_alert_recv, alert, timeout)
|
||||
_SYSCALL_HANDLER(k_alert_recv, alert, timeout)
|
||||
{
|
||||
_SYSCALL_OBJ(alert, K_OBJ_ALERT);
|
||||
return _impl_k_alert_recv((struct k_alert *)alert, timeout);
|
||||
|
|
|
@ -277,11 +277,12 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
* the bolierplate. The macros ensure that the seventh argument is named
|
||||
* "ssf" as this is now referenced by various other _SYSCALL macros.
|
||||
*
|
||||
* The different variants here simply depend on how many of the 6 arguments
|
||||
* passed in are really used.
|
||||
* Use the _SYSCALL_HANDLER(name_, arg0, ..., arg6) variant, as it will
|
||||
* automatically deduce the correct version of __SYSCALL_HANDLERn() to
|
||||
* use depending on the number of arguments.
|
||||
*/
|
||||
|
||||
#define _SYSCALL_HANDLER0(name_) \
|
||||
#define __SYSCALL_HANDLER0(name_) \
|
||||
u32_t _handler_ ## name_(u32_t arg1 __unused, \
|
||||
u32_t arg2 __unused, \
|
||||
u32_t arg3 __unused, \
|
||||
|
@ -290,7 +291,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
u32_t arg6 __unused, \
|
||||
void *ssf)
|
||||
|
||||
#define _SYSCALL_HANDLER1(name_, arg1_) \
|
||||
#define __SYSCALL_HANDLER1(name_, arg1_) \
|
||||
u32_t _handler_ ## name_(u32_t arg1_, \
|
||||
u32_t arg2 __unused, \
|
||||
u32_t arg3 __unused, \
|
||||
|
@ -299,7 +300,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
u32_t arg6 __unused, \
|
||||
void *ssf)
|
||||
|
||||
#define _SYSCALL_HANDLER2(name_, arg1_, arg2_) \
|
||||
#define __SYSCALL_HANDLER2(name_, arg1_, arg2_) \
|
||||
u32_t _handler_ ## name_(u32_t arg1_, \
|
||||
u32_t arg2_, \
|
||||
u32_t arg3 __unused, \
|
||||
|
@ -308,7 +309,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
u32_t arg6 __unused, \
|
||||
void *ssf)
|
||||
|
||||
#define _SYSCALL_HANDLER3(name_, arg1_, arg2_, arg3_) \
|
||||
#define __SYSCALL_HANDLER3(name_, arg1_, arg2_, arg3_) \
|
||||
u32_t _handler_ ## name_(u32_t arg1_, \
|
||||
u32_t arg2_, \
|
||||
u32_t arg3_, \
|
||||
|
@ -317,7 +318,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
u32_t arg6 __unused, \
|
||||
void *ssf)
|
||||
|
||||
#define _SYSCALL_HANDLER4(name_, arg1_, arg2_, arg3_, arg4_) \
|
||||
#define __SYSCALL_HANDLER4(name_, arg1_, arg2_, arg3_, arg4_) \
|
||||
u32_t _handler_ ## name_(u32_t arg1_, \
|
||||
u32_t arg2_, \
|
||||
u32_t arg3_, \
|
||||
|
@ -326,7 +327,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
u32_t arg6 __unused, \
|
||||
void *ssf)
|
||||
|
||||
#define _SYSCALL_HANDLER5(name_, arg1_, arg2_, arg3_, arg4_, arg5_) \
|
||||
#define __SYSCALL_HANDLER5(name_, arg1_, arg2_, arg3_, arg4_, arg5_) \
|
||||
u32_t _handler_ ## name_(u32_t arg1_, \
|
||||
u32_t arg2_, \
|
||||
u32_t arg3_, \
|
||||
|
@ -335,7 +336,7 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
u32_t arg6 __unused, \
|
||||
void *ssf)
|
||||
|
||||
#define _SYSCALL_HANDLER6(name_, arg1_, arg2_, arg3_, arg4_, arg5_, arg6_) \
|
||||
#define __SYSCALL_HANDLER6(name_, arg1_, arg2_, arg3_, arg4_, arg5_, arg6_) \
|
||||
u32_t _handler_ ## name_(u32_t arg1_, \
|
||||
u32_t arg2_, \
|
||||
u32_t arg3_, \
|
||||
|
@ -344,6 +345,19 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
u32_t arg6_, \
|
||||
void *ssf)
|
||||
|
||||
#define _SYSCALL_CONCAT(arg1, arg2) __SYSCALL_CONCAT(arg1, arg2)
|
||||
#define __SYSCALL_CONCAT(arg1, arg2) ___SYSCALL_CONCAT(arg1, arg2)
|
||||
#define ___SYSCALL_CONCAT(arg1, arg2) arg1##arg2
|
||||
|
||||
#define _SYSCALL_NARG(...) __SYSCALL_NARG(__VA_ARGS__, __SYSCALL_RSEQ_N())
|
||||
#define __SYSCALL_NARG(...) __SYSCALL_ARG_N(__VA_ARGS__)
|
||||
#define __SYSCALL_ARG_N(_1, _2, _3, _4, _5, _6, _7, N, ...) N
|
||||
#define __SYSCALL_RSEQ_N() 6, 5, 4, 3, 2, 1, 0
|
||||
|
||||
#define _SYSCALL_HANDLER(...) \
|
||||
_SYSCALL_CONCAT(__SYSCALL_HANDLER, \
|
||||
_SYSCALL_NARG(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Helper macros for a very common case: calls which just take one argument
|
||||
* which is an initialized kernel object of a specific type. Verify the object
|
||||
|
@ -351,25 +365,25 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
|
|||
*/
|
||||
|
||||
#define _SYSCALL_HANDLER1_SIMPLE(name_, obj_enum_, obj_type_) \
|
||||
_SYSCALL_HANDLER1(name_, arg1) { \
|
||||
__SYSCALL_HANDLER1(name_, arg1) { \
|
||||
_SYSCALL_OBJ(arg1, obj_enum_); \
|
||||
return (u32_t)_impl_ ## name_((obj_type_)arg1); \
|
||||
}
|
||||
|
||||
#define _SYSCALL_HANDLER1_SIMPLE_VOID(name_, obj_enum_, obj_type_) \
|
||||
_SYSCALL_HANDLER1(name_, arg1) { \
|
||||
__SYSCALL_HANDLER1(name_, arg1) { \
|
||||
_SYSCALL_OBJ(arg1, obj_enum_); \
|
||||
_impl_ ## name_((obj_type_)arg1); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define _SYSCALL_HANDLER0_SIMPLE(name_) \
|
||||
_SYSCALL_HANDLER0(name_) { \
|
||||
__SYSCALL_HANDLER0(name_) { \
|
||||
return (u32_t)_impl_ ## name_(); \
|
||||
}
|
||||
|
||||
#define _SYSCALL_HANDLER0_SIMPLE_VOID(name_) \
|
||||
_SYSCALL_HANDLER0(name_) { \
|
||||
__SYSCALL_HANDLER0(name_) { \
|
||||
_impl_ ## name_(); \
|
||||
return 0; \
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ void _impl_k_msgq_init(struct k_msgq *q, char *buffer,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER4(k_msgq_init, q, buffer, msg_size, max_msgs)
|
||||
_SYSCALL_HANDLER(k_msgq_init, q, buffer, msg_size, max_msgs)
|
||||
{
|
||||
_SYSCALL_OBJ_INIT(q, K_OBJ_MSGQ);
|
||||
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, max_msgs, msg_size);
|
||||
|
@ -124,7 +124,7 @@ int _impl_k_msgq_put(struct k_msgq *q, void *data, s32_t timeout)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER3(k_msgq_put, msgq_p, data, timeout)
|
||||
_SYSCALL_HANDLER(k_msgq_put, msgq_p, data, timeout)
|
||||
{
|
||||
struct k_msgq *q = (struct k_msgq *)msgq_p;
|
||||
|
||||
|
@ -190,7 +190,7 @@ int _impl_k_msgq_get(struct k_msgq *q, void *data, s32_t timeout)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER3(k_msgq_get, msgq_p, data, timeout)
|
||||
_SYSCALL_HANDLER(k_msgq_get, msgq_p, data, timeout)
|
||||
{
|
||||
struct k_msgq *q = (struct k_msgq *)msgq_p;
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ void _impl_k_mutex_init(struct k_mutex *mutex)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER1(k_mutex_init, mutex)
|
||||
_SYSCALL_HANDLER(k_mutex_init, mutex)
|
||||
{
|
||||
_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX);
|
||||
_impl_k_mutex_init((struct k_mutex *)mutex);
|
||||
|
@ -200,7 +200,7 @@ int _impl_k_mutex_lock(struct k_mutex *mutex, s32_t timeout)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER2(k_mutex_lock, mutex, timeout)
|
||||
_SYSCALL_HANDLER(k_mutex_lock, mutex, timeout)
|
||||
{
|
||||
_SYSCALL_OBJ(mutex, K_OBJ_MUTEX);
|
||||
return _impl_k_mutex_lock((struct k_mutex *)mutex, (s32_t)timeout);
|
||||
|
|
|
@ -141,7 +141,7 @@ void _impl_k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER3(k_pipe_init, pipe, buffer, size)
|
||||
_SYSCALL_HANDLER(k_pipe_init, pipe, buffer, size)
|
||||
{
|
||||
_SYSCALL_OBJ_INIT(pipe, K_OBJ_PIPE);
|
||||
_SYSCALL_MEMORY_WRITE(buffer, size);
|
||||
|
@ -684,7 +684,7 @@ int _impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER6(k_pipe_get,
|
||||
_SYSCALL_HANDLER(k_pipe_get,
|
||||
pipe, data, bytes_to_read, bytes_read_p, min_xfer_p, timeout)
|
||||
{
|
||||
size_t *bytes_read = (size_t *)bytes_read_p;
|
||||
|
@ -713,7 +713,7 @@ int _impl_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER6(k_pipe_put, pipe, data, bytes_to_write, bytes_written_p,
|
||||
_SYSCALL_HANDLER(k_pipe_put, pipe, data, bytes_to_write, bytes_written_p,
|
||||
min_xfer_p, timeout)
|
||||
{
|
||||
size_t *bytes_written = (size_t *)bytes_written_p;
|
||||
|
|
|
@ -285,7 +285,7 @@ void _impl_k_thread_priority_set(k_tid_t tid, int prio)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER2(k_thread_priority_set, thread_p, prio)
|
||||
_SYSCALL_HANDLER(k_thread_priority_set, thread_p, prio)
|
||||
{
|
||||
struct k_thread *thread = (struct k_thread *)thread_p;
|
||||
|
||||
|
@ -380,7 +380,7 @@ void _impl_k_sleep(s32_t duration)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER1(k_sleep, duration)
|
||||
_SYSCALL_HANDLER(k_sleep, duration)
|
||||
{
|
||||
/* FIXME there were some discussions recently on whether we should
|
||||
* relax this, thread would be unscheduled until k_wakeup issued
|
||||
|
|
|
@ -71,7 +71,7 @@ void _impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER3(k_sem_init, sem, initial_count, limit)
|
||||
_SYSCALL_HANDLER(k_sem_init, sem, initial_count, limit)
|
||||
{
|
||||
_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM);
|
||||
_SYSCALL_VERIFY(limit != 0);
|
||||
|
@ -179,7 +179,7 @@ int _impl_k_sem_take(struct k_sem *sem, s32_t timeout)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER2(k_sem_take, sem, timeout)
|
||||
_SYSCALL_HANDLER(k_sem_take, sem, timeout)
|
||||
{
|
||||
_SYSCALL_OBJ(sem, K_OBJ_SEM);
|
||||
return _impl_k_sem_take((struct k_sem *)sem, timeout);
|
||||
|
|
|
@ -57,7 +57,7 @@ void _impl_k_stack_init(struct k_stack *stack, u32_t *buffer,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER3(k_stack_init, stack, buffer, num_entries)
|
||||
_SYSCALL_HANDLER(k_stack_init, stack, buffer, num_entries)
|
||||
{
|
||||
_SYSCALL_OBJ_INIT(stack, K_OBJ_STACK);
|
||||
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, num_entries, sizeof(u32_t));
|
||||
|
@ -99,7 +99,7 @@ void _impl_k_stack_push(struct k_stack *stack, u32_t data)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER2(k_stack_push, stack_p, data)
|
||||
_SYSCALL_HANDLER(k_stack_push, stack_p, data)
|
||||
{
|
||||
struct k_stack *stack = (struct k_stack *)stack_p;
|
||||
|
||||
|
@ -140,7 +140,7 @@ int _impl_k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER3(k_stack_pop, stack, data, timeout)
|
||||
_SYSCALL_HANDLER(k_stack_pop, stack, data, timeout)
|
||||
{
|
||||
_SYSCALL_OBJ(stack, K_OBJ_STACK);
|
||||
_SYSCALL_MEMORY_WRITE(data, sizeof(u32_t));
|
||||
|
|
|
@ -79,7 +79,7 @@ u32_t _impl_k_uptime_get_32(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER0(k_uptime_get_32)
|
||||
_SYSCALL_HANDLER(k_uptime_get_32)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
_SYSCALL_VERIFY(_sys_clock_always_on);
|
||||
|
@ -126,7 +126,7 @@ s64_t _impl_k_uptime_get(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER1(k_uptime_get, ret_p)
|
||||
_SYSCALL_HANDLER(k_uptime_get, ret_p)
|
||||
{
|
||||
u64_t *ret = (u64_t *)ret_p;
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ void _impl_k_thread_custom_data_set(void *value)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER1(k_thread_custom_data_set, data)
|
||||
_SYSCALL_HANDLER(k_thread_custom_data_set, data)
|
||||
{
|
||||
_impl_k_thread_custom_data_set((void *)data);
|
||||
return 0;
|
||||
|
|
|
@ -47,7 +47,7 @@ void _impl_k_thread_abort(k_tid_t thread)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER1(k_thread_abort, thread_p)
|
||||
_SYSCALL_HANDLER(k_thread_abort, thread_p)
|
||||
{
|
||||
struct k_thread *thread = (struct k_thread *)thread_p;
|
||||
_SYSCALL_OBJ(thread, K_OBJ_THREAD);
|
||||
|
|
|
@ -132,7 +132,7 @@ void _impl_k_timer_start(struct k_timer *timer, s32_t duration, s32_t period)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER3(k_timer_start, timer, duration_p, period_p)
|
||||
_SYSCALL_HANDLER(k_timer_start, timer, duration_p, period_p)
|
||||
{
|
||||
s32_t duration, period;
|
||||
|
||||
|
@ -259,7 +259,7 @@ s32_t _timeout_remaining_get(struct _timeout *timeout)
|
|||
_SYSCALL_HANDLER1_SIMPLE(k_timer_remaining_get, K_OBJ_TIMER, struct k_timer *);
|
||||
_SYSCALL_HANDLER1_SIMPLE(k_timer_user_data_get, K_OBJ_TIMER, struct k_timer *);
|
||||
|
||||
_SYSCALL_HANDLER2(k_timer_user_data_set, timer, user_data)
|
||||
_SYSCALL_HANDLER(k_timer_user_data_set, timer, user_data)
|
||||
{
|
||||
_SYSCALL_OBJ(timer, K_OBJ_TIMER);
|
||||
_impl_k_timer_user_data_set((struct k_timer *)timer, (void *)user_data);
|
||||
|
|
|
@ -35,7 +35,7 @@ static struct _k_object *validate_any_object(void *obj)
|
|||
* To avoid double _k_object_find() lookups, we don't call the implementation
|
||||
* function, but call a level deeper.
|
||||
*/
|
||||
_SYSCALL_HANDLER2(k_object_access_grant, object, thread)
|
||||
_SYSCALL_HANDLER(k_object_access_grant, object, thread)
|
||||
{
|
||||
struct _k_object *ko;
|
||||
|
||||
|
@ -47,7 +47,7 @@ _SYSCALL_HANDLER2(k_object_access_grant, object, thread)
|
|||
return 0;
|
||||
}
|
||||
|
||||
_SYSCALL_HANDLER2(k_object_access_revoke, object, thread)
|
||||
_SYSCALL_HANDLER(k_object_access_revoke, object, thread)
|
||||
{
|
||||
struct _k_object *ko;
|
||||
|
||||
|
@ -59,7 +59,7 @@ _SYSCALL_HANDLER2(k_object_access_revoke, object, thread)
|
|||
return 0;
|
||||
}
|
||||
|
||||
_SYSCALL_HANDLER1(k_object_access_all_grant, object)
|
||||
_SYSCALL_HANDLER(k_object_access_all_grant, object)
|
||||
{
|
||||
struct _k_object *ko;
|
||||
|
||||
|
|
|
@ -297,7 +297,7 @@ void _impl_k_str_out(char *c, size_t n)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_SYSCALL_HANDLER2(k_str_out, c, n)
|
||||
_SYSCALL_HANDLER(k_str_out, c, n)
|
||||
{
|
||||
_SYSCALL_MEMORY_READ(c, n);
|
||||
_impl_k_str_out((char *)c, n);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <sensor.h>
|
||||
#include <syscall_handler.h>
|
||||
|
||||
_SYSCALL_HANDLER4(sensor_attr_set, dev, chan, attr, val)
|
||||
_SYSCALL_HANDLER(sensor_attr_set, dev, chan, attr, val)
|
||||
{
|
||||
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
|
||||
_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value));
|
||||
|
@ -18,13 +18,13 @@ _SYSCALL_HANDLER4(sensor_attr_set, dev, chan, attr, val)
|
|||
_SYSCALL_HANDLER1_SIMPLE(sensor_sample_fetch, K_OBJ_DRIVER_SENSOR,
|
||||
struct device *);
|
||||
|
||||
_SYSCALL_HANDLER2(sensor_semple_fetch_chan, dev, type)
|
||||
_SYSCALL_HANDLER(sensor_semple_fetch_chan, dev, type)
|
||||
{
|
||||
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
|
||||
return _impl_sensor_sample_fetch_chan((struct device *)dev, type);
|
||||
}
|
||||
|
||||
_SYSCALL_HANDLER3(sensor_channel_get, dev, chan, val)
|
||||
_SYSCALL_HANDLER(sensor_channel_get, dev, chan, val)
|
||||
{
|
||||
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
|
||||
_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue