dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / uts / intel / amd64 / sys / privregs.h
bloba37c94a8bfaf280d0b5ca2793e071610f02a9c76
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _AMD64_SYS_PRIVREGS_H
28 #define _AMD64_SYS_PRIVREGS_H
30 #include <sys/ccompile.h>
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
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.
41 #if !defined(__amd64)
42 #error "non-amd64 code depends on amd64 privileged header!"
43 #endif
45 #ifndef _ASM
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>.
53 struct regs {
55 * Extra frame for mdb to follow through high level interrupts and
56 * system traps. Set them to 0 to terminate stacktrace.
58 greg_t r_savfp; /* a copy of %rbp */
59 greg_t r_savpc; /* a copy of %rip */
61 greg_t r_rdi; /* 1st arg to function */
62 greg_t r_rsi; /* 2nd arg to function */
63 greg_t r_rdx; /* 3rd arg to function, 2nd return register */
64 greg_t r_rcx; /* 4th arg to function */
66 greg_t r_r8; /* 5th arg to function */
67 greg_t r_r9; /* 6th arg to function */
68 greg_t r_rax; /* 1st return register, # SSE registers */
69 greg_t r_rbx; /* callee-saved, optional base pointer */
71 greg_t r_rbp; /* callee-saved, optional frame pointer */
72 greg_t r_r10; /* temporary register, static chain pointer */
73 greg_t r_r11; /* temporary register */
74 greg_t r_r12; /* callee-saved */
76 greg_t r_r13; /* callee-saved */
77 greg_t r_r14; /* callee-saved */
78 greg_t r_r15; /* callee-saved */
81 * fsbase and gsbase are sampled on every exception in DEBUG kernels
82 * only. They remain in the non-DEBUG kernel to avoid any flag days.
84 greg_t __r_fsbase; /* no longer used in non-DEBUG builds */
85 greg_t __r_gsbase; /* no longer used in non-DEBUG builds */
86 greg_t r_ds;
87 greg_t r_es;
88 greg_t r_fs; /* %fs is *never* used by the kernel */
89 greg_t r_gs;
91 greg_t r_trapno;
94 * (the rest of these are defined by the hardware)
96 greg_t r_err;
97 greg_t r_rip;
98 greg_t r_cs;
99 greg_t r_rfl;
100 greg_t r_rsp;
101 greg_t r_ss;
104 #define r_r0 r_rax /* r0 for portability */
105 #define r_r1 r_rdx /* r1 for portability */
106 #define r_fp r_rbp /* kernel frame pointer */
107 #define r_sp r_rsp /* user stack pointer */
108 #define r_pc r_rip /* user's instruction pointer */
109 #define r_ps r_rfl /* user's RFLAGS */
111 #ifdef _KERNEL
112 #define lwptoregs(lwp) ((struct regs *)((lwp)->lwp_regs))
113 #endif /* _KERNEL */
115 #else /* !_ASM */
117 #if defined(_MACHDEP)
119 #include <sys/machprivregs.h>
120 #include <sys/pcb.h>
123 * We can not safely sample {fs,gs}base on the hypervisor. The rdmsr
124 * instruction triggers a #gp fault which is emulated in the hypervisor
125 * on behalf of the guest. This is normally ok but if the guest is in
126 * the special failsafe handler it must not fault again or the hypervisor
127 * will kill the domain. We could use something different than INTR_PUSH
128 * in xen_failsafe_callback but for now we will not sample them.
130 #if defined(DEBUG) && !defined(__xpv)
131 #define __SAVE_BASES \
132 movl $MSR_AMD_FSBASE, %ecx; \
133 rdmsr; \
134 movl %eax, REGOFF_FSBASE(%rsp); \
135 movl %edx, REGOFF_FSBASE+4(%rsp); \
136 movl $MSR_AMD_GSBASE, %ecx; \
137 rdmsr; \
138 movl %eax, REGOFF_GSBASE(%rsp); \
139 movl %edx, REGOFF_GSBASE+4(%rsp)
140 #else
141 #define __SAVE_BASES
142 #endif
145 * Create a struct regs on the stack suitable for an
146 * interrupt trap.
148 * Assumes that the trap handler has already pushed an
149 * appropriate r_err and r_trapno
151 #define __SAVE_REGS \
152 movq %r15, REGOFF_R15(%rsp); \
153 movq %r14, REGOFF_R14(%rsp); \
154 movq %r13, REGOFF_R13(%rsp); \
155 movq %r12, REGOFF_R12(%rsp); \
156 movq %r11, REGOFF_R11(%rsp); \
157 movq %r10, REGOFF_R10(%rsp); \
158 movq %rbp, REGOFF_RBP(%rsp); \
159 movq %rbx, REGOFF_RBX(%rsp); \
160 movq %rax, REGOFF_RAX(%rsp); \
161 movq %r9, REGOFF_R9(%rsp); \
162 movq %r8, REGOFF_R8(%rsp); \
163 movq %rcx, REGOFF_RCX(%rsp); \
164 movq %rdx, REGOFF_RDX(%rsp); \
165 movq %rsi, REGOFF_RSI(%rsp); \
166 movq %rdi, REGOFF_RDI(%rsp); \
167 movq %rbp, REGOFF_SAVFP(%rsp); \
168 movq REGOFF_RIP(%rsp), %rcx; \
169 movq %rcx, REGOFF_SAVPC(%rsp); \
170 xorl %ecx, %ecx; \
171 movw %gs, %cx; \
172 movq %rcx, REGOFF_GS(%rsp); \
173 movw %fs, %cx; \
174 movq %rcx, REGOFF_FS(%rsp); \
175 movw %es, %cx; \
176 movq %rcx, REGOFF_ES(%rsp); \
177 movw %ds, %cx; \
178 movq %rcx, REGOFF_DS(%rsp); \
179 __SAVE_BASES
181 #define __RESTORE_REGS \
182 movq REGOFF_RDI(%rsp), %rdi; \
183 movq REGOFF_RSI(%rsp), %rsi; \
184 movq REGOFF_RDX(%rsp), %rdx; \
185 movq REGOFF_RCX(%rsp), %rcx; \
186 movq REGOFF_R8(%rsp), %r8; \
187 movq REGOFF_R9(%rsp), %r9; \
188 movq REGOFF_RAX(%rsp), %rax; \
189 movq REGOFF_RBX(%rsp), %rbx; \
190 movq REGOFF_RBP(%rsp), %rbp; \
191 movq REGOFF_R10(%rsp), %r10; \
192 movq REGOFF_R11(%rsp), %r11; \
193 movq REGOFF_R12(%rsp), %r12; \
194 movq REGOFF_R13(%rsp), %r13; \
195 movq REGOFF_R14(%rsp), %r14; \
196 movq REGOFF_R15(%rsp), %r15
199 * Push register state onto the stack. If we've
200 * interrupted userland, do a swapgs as well.
202 #define INTR_PUSH \
203 subq $REGOFF_TRAPNO, %rsp; \
204 __SAVE_REGS; \
205 cmpw $KCS_SEL, REGOFF_CS(%rsp); \
206 je 6f; \
207 movq $0, REGOFF_SAVFP(%rsp); \
208 SWAPGS; \
209 6: CLEAN_CS
211 #define INTR_POP \
212 leaq sys_lcall32(%rip), %r11;\
213 cmpq %r11, REGOFF_RIP(%rsp); \
214 __RESTORE_REGS; \
215 je 5f; \
216 cmpw $KCS_SEL, REGOFF_CS(%rsp);\
217 je 8f; \
218 5: SWAPGS; \
219 8: addq $REGOFF_RIP, %rsp
221 #define USER_POP \
222 __RESTORE_REGS; \
223 SWAPGS; \
224 addq $REGOFF_RIP, %rsp /* Adjust %rsp to prepare for iretq */
226 #define USER32_POP \
227 movl REGOFF_RDI(%rsp), %edi; \
228 movl REGOFF_RSI(%rsp), %esi; \
229 movl REGOFF_RDX(%rsp), %edx; \
230 movl REGOFF_RCX(%rsp), %ecx; \
231 movl REGOFF_RAX(%rsp), %eax; \
232 movl REGOFF_RBX(%rsp), %ebx; \
233 movl REGOFF_RBP(%rsp), %ebp; \
234 SWAPGS; \
235 addq $REGOFF_RIP, %rsp /* Adjust %rsp to prepare for iretq */
237 #define DFTRAP_PUSH \
238 subq $REGOFF_TRAPNO, %rsp; \
239 __SAVE_REGS
241 #endif /* _MACHDEP */
244 * Used to set rflags to known values at the head of an
245 * interrupt gate handler, i.e. interrupts are -already- disabled.
247 #define INTGATE_INIT_KERNEL_FLAGS \
248 pushq $F_OFF; \
249 popfq
251 #endif /* !_ASM */
253 #include <sys/controlregs.h>
255 #if defined(_KERNEL) && !defined(_ASM)
257 extern __GNU_INLINE ulong_t
258 getcr8(void)
260 uint64_t value;
262 __asm__ __volatile__(
263 "movq %%cr8, %0"
264 : "=r" (value));
265 return (value);
268 extern __GNU_INLINE void
269 setcr8(ulong_t value)
271 __asm__ __volatile__(
272 "movq %0, %%cr8"
273 : /* no output */
274 : "r" (value));
277 #endif /* _KERNEL && !_ASM */
279 /* Control register layout for panic dump */
281 #define CREGSZ 0x68
282 #define CREG_GDT 0
283 #define CREG_IDT 0x10
284 #define CREG_LDT 0x20
285 #define CREG_TASKR 0x28
286 #define CREG_CR0 0x30
287 #define CREG_CR2 0x38
288 #define CREG_CR3 0x40
289 #define CREG_CR4 0x48
290 #define CREG_CR8 0x50
291 #define CREG_KGSBASE 0x58
292 #define CREG_EFER 0x60
294 #if !defined(_ASM) && defined(_INT64_TYPE)
296 typedef uint64_t creg64_t;
297 typedef upad128_t creg128_t;
299 struct cregs {
300 creg128_t cr_gdt;
301 creg128_t cr_idt;
302 creg64_t cr_ldt;
303 creg64_t cr_task;
304 creg64_t cr_cr0;
305 creg64_t cr_cr2;
306 creg64_t cr_cr3;
307 creg64_t cr_cr4;
308 creg64_t cr_cr8;
309 creg64_t cr_kgsbase;
310 creg64_t cr_efer;
313 #if defined(_KERNEL)
314 extern void getcregs(struct cregs *);
315 #endif /* _KERNEL */
317 #endif /* !_ASM && _INT64_TYPE */
319 #ifdef __cplusplus
321 #endif
323 #endif /* !_AMD64_SYS_PRIVREGS_H */