1 /*-
2 * Copyright (c) 1998 Jonathan Lemon
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 */
28
29 #include <machine/asmacros.h> /* miscellaneous asm macros */
30 #include <machine/trap.h>
31
32 #include "assym.s"
33
34 #define SCR_NEWPTD PCB_ESI /* readability macros */
35 #define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */
36 #define SCR_STACK PCB_ESP
37 #define SCR_PGTABLE PCB_EBX
38 #define SCR_ARGFRAME PCB_EIP
39 #define SCR_TSS0 PCB_SPARE
40 #define SCR_TSS1 (PCB_SPARE+4)
41
42 .data
43 ALIGN_DATA
44
45 .globl _in_vm86call, _vm86pcb
46
47 _in_vm86call: .long 0
48 _vm86pcb: .long 0
49
50 .text
51
52 /*
53 * vm86_bioscall(struct trapframe_vm86 *vm86)
54 */
55 ENTRY(vm86_bioscall)
56 movl _vm86pcb,%edx /* scratch data area */
57 movl 4(%esp),%eax
58 movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */
59 pushl %ebx
60 pushl %ebp
61 pushl %esi
62 pushl %edi
63 pushl %gs
64
65 #ifdef SMP
66 pushl %edx
67 MP_LOCK /* Get global lock */
68 popl %edx
69 #endif
70
71 #if NNPX > 0
72 movl _curproc,%ecx
73 cmpl %ecx,_npxproc /* do we need to save fp? */
74 jne 1f
75 testl %ecx,%ecx
76 je 1f /* no curproc/npxproc */
77 pushl %edx
78 movl P_ADDR(%ecx),%ecx
79 addl $PCB_SAVEFPU,%ecx
80 pushl %ecx
81 call _npxsave
82 popl %ecx
83 popl %edx /* recover our pcb */
84 #endif
85
86 1:
87 movl SCR_VMFRAME(%edx),%ebx /* target frame location */
88 movl %ebx,%edi /* destination */
89 movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */
90 movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */
91 cld
92 rep
93 movsl /* copy frame to new stack */
94
95 movl _curpcb,%eax
96 pushl %eax /* save curpcb */
97 movl %edx,_curpcb /* set curpcb to vm86pcb */
98
99 movl _tss_gdt,%ebx /* entry in GDT */
100 movl 0(%ebx),%eax
101 movl %eax,SCR_TSS0(%edx) /* save first word */
102 movl 4(%ebx),%eax
103 andl $~0x200, %eax /* flip 386BSY -> 386TSS */
104 movl %eax,SCR_TSS1(%edx) /* save second word */
105
106 movl PCB_EXT(%edx),%edi /* vm86 tssd entry */
107 movl 0(%edi),%eax
108 movl %eax,0(%ebx)
109 movl 4(%edi),%eax
110 movl %eax,4(%ebx)
111 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
112 ltr %si
113
114 movl %cr3,%eax
115 pushl %eax /* save address space */
116 movl _IdlePTD,%ecx
117 movl %ecx,%ebx
118 addl $KERNBASE,%ebx /* va of Idle PTD */
119 movl 0(%ebx),%eax
120 pushl %eax /* old ptde != 0 when booting */
121 pushl %ebx /* keep for reuse */
122
123 movl %esp,SCR_STACK(%edx) /* save current stack location */
124
125 movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */
126 movl %eax,0(%ebx) /* ... install as PTD entry 0 */
127
128 #ifdef PAE
129 movl $_IdlePDPT-KERNBASE,%ecx
130 #endif
131 movl %ecx,%cr3 /* new page tables */
132 movl SCR_VMFRAME(%edx),%esp /* switch to new stack */
133
134 call _vm86_prepcall /* finish setup */
135
136 movl $1,_in_vm86call /* set flag for trap() */
137
138 /*
139 * Return via _doreti
140 */
141 #ifdef SMP
142 pushl _cpl /* cpl to restore */
143 #else
144 pushl _cpl /* cpl to restore */
145 #endif
146 subl $4,%esp /* dummy unit */
147 incb _intr_nesting_level
148 MEXITCOUNT
149 jmp _doreti
150
151
152 /*
153 * vm86_biosret(struct trapframe_vm86 *vm86)
154 */
155 ENTRY(vm86_biosret)
156 movl _vm86pcb,%edx /* data area */
157
158 movl 4(%esp),%esi /* source */
159 movl SCR_ARGFRAME(%edx),%edi /* destination */
160 movl $VM86_FRAMESIZE/4,%ecx /* size */
161 cld
162 rep
163 movsl /* copy frame to original frame */
164
165 movl SCR_STACK(%edx),%esp /* back to old stack */
166 popl %ebx /* saved va of Idle PTD */
167 popl %eax
168 movl %eax,0(%ebx) /* restore old pte */
169 popl %eax
170 movl %eax,%cr3 /* install old page table */
171
172 movl $0,_in_vm86call /* reset trapflag */
173
174 movl _tss_gdt,%ebx /* entry in GDT */
175 movl SCR_TSS0(%edx),%eax
176 movl %eax,0(%ebx) /* restore first word */
177 movl SCR_TSS1(%edx),%eax
178 movl %eax,4(%ebx) /* restore second word */
179 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
180 ltr %si
181
182 popl _curpcb /* restore curpcb/curproc */
183 movl SCR_ARGFRAME(%edx),%edx /* original stack frame */
184 movl TF_TRAPNO(%edx),%eax /* return (trapno) */
185
186 popl %gs
187 popl %edi
188 popl %esi
189 popl %ebp
190 popl %ebx
191 ret /* back to our normal program */
Cache object: 9862b12cee4f90ade4a7080f7009f776
|