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