Skip to content
Permalink
Browse files

arch/x86: refactor kernel_arch_thread.h

This data is subarchitecture-specific, so move it to ia32/
and add a layer of indirection at the architecture level.

Signed-off-by: Charles E. Youse <charles.youse@intel.com>
  • Loading branch information...
Charles E. Youse authored and nashif committed Jun 29, 2019
1 parent aa6d5b4 commit f40fe36ca60ab7e1ba509fbcd99add194c988e19
Showing with 233 additions and 220 deletions.
  1. +230 −0 arch/x86/include/ia32/kernel_arch_thread.h
  2. +3 −220 arch/x86/include/kernel_arch_thread.h
@@ -0,0 +1,230 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief Per-arch thread definition
*
* This file contains definitions for
*
* struct _thread_arch
* struct _callee_saved
*
* necessary to instantiate instances of struct k_thread.
*/

#ifndef ZEPHYR_ARCH_X86_INCLUDE_IA32_KERNEL_ARCH_THREAD_H_
#define ZEPHYR_ARCH_X86_INCLUDE_IA32_KERNEL_ARCH_THREAD_H_

/**
* Floating point register set alignment.
*
* If support for SSEx extensions is enabled a 16 byte boundary is required,
* since the 'fxsave' and 'fxrstor' instructions require this. In all other
* cases a 4 byte boundary is sufficient.
*/

#ifdef CONFIG_SSE
#define FP_REG_SET_ALIGN 16
#else
#define FP_REG_SET_ALIGN 4
#endif

#ifndef _ASMLANGUAGE
#include <stdint.h>

/*
* The following structure defines the set of 'non-volatile' integer registers.
* These registers must be preserved by a called C function. These are the
* only registers that need to be saved/restored when a cooperative context
* switch occurs.
*/

struct _callee_saved {
unsigned long esp;

/*
* The following registers are considered non-volatile, i.e.
* callee-save,
* but their values are pushed onto the stack rather than stored in the
* TCS
* structure:
*
* unsigned long ebp;
* unsigned long ebx;
* unsigned long esi;
* unsigned long edi;
*/

};

typedef struct _callee_saved _callee_saved_t;

/*
* The macros CONFIG_{LAZY|EAGER}_FP_SHARING shall be set to indicate that the
* saving/restoring of the traditional x87 floating point (and MMX) registers
* are supported by the kernel's context swapping code. The macro
* CONFIG_SSE shall _also_ be set if saving/restoring of the XMM
* registers is also supported in the kernel's context swapping code.
*/

#if defined(CONFIG_EAGER_FP_SHARING) || defined(CONFIG_LAZY_FP_SHARING)

/* definition of a single x87 (floating point / MMX) register */

typedef struct s_FpReg {
unsigned char reg[10]; /* 80 bits: ST[0-7] */
} tFpReg;

/*
* The following is the "normal" floating point register save area, or
* more accurately the save area required by the 'fnsave' and 'frstor'
* instructions. The structure matches the layout described in the
* "Intel(r) 64 and IA-32 Architectures Software Developer's Manual
* Volume 1: Basic Architecture": Protected Mode x87 FPU State Image in
* Memory, 32-Bit Format.
*/

typedef struct s_FpRegSet { /* # of bytes: name of register */
unsigned short fcw; /* 2 : x87 FPU control word */
unsigned short pad1; /* 2 : N/A */
unsigned short fsw; /* 2 : x87 FPU status word */
unsigned short pad2; /* 2 : N/A */
unsigned short ftw; /* 2 : x87 FPU tag word */
unsigned short pad3; /* 2 : N/A */
unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */
unsigned short cs; /* 2 : x87 FPU instruction pointer selector */
unsigned short fop : 11; /* 2 : x87 FPU opcode */
unsigned short pad4 : 5; /* : 5 bits = 00000 */
unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */
unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */
unsigned short pad5; /* 2 : N/A */
tFpReg fpReg[8]; /* 80 : ST0 -> ST7 */
} tFpRegSet __aligned(FP_REG_SET_ALIGN);

#ifdef CONFIG_SSE

/* definition of a single x87 (floating point / MMX) register */

typedef struct s_FpRegEx {
unsigned char reg[10]; /* 80 bits: ST[0-7] or MM[0-7] */
unsigned char rsrvd[6]; /* 48 bits: reserved */
} tFpRegEx;

/* definition of a single XMM register */

typedef struct s_XmmReg {
unsigned char reg[16]; /* 128 bits: XMM[0-7] */
} tXmmReg;

/*
* The following is the "extended" floating point register save area, or
* more accurately the save area required by the 'fxsave' and 'fxrstor'
* instructions. The structure matches the layout described in the
* "Intel 64 and IA-32 Architectures Software Developer's Manual
* Volume 2A: Instruction Set Reference, A-M", except for the bytes from offset
* 464 to 511 since these "are available to software use. The processor does
* not write to bytes 464:511 of an FXSAVE area".
*
* This structure must be aligned on a 16 byte boundary when the instructions
* fxsave/fxrstor are used to write/read the data to/from the structure.
*/

typedef struct s_FpRegSetEx /* # of bytes: name of register */
{
unsigned short fcw; /* 2 : x87 FPU control word */
unsigned short fsw; /* 2 : x87 FPU status word */
unsigned char ftw; /* 1 : x87 FPU abridged tag word */
unsigned char rsrvd0; /* 1 : reserved */
unsigned short fop; /* 2 : x87 FPU opcode */
unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */
unsigned short cs; /* 2 : x87 FPU instruction pointer selector */
unsigned short rsrvd1; /* 2 : reserved */
unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */
unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */
unsigned short rsrvd2; /* 2 : reserved */
unsigned int mxcsr; /* 4 : MXCSR register state */
unsigned int mxcsrMask; /* 4 : MXCSR register mask */
tFpRegEx fpReg[8]; /* 128 : x87 FPU/MMX registers */
tXmmReg xmmReg[8]; /* 128 : XMM registers */
unsigned char rsrvd3[176]; /* 176 : reserved */
} tFpRegSetEx __aligned(FP_REG_SET_ALIGN);

#else /* CONFIG_SSE == 0 */

typedef struct s_FpRegSetEx {
} tFpRegSetEx;

#endif /* CONFIG_SSE == 0 */

#else /* !CONFIG_LAZY_FP_SHARING && !CONFIG_EAGER_FP_SHARING */

/* empty floating point register definition */

typedef struct s_FpRegSet {
} tFpRegSet;

typedef struct s_FpRegSetEx {
} tFpRegSetEx;

#endif /* CONFIG_LAZY_FP_SHARING || CONFIG_EAGER_FP_SHARING */

/*
* The following structure defines the set of 'volatile' x87 FPU/MMX/SSE
* registers. These registers need not be preserved by a called C function.
* Given that they are not preserved across function calls, they must be
* save/restored (along with s_coopFloatReg) when a preemptive context
* switch occurs.
*/

typedef struct s_preempFloatReg {
union {
/* threads with K_FP_REGS utilize this format */
tFpRegSet fpRegs;
/* threads with K_SSE_REGS utilize this format */
tFpRegSetEx fpRegsEx;
} floatRegsUnion;
} tPreempFloatReg;

/*
* The thread control structure definition. It contains the
* various fields to manage a _single_ thread. The TCS will be aligned
* to the appropriate architecture specific boundary via the
* z_new_thread() call.
*/

struct _thread_arch {

#if defined(CONFIG_LAZY_FP_SHARING)
/*
* Nested exception count to maintain setting of EXC_ACTIVE flag across
* outermost exception. EXC_ACTIVE is used by z_swap() lazy FP
* save/restore and by debug tools.
*/
unsigned excNestCount; /* nested exception count */
#endif /* CONFIG_LAZY_FP_SHARING */

/*
* The location of all floating point related structures/fields MUST be
* located at the end of struct k_thread. This way only the
* threads that actually utilize non-integer capabilities need to
* account for the increased memory required for storing FP state when
* sizing stacks.
*
* Given that stacks "grow down" on IA-32, and the TCS is located
* at the start of a thread's "workspace" memory, the stacks of
* threads that do not utilize floating point instruction can
* effectively consume the memory occupied by the 'tPreempFloatReg'
* struct without ill effect.
*/
tPreempFloatReg preempFloatReg; /* volatile float register storage */
};

typedef struct _thread_arch _thread_arch_t;

#endif /* _ASMLANGUAGE */

#endif /* ZEPHYR_ARCH_X86_INCLUDE_IA32_KERNEL_ARCH_THREAD_H_ */

0 comments on commit f40fe36

Please sign in to comment.
You can’t perform that action at this time.