ia64/xen-unstable

view tools/firmware/vmxassist/trap.S @ 12773:275a8f9a0710

Remove useless segments push/pop in VMXAssist.
According to Intel Spec, segments registors are cleared when exiting
virtual-8086 mode through trap or interrupts gate, so it's no need to
save their values in stack.
Signed-off-by: Xin Li <xin.b.li@intel.com>
author kfraser@localhost.localdomain
date Mon Dec 04 09:20:12 2006 +0000 (2006-12-04)
parents 4c40bed66ade
children
line source
1 /*
2 * trap.S: Trap and world switch handlers
3 *
4 * Leendert van Doorn, leendert@watson.ibm.com
5 * Copyright (c) 2005, International Business Machines Corporation.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 */
20 #include "machine.h"
21 #include "vm86.h"
22 #include "offsets.h"
24 /*
25 * All processor exception/faults/interrupts end up here.
26 *
27 * On an exception/fault, the processor pushes CS:EIP, SS, ESP and an
28 * optional error code onto the stack. The common_trap routine
29 * below saves the processor context and transfers control to trap()
30 * whose job it is to virtualize and pass on the trap.
31 */
32 .macro TRAP_HANDLER trapno error
33 .text
34 .align 16
35 1: .if \error == 0
36 pushl $0 /* dummy error code */
37 .endif
38 pushl $\trapno
39 jmp common_trap
40 .section .rodata
41 .long 1b
42 .text
43 .endm
45 .section .rodata
46 .code32
47 .align 4
48 .global trap_handlers
49 trap_handlers:
50 TRAP_HANDLER 0, 0 /* divide error */
51 TRAP_HANDLER 1, 0 /* debug */
52 TRAP_HANDLER 2, 0 /* NMI interrupt */
53 TRAP_HANDLER 3, 0 /* breakpoint */
54 TRAP_HANDLER 4, 0 /* overflow */
55 TRAP_HANDLER 5, 0 /* BOUND range exceeded */
56 TRAP_HANDLER 6, 0 /* invalid opcode */
57 TRAP_HANDLER 7, 0 /* device not available */
58 TRAP_HANDLER 8, 1 /* double fault */
59 TRAP_HANDLER 9, 0 /* coprocessor segment overrun */
60 TRAP_HANDLER 10, 1 /* invalid TSS */
61 TRAP_HANDLER 11, 1 /* segment not present */
62 TRAP_HANDLER 12, 1 /* stack-segment fault */
63 TRAP_HANDLER 13, 1 /* general protection */
64 TRAP_HANDLER 14, 1 /* page fault */
65 TRAP_HANDLER 15, 0 /* reserved */
66 TRAP_HANDLER 16, 0 /* FPU floating-point error */
67 TRAP_HANDLER 17, 1 /* alignment check */
68 TRAP_HANDLER 18, 0 /* machine check */
69 TRAP_HANDLER 19, 0 /* SIMD floating-point error */
70 TRAP_HANDLER 20, 0 /* reserved */
71 TRAP_HANDLER 21, 0 /* reserved */
72 TRAP_HANDLER 22, 0 /* reserved */
73 TRAP_HANDLER 23, 0 /* reserved */
74 TRAP_HANDLER 24, 0 /* reserved */
75 TRAP_HANDLER 25, 0 /* reserved */
76 TRAP_HANDLER 26, 0 /* reserved */
77 TRAP_HANDLER 27, 0 /* reserved */
78 TRAP_HANDLER 28, 0 /* reserved */
79 TRAP_HANDLER 29, 0 /* reserved */
80 TRAP_HANDLER 30, 0 /* reserved */
81 TRAP_HANDLER 31, 0 /* reserved */
82 TRAP_HANDLER 32, 0 /* irq 0 */
83 TRAP_HANDLER 33, 0 /* irq 1 */
84 TRAP_HANDLER 34, 0 /* irq 2 */
85 TRAP_HANDLER 35, 0 /* irq 3 */
86 TRAP_HANDLER 36, 0 /* irq 4 */
87 TRAP_HANDLER 37, 0 /* irq 5 */
88 TRAP_HANDLER 38, 0 /* irq 6 */
89 TRAP_HANDLER 39, 0 /* irq 7 */
90 TRAP_HANDLER 40, 0 /* irq 8 */
91 TRAP_HANDLER 41, 0 /* irq 9 */
92 TRAP_HANDLER 42, 0 /* irq 10 */
93 TRAP_HANDLER 43, 0 /* irq 11 */
94 TRAP_HANDLER 44, 0 /* irq 12 */
95 TRAP_HANDLER 45, 0 /* irq 13 */
96 TRAP_HANDLER 46, 0 /* irq 14 */
97 TRAP_HANDLER 47, 0 /* irq 15 */
99 .text
100 .code32
101 .align 16
102 common_trap: /* common trap handler */
103 pushal
105 movl $(DATA_SELECTOR), %eax /* make sure these are sane */
106 movl %eax, %ds
107 movl %eax, %es
108 movl %eax, %fs
109 movl %eax, %gs
110 movl %esp, %ebp
112 pushl %ebp
113 pushl 36(%ebp)
114 pushl 32(%ebp)
115 call trap /* trap(trapno, errno, regs) */
116 addl $12, %esp
118 trap_return:
119 popal
120 addl $8, %esp /* skip trapno, errno */
121 iret
122 /* NOT REACHED */
125 /*
126 * A world switch to real mode occured. The hypervisor saved the
127 * executing context into "oldctx" and instantiated "newctx", which
128 * gets us here. Here we push a stack frame that is compatible with
129 * a trap frame (see above) so that we can handle this event as a
130 * regular trap.
131 */
132 .text
133 .align 16
134 .globl switch_to_real_mode
135 switch_to_real_mode:
136 pushl oldctx+VMX_ASSIST_CTX_GS_SEL /* 16 to 32-bit transition */
137 pushl oldctx+VMX_ASSIST_CTX_FS_SEL
138 pushl oldctx+VMX_ASSIST_CTX_DS_SEL
139 pushl oldctx+VMX_ASSIST_CTX_ES_SEL
140 pushl oldctx+VMX_ASSIST_CTX_SS_SEL
141 pushl oldctx+VMX_ASSIST_CTX_ESP
142 pushl oldctx+VMX_ASSIST_CTX_EFLAGS
143 pushl oldctx+VMX_ASSIST_CTX_CS_SEL
144 pushl oldctx+VMX_ASSIST_CTX_EIP
145 pushl $-1 /* trapno, errno */
146 pushl $-1
147 pushal
149 movl %esp, %ebp
150 pushl %ebp
151 call enter_real_mode
152 addl $4, %esp
154 jmp trap_return
155 /* NOT REACHED */
158 /*
159 * Switch to protected mode. At this point all the registers have
160 * been reloaded by trap_return and all we have to do is cause a
161 * world switch by turning on CR0.PE.
162 */
163 .text
164 .align 16
165 .globl switch_to_protected_mode
166 switch_to_protected_mode:
167 movl oldctx+VMX_ASSIST_CTX_CR0, %esp
168 movl %esp, %cr0 /* actual world switch ! */
170 /* NOT REACHED */
171 pushl $switch_failed
172 call panic
173 jmp .
175 .data
176 .align 4
177 switch_failed:
178 .asciz "World switch to protected mode failed\n"