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#pragma	ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <sys/asm_linkage.h>
30#include <sys/hypervisor.h>
31#include <sys/privregs.h>
32#include <sys/segments.h>
33#include <sys/traptrace.h>
34#include <sys/trap.h>
35#include <sys/psw.h>
36#include <sys/x86_archext.h>
37#include <sys/asm_misc.h>
38#include <sys/panic.h>
39
40#if !defined(__lint)
41#include "assym.h"
42#endif
43
44#if defined(__lint)
45
46void
47xpv_panic_callback(void)
48{}
49
50/* ARGSUSED */
51void
52xpv_panic_setcr3(ulong_t cr3)
53{}
54
55void
56xpv_panic_reload_cr3(void)
57{}
58
59void
60xpv_resetgs(void)
61{}
62
63#else	/* __lint */
64
65#if defined(__amd64)
66	ENTRY_NP(xpv_panic_getcr3)
67	movq	%cr3, %rax
68	ret
69	SET_SIZE(xpv_panic_getcr3)
70
71	ENTRY_NP(xpv_panic_setcr3)
72	movq	%rdi, %cr3
73	ret
74	SET_SIZE(xpv_panic_setcr3)
75
76	ENTRY(xpv_panic_reload_cr3)
77	movq	%cr3, %rdi
78	movq	%rdi, %cr3
79	ret
80	SET_SIZE(xpv_panic_reload_cr3)
81
82	ENTRY_NP(xpv_panic_prep)
83	pushq   %rbp
84	movq	%rsp, %rbp
85
86	subq	$REGSIZE, %rsp
87	movq	%rax, REGOFF_RAX(%rsp)
88	movq	%rbx, REGOFF_RBX(%rsp)
89	movq	%rsp, %rax
90	addq	$REGSIZE, %rax
91	movq	(%rax), %rbx
92	movq	%rbx, REGOFF_RBP(%rsp)
93	movq	8(%rax), %rbx
94	movq	%rbx, REGOFF_TRAPNO(%rsp)
95	movq	16(%rax), %rbx
96	movq	%rbx, REGOFF_ERR(%rsp)
97	movq	24(%rax), %rbx
98	movq	%rbx, REGOFF_RIP(%rsp)
99	movq	32(%rax), %rbx
100	movq	%rbx, REGOFF_CS(%rsp)
101	movq	40(%rax), %rbx
102	movq	%rbx, REGOFF_RFL(%rsp)
103	addq	$56, %rax
104	movq	%rax, REGOFF_RSP(%rsp)
105	xorl	%eax, %eax
106	movw	%gs, %ax
107	mov	%rax, REGOFF_GS(%rsp)
108	movw	%fs, %ax
109	mov	%rax, REGOFF_FS(%rsp)
110	movw	%es, %ax
111	mov	%rax, REGOFF_ES(%rsp)
112	movw	%ds, %ax
113	mov	%rax, REGOFF_DS(%rsp)
114	movw	%ss, %ax
115	mov	%rax, REGOFF_SS(%rsp)
116	movq	%rcx, REGOFF_RCX(%rsp)
117	movq	%rdx, REGOFF_RDX(%rsp)
118	movq	%rdi, REGOFF_RDI(%rsp)
119	movq	%rsi, REGOFF_RSI(%rsp)
120	movq	%r8, REGOFF_R8(%rsp)
121	movq	%r9, REGOFF_R9(%rsp)
122	movq	%r10, REGOFF_R10(%rsp)
123	movq	%r11, REGOFF_R11(%rsp)
124	movq	%r12, REGOFF_R12(%rsp)
125	movq	%r13, REGOFF_R13(%rsp)
126	movq	%r14, REGOFF_R14(%rsp)
127	movq	%r15, REGOFF_R15(%rsp)
128
129	movq	%rsp, %rdi
130	call	xpv_die
131	SET_SIZE(xpv_panic_prep)
132
133	/*
134	 * Switch to the Solaris panic stack and jump into the Xen panic
135	 * handling code.
136	 */
137	ENTRY_NP(xpv_panic_hdlr)
138	leaq	panic_stack(%rip), %rsp
139	addq	$PANICSTKSIZE, %rsp
140	call	xpv_do_panic
141	SET_SIZE(xpv_panic_hdlr)
142
143	ENTRY_NP(xpv_surprise_intr)
144	pushq   %rbp
145	movq	%rsp, %rbp
146	subq	$REGOFF_TRAPNO, %rsp
147	__SAVE_REGS
148	movq	%rsp, %rdi
149	addq	$REGOFF_TRAPNO, %rdi
150	call	xpv_interrupt
151	__RESTORE_REGS
152	addq	$REGOFF_TRAPNO, %rsp
153	popq	%rbp
154	iretq
155	SET_SIZE(xpv_surprise_intr)
156
157	ENTRY_NP(xpv_timer_trap)
158	pushq   %rbp
159	movq	%rsp, %rbp
160	subq	$REGOFF_TRAPNO, %rsp
161	__SAVE_REGS
162	movq	%rsp, %rdi
163	addq	$REGOFF_TRAPNO, %rdi
164	call	xpv_timer_tick
165	__RESTORE_REGS
166	addq	$REGOFF_TRAPNO, %rsp
167	popq	%rbp
168	iretq
169	SET_SIZE(xpv_timer_trap)
170
171#elif defined(__i386)
172
173	ENTRY_NP(xpv_panic_setcr3)
174	movl	4(%esp), %eax
175	movl	%eax, %cr3
176	ret
177	SET_SIZE(xpv_panic_setcr3)
178
179	ENTRY(xpv_panic_reload_cr3)
180	movl    %cr3, %eax
181	movl    %eax, %cr3
182	ret
183	SET_SIZE(xpv_panic_reload_cr3)
184
185	/*
186	 * Stack on entry:
187	 *  +------------+
188	 *  |   EFLAGS  |
189	 *  |   CS      |
190	 *  |   EIP     |
191	 *  |   Error   |
192	 *  |   Trap    |   <---- %esp
193	 *  +------------+
194	 */
195	ENTRY_NP(xpv_panic_prep)
196	pushl   %ebp
197	movl	%esp, %ebp
198
199	subl	$REGSIZE, %esp
200	movl	%eax, REGOFF_EAX(%esp)
201	movl	%ebx, REGOFF_EBX(%esp)
202	movl	%esp, %eax
203	addl	$REGSIZE, %eax
204	movl	(%eax), %ebx
205	movl	%ebx, REGOFF_EBP(%esp)
206	movl	4(%eax), %ebx
207	movl	%ebx, REGOFF_TRAPNO(%esp)
208	movl	8(%eax), %ebx
209	movl	%ebx, REGOFF_ERR(%esp)
210	movl	12(%eax), %ebx
211	movl	%ebx, REGOFF_EIP(%esp)
212	movl	16(%eax), %ebx
213	movl	%ebx, REGOFF_CS(%esp)
214	movl	20(%eax), %ebx
215	movl	%ebx, REGOFF_EFL(%esp)
216	addl	$28, %eax
217	movl	%eax, REGOFF_ESP(%esp)
218	xorl	%eax, %eax
219	movw	%gs, %ax
220	mov	%eax, REGOFF_GS(%esp)
221	movw	%fs, %ax
222	mov	%eax, REGOFF_FS(%esp)
223	movw	%es, %ax
224	mov	%eax, REGOFF_ES(%esp)
225	movw	%ds, %ax
226	mov	%eax, REGOFF_DS(%esp)
227	movw	%ss, %ax
228	mov	%eax, REGOFF_SS(%esp)
229	movl	%ecx, REGOFF_ECX(%esp)
230	movl	%edx, REGOFF_EDX(%esp)
231	movl	%edi, REGOFF_EDI(%esp)
232	movl	%esi, REGOFF_ESI(%esp)
233	pushl  	%esp
234	call	xpv_die
235	SET_SIZE(xpv_panic_prep)
236
237	/*
238	 * Switch to the Solaris panic stack and jump into the Xen panic
239	 * handling code.
240	 */
241	ENTRY_NP(xpv_panic_hdlr)
242	movl	4(%esp), %eax
243	lea	panic_stack, %esp
244	add	$PANICSTKSIZE, %esp
245	pushl	%eax
246	call	xpv_do_panic
247	SET_SIZE(xpv_panic_hdlr)
248
249	ENTRY_NP(xpv_surprise_intr)
250	push	%ebp
251	movl	%esp, %ebp
252	pusha
253	call	xpv_interrupt
254	popa
255	pop	%ebp
256	iret
257	SET_SIZE(xpv_surprise_intr)
258
259	ENTRY_NP(xpv_timer_trap)
260	push	%ebp
261	movl	%esp, %ebp
262	pusha
263	call	xpv_timer_tick
264	popa
265	pop	%ebp
266	iret
267	SET_SIZE(xpv_timer_trap)
268
269#endif	/* __i386 */
270
271	ENTRY_NP(xpv_panic_sti)
272	sti
273	ret
274	SET_SIZE(xpv_panic_sti)
275
276	ENTRY_NP(xpv_panic_halt)
277	sti
278	hlt
279	ret
280	SET_SIZE(xpv_panic_halt)
281
282	ENTRY_NP(xpv_panic_resetgs)
283	movl	$KGS_SEL, %eax
284	movw	%ax, %gs
285	ret
286	SET_SIZE(xpv_panic_resetgs)
287
288	ENTRY_NP(xpv_invaltrap)
289	push	$0xbad0
290	push	$0x0bad
291	jmp	xpv_panic_prep
292	SET_SIZE(xpv_invaltrap)
293
294	ENTRY_NP(xpv_div0trap)
295	push	$0
296	push	$T_ZERODIV
297	jmp	xpv_panic_prep
298	SET_SIZE(xpv_div0trap)
299
300	ENTRY_NP(xpv_dbgtrap)
301	push	$0
302	push	$T_SGLSTP
303	jmp	xpv_panic_prep
304	SET_SIZE(xpv_dbgtrap)
305
306	ENTRY_NP(xpv_nmiint)
307	push	$0
308	push	$T_NMIFLT
309	jmp	xpv_panic_prep
310	SET_SIZE(xpv_nmiint)
311
312	ENTRY_NP(xpv_brktrap)
313	/* XXX: check for error */
314	push	$T_BPTFLT
315	jmp	xpv_panic_prep
316	SET_SIZE(xpv_brktrap)
317
318	ENTRY_NP(xpv_ovflotrap)
319	push	$0
320	push	$T_OVFLW
321	jmp	xpv_panic_prep
322	SET_SIZE(xpv_ovflotrap)
323
324	ENTRY_NP(xpv_boundstrap)
325	push	$0
326	push	$T_BOUNDFLT
327	jmp	xpv_panic_prep
328	SET_SIZE(xpv_boundstrap)
329
330	ENTRY_NP(xpv_invoptrap)
331	push	$T_ILLINST
332	jmp	xpv_panic_prep
333	SET_SIZE(xpv_invoptrap)
334
335	ENTRY_NP(xpv_ndptrap)
336	push	$0
337	push	$T_NOEXTFLT
338	jmp	xpv_panic_prep
339	SET_SIZE(xpv_ndptrap)
340
341	ENTRY_NP(xpv_syserrtrap)
342	/* XXX: check for error */
343	push	$T_DBLFLT
344	jmp	xpv_panic_prep
345	SET_SIZE(xpv_syserrtrap)
346
347	ENTRY_NP(xpv_invtsstrap)
348	push	$T_TSSFLT
349	jmp	xpv_panic_prep
350	SET_SIZE(xpv_invtsstrap)
351
352	ENTRY_NP(xpv_segnptrap)
353	push	$T_SEGFLT
354	jmp	xpv_panic_prep
355	SET_SIZE(xpv_segnptrap)
356
357	ENTRY_NP(xpv_stktrap)
358	push	$T_STKFLT
359	jmp	xpv_panic_prep
360	SET_SIZE(xpv_stktrap)
361
362	ENTRY_NP(xpv_gptrap)
363	push	$T_GPFLT
364	jmp	xpv_panic_prep
365	SET_SIZE(xpv_gptrap)
366
367	ENTRY_NP(xpv_pftrap)
368	push	$T_PGFLT
369	jmp	xpv_panic_prep
370	SET_SIZE(xpv_pftrap)
371
372	ENTRY_NP(xpv_ndperr)
373	push	$0
374	push	$T_EXTERRFLT
375	jmp	xpv_panic_prep
376	SET_SIZE(xpv_ndperr)
377
378	ENTRY_NP(xpv_achktrap)
379	push	$T_ALIGNMENT
380	jmp	xpv_panic_prep
381	SET_SIZE(xpv_achktrap)
382
383	ENTRY_NP(xpv_mcetrap)
384	push	$0
385	push	$T_MCE
386	jmp	xpv_panic_prep
387	SET_SIZE(xpv_mcetrap)
388
389	ENTRY_NP(xpv_xmtrap)
390	push	$0
391	push	$T_SIMDFPE
392	jmp	xpv_panic_prep
393	SET_SIZE(xpv_xmtrap)
394
395#endif	/* __lint */
396