2 * Copyright (c) 1998 Jonathan Lemon
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
26 * $FreeBSD: src/sys/i386/i386/vm86bios.s,v 1.15.2.1 2000/05/16 06:58:07 dillon Exp $
27 * $DragonFly: src/sys/platform/pc32/i386/vm86bios.s,v 1.14 2007/01/22 19:37:04 corecode Exp $
30 #include <machine/asmacros.h> /* miscellaneous asm macros */
31 #include <machine/trap.h>
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)
46 .globl in_vm86call, vm86pcb
54 * vm86_bioscall(struct trapframe_vm86 *vm86)
57 movl vm86pcb
,%edx
/* scratch data area */
59 movl
%eax
,SCR_ARGFRAME
(%edx
) /* save argument pointer */
67 movl PCPU
(curthread
),%ecx
68 cmpl %ecx
,PCPU
(npxthread
) /* do we need to save fp? */
71 je
1f
/* no curthread/npxthread */
73 pushl TD_SAVEFPU
(%ecx
)
75 popl
%ecx
/* pop argument (now garabge) */
76 popl
%edx
/* recover our pcb */
79 /* %ecx is garbage at this point */
81 movl SCR_VMFRAME
(%edx
),%ebx
/* target frame location */
82 movl
%ebx
,%edi
/* destination */
83 movl SCR_ARGFRAME
(%edx
),%esi
/* source (set on entry) */
84 movl $VM86_FRAMESIZE
/4,%ecx
/* sizeof(struct vm86frame)/4 */
87 movsl
/* copy frame to new stack */
90 * YYY I really dislike replacing td_pcb, even temporarily. Find
93 movl PCPU
(curthread
),%ebx
94 movl TD_PCB
(%ebx
),%eax
/* save curpcb */
95 pushl
%eax
/* save curpcb */
96 pushl TD_SAVEFPU
(%ebx
) /* save fpu pointer */
97 movl
%edx
,TD_PCB
(%ebx
) /* set curpcb to vm86pcb */
98 leal PCB_SAVEFPU
(%edx
),%eax
/* new savefpu pointer */
99 movl
%eax
,TD_SAVEFPU
(%ebx
)
101 movl PCPU
(tss_gdt
),%ebx
/* entry in GDT */
103 movl
%eax
,SCR_TSS0
(%edx
) /* save first word */
105 andl $~
0x200, %eax
/* flip 386BSY -> 386TSS */
106 movl
%eax
,SCR_TSS1
(%edx
) /* save second word */
108 movl PCB_EXT
(%edx
),%edi
/* vm86 tssd entry */
113 movl $GPROC0_SEL
*8,%esi
/* GSEL(entry, SEL_KPL) */
117 pushl
%eax
/* save address space */
120 addl $KERNBASE
,%ebx
/* va of Idle PTD */
122 pushl
%eax
/* old ptde != 0 when booting */
123 pushl
%ebx
/* keep for reuse */
125 movl
%esp
,SCR_STACK
(%edx
) /* save current stack location */
127 movl SCR_NEWPTD
(%edx
),%eax
/* mapping for vm86 page table */
128 movl
%eax
,0(%ebx
) /* ... install as PTD entry 0 */
130 movl
%ecx
,%cr3
/* new page tables */
131 movl SCR_VMFRAME
(%edx
),%esp
/* switch to new stack */
133 pushl
%esp
/* pass frame by reference */
134 call vm86_prepcall
/* finish setup */
137 movl $
1,in_vm86call
/* set flag for trap() */
140 * Return via _doreti, restore the same cpl as our current cpl
142 movl PCPU
(curthread
),%eax
143 pushl $
0 /* DUMMY CPL FOR DORETI */
149 * vm86_biosret(struct trapframe_vm86 *vm86)
152 movl vm86pcb
,%edx
/* data area */
154 movl
4(%esp
),%esi
/* source */
155 movl SCR_ARGFRAME
(%edx
),%edi
/* destination */
156 movl $VM86_FRAMESIZE
/4,%ecx
/* size */
159 movsl
/* copy frame to original frame */
161 movl SCR_STACK
(%edx
),%esp
/* back to old stack */
162 popl
%ebx
/* saved va of Idle PTD */
164 movl
%eax
,0(%ebx
) /* restore old pte */
166 movl
%eax
,%cr3
/* install old page table */
168 movl $
0,in_vm86call
/* reset trapflag */
170 movl PCPU
(tss_gdt
),%ebx
/* entry in GDT */
171 movl SCR_TSS0
(%edx
),%eax
172 movl
%eax
,0(%ebx
) /* restore first word */
173 movl SCR_TSS1
(%edx
),%eax
174 movl
%eax
,4(%ebx
) /* restore second word */
175 movl $GPROC0_SEL
*8,%esi
/* GSEL(entry, SEL_KPL) */
178 movl PCPU
(curthread
),%eax
179 popl TD_SAVEFPU
(%eax
) /* restore savefpu pointer */
180 popl TD_PCB
(%eax
) /* restore curpcb */
181 movl SCR_ARGFRAME
(%edx
),%edx
/* original stack frame */
182 movl TF_TRAPNO
(%edx
),%eax
/* return (trapno) */
189 ret
/* back to our normal program */