Skip to content

Commit 59903e2

Browse files
katsustercarlescufi
authored andcommitted
kernel: arch: introduce k_float_enable()
This patch introduce new API to enable FPU of thread. This is pair of existed k_float_disable() API. And also add empty arch_float_enable() into each architectures that have arch_float_disable(). The arc and riscv already implemented arch_float_enable() so I do not touch these implementations. Motivation: Current Zephyr implementation does not allow to use FPU on main and other system threads like as work queue. Users need to create an other thread with K_FP_REGS for floating point programs. Users can use FPU more easily if they can enable FPU on running threads. Signed-off-by: Katsuhiro Suzuki <[email protected]>
1 parent f5df098 commit 59903e2

File tree

10 files changed

+93
-34
lines changed

10 files changed

+93
-34
lines changed

arch/arc/core/thread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ int arch_float_disable(struct k_thread *thread)
232232
}
233233

234234

235-
int arch_float_enable(struct k_thread *thread)
235+
int arch_float_enable(struct k_thread *thread, unsigned int options)
236236
{
237237
unsigned int key;
238238

arch/arm/core/aarch32/thread.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ int arch_float_disable(struct k_thread *thread)
458458

459459
return 0;
460460
}
461+
462+
int arch_float_enable(struct k_thread *thread, unsigned int options)
463+
{
464+
/* This is not supported in Cortex-M and Cortex-R does not have FPU */
465+
return -ENOTSUP;
466+
}
461467
#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */
462468

463469
/* Internal function for Cortex-M initialization,

arch/riscv/core/thread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ int arch_float_disable(struct k_thread *thread)
152152
}
153153

154154

155-
int arch_float_enable(struct k_thread *thread)
155+
int arch_float_enable(struct k_thread *thread, unsigned int options)
156156
{
157157
unsigned int key;
158158

arch/sparc/core/thread.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,9 @@ int arch_float_disable(struct k_thread *thread)
7878
{
7979
return -ENOSYS;
8080
}
81+
82+
int arch_float_enable(struct k_thread *thread, unsigned int options)
83+
{
84+
return -ENOTSUP;
85+
}
8186
#endif /* CONFIG_FPU_SHARING */

arch/x86/core/ia32/float.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ static inline void FpCtxInit(struct k_thread *thread)
179179
* The locking isn't really needed when the routine is called by a cooperative
180180
* thread (since context switching can't occur), but it is harmless.
181181
*/
182-
void k_float_enable(struct k_thread *thread, unsigned int options)
182+
void z_float_enable(struct k_thread *thread, unsigned int options)
183183
{
184184
unsigned int imask;
185185
struct k_thread *fp_owner;

arch/x86/core/ia32/thread.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ int arch_float_disable(struct k_thread *thread)
5959
return -ENOSYS;
6060
#endif /* CONFIG_LAZY_FPU_SHARING */
6161
}
62+
63+
extern int z_float_enable(struct k_thread *thread, unsigned int options);
64+
65+
int arch_float_enable(struct k_thread *thread, unsigned int options)
66+
{
67+
#if defined(CONFIG_LAZY_FPU_SHARING)
68+
return z_float_enable(thread, options);
69+
#else
70+
return -ENOTSUP;
71+
#endif /* CONFIG_LAZY_FPU_SHARING */
72+
}
6273
#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */
6374

6475
void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,

include/arch/x86/ia32/arch.h

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -396,37 +396,6 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void)
396396

397397
struct k_thread;
398398

399-
/**
400-
* @brief Enable preservation of floating point context information.
401-
*
402-
* This routine informs the kernel that the specified thread (which may be
403-
* the current thread) will be using the floating point registers.
404-
* The @a options parameter indicates which floating point register sets
405-
* will be used by the specified thread:
406-
*
407-
* - K_FP_REGS indicates x87 FPU and MMX registers only
408-
* - K_SSE_REGS indicates SSE registers (and also x87 FPU and MMX registers)
409-
*
410-
* Invoking this routine initializes the thread's floating point context info
411-
* to that of an FPU that has been reset. The next time the thread is scheduled
412-
* by z_swap() it will either inherit an FPU that is guaranteed to be in a "sane"
413-
* state (if the most recent user of the FPU was cooperatively swapped out)
414-
* or the thread's own floating point context will be loaded (if the most
415-
* recent user of the FPU was preempted, or if this thread is the first user
416-
* of the FPU). Thereafter, the kernel will protect the thread's FP context
417-
* so that it is not altered during a preemptive context switch.
418-
*
419-
* @warning
420-
* This routine should only be used to enable floating point support for a
421-
* thread that does not currently have such support enabled already.
422-
*
423-
* @param thread ID of thread.
424-
* @param options Registers to be preserved (K_FP_REGS or K_SSE_REGS).
425-
*
426-
* @return N/A
427-
*/
428-
extern void k_float_enable(struct k_thread *thread, unsigned int options);
429-
430399
/**
431400
* @}
432401
*/

include/kernel.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5544,6 +5544,46 @@ __syscall void k_str_out(char *c, size_t n);
55445544
*/
55455545
__syscall int k_float_disable(struct k_thread *thread);
55465546

5547+
/**
5548+
* @brief Enable preservation of floating point context information.
5549+
*
5550+
* This routine informs the kernel that the specified thread
5551+
* will use the floating point registers.
5552+
5553+
* Invoking this routine initializes the thread's floating point context info
5554+
* to that of an FPU that has been reset. The next time the thread is scheduled
5555+
* by z_swap() it will either inherit an FPU that is guaranteed to be in a
5556+
* "sane" state (if the most recent user of the FPU was cooperatively swapped
5557+
* out) or the thread's own floating point context will be loaded (if the most
5558+
* recent user of the FPU was preempted, or if this thread is the first user
5559+
* of the FPU). Thereafter, the kernel will protect the thread's FP context
5560+
* so that it is not altered during a preemptive context switch.
5561+
*
5562+
* The @a options parameter indicates which floating point register sets will
5563+
* be used by the specified thread.
5564+
*
5565+
* For x86 options:
5566+
*
5567+
* - K_FP_REGS indicates x87 FPU and MMX registers only
5568+
* - K_SSE_REGS indicates SSE registers (and also x87 FPU and MMX registers)
5569+
*
5570+
* @warning
5571+
* Some architectures apply restrictions on how the enabling of floating
5572+
* point preservation may be requested, see arch_float_enable.
5573+
*
5574+
* @warning
5575+
* This routine should only be used to enable floating point support for
5576+
* a thread that currently has such support enabled.
5577+
*
5578+
* @param thread ID of thread.
5579+
* @param options architecture dependent options
5580+
*
5581+
* @retval 0 On success.
5582+
* @retval -ENOTSUP If the floating point enabling is not implemented.
5583+
* -EINVAL If the floating point enabling could not be performed.
5584+
*/
5585+
__syscall int k_float_enable(struct k_thread *thread, unsigned int options);
5586+
55475587
#ifdef CONFIG_THREAD_RUNTIME_STATS
55485588

55495589
/**

kernel/include/kernel_arch_interface.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,25 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr,
185185
* @retval -EINVAL If the floating point disabling could not be performed.
186186
*/
187187
int arch_float_disable(struct k_thread *thread);
188+
189+
/**
190+
* @brief Enable floating point context preservation
191+
*
192+
* The function is used to enable the preservation of floating
193+
* point context information for a particular thread.
194+
* This API depends on each architecture implimentation. If the architecture
195+
* does not support enableing, this API will always be failed.
196+
*
197+
* The @a options parameter indicates which floating point register sets will
198+
* be used by the specified thread. Currently it is used by x86 only.
199+
*
200+
* @param thread ID of thread.
201+
* @param options architecture dependent options
202+
*
203+
* @retval 0 On success.
204+
* @retval -EINVAL If the floating point enabling could not be performed.
205+
*/
206+
int arch_float_enable(struct k_thread *thread, unsigned int options);
188207
#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */
189208

190209
/** @} */

kernel/thread.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,15 @@ int z_impl_k_float_disable(struct k_thread *thread)
884884
#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */
885885
}
886886

887+
int z_impl_k_float_enable(struct k_thread *thread, unsigned int options)
888+
{
889+
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
890+
return arch_float_enable(thread, options);
891+
#else
892+
return -ENOTSUP;
893+
#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */
894+
}
895+
887896
#ifdef CONFIG_USERSPACE
888897
static inline int z_vrfy_k_float_disable(struct k_thread *thread)
889898
{

0 commit comments

Comments
 (0)