Finish migrating the cpl into the thread structure.
[dragonfly.git] / sys / i386 / i386 / vm86bios.s
CommitLineData
984263bc
MD
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: src/sys/i386/i386/vm86bios.s,v 1.15.2.1 2000/05/16 06:58:07 dillon Exp $
8f41e33b 27 * $DragonFly: src/sys/i386/i386/Attic/vm86bios.s,v 1.6 2003/06/22 08:54:18 dillon Exp $
984263bc
MD
28 */
29
30#include <machine/asmacros.h> /* miscellaneous asm macros */
31#include <machine/trap.h>
32
33#include "assym.s"
34
35#define SCR_NEWPTD PCB_ESI /* readability macros */
36#define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */
37#define SCR_STACK PCB_ESP
38#define SCR_PGTABLE PCB_EBX
39#define SCR_ARGFRAME PCB_EIP
40#define SCR_TSS0 PCB_SPARE
41#define SCR_TSS1 (PCB_SPARE+4)
42
43 .data
44 ALIGN_DATA
45
46 .globl _in_vm86call, _vm86pcb
47
48_in_vm86call: .long 0
49_vm86pcb: .long 0
50
51 .text
52
53/*
54 * vm86_bioscall(struct trapframe_vm86 *vm86)
55 */
56ENTRY(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 SMP
67 pushl %edx
68 MP_LOCK /* Get global lock */
69 popl %edx
70#endif
71
72#if NNPX > 0
84b592ba 73 movl _curthread,%ecx
af0bff84 74 cmpl %ecx,_npxthread /* do we need to save fp? */
984263bc
MD
75 jne 1f
76 testl %ecx,%ecx
af0bff84 77 je 1f /* no curthread/npxthread */
984263bc 78 pushl %edx
b7c628e4 79 movl TD_PCB(%ecx),%ecx
984263bc
MD
80 addl $PCB_SAVEFPU,%ecx
81 pushl %ecx
82 call _npxsave
83 popl %ecx
84 popl %edx /* recover our pcb */
85#endif
86
af0bff84 87 /* %ecx is garbage at this point */
984263bc
MD
881:
89 movl SCR_VMFRAME(%edx),%ebx /* target frame location */
90 movl %ebx,%edi /* destination */
91 movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */
92 movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */
93 cld
94 rep
95 movsl /* copy frame to new stack */
96
b7c628e4
MD
97 /*
98 * YYY I really dislike replacing td_pcb, even temporarily. Find
99 * another way.
100 */
101 movl _curthread,%ebx
102 movl TD_PCB(%ebx),%eax /* save curpcb */
984263bc 103 pushl %eax /* save curpcb */
b7c628e4 104 movl %edx,TD_PCB(%ebx) /* set curpcb to vm86pcb */
984263bc
MD
105
106 movl _tss_gdt,%ebx /* entry in GDT */
107 movl 0(%ebx),%eax
108 movl %eax,SCR_TSS0(%edx) /* save first word */
109 movl 4(%ebx),%eax
110 andl $~0x200, %eax /* flip 386BSY -> 386TSS */
111 movl %eax,SCR_TSS1(%edx) /* save second word */
112
113 movl PCB_EXT(%edx),%edi /* vm86 tssd entry */
114 movl 0(%edi),%eax
115 movl %eax,0(%ebx)
116 movl 4(%edi),%eax
117 movl %eax,4(%ebx)
118 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
119 ltr %si
120
121 movl %cr3,%eax
122 pushl %eax /* save address space */
123 movl _IdlePTD,%ecx
124 movl %ecx,%ebx
125 addl $KERNBASE,%ebx /* va of Idle PTD */
126 movl 0(%ebx),%eax
127 pushl %eax /* old ptde != 0 when booting */
128 pushl %ebx /* keep for reuse */
129
130 movl %esp,SCR_STACK(%edx) /* save current stack location */
131
132 movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */
133 movl %eax,0(%ebx) /* ... install as PTD entry 0 */
134
135 movl %ecx,%cr3 /* new page tables */
136 movl SCR_VMFRAME(%edx),%esp /* switch to new stack */
137
138 call _vm86_prepcall /* finish setup */
139
140 movl $1,_in_vm86call /* set flag for trap() */
141
142 /*
8f41e33b 143 * Return via _doreti, restore the same cpl as our current cpl
984263bc 144 */
8f41e33b
MD
145 movl _curthread,%eax
146 pushl TD_MACH+MTD_CPL(%eax)
984263bc 147 subl $4,%esp /* dummy unit */
8f41e33b 148 incb _intr_nesting_level /* dummy to match doreti */
984263bc
MD
149 MEXITCOUNT
150 jmp _doreti
151
152
153/*
154 * vm86_biosret(struct trapframe_vm86 *vm86)
155 */
156ENTRY(vm86_biosret)
157 movl _vm86pcb,%edx /* data area */
158
159 movl 4(%esp),%esi /* source */
160 movl SCR_ARGFRAME(%edx),%edi /* destination */
161 movl $VM86_FRAMESIZE/4,%ecx /* size */
162 cld
163 rep
164 movsl /* copy frame to original frame */
165
166 movl SCR_STACK(%edx),%esp /* back to old stack */
167 popl %ebx /* saved va of Idle PTD */
168 popl %eax
169 movl %eax,0(%ebx) /* restore old pte */
170 popl %eax
171 movl %eax,%cr3 /* install old page table */
172
173 movl $0,_in_vm86call /* reset trapflag */
174
175 movl _tss_gdt,%ebx /* entry in GDT */
176 movl SCR_TSS0(%edx),%eax
177 movl %eax,0(%ebx) /* restore first word */
178 movl SCR_TSS1(%edx),%eax
179 movl %eax,4(%ebx) /* restore second word */
180 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
181 ltr %si
b7c628e4
MD
182
183 movl _curthread,%eax
184 popl TD_PCB(%eax) /* restore curpcb */
984263bc
MD
185 movl SCR_ARGFRAME(%edx),%edx /* original stack frame */
186 movl TF_TRAPNO(%edx),%eax /* return (trapno) */
187
188 popl %gs
189 popl %edi
190 popl %esi
191 popl %ebp
192 popl %ebx
193 ret /* back to our normal program */