From a6cb8b06dbdd20b96a884c2bf957f9da1e53ab32 Mon Sep 17 00:00:00 2001 From: Ioannis Glaropoulos Date: Thu, 9 May 2019 21:55:10 +0200 Subject: [PATCH] kernel: introduce k_float_disable system call We introduce k_float_disable() system call, to allow threads to disable floating point context preservation. The system call is to be used in FP Sharing Registers mode (CONFIG_FP_SHARING=y). Signed-off-by: Ioannis Glaropoulos --- include/kernel.h | 23 +++++++++++++++++++++++ kernel/include/kernel_internal.h | 18 ++++++++++++++++++ kernel/thread.c | 20 ++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/include/kernel.h b/include/kernel.h index 3f70f6e2145..529cc58594a 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -4906,6 +4906,29 @@ __syscall void k_str_out(char *c, size_t n); extern void z_arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, void (*fn)(int key, void *data), void *arg); + +/** + * @brief Disable preservation of floating point context information. + * + * This routine informs the kernel that the specified thread + * will no longer be using the floating point registers. + * + * @warning + * Some architectures apply restrictions on how the disabling of floating + * point preservation may be requested, see z_arch_float_disable. + * + * @warning + * This routine should only be used to disable floating point support for + * a thread that currently has such support enabled. + * + * @param thread ID of thread. + * + * @retval 0 On success. + * @retval -ENOSYS If the floating point disabling is not implemented. + * -EINVAL If the floating point disabling could not be performed. + */ +__syscall int k_float_disable(struct k_thread *thread); + #ifdef __cplusplus } #endif diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index dfc1c1fa33e..efe708dea49 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -51,6 +51,24 @@ extern void z_setup_new_thread(struct k_thread *new_thread, void *p1, void *p2, void *p3, int prio, u32_t options, const char *name); +#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING) +/** + * @brief Disable floating point context preservation + * + * The function is used to disable the preservation of floating + * point context information for a particular thread. + * + * @note + * For ARM architecture, disabling floating point preservation + * - may only be requested for the current thread + * - cannot be requested in ISRs. + * + * @retval 0 On success. + * @retval -EINVAL If the floating point disabling could not be performed. + */ +extern int z_arch_float_disable(struct k_thread *thread); +#endif /* CONFIG_FLOAT && CONFIG_FP_SHARING */ + #ifdef CONFIG_USERSPACE /** * @brief Get the maximum number of partitions for a memory domain diff --git a/kernel/thread.c b/kernel/thread.c index de40fa7c804..b2494a48a64 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -727,4 +727,24 @@ void z_spin_lock_set_owner(struct k_spinlock *l) l->thread_cpu = _current_cpu->id | (uintptr_t)_current; } +int z_impl_k_float_disable(struct k_thread *thread) +{ +#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING) + return z_arch_float_disable(thread); +#else + return -ENOSYS; +#endif /* CONFIG_FLOAT && CONFIG_FP_SHARING */ +} + +#ifdef CONFIG_USERSPACE +Z_SYSCALL_HANDLER(k_float_disable, thread_p) +{ + struct k_thread *thread = (struct k_thread *)thread_p; + + Z_OOPS(Z_SYSCALL_OBJ(thread, K_OBJ_THREAD)); + + return z_impl_k_float_disable((struct k_thread *)thread_p); +} +#endif /* CONFIG_USERSPACE */ + #endif