xref: /illumos-gate/usr/src/uts/intel/ia32/sys/privregs.h (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_IA32_SYS_PRIVREGS_H
28*7c478bd9Sstevel@tonic-gate #define	_IA32_SYS_PRIVREGS_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
33*7c478bd9Sstevel@tonic-gate extern "C" {
34*7c478bd9Sstevel@tonic-gate #endif
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate /*
37*7c478bd9Sstevel@tonic-gate  * This file describes the cpu's privileged register set, and
38*7c478bd9Sstevel@tonic-gate  * how the machine state is saved on the stack when a trap occurs.
39*7c478bd9Sstevel@tonic-gate  */
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate #if !defined(__i386)
42*7c478bd9Sstevel@tonic-gate #error	"non-i386 code depends on i386 privileged header!"
43*7c478bd9Sstevel@tonic-gate #endif
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #ifndef _ASM
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate /*
48*7c478bd9Sstevel@tonic-gate  * This is NOT the structure to use for general purpose debugging;
49*7c478bd9Sstevel@tonic-gate  * see /proc for that.  This is NOT the structure to use to decode
50*7c478bd9Sstevel@tonic-gate  * the ucontext or grovel about in a core file; see <sys/regset.h>.
51*7c478bd9Sstevel@tonic-gate  */
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate struct regs {
54*7c478bd9Sstevel@tonic-gate 	/*
55*7c478bd9Sstevel@tonic-gate 	 * Extra frame for mdb to follow through high level interrupts and
56*7c478bd9Sstevel@tonic-gate 	 * system traps.  Set them to 0 to terminate stacktrace.
57*7c478bd9Sstevel@tonic-gate 	 */
58*7c478bd9Sstevel@tonic-gate 	greg_t  r_savfp;	/* a copy of %ebp */
59*7c478bd9Sstevel@tonic-gate 	greg_t  r_savpc;	/* a copy of %eip */
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate 	greg_t	r_gs;
62*7c478bd9Sstevel@tonic-gate 	greg_t	r_fs;
63*7c478bd9Sstevel@tonic-gate 	greg_t	r_es;
64*7c478bd9Sstevel@tonic-gate 	greg_t	r_ds;
65*7c478bd9Sstevel@tonic-gate 	greg_t	r_edi;
66*7c478bd9Sstevel@tonic-gate 	greg_t	r_esi;
67*7c478bd9Sstevel@tonic-gate 	greg_t	r_ebp;
68*7c478bd9Sstevel@tonic-gate 	greg_t	r_esp;
69*7c478bd9Sstevel@tonic-gate 	greg_t	r_ebx;
70*7c478bd9Sstevel@tonic-gate 	greg_t	r_edx;
71*7c478bd9Sstevel@tonic-gate 	greg_t	r_ecx;
72*7c478bd9Sstevel@tonic-gate 	greg_t	r_eax;
73*7c478bd9Sstevel@tonic-gate 	greg_t	r_trapno;
74*7c478bd9Sstevel@tonic-gate 	greg_t	r_err;
75*7c478bd9Sstevel@tonic-gate 	greg_t	r_eip;
76*7c478bd9Sstevel@tonic-gate 	greg_t	r_cs;
77*7c478bd9Sstevel@tonic-gate 	greg_t	r_efl;
78*7c478bd9Sstevel@tonic-gate 	greg_t	r_uesp;
79*7c478bd9Sstevel@tonic-gate 	greg_t	r_ss;
80*7c478bd9Sstevel@tonic-gate };
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate #define	r_r0	r_eax		/* r0 for portability */
83*7c478bd9Sstevel@tonic-gate #define	r_r1	r_edx		/* r1 for portability */
84*7c478bd9Sstevel@tonic-gate #define	r_fp	r_ebp		/* system frame pointer */
85*7c478bd9Sstevel@tonic-gate #define	r_sp	r_uesp		/* user stack pointer */
86*7c478bd9Sstevel@tonic-gate #define	r_pc	r_eip		/* user's instruction pointer */
87*7c478bd9Sstevel@tonic-gate #define	r_ps	r_efl		/* user's EFLAGS */
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate #define	GREG_NUM	8	/* Number of regs between %edi and %eax */
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate #endif	/* !_ASM */
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL
94*7c478bd9Sstevel@tonic-gate #define	lwptoregs(lwp)	((struct regs *)((lwp)->lwp_regs))
95*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate /*
98*7c478bd9Sstevel@tonic-gate  * Save current frame on the stack.  Uses %eax.
99*7c478bd9Sstevel@tonic-gate  */
100*7c478bd9Sstevel@tonic-gate #define	__FRAME_PUSH				\
101*7c478bd9Sstevel@tonic-gate 	subl	$8, %esp;			\
102*7c478bd9Sstevel@tonic-gate 	movl	REGOFF_EIP(%esp), %eax;		\
103*7c478bd9Sstevel@tonic-gate 	movl	%eax, REGOFF_SAVPC(%esp);	\
104*7c478bd9Sstevel@tonic-gate 	movl	%ebp, REGOFF_SAVFP(%esp);
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate /*
107*7c478bd9Sstevel@tonic-gate  * Save segment registers on the stack.
108*7c478bd9Sstevel@tonic-gate  */
109*7c478bd9Sstevel@tonic-gate #define	__SEGREGS_PUSH		\
110*7c478bd9Sstevel@tonic-gate 	subl	$16, %esp;	\
111*7c478bd9Sstevel@tonic-gate 	movw	%ds, 12(%esp);	\
112*7c478bd9Sstevel@tonic-gate 	movw	%es, 8(%esp);	\
113*7c478bd9Sstevel@tonic-gate 	movw	%fs, 4(%esp);	\
114*7c478bd9Sstevel@tonic-gate 	movw	%gs, 0(%esp);
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate /*
117*7c478bd9Sstevel@tonic-gate  * Load segment register with kernel selectors.
118*7c478bd9Sstevel@tonic-gate  * %gs must be the last one to be set to make the
119*7c478bd9Sstevel@tonic-gate  * check in cmnint valid.
120*7c478bd9Sstevel@tonic-gate  */
121*7c478bd9Sstevel@tonic-gate #define	__SEGREGS_LOAD_KERNEL	\
122*7c478bd9Sstevel@tonic-gate 	movw	$KDS_SEL, %ax;	\
123*7c478bd9Sstevel@tonic-gate 	movw	$KFS_SEL, %cx;	\
124*7c478bd9Sstevel@tonic-gate 	movw	$KGS_SEL, %dx;	\
125*7c478bd9Sstevel@tonic-gate 	movw	%ax, %ds;	\
126*7c478bd9Sstevel@tonic-gate 	movw	%ax, %es;	\
127*7c478bd9Sstevel@tonic-gate 	movw	%cx, %fs;	\
128*7c478bd9Sstevel@tonic-gate 	movw	%dx, %gs;
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate /*
131*7c478bd9Sstevel@tonic-gate  * Restore segment registers off the stack.
132*7c478bd9Sstevel@tonic-gate  *
133*7c478bd9Sstevel@tonic-gate  * NOTE THE ORDER IS VITAL!
134*7c478bd9Sstevel@tonic-gate  *
135*7c478bd9Sstevel@tonic-gate  * Also note the subtle interdependency with kern_gpfault()
136*7c478bd9Sstevel@tonic-gate  * that needs to disassemble these instructions to diagnose
137*7c478bd9Sstevel@tonic-gate  * what happened when things (like bad segment register
138*7c478bd9Sstevel@tonic-gate  * values) go horribly wrong.
139*7c478bd9Sstevel@tonic-gate  */
140*7c478bd9Sstevel@tonic-gate #define	__SEGREGS_POP		\
141*7c478bd9Sstevel@tonic-gate 	movw	0(%esp), %gs;	\
142*7c478bd9Sstevel@tonic-gate 	movw	4(%esp), %fs;	\
143*7c478bd9Sstevel@tonic-gate 	movw	8(%esp), %es;	\
144*7c478bd9Sstevel@tonic-gate 	movw	12(%esp), %ds;	\
145*7c478bd9Sstevel@tonic-gate 	addl	$16, %esp;
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate /*
148*7c478bd9Sstevel@tonic-gate  * Macros for saving all registers necessary on interrupt entry,
149*7c478bd9Sstevel@tonic-gate  * and restoring them on exit.
150*7c478bd9Sstevel@tonic-gate  */
151*7c478bd9Sstevel@tonic-gate #define	INTR_PUSH			\
152*7c478bd9Sstevel@tonic-gate 	pusha;				\
153*7c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH			\
154*7c478bd9Sstevel@tonic-gate 	__FRAME_PUSH			\
155*7c478bd9Sstevel@tonic-gate 	cmpw	$KGS_SEL, REGOFF_GS(%esp);	\
156*7c478bd9Sstevel@tonic-gate 	je	7f;			\
157*7c478bd9Sstevel@tonic-gate 	movl	$0, REGOFF_SAVFP(%esp);	\
158*7c478bd9Sstevel@tonic-gate 	__SEGREGS_LOAD_KERNEL		\
159*7c478bd9Sstevel@tonic-gate 7:
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate #define	INTR_POP			\
162*7c478bd9Sstevel@tonic-gate 	popa;				\
163*7c478bd9Sstevel@tonic-gate 	addl	$8, %esp;	/* get TRAPNO and ERR off the stack */
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate #define	INTR_POP_USER			\
166*7c478bd9Sstevel@tonic-gate 	addl	$8, %esp;	/* get extra frame off the stack */ \
167*7c478bd9Sstevel@tonic-gate 	__SEGREGS_POP			\
168*7c478bd9Sstevel@tonic-gate 	INTR_POP
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate #define	INTR_POP_KERNEL			\
171*7c478bd9Sstevel@tonic-gate 	addl	$24, %esp;	/* skip extra frame and segment registers */ \
172*7c478bd9Sstevel@tonic-gate 	INTR_POP
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate /*
175*7c478bd9Sstevel@tonic-gate  * Macros for saving the original segment registers and restoring them
176*7c478bd9Sstevel@tonic-gate  * for fast traps.
177*7c478bd9Sstevel@tonic-gate  */
178*7c478bd9Sstevel@tonic-gate #define	FAST_INTR_PUSH	\
179*7c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH	\
180*7c478bd9Sstevel@tonic-gate 	__SEGREGS_LOAD_KERNEL
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate #define	FAST_INTR_POP	\
183*7c478bd9Sstevel@tonic-gate 	__SEGREGS_POP
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate #define	DISABLE_INTR_FLAGS		\
186*7c478bd9Sstevel@tonic-gate 	pushl	$F_OFF;			\
187*7c478bd9Sstevel@tonic-gate 	popfl;
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate #define	ENABLE_INTR_FLAGS		\
190*7c478bd9Sstevel@tonic-gate 	pushl	$F_ON;			\
191*7c478bd9Sstevel@tonic-gate 	popfl;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate /*
194*7c478bd9Sstevel@tonic-gate  * Macros for saving all registers necessary on system call entry,
195*7c478bd9Sstevel@tonic-gate  * and restoring them on exit.
196*7c478bd9Sstevel@tonic-gate  */
197*7c478bd9Sstevel@tonic-gate #define	SYSCALL_PUSH			\
198*7c478bd9Sstevel@tonic-gate 	pusha;				\
199*7c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH			\
200*7c478bd9Sstevel@tonic-gate 	__FRAME_PUSH			\
201*7c478bd9Sstevel@tonic-gate 	pushfl;				\
202*7c478bd9Sstevel@tonic-gate 	popl	%ecx;			\
203*7c478bd9Sstevel@tonic-gate 	orl	$PS_IE, %ecx;		\
204*7c478bd9Sstevel@tonic-gate 	movl	%ecx, REGOFF_EFL(%esp);	\
205*7c478bd9Sstevel@tonic-gate 	movl	$0, REGOFF_SAVFP(%esp);	\
206*7c478bd9Sstevel@tonic-gate 	__SEGREGS_LOAD_KERNEL
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate #define	SYSENTER_PUSH			\
209*7c478bd9Sstevel@tonic-gate 	pusha;				\
210*7c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH			\
211*7c478bd9Sstevel@tonic-gate 	__FRAME_PUSH			\
212*7c478bd9Sstevel@tonic-gate 	movl	$0, REGOFF_SAVFP(%esp);	\
213*7c478bd9Sstevel@tonic-gate 	__SEGREGS_LOAD_KERNEL
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate #define	SYSCALL_POP			\
216*7c478bd9Sstevel@tonic-gate 	INTR_POP_USER
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate #include <sys/controlregs.h>
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate /* Control register layout for panic dump */
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate #define	CREGSZ		36
225*7c478bd9Sstevel@tonic-gate #define	CREG_GDT	0
226*7c478bd9Sstevel@tonic-gate #define	CREG_IDT	8
227*7c478bd9Sstevel@tonic-gate #define	CREG_LDT	16
228*7c478bd9Sstevel@tonic-gate #define	CREG_TASKR	18
229*7c478bd9Sstevel@tonic-gate #define	CREG_CR0	20
230*7c478bd9Sstevel@tonic-gate #define	CREG_CR2	24
231*7c478bd9Sstevel@tonic-gate #define	CREG_CR3	28
232*7c478bd9Sstevel@tonic-gate #define	CREG_CR4	32
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate #if !defined(_ASM) && defined(_INT64_TYPE)
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate typedef	uint64_t	creg64_t;
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate struct cregs {
239*7c478bd9Sstevel@tonic-gate 	creg64_t	cr_gdt;
240*7c478bd9Sstevel@tonic-gate 	creg64_t	cr_idt;
241*7c478bd9Sstevel@tonic-gate 	uint16_t	cr_ldt;
242*7c478bd9Sstevel@tonic-gate 	uint16_t	cr_task;
243*7c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr0;
244*7c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr2;
245*7c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr3;
246*7c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr4;
247*7c478bd9Sstevel@tonic-gate };
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate #if defined(_KERNEL)
250*7c478bd9Sstevel@tonic-gate extern void getcregs(struct cregs *);
251*7c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate #endif	/* !_ASM && _INT64_TYPE */
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
256*7c478bd9Sstevel@tonic-gate }
257*7c478bd9Sstevel@tonic-gate #endif
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate #endif	/* !_IA32_SYS_PRIVREGS_H */
260