vm86bios.s revision 47080
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 * $Id: vm86bios.s,v 1.11 1999/05/11 16:04:40 luoqi Exp $ 27 */ 28 29#include "opt_vm86.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_SPARE 42#define SCR_TSS1 (PCB_SPARE+4) 43 44 .data 45 ALIGN_DATA 46 47 .globl _in_vm86call, _vm86pcb 48 49_in_vm86call: .long 0 50_vm86pcb: .long 0 51 52 .text 53 54/* 55 * vm86_bioscall(struct trapframe_vm86 *vm86) 56 */ 57ENTRY(vm86_bioscall) 58 movl _vm86pcb,%edx /* scratch data area */ 59 movl 4(%esp),%eax 60 movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */ 61 pushl %ebx 62 pushl %ebp 63 pushl %esi 64 pushl %edi 65 pushl %gs 66 67#ifdef SMP 68 pushl %edx 69 ALIGN_LOCK /* Get global lock */ 70 popl %edx 71#endif 72 73#if NNPX > 0 74 movl _curproc,%ecx 75 cmpl %ecx,_npxproc /* do we need to save fp? */ 76 jne 1f 77 testl %ecx,%ecx 78 je 1f /* no curproc/npxproc */ 79 pushl %edx 80 movl P_ADDR(%ecx),%ecx 81 addl $PCB_SAVEFPU,%ecx 82 pushl %ecx 83 call _npxsave 84 popl %ecx 85 popl %edx /* recover our pcb */ 86#endif 87 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 97 movl _curpcb,%eax 98 pushl %eax /* save curpcb */ 99 movl %edx,_curpcb /* set curpcb to vm86pcb */ 100 101 movl $GPROC0_SEL,%esi 102 leal _gdt(,%esi,8),%ebx /* entry in GDT */ 103 movl 0(%ebx),%eax 104 movl %eax,SCR_TSS0(%edx) /* save first word */ 105 movl 4(%ebx),%eax 106 andl $~0x200, %eax /* flip 386BSY -> 386TSS */ 107 movl %eax,SCR_TSS1(%edx) /* save second word */ 108 109 movl PCB_EXT(%edx),%edi /* vm86 tssd entry */ 110 movl 0(%edi),%eax 111 movl %eax,0(%ebx) 112 movl 4(%edi),%eax 113 movl %eax,4(%ebx) 114 shll $3,%esi /* GSEL(entry, SEL_KPL) */ 115 ltr %si 116 117 movl %cr3,%eax 118 pushl %eax /* save address space */ 119 movl _IdlePTD,%ecx 120 movl %ecx,%ebx 121 addl $KERNBASE,%ebx /* va of Idle PTD */ 122 movl 0(%ebx),%eax 123 pushl %eax /* old ptde != 0 when booting */ 124 pushl %ebx /* keep for reuse */ 125 126 movl %esp,SCR_STACK(%edx) /* save current stack location */ 127 128 movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */ 129 movl %eax,0(%ebx) /* ... install as PTD entry 0 */ 130 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 ECPL_LOCK 143#ifdef CPL_AND_CML 144#error Not ready for CPL_AND_CML 145#endif 146 pushl _cpl /* cpl to restore */ 147 ECPL_UNLOCK 148#else 149 pushl _cpl /* cpl to restore */ 150#endif 151 subl $4,%esp /* dummy unit */ 152 MPLOCKED incb _intr_nesting_level 153 MEXITCOUNT 154 jmp _doreti 155 156 157/* 158 * vm86_biosret(struct trapframe_vm86 *vm86) 159 */ 160ENTRY(vm86_biosret) 161 movl _vm86pcb,%edx /* data area */ 162 163 movl 4(%esp),%esi /* source */ 164 movl SCR_ARGFRAME(%edx),%edi /* destination */ 165 movl $VM86_FRAMESIZE/4,%ecx /* size */ 166 cld 167 rep 168 movsl /* copy frame to original frame */ 169 170 movl SCR_STACK(%edx),%esp /* back to old stack */ 171 popl %ebx /* saved va of Idle PTD */ 172 popl %eax 173 movl %eax,0(%ebx) /* restore old pte */ 174 popl %eax 175 movl %eax,%cr3 /* install old page table */ 176 177 movl $0,_in_vm86call /* reset trapflag */ 178 179 movl $GPROC0_SEL,%esi 180 leal _gdt(,%esi,8),%ebx /* entry in GDT */ 181 movl SCR_TSS0(%edx),%eax 182 movl %eax,0(%ebx) /* restore first word */ 183 movl SCR_TSS1(%edx),%eax 184 movl %eax,4(%ebx) /* restore second word */ 185 shll $3,%esi /* GSEL(entry, SEL_KPL) */ 186 ltr %si 187 188 popl _curpcb /* restore curpcb/curproc */ 189 movl SCR_ARGFRAME(%edx),%edx /* original stack frame */ 190 movl TF_TRAPNO(%edx),%eax /* return (trapno) */ 191 192 popl %gs 193 popl %edi 194 popl %esi 195 popl %ebp 196 popl %ebx 197 ret /* back to our normal program */ 198