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