xref: /illumos-gate/usr/src/uts/intel/sys/regset.h (revision 2bbdd445a21f9d61f4a0ca0faf05d5ceb2bd91f3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 /*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T		*/
27 /*	All Rights Reserved	*/
28 
29 #ifndef	_SYS_REGSET_H
30 #define	_SYS_REGSET_H
31 
32 #include <sys/feature_tests.h>
33 
34 #if !defined(_ASM)
35 #include <sys/types.h>
36 #endif
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
43 
44 /*
45  * The names and offsets defined here should be specified by the
46  * AMD64 ABI suppl.
47  *
48  * We make fsbase and gsbase part of the lwp context (since they're
49  * the only way to access the full 64-bit address range via the segment
50  * registers) and thus belong here too.  However we treat them as
51  * read-only; if %fs or %gs are updated, the results of the descriptor
52  * table lookup that those updates implicitly cause will be reflected
53  * in the corresponding fsbase and/or gsbase values the next time the
54  * context can be inspected.  However it is NOT possible to override
55  * the fsbase/gsbase settings via this interface.
56  *
57  * Direct modification of the base registers (thus overriding the
58  * descriptor table base address) can be achieved with _lwp_setprivate.
59  */
60 
61 #define	REG_GSBASE	27
62 #define	REG_FSBASE	26
63 #define	REG_DS		25
64 #define	REG_ES		24
65 
66 #define	REG_GS		23
67 #define	REG_FS		22
68 #define	REG_SS		21
69 #define	REG_RSP		20
70 #define	REG_RFL		19
71 #define	REG_CS		18
72 #define	REG_RIP		17
73 #define	REG_ERR		16
74 #define	REG_TRAPNO	15
75 #define	REG_RAX		14
76 #define	REG_RCX		13
77 #define	REG_RDX		12
78 #define	REG_RBX		11
79 #define	REG_RBP		10
80 #define	REG_RSI		9
81 #define	REG_RDI		8
82 #define	REG_R8		7
83 #define	REG_R9		6
84 #define	REG_R10		5
85 #define	REG_R11		4
86 #define	REG_R12		3
87 #define	REG_R13		2
88 #define	REG_R14		1
89 #define	REG_R15		0
90 
91 /*
92  * The names and offsets defined here are specified by i386 ABI suppl.
93  */
94 
95 #define	SS		18	/* only stored on a privilege transition */
96 #define	UESP		17	/* only stored on a privilege transition */
97 #define	EFL		16
98 #define	CS		15
99 #define	EIP		14
100 #define	ERR		13
101 #define	TRAPNO		12
102 #define	EAX		11
103 #define	ECX		10
104 #define	EDX		9
105 #define	EBX		8
106 #define	ESP		7
107 #define	EBP		6
108 #define	ESI		5
109 #define	EDI		4
110 #define	DS		3
111 #define	ES		2
112 #define	FS		1
113 #define	GS		0
114 
115 /* aliases for portability */
116 
117 #if defined(__amd64)
118 
119 #define	REG_PC	REG_RIP
120 #define	REG_FP	REG_RBP
121 #define	REG_SP	REG_RSP
122 #define	REG_PS	REG_RFL
123 #define	REG_R0	REG_RAX
124 #define	REG_R1	REG_RDX
125 
126 #else	/* __i386 */
127 
128 #define	REG_PC	EIP
129 #define	REG_FP	EBP
130 #define	REG_SP	UESP
131 #define	REG_PS	EFL
132 #define	REG_R0	EAX
133 #define	REG_R1	EDX
134 
135 #endif	/* __i386 */
136 
137 #endif	/* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
138 
139 /*
140  * A gregset_t is defined as an array type for compatibility with the reference
141  * source. This is important due to differences in the way the C language
142  * treats arrays and structures as parameters.
143  */
144 #if defined(__amd64)
145 #define	_NGREG	28
146 #else
147 #define	_NGREG	19
148 #endif
149 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
150 #define	NGREG	_NGREG
151 #endif
152 
153 #if !defined(_ASM)
154 
155 #if defined(_LP64) || defined(_I32LPx)
156 typedef long	greg_t;
157 #else
158 typedef int	greg_t;
159 #endif
160 
161 #if defined(_SYSCALL32)
162 
163 typedef int32_t greg32_t;
164 typedef int64_t	greg64_t;
165 
166 #endif	/* _SYSCALL32 */
167 
168 typedef greg_t	gregset_t[_NGREG];
169 
170 #if defined(_SYSCALL32)
171 
172 #define	_NGREG32	19
173 #define	_NGREG64	28
174 
175 typedef greg32_t gregset32_t[_NGREG32];
176 typedef	greg64_t gregset64_t[_NGREG64];
177 
178 #endif	/* _SYSCALL32 */
179 
180 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
181 
182 /*
183  * Floating point definitions.
184  */
185 
186 /*
187  * This structure is written to memory by an 'fnsave' instruction
188  */
189 struct fnsave_state {
190 	uint16_t	f_fcw;
191 	uint16_t	__f_ign0;
192 	uint16_t	f_fsw;
193 	uint16_t	__f_ign1;
194 	uint16_t	f_ftw;
195 	uint16_t	__f_ign2;
196 	uint32_t	f_eip;
197 	uint16_t	f_cs;
198 	uint16_t	f_fop;
199 	uint32_t	f_dp;
200 	uint16_t	f_ds;
201 	uint16_t	__f_ign3;
202 	union {
203 		uint16_t fpr_16[5];	/* 80-bits of x87 state */
204 	} f_st[8];
205 };	/* 108 bytes */
206 
207 /*
208  * This structure is written to memory by an 'fxsave' instruction
209  * Note the variant behaviour of this instruction between long mode
210  * and legacy environments!
211  */
212 struct fxsave_state {
213 	uint16_t	fx_fcw;
214 	uint16_t	fx_fsw;
215 	uint16_t	fx_fctw;	/* compressed tag word */
216 	uint16_t	fx_fop;
217 #if defined(__amd64)
218 	uint64_t	fx_rip;
219 	uint64_t	fx_rdp;
220 #else
221 	uint32_t	fx_eip;
222 	uint16_t	fx_cs;
223 	uint16_t	__fx_ign0;
224 	uint32_t	fx_dp;
225 	uint16_t	fx_ds;
226 	uint16_t	__fx_ign1;
227 #endif
228 	uint32_t	fx_mxcsr;
229 	uint32_t	fx_mxcsr_mask;
230 	union {
231 		uint16_t fpr_16[5];	/* 80-bits of x87 state */
232 		u_longlong_t fpr_mmx;	/* 64-bit mmx register */
233 		uint32_t __fpr_pad[4];	/* (pad out to 128-bits) */
234 	} fx_st[8];
235 #if defined(__amd64)
236 	upad128_t	fx_xmm[16];	/* 128-bit registers */
237 	upad128_t	__fx_ign2[6];
238 #else
239 	upad128_t	fx_xmm[8];	/* 128-bit registers */
240 	upad128_t	__fx_ign2[14];
241 #endif
242 };	/* 512 bytes */
243 
244 /*
245  * This structure is written to memory by an 'xsave' instruction.
246  * First 512 byte is compatible with the format of an 'fxsave' area.
247  */
248 struct xsave_state {
249 	struct fxsave_state	xs_fxsave;
250 	uint64_t		xs_xstate_bv;	/* 512 */
251 	uint64_t		xs_rsv_mbz[2];
252 	uint64_t		xs_reserved[5];
253 	upad128_t		xs_ymm[16];	/* avx - 576 */
254 };	/* 832 bytes, asserted in fpnoextflt() */
255 
256 #if defined(__amd64)
257 
258 typedef struct fpu {
259 	union {
260 		struct fpchip_state {
261 			uint16_t cw;
262 			uint16_t sw;
263 			uint8_t  fctw;
264 			uint8_t  __fx_rsvd;
265 			uint16_t fop;
266 			uint64_t rip;
267 			uint64_t rdp;
268 			uint32_t mxcsr;
269 			uint32_t mxcsr_mask;
270 			union {
271 				uint16_t fpr_16[5];
272 				upad128_t __fpr_pad;
273 			} st[8];
274 			upad128_t xmm[16];
275 			upad128_t __fx_ign2[6];
276 			uint32_t status;	/* sw at exception */
277 			uint32_t xstatus;	/* mxcsr at exception */
278 		} fpchip_state;
279 		uint32_t	f_fpregs[130];
280 	} fp_reg_set;
281 } fpregset_t;
282 
283 #else	/* __i386 */
284 
285 /*
286  * This definition of the floating point structure is binary
287  * compatible with the Intel386 psABI definition, and source
288  * compatible with that specification for x87-style floating point.
289  * It also allows SSE/SSE2 state to be accessed on machines that
290  * possess such hardware capabilities.
291  */
292 typedef struct fpu {
293 	union {
294 		struct fpchip_state {
295 			uint32_t state[27];	/* 287/387 saved state */
296 			uint32_t status;	/* saved at exception */
297 			uint32_t mxcsr;		/* SSE control and status */
298 			uint32_t xstatus;	/* SSE mxcsr at exception */
299 			uint32_t __pad[2];	/* align to 128-bits */
300 			upad128_t xmm[8];	/* %xmm0-%xmm7 */
301 		} fpchip_state;
302 		struct fp_emul_space {		/* for emulator(s) */
303 			uint8_t	fp_emul[246];
304 			uint8_t	fp_epad[2];
305 		} fp_emul_space;
306 		uint32_t	f_fpregs[95];	/* union of the above */
307 	} fp_reg_set;
308 } fpregset_t;
309 
310 /*
311  * (This structure definition is specified in the i386 ABI supplement)
312  */
313 typedef struct __old_fpu {
314 	union {
315 		struct __old_fpchip_state	/* fp extension state */
316 		{
317 			int 	state[27];	/* 287/387 saved state */
318 			int 	status;		/* status word saved at */
319 						/* exception */
320 		} fpchip_state;
321 		struct __old_fp_emul_space	/* for emulator(s) */
322 		{
323 			char	fp_emul[246];
324 			char	fp_epad[2];
325 		} fp_emul_space;
326 		int 	f_fpregs[62];		/* union of the above */
327 	} fp_reg_set;
328 	long    	f_wregs[33];		/* saved weitek state */
329 } __old_fpregset_t;
330 
331 #endif	/* __i386 */
332 
333 #if defined(_SYSCALL32)
334 
335 /* Kernel view of user i386 fpu structure */
336 
337 typedef struct fpu32 {
338 	union {
339 		struct fpchip32_state {
340 			uint32_t state[27];	/* 287/387 saved state */
341 			uint32_t status;	/* saved at exception */
342 			uint32_t mxcsr;		/* SSE control and status */
343 			uint32_t xstatus;	/* SSE mxcsr at exception */
344 			uint32_t __pad[2];	/* align to 128-bits */
345 			uint32_t xmm[8][4];	/* %xmm0-%xmm7 */
346 		} fpchip_state;
347 		uint32_t	f_fpregs[95];	/* union of the above */
348 	} fp_reg_set;
349 } fpregset32_t;
350 
351 #endif	/* _SYSCALL32 */
352 
353 /*
354  * Kernel's FPU save area
355  */
356 typedef struct {
357 	union _kfpu_u {
358 		struct fxsave_state kfpu_fx;
359 #if defined(__i386)
360 		struct fnsave_state kfpu_fn;
361 #endif
362 		struct xsave_state kfpu_xs;
363 	} kfpu_u;
364 	uint32_t kfpu_status;		/* saved at #mf exception */
365 	uint32_t kfpu_xstatus;		/* saved at #xm exception */
366 } kfpu_t;
367 
368 #if defined(__amd64)
369 #define	NDEBUGREG	16
370 #else
371 #define	NDEBUGREG	8
372 #endif
373 
374 typedef struct dbregset {
375 	unsigned long	debugreg[NDEBUGREG];
376 } dbregset_t;
377 
378 /*
379  * Structure mcontext defines the complete hardware machine state.
380  * (This structure is specified in the i386 ABI suppl.)
381  */
382 typedef struct {
383 	gregset_t	gregs;		/* general register set */
384 	fpregset_t	fpregs;		/* floating point register set */
385 } mcontext_t;
386 
387 #if defined(_SYSCALL32)
388 
389 typedef struct {
390 	gregset32_t	gregs;		/* general register set */
391 	fpregset32_t	fpregs;		/* floating point register set */
392 } mcontext32_t;
393 
394 #endif	/* _SYSCALL32 */
395 
396 #endif	/* _ASM */
397 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
398 
399 /*
400  * The version of privregs.h that is used on implementations that run on
401  * processors that support the AMD64 instruction set is deliberately not
402  * imported here.
403  *
404  * The amd64 'struct regs' definition may -not- compatible with either
405  * 32-bit or 64-bit core file contents, nor with the ucontext.  As a result,
406  * the 'regs' structure cannot be used portably by applications, and should
407  * only be used by the kernel implementation.
408  *
409  * The inclusion of the i386 version of privregs.h allows for some limited
410  * source compatibility with 32-bit applications who expect to use
411  * 'struct regs' to match the context of a 32-bit core file, or a ucontext_t.
412  *
413  * Note that the ucontext_t actually describes the general register in terms
414  * of the gregset_t data type, as described in this file.  Note also
415  * that the core file content is defined by core(4) in terms of data types
416  * defined by procfs -- see proc(4).
417  */
418 #if defined(__i386) && \
419 	(!defined(_KERNEL) && !defined(_XPG4_2) || defined(__EXTENSIONS__))
420 #include <sys/privregs.h>
421 #endif	/* __i386 (!_KERNEL && !_XPG4_2 || __EXTENSIONS__) */
422 
423 /*
424  * The following is here for XPG4.2 standards compliance.
425  * regset.h is included in ucontext.h for the definition of
426  * mcontext_t, all of which breaks XPG4.2 namespace.
427  */
428 
429 #if defined(_XPG4_2) && !defined(__EXTENSIONS__) && !defined(_ASM)
430 
431 /*
432  * The following is here for UNIX 95 compliance (XPG Issue 4, Version 2
433  * System Interfaces and Headers). The structures included here are identical
434  * to those visible elsewhere in this header except that the structure
435  * element names have been changed in accordance with the X/Open namespace
436  * rules.  Specifically, depending on the name and scope, the names have
437  * been prepended with a single or double underscore (_ or __).  See the
438  * structure definitions in the non-X/Open namespace for more detailed
439  * comments describing each of these structures.
440  */
441 
442 #if defined(__amd64)
443 
444 typedef struct __fpu {
445 	union {
446 		struct __fpchip_state {
447 			uint16_t __fx_cw;
448 			uint16_t __fx_sw;
449 			uint16_t __fx_ctw;
450 			uint16_t __fx_op;
451 			uint64_t __fx_rip;
452 			uint64_t __fx_rdp;
453 			uint32_t __fx_mxcsr;
454 			uint32_t __fx_mxcsr_mask;
455 			union {
456 				uint16_t __fpr_16[5];
457 				upad128_t __fpr_pad;
458 			} __fx_st[8];
459 			upad128_t __fx_xmm[16];
460 			upad128_t __fx_ign2[6];
461 			uint32_t __status;
462 			uint32_t __xstatus;
463 		} __fpchip_state;
464 		uint32_t	__f_fpregs[130];
465 	} __fp_reg_set;
466 } fpregset_t;
467 
468 #else	/* __i386 */
469 
470 typedef struct __fpu {
471 	union {
472 		struct __fpchip_state {
473 			uint32_t __state[27];	/* 287/387 saved state */
474 			uint32_t __status;	/* saved at exception */
475 			uint32_t __mxcsr;	/* SSE control and status */
476 			uint32_t __xstatus;	/* SSE mxcsr at exception */
477 			uint32_t __pad[2];	/* align to 128-bits */
478 			upad128_t __xmm[8];	/* %xmm0-%xmm7 */
479 		} __fpchip_state;
480 		struct __fp_emul_space {	/* for emulator(s) */
481 			uint8_t	 __fp_emul[246];
482 			uint8_t	 __fp_epad[2];
483 		} __fp_emul_space;
484 		uint32_t	__f_fpregs[95];	/* union of the above */
485 	} __fp_reg_set;
486 } fpregset_t;
487 
488 #endif	/* __i386 */
489 
490 typedef struct {
491 	gregset_t	__gregs;	/* general register set */
492 	fpregset_t	__fpregs;	/* floating point register set */
493 } mcontext_t;
494 
495 #endif /* _XPG4_2 && !__EXTENSIONS__ && !_ASM */
496 
497 #ifdef	__cplusplus
498 }
499 #endif
500 
501 #endif	/* _SYS_REGSET_H */
502