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: releng/11.0/sys/i386/i386/vm86bios.s 281495 2015-04-13 15:22:45Z kib $
27 */
28
29 #include "opt_npx.h"
30
31 #include <machine/asmacros.h> /* miscellaneous asm macros */
32 #include <machine/trap.h>
33
34 #include "assym.s"
35
36 #define SCR_NEWPTD PCB_ESI /* readability macros */
37 #define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */
38 #define SCR_STACK PCB_ESP
39 #define SCR_PGTABLE PCB_EBX
40 #define SCR_ARGFRAME PCB_EIP
41 #define SCR_TSS0 PCB_VM86
42 #define SCR_TSS1 (PCB_VM86+4)
43
44 .data
45 ALIGN_DATA
46
47 .globl vm86pcb
48
49 vm86pcb: .long 0
50
51 .text
52
53 /*
54 * vm86_bioscall(struct trapframe_vm86 *vm86)
55 */
56 ENTRY(vm86_bioscall)
57 movl vm86pcb,%edx /* scratch data area */
58 movl 4(%esp),%eax
59 movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */
60 pushl %ebx
61 pushl %ebp
62 pushl %esi
63 pushl %edi
64 pushl %gs
65
66 #ifdef DEV_NPX
67 pushfl
68 cli
69 movl PCPU(CURTHREAD),%ecx
70 cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */
71 jne 1f
72 pushl %edx
73 movl TD_PCB(%ecx),%ecx
74 pushl PCB_SAVEFPU(%ecx)
75 call npxsave
76 addl $4,%esp
77 popl %edx /* recover our pcb */
78 1:
79 popfl
80 #endif
81
82 movl SCR_VMFRAME(%edx),%ebx /* target frame location */
83 movl %ebx,%edi /* destination */
84 movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */
85 movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */
86 cld
87 rep
88 movsl /* copy frame to new stack */
89
90 movl PCPU(CURPCB),%eax
91 pushl %eax /* save curpcb */
92 movl %edx,PCPU(CURPCB) /* set curpcb to vm86pcb */
93
94 movl PCPU(TSS_GDT),%ebx /* entry in GDT */
95 movl 0(%ebx),%eax
96 movl %eax,SCR_TSS0(%edx) /* save first word */
97 movl 4(%ebx),%eax
98 andl $~0x200, %eax /* flip 386BSY -> 386TSS */
99 movl %eax,SCR_TSS1(%edx) /* save second word */
100
101 movl PCB_EXT(%edx),%edi /* vm86 tssd entry */
102 movl 0(%edi),%eax
103 movl %eax,0(%ebx)
104 movl 4(%edi),%eax
105 movl %eax,4(%ebx)
106 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
107 ltr %si
108
109 movl %cr3,%eax
110 pushl %eax /* save address space */
111 movl IdlePTD,%ecx
112 movl %ecx,%ebx
113 addl $KERNBASE,%ebx /* va of Idle PTD */
114 movl 0(%ebx),%eax
115 pushl %eax /* old ptde != 0 when booting */
116 pushl %ebx /* keep for reuse */
117
118 movl %esp,SCR_STACK(%edx) /* save current stack location */
119
120 movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */
121 movl %eax,0(%ebx) /* ... install as PTD entry 0 */
122
123 #if defined(PAE) || defined(PAE_TABLES)
124 movl IdlePDPT,%ecx
125 #endif
126 movl %ecx,%cr3 /* new page tables */
127 movl SCR_VMFRAME(%edx),%esp /* switch to new stack */
128
129 pushl %esp
130 call vm86_prepcall /* finish setup */
131 add $4, %esp
132
133 /*
134 * Return via doreti
135 */
136 MEXITCOUNT
137 jmp doreti
138
139
140 /*
141 * vm86_biosret(struct trapframe_vm86 *vm86)
142 */
143 ENTRY(vm86_biosret)
144 movl vm86pcb,%edx /* data area */
145
146 movl 4(%esp),%esi /* source */
147 movl SCR_ARGFRAME(%edx),%edi /* destination */
148 movl $VM86_FRAMESIZE/4,%ecx /* size */
149 cld
150 rep
151 movsl /* copy frame to original frame */
152
153 movl SCR_STACK(%edx),%esp /* back to old stack */
154 popl %ebx /* saved va of Idle PTD */
155 popl %eax
156 movl %eax,0(%ebx) /* restore old pte */
157 popl %eax
158 movl %eax,%cr3 /* install old page table */
159
160 movl PCPU(TSS_GDT),%ebx /* entry in GDT */
161 movl SCR_TSS0(%edx),%eax
162 movl %eax,0(%ebx) /* restore first word */
163 movl SCR_TSS1(%edx),%eax
164 movl %eax,4(%ebx) /* restore second word */
165 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
166 ltr %si
167
168 popl PCPU(CURPCB) /* restore curpcb/curproc */
169 movl SCR_ARGFRAME(%edx),%edx /* original stack frame */
170 movl TF_TRAPNO(%edx),%eax /* return (trapno) */
171
172 popl %gs
173 popl %edi
174 popl %esi
175 popl %ebp
176 popl %ebx
177 ret /* back to our normal program */
Cache object: 1a51938fc21076768d220cda3f5d0561
|