diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index 669624cf07..0cf26ffae3 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -232,7 +232,7 @@ int arch_float_disable(struct k_thread *thread) } -int arch_float_enable(struct k_thread *thread) +int arch_float_enable(struct k_thread *thread, unsigned int options) { unsigned int key; diff --git a/arch/arm/core/aarch32/thread.c b/arch/arm/core/aarch32/thread.c index 509a86b192..6978b8bd0b 100644 --- a/arch/arm/core/aarch32/thread.c +++ b/arch/arm/core/aarch32/thread.c @@ -458,6 +458,12 @@ int arch_float_disable(struct k_thread *thread) return 0; } + +int arch_float_enable(struct k_thread *thread, unsigned int options) +{ + /* This is not supported in Cortex-M and Cortex-R does not have FPU */ + return -ENOTSUP; +} #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ /* Internal function for Cortex-M initialization, diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index 0513b07030..77d7b01a43 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -152,7 +152,7 @@ int arch_float_disable(struct k_thread *thread) } -int arch_float_enable(struct k_thread *thread) +int arch_float_enable(struct k_thread *thread, unsigned int options) { unsigned int key; diff --git a/arch/sparc/core/thread.c b/arch/sparc/core/thread.c index ee7e4e9b63..2d5df75361 100644 --- a/arch/sparc/core/thread.c +++ b/arch/sparc/core/thread.c @@ -78,4 +78,9 @@ int arch_float_disable(struct k_thread *thread) { return -ENOSYS; } + +int arch_float_enable(struct k_thread *thread, unsigned int options) +{ + return -ENOTSUP; +} #endif /* CONFIG_FPU_SHARING */ diff --git a/arch/x86/core/ia32/float.c b/arch/x86/core/ia32/float.c index 3f52232041..a4f78687e6 100644 --- a/arch/x86/core/ia32/float.c +++ b/arch/x86/core/ia32/float.c @@ -179,7 +179,7 @@ static inline void FpCtxInit(struct k_thread *thread) * The locking isn't really needed when the routine is called by a cooperative * thread (since context switching can't occur), but it is harmless. */ -void k_float_enable(struct k_thread *thread, unsigned int options) +void z_float_enable(struct k_thread *thread, unsigned int options) { unsigned int imask; struct k_thread *fp_owner; diff --git a/arch/x86/core/ia32/thread.c b/arch/x86/core/ia32/thread.c index dc46958ea8..cff38e92f8 100644 --- a/arch/x86/core/ia32/thread.c +++ b/arch/x86/core/ia32/thread.c @@ -59,6 +59,17 @@ int arch_float_disable(struct k_thread *thread) return -ENOSYS; #endif /* CONFIG_LAZY_FPU_SHARING */ } + +extern int z_float_enable(struct k_thread *thread, unsigned int options); + +int arch_float_enable(struct k_thread *thread, unsigned int options) +{ +#if defined(CONFIG_LAZY_FPU_SHARING) + return z_float_enable(thread, options); +#else + return -ENOTSUP; +#endif /* CONFIG_LAZY_FPU_SHARING */ +} #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, diff --git a/include/arch/x86/ia32/arch.h b/include/arch/x86/ia32/arch.h index 5058cc7eca..11457b8f44 100644 --- a/include/arch/x86/ia32/arch.h +++ b/include/arch/x86/ia32/arch.h @@ -396,37 +396,6 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) struct k_thread; -/** - * @brief Enable preservation of floating point context information. - * - * This routine informs the kernel that the specified thread (which may be - * the current thread) will be using the floating point registers. - * The @a options parameter indicates which floating point register sets - * will be used by the specified thread: - * - * - K_FP_REGS indicates x87 FPU and MMX registers only - * - K_SSE_REGS indicates SSE registers (and also x87 FPU and MMX registers) - * - * Invoking this routine initializes the thread's floating point context info - * to that of an FPU that has been reset. The next time the thread is scheduled - * by z_swap() it will either inherit an FPU that is guaranteed to be in a "sane" - * state (if the most recent user of the FPU was cooperatively swapped out) - * or the thread's own floating point context will be loaded (if the most - * recent user of the FPU was preempted, or if this thread is the first user - * of the FPU). Thereafter, the kernel will protect the thread's FP context - * so that it is not altered during a preemptive context switch. - * - * @warning - * This routine should only be used to enable floating point support for a - * thread that does not currently have such support enabled already. - * - * @param thread ID of thread. - * @param options Registers to be preserved (K_FP_REGS or K_SSE_REGS). - * - * @return N/A - */ -extern void k_float_enable(struct k_thread *thread, unsigned int options); - /** * @} */ diff --git a/include/kernel.h b/include/kernel.h index ee7aa34504..66c56b80a4 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -5544,6 +5544,46 @@ __syscall void k_str_out(char *c, size_t n); */ __syscall int k_float_disable(struct k_thread *thread); +/** + * @brief Enable preservation of floating point context information. + * + * This routine informs the kernel that the specified thread + * will use the floating point registers. + + * Invoking this routine initializes the thread's floating point context info + * to that of an FPU that has been reset. The next time the thread is scheduled + * by z_swap() it will either inherit an FPU that is guaranteed to be in a + * "sane" state (if the most recent user of the FPU was cooperatively swapped + * out) or the thread's own floating point context will be loaded (if the most + * recent user of the FPU was preempted, or if this thread is the first user + * of the FPU). Thereafter, the kernel will protect the thread's FP context + * so that it is not altered during a preemptive context switch. + * + * The @a options parameter indicates which floating point register sets will + * be used by the specified thread. + * + * For x86 options: + * + * - K_FP_REGS indicates x87 FPU and MMX registers only + * - K_SSE_REGS indicates SSE registers (and also x87 FPU and MMX registers) + * + * @warning + * Some architectures apply restrictions on how the enabling of floating + * point preservation may be requested, see arch_float_enable. + * + * @warning + * This routine should only be used to enable floating point support for + * a thread that currently has such support enabled. + * + * @param thread ID of thread. + * @param options architecture dependent options + * + * @retval 0 On success. + * @retval -ENOTSUP If the floating point enabling is not implemented. + * -EINVAL If the floating point enabling could not be performed. + */ +__syscall int k_float_enable(struct k_thread *thread, unsigned int options); + #ifdef CONFIG_THREAD_RUNTIME_STATS /** diff --git a/kernel/include/kernel_arch_interface.h b/kernel/include/kernel_arch_interface.h index 796e8f0238..eb0e853600 100644 --- a/kernel/include/kernel_arch_interface.h +++ b/kernel/include/kernel_arch_interface.h @@ -185,6 +185,25 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, * @retval -EINVAL If the floating point disabling could not be performed. */ int arch_float_disable(struct k_thread *thread); + +/** + * @brief Enable floating point context preservation + * + * The function is used to enable the preservation of floating + * point context information for a particular thread. + * This API depends on each architecture implimentation. If the architecture + * does not support enableing, this API will always be failed. + * + * The @a options parameter indicates which floating point register sets will + * be used by the specified thread. Currently it is used by x86 only. + * + * @param thread ID of thread. + * @param options architecture dependent options + * + * @retval 0 On success. + * @retval -EINVAL If the floating point enabling could not be performed. + */ +int arch_float_enable(struct k_thread *thread, unsigned int options); #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ /** @} */ diff --git a/kernel/thread.c b/kernel/thread.c index d91db4960e..d479b46b2f 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -884,6 +884,15 @@ int z_impl_k_float_disable(struct k_thread *thread) #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ } +int z_impl_k_float_enable(struct k_thread *thread, unsigned int options) +{ +#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) + return arch_float_enable(thread, options); +#else + return -ENOTSUP; +#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ +} + #ifdef CONFIG_USERSPACE static inline int z_vrfy_k_float_disable(struct k_thread *thread) {