Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | /*
* 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_INCLUDE_ARCH_X86_IA32_THREAD_H_
#define ZEPHYR_INCLUDE_ARCH_X86_IA32_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
/*
* Bits for _thread_arch.flags, see their use in intstub.S et al.
*/
#define X86_THREAD_FLAG_INT 0x01
#define X86_THREAD_FLAG_EXC 0x02
#define X86_THREAD_FLAG_ALL (X86_THREAD_FLAG_INT | X86_THREAD_FLAG_EXC)
#ifndef _ASMLANGUAGE
#include <stdint.h>
#include <arch/x86/mmustructs.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
* arch_new_thread() call.
*/
struct _thread_arch {
u8_t flags;
#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_INCLUDE_ARCH_X86_IA32_THREAD_H_ */
|