xref: /illumos-gate/usr/src/uts/intel/ia32/sys/privregs.h (revision fafb665d)
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  */
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  */
277c478bd9Sstevel@tonic-gate #ifndef	_IA32_SYS_PRIVREGS_H
287c478bd9Sstevel@tonic-gate #define	_IA32_SYS_PRIVREGS_H
307c478bd9Sstevel@tonic-gate #ifdef __cplusplus
317c478bd9Sstevel@tonic-gate extern "C" {
327c478bd9Sstevel@tonic-gate #endif
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * This file describes the cpu's privileged register set, and
367c478bd9Sstevel@tonic-gate  * how the machine state is saved on the stack when a trap occurs.
377c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate #if !defined(__i386)
407c478bd9Sstevel@tonic-gate #error	"non-i386 code depends on i386 privileged header!"
417c478bd9Sstevel@tonic-gate #endif
437c478bd9Sstevel@tonic-gate #ifndef _ASM
457c478bd9Sstevel@tonic-gate /*
467c478bd9Sstevel@tonic-gate  * This is NOT the structure to use for general purpose debugging;
477c478bd9Sstevel@tonic-gate  * see /proc for that.  This is NOT the structure to use to decode
487c478bd9Sstevel@tonic-gate  * the ucontext or grovel about in a core file; see <sys/regset.h>.
497c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate struct regs {
527c478bd9Sstevel@tonic-gate 	/*
537c478bd9Sstevel@tonic-gate 	 * Extra frame for mdb to follow through high level interrupts and
547c478bd9Sstevel@tonic-gate 	 * system traps.  Set them to 0 to terminate stacktrace.
557c478bd9Sstevel@tonic-gate 	 */
567c478bd9Sstevel@tonic-gate 	greg_t  r_savfp;	/* a copy of %ebp */
577c478bd9Sstevel@tonic-gate 	greg_t  r_savpc;	/* a copy of %eip */
597c478bd9Sstevel@tonic-gate 	greg_t	r_gs;
607c478bd9Sstevel@tonic-gate 	greg_t	r_fs;
617c478bd9Sstevel@tonic-gate 	greg_t	r_es;
627c478bd9Sstevel@tonic-gate 	greg_t	r_ds;
637c478bd9Sstevel@tonic-gate 	greg_t	r_edi;
647c478bd9Sstevel@tonic-gate 	greg_t	r_esi;
657c478bd9Sstevel@tonic-gate 	greg_t	r_ebp;
667c478bd9Sstevel@tonic-gate 	greg_t	r_esp;
677c478bd9Sstevel@tonic-gate 	greg_t	r_ebx;
687c478bd9Sstevel@tonic-gate 	greg_t	r_edx;
697c478bd9Sstevel@tonic-gate 	greg_t	r_ecx;
707c478bd9Sstevel@tonic-gate 	greg_t	r_eax;
717c478bd9Sstevel@tonic-gate 	greg_t	r_trapno;
727c478bd9Sstevel@tonic-gate 	greg_t	r_err;
737c478bd9Sstevel@tonic-gate 	greg_t	r_eip;
747c478bd9Sstevel@tonic-gate 	greg_t	r_cs;
757c478bd9Sstevel@tonic-gate 	greg_t	r_efl;
767c478bd9Sstevel@tonic-gate 	greg_t	r_uesp;
777c478bd9Sstevel@tonic-gate 	greg_t	r_ss;
787c478bd9Sstevel@tonic-gate };
807c478bd9Sstevel@tonic-gate #define	r_r0	r_eax		/* r0 for portability */
817c478bd9Sstevel@tonic-gate #define	r_r1	r_edx		/* r1 for portability */
827c478bd9Sstevel@tonic-gate #define	r_fp	r_ebp		/* system frame pointer */
837c478bd9Sstevel@tonic-gate #define	r_sp	r_uesp		/* user stack pointer */
847c478bd9Sstevel@tonic-gate #define	r_pc	r_eip		/* user's instruction pointer */
857c478bd9Sstevel@tonic-gate #define	r_ps	r_efl		/* user's EFLAGS */
877c478bd9Sstevel@tonic-gate #define	GREG_NUM	8	/* Number of regs between %edi and %eax */
897c478bd9Sstevel@tonic-gate #ifdef _KERNEL
907c478bd9Sstevel@tonic-gate #define	lwptoregs(lwp)	((struct regs *)((lwp)->lwp_regs))
917c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
93*ae115bc7Smrj #else	/* !_ASM */
95*ae115bc7Smrj #if defined(_MACHDEP)
97*ae115bc7Smrj #include <sys/machprivregs.h>
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate  * Save current frame on the stack.  Uses %eax.
1017c478bd9Sstevel@tonic-gate  */
1027c478bd9Sstevel@tonic-gate #define	__FRAME_PUSH				\
1037c478bd9Sstevel@tonic-gate 	subl	$8, %esp;			\
1047c478bd9Sstevel@tonic-gate 	movl	REGOFF_EIP(%esp), %eax;		\
1057c478bd9Sstevel@tonic-gate 	movl	%eax, REGOFF_SAVPC(%esp);	\
1067c478bd9Sstevel@tonic-gate 	movl	%ebp, REGOFF_SAVFP(%esp);
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate  * Save segment registers on the stack.
1107c478bd9Sstevel@tonic-gate  */
1117c478bd9Sstevel@tonic-gate #define	__SEGREGS_PUSH		\
1127c478bd9Sstevel@tonic-gate 	subl	$16, %esp;	\
1137c478bd9Sstevel@tonic-gate 	movw	%ds, 12(%esp);	\
1147c478bd9Sstevel@tonic-gate 	movw	%es, 8(%esp);	\
1157c478bd9Sstevel@tonic-gate 	movw	%fs, 4(%esp);	\
1167c478bd9Sstevel@tonic-gate 	movw	%gs, 0(%esp);
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate  * Load segment register with kernel selectors.
1207c478bd9Sstevel@tonic-gate  * %gs must be the last one to be set to make the
1217c478bd9Sstevel@tonic-gate  * check in cmnint valid.
1227c478bd9Sstevel@tonic-gate  */
1237c478bd9Sstevel@tonic-gate #define	__SEGREGS_LOAD_KERNEL	\
124990a5ef8Ssherrym 	movw	$KDS_SEL, %cx;	\
125990a5ef8Ssherrym 	movw	%cx, %ds;	\
126990a5ef8Ssherrym 	movw	%cx, %es;	\
1277c478bd9Sstevel@tonic-gate 	movw	$KFS_SEL, %cx;	\
1287c478bd9Sstevel@tonic-gate 	movw	$KGS_SEL, %dx;	\
1297c478bd9Sstevel@tonic-gate 	movw	%cx, %fs;	\
1307c478bd9Sstevel@tonic-gate 	movw	%dx, %gs;
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate  * Restore segment registers off the stack.
1347c478bd9Sstevel@tonic-gate  *
1357c478bd9Sstevel@tonic-gate  * NOTE THE ORDER IS VITAL!
1367c478bd9Sstevel@tonic-gate  *
1377c478bd9Sstevel@tonic-gate  * Also note the subtle interdependency with kern_gpfault()
1387c478bd9Sstevel@tonic-gate  * that needs to disassemble these instructions to diagnose
1397c478bd9Sstevel@tonic-gate  * what happened when things (like bad segment register
1407c478bd9Sstevel@tonic-gate  * values) go horribly wrong.
1417c478bd9Sstevel@tonic-gate  */
1427c478bd9Sstevel@tonic-gate #define	__SEGREGS_POP		\
1437c478bd9Sstevel@tonic-gate 	movw	0(%esp), %gs;	\
1447c478bd9Sstevel@tonic-gate 	movw	4(%esp), %fs;	\
1457c478bd9Sstevel@tonic-gate 	movw	8(%esp), %es;	\
1467c478bd9Sstevel@tonic-gate 	movw	12(%esp), %ds;	\
1477c478bd9Sstevel@tonic-gate 	addl	$16, %esp;
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate  * Macros for saving all registers necessary on interrupt entry,
1517c478bd9Sstevel@tonic-gate  * and restoring them on exit.
1527c478bd9Sstevel@tonic-gate  */
1537c478bd9Sstevel@tonic-gate #define	INTR_PUSH			\
154*ae115bc7Smrj 	cld;				\
1557c478bd9Sstevel@tonic-gate 	pusha;				\
1567c478bd9Sstevel@tonic-gate 	__SEGREGS_PUSH			\
1577c478bd9Sstevel@tonic-gate 	__FRAME_PUSH			\
158*ae115bc7Smrj 	cmpw	$KGS_SEL, REGOFF_GS(%esp); \
159*ae115bc7Smrj 	je	8f;			\
1607c478bd9Sstevel@tonic-gate 	movl	$0, REGOFF_SAVFP(%esp);	\
1617c478bd9Sstevel@tonic-gate 	__SEGREGS_LOAD_KERNEL		\
162*ae115bc7Smrj 8:	CLEAN_CS