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.


Modified boot and vmxassist to handle real/protected transition.
[palacios.git] / bios / 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         pushal
104
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
111
112         pushl   %ebp
113         pushl   36(%ebp)
114         pushl   32(%ebp)
115         call    trap                    /* trap(trapno, errno, regs) */
116         addl    $12, %esp
117
118 trap_return:
119         popal
120         addl    $8, %esp                /* skip trapno, errno */
121         iret
122         /* NOT REACHED */
123
124
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
148
149         movl    %esp, %ebp
150         pushl   %ebp
151         call    enter_real_mode
152         addl    $4, %esp
153
154         jmp     trap_return
155         /* NOT REACHED */
156
157
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 ! */
169
170         /* NOT REACHED */
171         pushl   $switch_failed
172         call    panic
173         jmp     .
174
175         .data
176         .align  4
177 switch_failed:
178         .asciz  "World switch to protected mode failed\n"
179