]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/i386/vm86bios.s
THIS BRANCH IS OBSOLETE, PLEASE READ:
[FreeBSD/FreeBSD.git] / sys / i386 / i386 / vm86bios.s
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.inc"
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_VM86
40 #define SCR_TSS1        (PCB_VM86+4)
41
42         .data
43         ALIGN_DATA
44
45         .globl  vm86pcb
46
47 vm86pcb:                .long   0
48
49         .text
50
51 /*
52  * vm86_bioscall(struct trapframe_vm86 *vm86)
53  */
54 ENTRY(vm86_bioscall)
55         movl    vm86pcb,%edx            /* scratch data area */
56         movl    4(%esp),%eax
57         movl    %eax,SCR_ARGFRAME(%edx) /* save argument pointer */
58         pushl   %ebx
59         pushl   %ebp
60         pushl   %esi
61         pushl   %edi
62         pushl   %gs
63
64         movl    PCPU(CURTHREAD),%ecx
65         cmpl    %ecx,PCPU(FPCURTHREAD)  /* do we need to save fp? */
66         jne     1f
67         pushl   %edx
68         movl    TD_PCB(%ecx),%ecx
69         pushl   PCB_SAVEFPU(%ecx)
70         movl    $npxsave,%eax
71         call    *%eax
72         addl    $4,%esp
73         popl    %edx                    /* recover our pcb */
74 1:
75         movl    SCR_VMFRAME(%edx),%ebx  /* target frame location */
76         movl    %ebx,%edi               /* destination */
77         movl    SCR_ARGFRAME(%edx),%esi /* source (set on entry) */
78         movl    $VM86_FRAMESIZE/4,%ecx  /* sizeof(struct vm86frame)/4 */
79         cld
80         rep
81         movsl                           /* copy frame to new stack */
82
83         movl    PCPU(CURPCB),%eax
84         pushl   %eax                    /* save curpcb */
85         movl    %edx,PCPU(CURPCB)       /* set curpcb to vm86pcb */
86
87         movl    PCPU(TSS_GDT),%ebx      /* entry in GDT */
88         movl    0(%ebx),%eax
89         movl    %eax,SCR_TSS0(%edx)     /* save first word */
90         movl    4(%ebx),%eax
91         andl    $~0x200, %eax           /* flip 386BSY -> 386TSS */
92         movl    %eax,SCR_TSS1(%edx)     /* save second word */
93
94         movl    PCB_EXT(%edx),%edi      /* vm86 tssd entry */
95         movl    0(%edi),%eax
96         movl    %eax,0(%ebx)
97         movl    4(%edi),%eax
98         movl    %eax,4(%ebx)
99         movl    $GPROC0_SEL*8,%esi      /* GSEL(entry, SEL_KPL) */
100         ltr     %si
101
102         movl    %cr3,%eax
103         pushl   %eax                    /* save address space */
104         cmpb    $0,pae_mode
105         jne     2f
106         movl    IdlePTD_nopae,%ecx      /* va (and pa) of Idle PTD */
107         jmp     3f
108 2:      movl    IdlePTD_pae,%ecx
109 3:      movl    %ecx,%ebx
110         movl    0(%ebx),%eax
111         pushl   %eax                    /* old ptde != 0 when booting */
112         pushl   %ebx                    /* keep for reuse */
113
114         movl    %esp,SCR_STACK(%edx)    /* save current stack location */
115
116         movl    SCR_NEWPTD(%edx),%eax   /* mapping for vm86 page table */
117         movl    %eax,0(%ebx)            /* ... install as PTD entry 0 */
118
119         cmpb    $0,pae_mode
120         je      4f
121         movl    IdlePDPT,%ecx
122 4:      movl    %ecx,%cr3               /* new page tables */
123         movl    SCR_VMFRAME(%edx),%esp  /* switch to new stack */
124
125         pushl   %esp
126         movl    $vm86_prepcall, %eax
127         call    *%eax                   /* finish setup */
128         add     $4, %esp
129         
130         /*
131          * Return via doreti
132          */
133         MEXITCOUNT
134         jmp     doreti
135
136
137 /*
138  * vm86_biosret(struct trapframe_vm86 *vm86)
139  */
140 ENTRY(vm86_biosret)
141         movl    vm86pcb,%edx            /* data area */
142
143         movl    4(%esp),%esi            /* source */
144         movl    SCR_ARGFRAME(%edx),%edi /* destination */
145         movl    $VM86_FRAMESIZE/4,%ecx  /* size */
146         cld
147         rep
148         movsl                           /* copy frame to original frame */
149
150         movl    SCR_STACK(%edx),%esp    /* back to old stack */
151         popl    %ebx                    /* saved va of Idle PTD */
152         popl    %eax
153         movl    %eax,0(%ebx)            /* restore old pte */
154         popl    %eax
155         movl    %eax,%cr3               /* install old page table */
156
157         movl    PCPU(TSS_GDT),%ebx              /* entry in GDT */
158         movl    SCR_TSS0(%edx),%eax
159         movl    %eax,0(%ebx)            /* restore first word */
160         movl    SCR_TSS1(%edx),%eax
161         movl    %eax,4(%ebx)            /* restore second word */
162         movl    $GPROC0_SEL*8,%esi      /* GSEL(entry, SEL_KPL) */
163         ltr     %si
164         
165         popl    PCPU(CURPCB)            /* restore curpcb/curproc */
166         movl    SCR_ARGFRAME(%edx),%edx /* original stack frame */
167         movl    TF_TRAPNO(%edx),%eax    /* return (trapno) */
168
169         popl    %gs
170         popl    %edi
171         popl    %esi
172         popl    %ebp
173         popl    %ebx
174         ret                             /* back to our normal program */