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