Line data Source code
1 1 : /* 2 : * Copyright (c) 2017 Intel Corporation 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : /** 8 : * @file 9 : * @brief Per-arch thread definition 10 : * 11 : * This file contains definitions for 12 : * 13 : * struct _thread_arch 14 : * struct _callee_saved 15 : * 16 : * necessary to instantiate instances of struct k_thread. 17 : */ 18 : 19 : #ifndef ZEPHYR_INCLUDE_ARCH_X86_IA32_THREAD_H_ 20 : #define ZEPHYR_INCLUDE_ARCH_X86_IA32_THREAD_H_ 21 : 22 : /** 23 : * Floating point register set alignment. 24 : * 25 : * If support for SSEx extensions is enabled a 16 byte boundary is required, 26 : * since the 'fxsave' and 'fxrstor' instructions require this. In all other 27 : * cases a 4 byte boundary is sufficient. 28 : */ 29 : #if defined(CONFIG_EAGER_FPU_SHARING) || defined(CONFIG_LAZY_FPU_SHARING) 30 : #ifdef CONFIG_X86_SSE 31 : #define FP_REG_SET_ALIGN 16 32 : #else 33 : #define FP_REG_SET_ALIGN 4 34 : #endif 35 : #else 36 : /* Unused, no special alignment requirements, use default alignment for 37 : * char buffers on this arch 38 : */ 39 1 : #define FP_REG_SET_ALIGN 1 40 : #endif /* CONFIG_*_FP_SHARING */ 41 : 42 : /* 43 : * Bits for _thread_arch.flags, see their use in intstub.S et al. 44 : */ 45 : 46 0 : #define X86_THREAD_FLAG_INT 0x01 47 0 : #define X86_THREAD_FLAG_EXC 0x02 48 0 : #define X86_THREAD_FLAG_ALL (X86_THREAD_FLAG_INT | X86_THREAD_FLAG_EXC) 49 : 50 : #ifndef _ASMLANGUAGE 51 : #include <stdint.h> 52 : #include <zephyr/arch/x86/mmustructs.h> 53 : 54 : /* 55 : * The following structure defines the set of 'non-volatile' integer registers. 56 : * These registers must be preserved by a called C function. These are the 57 : * only registers that need to be saved/restored when a cooperative context 58 : * switch occurs. 59 : */ 60 : 61 : struct _callee_saved { 62 : unsigned long esp; 63 : 64 : /* 65 : * The following registers are considered non-volatile, i.e. 66 : * callee-save, 67 : * but their values are pushed onto the stack rather than stored in the 68 : * TCS 69 : * structure: 70 : * 71 : * unsigned long ebp; 72 : * unsigned long ebx; 73 : * unsigned long esi; 74 : * unsigned long edi; 75 : */ 76 : 77 : }; 78 : 79 : typedef struct _callee_saved _callee_saved_t; 80 : 81 : /* 82 : * The macros CONFIG_{LAZY|EAGER}_FPU_SHARING shall be set to indicate that the 83 : * saving/restoring of the traditional x87 floating point (and MMX) registers 84 : * are supported by the kernel's context swapping code. The macro 85 : * CONFIG_X86_SSE shall _also_ be set if saving/restoring of the XMM 86 : * registers is also supported in the kernel's context swapping code. 87 : */ 88 : 89 : #if defined(CONFIG_EAGER_FPU_SHARING) || defined(CONFIG_LAZY_FPU_SHARING) 90 : 91 : /* definition of a single x87 (floating point / MMX) register */ 92 : 93 : typedef struct s_FpReg { 94 : unsigned char reg[10]; /* 80 bits: ST[0-7] */ 95 : } tFpReg; 96 : 97 : /* 98 : * The following is the "normal" floating point register save area, or 99 : * more accurately the save area required by the 'fnsave' and 'frstor' 100 : * instructions. The structure matches the layout described in the 101 : * "Intel(r) 64 and IA-32 Architectures Software Developer's Manual 102 : * Volume 1: Basic Architecture": Protected Mode x87 FPU State Image in 103 : * Memory, 32-Bit Format. 104 : */ 105 : 106 : typedef struct s_FpRegSet { /* # of bytes: name of register */ 107 : unsigned short fcw; /* 2 : x87 FPU control word */ 108 : unsigned short pad1; /* 2 : N/A */ 109 : unsigned short fsw; /* 2 : x87 FPU status word */ 110 : unsigned short pad2; /* 2 : N/A */ 111 : unsigned short ftw; /* 2 : x87 FPU tag word */ 112 : unsigned short pad3; /* 2 : N/A */ 113 : unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */ 114 : unsigned short cs; /* 2 : x87 FPU instruction pointer selector */ 115 : unsigned short fop : 11; /* 2 : x87 FPU opcode */ 116 : unsigned short pad4 : 5; /* : 5 bits = 00000 */ 117 : unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */ 118 : unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */ 119 : unsigned short pad5; /* 2 : N/A */ 120 : tFpReg fpReg[8]; /* 80 : ST0 -> ST7 */ 121 : } tFpRegSet __aligned(FP_REG_SET_ALIGN); 122 : 123 : #ifdef CONFIG_X86_SSE 124 : 125 : /* definition of a single x87 (floating point / MMX) register */ 126 : 127 : typedef struct s_FpRegEx { 128 : unsigned char reg[10]; /* 80 bits: ST[0-7] or MM[0-7] */ 129 : unsigned char rsrvd[6]; /* 48 bits: reserved */ 130 : } tFpRegEx; 131 : 132 : /* definition of a single XMM register */ 133 : 134 : typedef struct s_XmmReg { 135 : unsigned char reg[16]; /* 128 bits: XMM[0-7] */ 136 : } tXmmReg; 137 : 138 : /* 139 : * The following is the "extended" floating point register save area, or 140 : * more accurately the save area required by the 'fxsave' and 'fxrstor' 141 : * instructions. The structure matches the layout described in the 142 : * "Intel 64 and IA-32 Architectures Software Developer's Manual 143 : * Volume 2A: Instruction Set Reference, A-M", except for the bytes from offset 144 : * 464 to 511 since these "are available to software use. The processor does 145 : * not write to bytes 464:511 of an FXSAVE area". 146 : * 147 : * This structure must be aligned on a 16 byte boundary when the instructions 148 : * fxsave/fxrstor are used to write/read the data to/from the structure. 149 : */ 150 : 151 : typedef struct s_FpRegSetEx /* # of bytes: name of register */ 152 : { 153 : unsigned short fcw; /* 2 : x87 FPU control word */ 154 : unsigned short fsw; /* 2 : x87 FPU status word */ 155 : unsigned char ftw; /* 1 : x87 FPU abridged tag word */ 156 : unsigned char rsrvd0; /* 1 : reserved */ 157 : unsigned short fop; /* 2 : x87 FPU opcode */ 158 : unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */ 159 : unsigned short cs; /* 2 : x87 FPU instruction pointer selector */ 160 : unsigned short rsrvd1; /* 2 : reserved */ 161 : unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */ 162 : unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */ 163 : unsigned short rsrvd2; /* 2 : reserved */ 164 : unsigned int mxcsr; /* 4 : MXCSR register state */ 165 : unsigned int mxcsrMask; /* 4 : MXCSR register mask */ 166 : tFpRegEx fpReg[8]; /* 128 : x87 FPU/MMX registers */ 167 : tXmmReg xmmReg[8]; /* 128 : XMM registers */ 168 : unsigned char rsrvd3[176]; /* 176 : reserved */ 169 : } tFpRegSetEx __aligned(FP_REG_SET_ALIGN); 170 : 171 : #else /* CONFIG_X86_SSE == 0 */ 172 : 173 : typedef struct s_FpRegSetEx { 174 : } tFpRegSetEx; 175 : 176 : #endif /* CONFIG_X86_SSE == 0 */ 177 : 178 : #else /* !CONFIG_LAZY_FPU_SHARING && !CONFIG_EAGER_FPU_SHARING */ 179 : 180 : /* empty floating point register definition */ 181 : 182 0 : typedef struct s_FpRegSet { 183 0 : } tFpRegSet; 184 : 185 0 : typedef struct s_FpRegSetEx { 186 0 : } tFpRegSetEx; 187 : 188 : #endif /* CONFIG_LAZY_FPU_SHARING || CONFIG_EAGER_FPU_SHARING */ 189 : 190 : /* 191 : * The following structure defines the set of 'volatile' x87 FPU/MMX/SSE 192 : * registers. These registers need not be preserved by a called C function. 193 : * Given that they are not preserved across function calls, they must be 194 : * save/restored (along with s_coopFloatReg) when a preemptive context 195 : * switch occurs. 196 : */ 197 : 198 0 : typedef struct s_preempFloatReg { 199 : union { 200 : /* threads with K_FP_REGS utilize this format */ 201 0 : tFpRegSet fpRegs; 202 : /* threads with K_SSE_REGS utilize this format */ 203 0 : tFpRegSetEx fpRegsEx; 204 0 : } floatRegsUnion; 205 0 : } tPreempFloatReg; 206 : 207 : /* 208 : * The thread control structure definition. It contains the 209 : * various fields to manage a _single_ thread. The TCS will be aligned 210 : * to the appropriate architecture specific boundary via the 211 : * arch_new_thread() call. 212 : */ 213 : 214 : struct _thread_arch { 215 : uint8_t flags; 216 : 217 : #ifdef CONFIG_USERSPACE 218 : #ifndef CONFIG_X86_COMMON_PAGE_TABLE 219 : /* Physical address of the page tables used by this thread */ 220 : uintptr_t ptables; 221 : #endif /* CONFIG_X86_COMMON_PAGE_TABLE */ 222 : 223 : /* Initial privilege mode stack pointer when doing a system call. 224 : * Un-set for supervisor threads. 225 : */ 226 : char *psp; 227 : #endif 228 : 229 : #if defined(CONFIG_LAZY_FPU_SHARING) 230 : /* 231 : * Nested exception count to maintain setting of EXC_ACTIVE flag across 232 : * outermost exception. EXC_ACTIVE is used by z_swap() lazy FP 233 : * save/restore and by debug tools. 234 : */ 235 : unsigned excNestCount; /* nested exception count */ 236 : #endif /* CONFIG_LAZY_FPU_SHARING */ 237 : 238 : tPreempFloatReg preempFloatReg; /* volatile float register storage */ 239 : }; 240 : 241 : typedef struct _thread_arch _thread_arch_t; 242 : 243 : #endif /* _ASMLANGUAGE */ 244 : 245 : #endif /* ZEPHYR_INCLUDE_ARCH_X86_IA32_THREAD_H_ */