Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


*** empty log message ***
[palacios.git] / palacios / src / vmboot / vmxassist / trap.S
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"
23
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
44
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 */
98
99         .text
100         .code32
101         .align  16
102 common_trap:                            /* common trap handler */
103         pushl   %gs
104         pushl   %fs
105         pushl   %ds
106         pushl   %es
107         pushal
108
109         movl    $DATA_SELECTOR, %eax    /* make sure these are sane */
110         movl    %eax, %ds
111         movl    %eax, %es
112         movl    %eax, %fs
113         movl    %eax, %gs
114         movl    %esp, %ebp
115
116         pushl   %ebp
117         pushl   52(%ebp)
118         pushl   48(%ebp)
119         call    trap                    /* trap(trapno, errno, regs) */
120         addl    $12, %esp
121
122 trap_return:
123         popal
124         popl    %es
125         popl    %ds
126         popl    %fs
127         popl    %gs
128         addl    $8, %esp                /* skip trapno, errno */
129         iret
130         /* NOT REACHED */
131
132
133 /*
134  * A world switch to real mode occured. The hypervisor saved the
135  * executing context into "oldctx" and instantiated "newctx", which
136  * gets us here. Here we push a stack frame that is compatible with
137  * a trap frame (see above) so that we can handle this event as a
138  * regular trap.
139  */
140         .text
141         .align  16
142         .globl  switch_to_real_mode
143 switch_to_real_mode:
144         pushl   oldctx+VMX_ASSIST_CTX_GS_SEL /* 16 to 32-bit transition */
145         pushl   oldctx+VMX_ASSIST_CTX_FS_SEL
146         pushl   oldctx+VMX_ASSIST_CTX_DS_SEL
147         pushl   oldctx+VMX_ASSIST_CTX_ES_SEL
148         pushl   oldctx+VMX_ASSIST_CTX_SS_SEL
149         pushl   oldctx+VMX_ASSIST_CTX_ESP
150         pushl   oldctx+VMX_ASSIST_CTX_EFLAGS
151         pushl   oldctx+VMX_ASSIST_CTX_CS_SEL
152         pushl   oldctx+VMX_ASSIST_CTX_EIP
153         pushl   $-1                     /* trapno, errno */
154         pushl   $-1
155         pushl   %gs
156         pushl   %fs
157         pushl   %ds
158         pushl   %es
159         pushal
160
161         movl    %esp, %ebp
162         pushl   %ebp
163         call    enter_real_mode
164         addl    $4, %esp
165
166         jmp     trap_return
167         /* NOT REACHED */
168
169
170 /*
171  * Switch to protected mode. At this point all the registers have
172  * been reloaded by trap_return and all we have to do is cause a
173  * world switch by turning on CR0.PE.
174  */
175         .text
176         .align  16
177         .globl  switch_to_protected_mode
178 switch_to_protected_mode:
179         movl    oldctx+VMX_ASSIST_CTX_CR0, %esp
180         movl    %esp, %cr0              /* actual world switch ! */
181
182         /* NOT REACHED */
183         pushl   $switch_failed
184         call    panic
185         jmp     .
186
187         .data
188         .align  4
189 switch_failed:
190         .asciz  "World switch to protected mode failed\n"
191