xref: /illumos-gate/usr/src/uts/intel/ia32/sys/privregs.h (revision ae115bc7)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*ae115bc7Smrj  * Common Development and Distribution License (the "License").
6*ae115bc7Smrj  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*ae115bc7Smrj 
227c478bd9Sstevel@tonic-gate /*
23*ae115bc7Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #ifndef	_IA32_SYS_PRIVREGS_H
287c478bd9Sstevel@tonic-gate #define	_IA32_SYS_PRIVREGS_H
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #ifdef __cplusplus
337c478bd9Sstevel@tonic-gate extern "C" {
347c478bd9Sstevel@tonic-gate #endif
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * This file describes the cpu's privileged register set, and
387c478bd9Sstevel@tonic-gate  * how the machine state is saved on the stack when a trap occurs.
397c478bd9Sstevel@tonic-gate  */
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #if !defined(__i386)
427c478bd9Sstevel@tonic-gate #error	"non-i386 code depends on i386 privileged header!"
437c478bd9Sstevel@tonic-gate #endif
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #ifndef _ASM
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate  * This is NOT the structure to use for general purpose debugging;
497c478bd9Sstevel@tonic-gate  * see /proc for that.  This is NOT the structure to use to decode
507c478bd9Sstevel@tonic-gate  * the ucontext or grovel about in a core file; see <sys/regset.h>.
517c478bd9Sstevel@tonic-gate  */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate struct regs {
547c478bd9Sstevel@tonic-gate 	/*
557c478bd9Sstevel@tonic-gate 	 * Extra frame for mdb to follow through high level interrupts and
567c478bd9Sstevel@tonic-gate 	 * system traps.  Set them to 0 to terminate stacktrace.
577c478bd9Sstevel@tonic-gate 	 */
587c478bd9Sstevel@tonic-gate 	greg_t  r_savfp;	/* a copy of %ebp */
597c478bd9Sstevel@tonic-gate 	greg_t  r_savpc;	/* a copy of %eip */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate 	greg_t	r_gs;
627c478bd9Sstevel@tonic-gate 	greg_t	r_fs;
637c478bd9Sstevel@tonic-gate 	greg_t	r_es;
647c478bd9Sstevel@tonic-gate 	greg_t	r_ds;
657c478bd9Sstevel@tonic-gate 	greg_t	r_edi;
667c478bd9Sstevel@tonic-gate 	greg_t	r_esi;
677c478bd9Sstevel@tonic-gate 	greg_t	r_ebp;
687c478bd9Sstevel@tonic-gate 	greg_t	r_esp;
697c478bd9Sstevel@tonic-gate 	greg_t	r_ebx;
707c478bd9Sstevel@tonic-gate 	greg_t	r_edx;
717c478bd9Sstevel@tonic-gate 	greg_t	r_ecx;
727c478bd9Sstevel@tonic-gate 	greg_t	r_eax;
737c478bd9Sstevel@tonic-gate 	greg_t	r_trapno;
747c478bd9Sstevel@tonic-gate 	greg_t	r_err;
757c478bd9Sstevel@tonic-gate 	greg_t	r_eip;
767c478bd9Sstevel@tonic-gate 	greg_t	r_cs;
777c478bd9Sstevel@tonic-gate 	greg_t	r_efl;
787c478bd9Sstevel@tonic-gate 	greg_t	r_uesp;
797c478bd9Sstevel@tonic-gate 	greg_t	r_ss;
807c478bd9Sstevel@tonic-gate };
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate #define	r_r0	r_eax		/* r0 for portability */
837c478bd9Sstevel@tonic-gate #define	r_r1	r_edx		/* r1 for portability */
847c478bd9Sstevel@tonic-gate #define	r_fp	r_ebp		/* system frame pointer */
857c478bd9Sstevel@tonic-gate #define	r_sp	r_uesp		/* user stack pointer */
867c478bd9Sstevel@tonic-gate #define	r_pc	r_eip		/* user's instruction pointer */
877c478bd9Sstevel@tonic-gate #define	r_ps	r_efl		/* user's EFLAGS */
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate #define	GREG_NUM	8	/* Number of regs between %edi and %eax */
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #ifdef _KERNEL
927c478bd9Sstevel@tonic-gate #define	lwptoregs(lwp)	((struct regs *)((lwp)->lwp_regs))
937c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
947c478bd9Sstevel@tonic-gate 
95*ae115bc7Smrj #else	/* !_ASM */
96*ae115bc7Smrj 
97*ae115bc7Smrj #if defined(_MACHDEP)
98*ae115bc7Smrj 
99*ae115bc7Smrj #include <sys/machprivregs.h>
100*ae115bc7Smrj 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * Save current frame on the stack.  Uses %eax.
1037c478bd9Sstevel@tonic-gate  */
1047c478bd9Sstevel@tonic-gate #define	__FRAME_PUSH				\
1057c478bd9Sstevel@tonic-gate 	subl	$8, %esp;			\
1067c478bd9Sstevel@tonic-gate 	movl	REGOFF_EIP(%esp), %eax;		\
1077c478bd9Sstevel@tonic-gate 	movl	%eax, REGOFF_SAVPC(%esp);	\
1087c478bd9Sstevel@tonic-gate 	movl	%ebp, REGOFF_SAVFP(%esp);
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate /*
1117c478bd9Sstevel@tonic-gate  * Save segment registers on the stack.
1127c478bd9Sstevel@tonic-gate  */
1137c478bd9Sstevel@tonic-gate #define	__SEGREGS_PUSH		\
1147c478bd9Sstevel@tonic-gate 	subl	$16, %esp;	\
1157c478bd9Sstevel@tonic-gate 	movw	%ds, 12(%esp);	\
1167c478bd9Sstevel@tonic-gate 	movw	%es, 8(%esp);	\
1177c478bd9Sstevel@tonic-gate 	movw	%fs, 4(%esp);	\
1187c478bd9Sstevel@tonic-gate 	movw	%gs, 0(%esp);
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate  * Load segment register with kernel selectors.
1227c478bd9Sstevel@tonic-gate  * %gs must be the last one to be set to make the
1237c478bd9Sstevel@tonic-gate  * check in cmnint valid.
1247c478bd9Sstevel@tonic-gate  */
1257c478bd9Sstevel@tonic-gate #define	__SEGREGS_LOAD_KERNEL	\
126990a5ef8Ssherrym 	movw	$KDS_SEL, %cx;	\
127990a5ef8Ssherrym 	movw	%cx, %ds;	\
128990a5ef8Ssherrym 	movw	%cx, %es;	\
1297c478bd9Sstevel@tonic-gate 	movw	$KFS_SEL, %cx;	\
1307c478bd9Sstevel@tonic-gate 	movw	$KGS_SEL, %dx;	\
1317c478bd9Sstevel@tonic-gate 	movw	%cx, %fs;	\
1327c478bd9Sstevel@tonic-gate 	movw	%dx, %gs;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate /*
1357c478bd9Sstevel@tonic-gate  * Restore segment registers off the stack.
1367c478bd9Sstevel@tonic-gate  *
1377c478bd9Sstevel@tonic-gate  * NOTE THE ORDER IS VITAL!
1387c478bd9Sstevel@tonic-gate  *
1397c478bd9Sstevel@tonic-gate  * Also note the subtle interdependency with kern_gpfault()
1407c478bd9Sstevel@tonic-gate  * that needs to disassemble these instructions to diagnose
1417c478bd9Sstevel@tonic-gate  * what happened when things (like bad segment register
1427c478bd9Sstevel@tonic-gate  * values) go horribly wrong.
1437c478bd9Sstevel@tonic-gate  */
1447c478bd9Sstevel@tonic-gate #define	__SEGREGS_POP		\
1457c478bd9Sstevel@tonic-gate 	movw	0(%esp), %gs;	\
1467c478bd9Sstevel@tonic-gate 	movw	4(%esp), %fs;	\
1477c478bd9Sstevel@tonic-gate 	movw	8(%esp), %es;	\
1487c478bd9Sstevel@tonic-gate 	movw	12(%esp), %ds;	\
1497c478bd9Sstevel@tonic-gate 	addl	$16, %esp;
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate /*
1527c478bd9Sstevel@tonic-gate  * Macros for saving all registers necessary on interrupt entry,
1537c478bd9Sstevel@tonic-gate  * and restoring them on exit.
1547c478bd9Sstevel@tonic-gate  */
1557c478bd9Sstevel@tonic-gate #define	INTR_PUSH			\
156*ae115bc7Smrj 	cld;				\
1577c478bd9Sstevel@tonic-gate 	pusha;				\
1587c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH			\
1597c478bd9Sstevel@tonic-gate 	__FRAME_PUSH			\
160*ae115bc7Smrj 	cmpw	$KGS_SEL, REGOFF_GS(%esp); \
161*ae115bc7Smrj 	je	8f;			\
1627c478bd9Sstevel@tonic-gate 	movl	$0, REGOFF_SAVFP(%esp);	\
1637c478bd9Sstevel@tonic-gate 	__SEGREGS_LOAD_KERNEL		\
164*ae115bc7Smrj 8:	CLEAN_CS
1657c478bd9Sstevel@tonic-gate 
166*ae115bc7Smrj #define	__INTR_POP			\
1677c478bd9Sstevel@tonic-gate 	popa;				\
1687c478bd9Sstevel@tonic-gate 	addl	$8, %esp;	/* get TRAPNO and ERR off the stack */
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate #define	INTR_POP_USER			\
1717c478bd9Sstevel@tonic-gate 	addl	$8, %esp;	/* get extra frame off the stack */ \
1727c478bd9Sstevel@tonic-gate 	__SEGREGS_POP			\
173*ae115bc7Smrj 	__INTR_POP
1747c478bd9Sstevel@tonic-gate 
175*ae115bc7Smrj #define	INTR_POP_KERNEL					\
1767c478bd9Sstevel@tonic-gate 	addl	$24, %esp;	/* skip extra frame and segment registers */ \
177*ae115bc7Smrj 	__INTR_POP
1787c478bd9Sstevel@tonic-gate /*
1797c478bd9Sstevel@tonic-gate  * Macros for saving all registers necessary on system call entry,
1807c478bd9Sstevel@tonic-gate  * and restoring them on exit.
1817c478bd9Sstevel@tonic-gate  */
1827c478bd9Sstevel@tonic-gate #define	SYSCALL_PUSH			\
183*ae115bc7Smrj 	cld;				\
1847c478bd9Sstevel@tonic-gate 	pusha;				\
1857c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH			\
186990a5ef8Ssherrym 	subl	$8, %esp;		\
1877c478bd9Sstevel@tonic-gate 	pushfl;				\
1887c478bd9Sstevel@tonic-gate 	popl	%ecx;			\
1897c478bd9Sstevel@tonic-gate 	orl	$PS_IE, %ecx;		\
1907c478bd9Sstevel@tonic-gate 	movl	%ecx, REGOFF_EFL(%esp);	\
191990a5ef8Ssherrym 	movl	$0, REGOFF_SAVPC(%esp);	\
1927c478bd9Sstevel@tonic-gate 	movl	$0, REGOFF_SAVFP(%esp);	\
193*ae115bc7Smrj 	__SEGREGS_LOAD_KERNEL;		\
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate #define	SYSENTER_PUSH			\
196*ae115bc7Smrj 	cld;				\
1977c478bd9Sstevel@tonic-gate 	pusha;				\
1987c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH			\
199990a5ef8Ssherrym 	subl	$8, %esp;		\
200990a5ef8Ssherrym 	movl	$0, REGOFF_SAVPC(%esp);	\
2017c478bd9Sstevel@tonic-gate 	movl	$0, REGOFF_SAVFP(%esp);	\
2027c478bd9Sstevel@tonic-gate 	__SEGREGS_LOAD_KERNEL
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate #define	SYSCALL_POP			\
2057c478bd9Sstevel@tonic-gate 	INTR_POP_USER
2067c478bd9Sstevel@tonic-gate 
207*ae115bc7Smrj #endif	/* _MACHDEP */
2087c478bd9Sstevel@tonic-gate 
209*ae115bc7Smrj /*
210*ae115bc7Smrj  * This is used to set eflags to known values at the head of an
211*ae115bc7Smrj  * interrupt gate handler, i.e. interrupts are -already- disabled.
212*ae115bc7Smrj  */
213*ae115bc7Smrj #define	INTGATE_INIT_KERNEL_FLAGS	\
214*ae115bc7Smrj 	pushl	$F_OFF;			\
215*ae115bc7Smrj 	popfl
216*ae115bc7Smrj 
217*ae115bc7Smrj #endif	/* !_ASM */
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate #include <sys/controlregs.h>
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate /* Control register layout for panic dump */
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate #define	CREGSZ		36
2247c478bd9Sstevel@tonic-gate #define	CREG_GDT	0
2257c478bd9Sstevel@tonic-gate #define	CREG_IDT	8
2267c478bd9Sstevel@tonic-gate #define	CREG_LDT	16
2277c478bd9Sstevel@tonic-gate #define	CREG_TASKR	18
2287c478bd9Sstevel@tonic-gate #define	CREG_CR0	20
2297c478bd9Sstevel@tonic-gate #define	CREG_CR2	24
2307c478bd9Sstevel@tonic-gate #define	CREG_CR3	28
2317c478bd9Sstevel@tonic-gate #define	CREG_CR4	32
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate #if !defined(_ASM) && defined(_INT64_TYPE)
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate typedef	uint64_t	creg64_t;
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate struct cregs {
2387c478bd9Sstevel@tonic-gate 	creg64_t	cr_gdt;
2397c478bd9Sstevel@tonic-gate 	creg64_t	cr_idt;
2407c478bd9Sstevel@tonic-gate 	uint16_t	cr_ldt;
2417c478bd9Sstevel@tonic-gate 	uint16_t	cr_task;
2427c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr0;
2437c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr2;
2447c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr3;
2457c478bd9Sstevel@tonic-gate 	uint32_t	cr_cr4;
2467c478bd9Sstevel@tonic-gate };
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate #if defined(_KERNEL)
2497c478bd9Sstevel@tonic-gate extern void getcregs(struct cregs *);
2507c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate #endif	/* !_ASM && _INT64_TYPE */
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate #ifdef __cplusplus
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate #endif
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate #endif	/* !_IA32_SYS_PRIVREGS_H */
259