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>
This commit is contained in:
parent
22c04bdc66
commit
c6bc09223e
9 changed files with 53 additions and 30 deletions
|
@ -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)
|
|||
* (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)
|
|||
* 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)
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
|||
* 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:
|
|||
|
||||
/* 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)
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
Normal file
33
include/zephyr/arch/x86/ia32/structs.h
Normal file
|
@ -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_ */
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue