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 : #ifdef CONFIG_HW_SHADOW_STACK
241 : long *shstk_addr;
242 : long *shstk_base;
243 : size_t shstk_size;
244 : #endif
245 : };
246 :
247 : typedef struct _thread_arch _thread_arch_t;
248 :
249 : #endif /* _ASMLANGUAGE */
250 :
251 : #endif /* ZEPHYR_INCLUDE_ARCH_X86_IA32_THREAD_H_ */
|