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 2015 Nexenta Systems, Inc.  All rights reserved.
23 *
24 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
25 */
26/*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
27
28/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T		*/
29/*	All Rights Reserved	*/
30
31#ifndef	_SYS_REGSET_H
32#define	_SYS_REGSET_H
33
34#include <sys/feature_tests.h>
35
36#if !defined(_ASM)
37#include <sys/types.h>
38#endif
39#include <sys/mcontext.h>
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45/*
46 * The names and offsets defined here should be specified by the
47 * AMD64 ABI suppl.
48 *
49 * We make fsbase and gsbase part of the lwp context (since they're
50 * the only way to access the full 64-bit address range via the segment
51 * registers) and thus belong here too.  However we treat them as
52 * read-only; if %fs or %gs are updated, the results of the descriptor
53 * table lookup that those updates implicitly cause will be reflected
54 * in the corresponding fsbase and/or gsbase values the next time the
55 * context can be inspected.  However it is NOT possible to override
56 * the fsbase/gsbase settings via this interface.
57 *
58 * Direct modification of the base registers (thus overriding the
59 * descriptor table base address) can be achieved with _lwp_setprivate.
60 */
61
62#define	REG_GSBASE	27
63#define	REG_FSBASE	26
64#define	REG_DS		25
65#define	REG_ES		24
66
67#define	REG_GS		23
68#define	REG_FS		22
69#define	REG_SS		21
70#define	REG_RSP		20
71#define	REG_RFL		19
72#define	REG_CS		18
73#define	REG_RIP		17
74#define	REG_ERR		16
75#define	REG_TRAPNO	15
76#define	REG_RAX		14
77#define	REG_RCX		13
78#define	REG_RDX		12
79#define	REG_RBX		11
80#define	REG_RBP		10
81#define	REG_RSI		9
82#define	REG_RDI		8
83#define	REG_R8		7
84#define	REG_R9		6
85#define	REG_R10		5
86#define	REG_R11		4
87#define	REG_R12		3
88#define	REG_R13		2
89#define	REG_R14		1
90#define	REG_R15		0
91
92/*
93 * The names and offsets defined here are specified by i386 ABI suppl.
94 */
95
96#define	SS		18	/* only stored on a privilege transition */
97#define	UESP		17	/* only stored on a privilege transition */
98#define	EFL		16
99#define	CS		15
100#define	EIP		14
101#define	ERR		13
102#define	TRAPNO		12
103#define	EAX		11
104#define	ECX		10
105#define	EDX		9
106#define	EBX		8
107#define	ESP		7
108#define	EBP		6
109#define	ESI		5
110#define	EDI		4
111#define	DS		3
112#define	ES		2
113#define	FS		1
114#define	GS		0
115
116/* aliases for portability */
117
118#if defined(__amd64)
119
120#define	REG_PC	REG_RIP
121#define	REG_FP	REG_RBP
122#define	REG_SP	REG_RSP
123#define	REG_PS	REG_RFL
124#define	REG_R0	REG_RAX
125#define	REG_R1	REG_RDX
126
127#else	/* __i386 */
128
129#define	REG_PC	EIP
130#define	REG_FP	EBP
131#define	REG_SP	UESP
132#define	REG_PS	EFL
133#define	REG_R0	EAX
134#define	REG_R1	EDX
135
136#endif	/* __i386 */
137
138#define	NGREG	_NGREG
139
140#if !defined(_ASM)
141
142#ifdef	__i386
143/*
144 * (This structure definition is specified in the i386 ABI supplement)
145 * It's likely we can just get rid of the struct __old_fpu or maybe
146 * move it to $SRC/uts/intel/ia32/os/fpu.c which appears to be the
147 * only place that uses it.  See: www.illumos.org/issues/6284
148 */
149typedef struct __old_fpu {
150	union {
151		struct __old_fpchip_state	/* fp extension state */
152		{
153			int 	state[27];	/* 287/387 saved state */
154			int 	status;		/* status word saved at */
155						/* exception */
156		} fpchip_state;
157		struct __old_fp_emul_space	/* for emulator(s) */
158		{
159			char	fp_emul[246];
160			char	fp_epad[2];
161		} fp_emul_space;
162		int 	f_fpregs[62];		/* union of the above */
163	} fp_reg_set;
164	long    	f_wregs[33];		/* saved weitek state */
165} __old_fpregset_t;
166#endif	/* __i386 */
167
168#if defined(__amd64)
169#define	_NDEBUGREG	16
170#else
171#define	_NDEBUGREG	8
172#endif
173
174typedef struct dbregset {
175	unsigned long	debugreg[_NDEBUGREG];
176} dbregset_t;
177
178#endif	/* _ASM */
179
180/*
181 * The version of privregs.h that is used on implementations that run on
182 * processors that support the AMD64 instruction set is deliberately not
183 * imported here.
184 *
185 * The amd64 'struct regs' definition may -not- compatible with either
186 * 32-bit or 64-bit core file contents, nor with the ucontext.  As a result,
187 * the 'regs' structure cannot be used portably by applications, and should
188 * only be used by the kernel implementation.
189 *
190 * The inclusion of the i386 version of privregs.h allows for some limited
191 * source compatibility with 32-bit applications who expect to use
192 * 'struct regs' to match the context of a 32-bit core file, or a ucontext_t.
193 *
194 * Note that the ucontext_t actually describes the general register in terms
195 * of the gregset_t data type, as described in this file.  Note also
196 * that the core file content is defined by core(4) in terms of data types
197 * defined by procfs -- see proc(4).
198 */
199#if defined(__i386) && \
200	(!defined(_KERNEL) && !defined(_XPG4_2) || defined(__EXTENSIONS__))
201#include <sys/privregs.h>
202#endif	/* __i386 (!_KERNEL && !_XPG4_2 || __EXTENSIONS__) */
203
204#ifdef	__cplusplus
205}
206#endif
207
208#endif	/* _SYS_REGSET_H */
209