Browse Source

kernel: Move current_fp field out of z_kernel

The current_fp field in the z_kernel structure is only used
by 32-bit x86 (which does not support SMP). As such, it should
reside in the arch specific of section of _kernel.cpus[0].

This also changes the name of 'current_fp' to 'fpu_owner' to
be more consistent with other architectures.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
pull/87087/head
Peter Mitsis 4 months ago committed by Benjamin Cabé
parent
commit
c6bc09223e
  1. 12
      arch/x86/core/ia32/float.c
  2. 6
      arch/x86/core/ia32/swap.S
  3. 6
      arch/x86/core/offsets/ia32_offsets.c
  4. 3
      arch/x86/include/ia32/offsets_short_arch.h
  5. 2
      include/zephyr/arch/structs.h
  6. 33
      include/zephyr/arch/x86/ia32/structs.h
  7. 14
      include/zephyr/kernel_structs.h
  8. 4
      kernel/include/kernel_offsets.h
  9. 3
      kernel/include/offsets_short.h

12
arch/x86/core/ia32/float.c

@ -194,7 +194,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options) @@ -194,7 +194,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options)
* must be preserved).
*/
fp_owner = _kernel.current_fp;
fp_owner = _kernel.cpus[0].arch.fpu_owner;
if (fp_owner != NULL) {
if ((fp_owner->arch.flags & X86_THREAD_FLAG_ALL) != 0) {
FpCtxSave(fp_owner);
@ -215,7 +215,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options) @@ -215,7 +215,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options)
* (The FP context is "live" in hardware, not saved in TCS.)
*/
_kernel.current_fp = thread;
_kernel.cpus[0].arch.fpu_owner = thread;
} else {
/*
* When enabling FP support for someone else, assign ownership
@ -230,7 +230,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options) @@ -230,7 +230,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options)
* to its original state.
*/
_kernel.current_fp = thread;
_kernel.cpus[0].arch.fpu_owner = thread;
z_FpAccessDisable();
} else {
/*
@ -280,10 +280,10 @@ int z_float_disable(struct k_thread *thread) @@ -280,10 +280,10 @@ int z_float_disable(struct k_thread *thread)
if (thread == _current) {
z_FpAccessDisable();
_kernel.current_fp = (struct k_thread *)0;
_kernel.cpus[0].arch.fpu_owner = (struct k_thread *)0;
} else {
if (_kernel.current_fp == thread) {
_kernel.current_fp = (struct k_thread *)0;
if (_kernel.cpus[0].arch.fpu_owner == thread) {
_kernel.cpus[0].arch.fpu_owner = (struct k_thread *)0;
}
}

6
arch/x86/core/ia32/swap.S

@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
* Floating point registers are handled using a lazy save/restore mechanism
* since it's expected relatively few threads will be created with the
* K_FP_REGS or K_SSE_REGS option bits. The kernel data structure maintains a
* 'current_fp' field to keep track of the thread that "owns" the floating
* 'fpu_owner' field to keep track of the thread that "owns" the floating
* point registers. Floating point registers consist of ST0->ST7 (x87 FPU and
* MMX registers) and XMM0 -> XMM7.
*
@ -176,7 +176,7 @@ SECTION_FUNC(PINNED_TEXT, arch_swap) @@ -176,7 +176,7 @@ SECTION_FUNC(PINNED_TEXT, arch_swap)
* If so, there there is no need to restore the floating point context.
*/
movl _kernel_offset_to_current_fp(%edi), %ebx
movl _kernel_offset_to_fpu_owner(%edi), %ebx
cmpl %ebx, %eax
je restoreContext_NoFloatSwap
@ -265,7 +265,7 @@ restoreContext_NoFloatRestore: @@ -265,7 +265,7 @@ restoreContext_NoFloatRestore:
/* record that the incoming thread "owns" the floating point registers */
movl %eax, _kernel_offset_to_current_fp(%edi)
movl %eax, _kernel_offset_to_fpu_owner(%edi)
/*

6
arch/x86/core/offsets/ia32_offsets.c

@ -33,6 +33,12 @@ @@ -33,6 +33,12 @@
GEN_OFFSET_SYM(_thread_arch_t, excNestCount);
#endif
#if defined(CONFIG_FPU_SHARING)
GEN_OFFSET_SYM(_kernel_t, cpus);
GEN_OFFSET_SYM(_cpu_t, arch);
GEN_OFFSET_SYM(_cpu_arch_t, fpu_owner);
#endif
#ifdef CONFIG_USERSPACE
GEN_OFFSET_SYM(_thread_arch_t, psp);
#ifndef CONFIG_X86_COMMON_PAGE_TABLE

3
arch/x86/include/ia32/offsets_short_arch.h

@ -14,6 +14,9 @@ @@ -14,6 +14,9 @@
#define _kernel_offset_to_isf \
(___kernel_t_arch_OFFSET + ___kernel_arch_t_isf_OFFSET)
#define _kernel_offset_to_fpu_owner \
(___kernel_t_cpus_OFFSET + ___cpu_t_arch_OFFSET + ___cpu_arch_t_fpu_owner_OFFSET)
/* end - kernel */
/* threads */

2
include/zephyr/arch/structs.h

@ -29,6 +29,8 @@ @@ -29,6 +29,8 @@
#include <zephyr/arch/riscv/structs.h>
#elif defined(CONFIG_ARM)
#include <zephyr/arch/arm/structs.h>
#elif defined(CONFIG_X86) && !defined(CONFIG_X86_64)
#include <zephyr/arch/x86/ia32/structs.h>
#else
/* Default definitions when no architecture specific definitions exist. */

33
include/zephyr/arch/x86/ia32/structs.h

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
/*
* Copyright (c) 2025 Intel
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_X86_STRUCTS_H_
#define ZEPHYR_INCLUDE_X86_STRUCTS_H_
#include <stdint.h>
struct k_thread;
/* Per CPU architecture specifics (empty) */
struct _cpu_arch {
#if defined(CONFIG_FPU_SHARING)
/*
* A 'sse_owner' field does not exist in addition to the 'fpu_owner'
* field since it's not possible to divide the IA-32 non-integer
* registers into 2 distinct blocks owned by differing threads. In
* other words, given that the 'fxnsave/fxrstor' instructions
* save/restore both the X87 FPU and XMM registers, it's not possible
* for a thread to only "own" the XMM registers.
*/
struct k_thread *fpu_owner;
#elif defined(__cplusplus)
/* Ensure this struct does not have a size of 0 which is not allowed in C++. */
uint8_t dummy;
#endif
};
#endif /* ZEPHYR_INCLUDE_X86_STRUCTS_H_ */

14
include/zephyr/kernel_structs.h

@ -217,20 +217,6 @@ struct z_kernel { @@ -217,20 +217,6 @@ struct z_kernel {
struct _ready_q ready_q;
#endif
#ifdef CONFIG_FPU_SHARING
/*
* A 'current_sse' field does not exist in addition to the 'current_fp'
* field since it's not possible to divide the IA-32 non-integer
* registers into 2 distinct blocks owned by differing threads. In
* other words, given that the 'fxnsave/fxrstor' instructions
* save/restore both the X87 FPU and XMM registers, it's not possible
* for a thread to only "own" the XMM registers.
*/
/* thread that owns the FP regs */
struct k_thread *current_fp;
#endif
#if defined(CONFIG_THREAD_MONITOR)
struct k_thread *threads; /* singly linked list of ALL threads */
#endif

4
kernel/include/kernel_offsets.h

@ -48,10 +48,6 @@ GEN_OFFSET_SYM(_kernel_t, ready_q); @@ -48,10 +48,6 @@ GEN_OFFSET_SYM(_kernel_t, ready_q);
GEN_OFFSET_SYM(_ready_q_t, cache);
#endif /* CONFIG_SMP */
#ifdef CONFIG_FPU_SHARING
GEN_OFFSET_SYM(_kernel_t, current_fp);
#endif /* CONFIG_FPU_SHARING */
GEN_OFFSET_SYM(_thread_base_t, user_options);
GEN_OFFSET_SYM(_thread_t, base);

3
kernel/include/offsets_short.h

@ -34,9 +34,6 @@ @@ -34,9 +34,6 @@
#define _kernel_offset_to_idle \
(___kernel_t_idle_OFFSET)
#define _kernel_offset_to_current_fp \
(___kernel_t_current_fp_OFFSET)
#define _kernel_offset_to_ready_q_cache \
(___kernel_t_ready_q_OFFSET + ___ready_q_t_cache_OFFSET)

Loading…
Cancel
Save