vm86bios.s revision 87702
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: head/sys/i386/i386/vm86bios.s 87702 2001-12-11 23:33:44Z jhb $ 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_SPARE 42#define SCR_TSS1 (PCB_SPARE+4) 43 44 .data 45 ALIGN_DATA 46 47 .globl in_vm86call, vm86pcb 48 49in_vm86call: .long 0 50vm86pcb: .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 DEV_NPX 68 pushfl 69 cli 70 movl PCPU(CURTHREAD),%ecx 71 cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */ 72 jne 1f 73 testl %ecx,%ecx 74 je 1f /* no curproc/npxproc */ 75 pushl %edx 76 movl TD_PCB(%ecx),%ecx 77 addl $PCB_SAVEFPU,%ecx 78 pushl %ecx 79 call npxsave 80 popl %ecx 81 popl %edx /* recover our pcb */ 821: 83 popfl 84#endif 85 86 movl SCR_VMFRAME(%edx),%ebx /* target frame location */ 87 movl %ebx,%edi /* destination */ 88 movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */ 89 movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */ 90 cld 91 rep 92 movsl /* copy frame to new stack */ 93 94 movl PCPU(CURPCB),%eax 95 pushl %eax /* save curpcb */ 96 movl %edx,PCPU(CURPCB) /* set curpcb to vm86pcb */ 97 98 movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 99 movl 0(%ebx),%eax 100 movl %eax,SCR_TSS0(%edx) /* save first word */ 101 movl 4(%ebx),%eax 102 andl $~0x200, %eax /* flip 386BSY -> 386TSS */ 103 movl %eax,SCR_TSS1(%edx) /* save second word */ 104 105 movl PCB_EXT(%edx),%edi /* vm86 tssd entry */ 106 movl 0(%edi),%eax 107 movl %eax,0(%ebx) 108 movl 4(%edi),%eax 109 movl %eax,4(%ebx) 110 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 111 ltr %si 112 113 movl %cr3,%eax 114 pushl %eax /* save address space */ 115 movl IdlePTD,%ecx 116 movl %ecx,%ebx 117 addl $KERNBASE,%ebx /* va of Idle PTD */ 118 movl 0(%ebx),%eax 119 pushl %eax /* old ptde != 0 when booting */ 120 pushl %ebx /* keep for reuse */ 121 122 movl %esp,SCR_STACK(%edx) /* save current stack location */ 123 124 movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */ 125 movl %eax,0(%ebx) /* ... install as PTD entry 0 */ 126 127 movl %ecx,%cr3 /* new page tables */ 128 movl SCR_VMFRAME(%edx),%esp /* switch to new stack */ 129 130 call vm86_prepcall /* finish setup */ 131 132 movl $1,in_vm86call /* set flag for trap() */ 133 134 /* 135 * Return via doreti 136 */ 137 MEXITCOUNT 138 jmp doreti 139 140 141/* 142 * vm86_biosret(struct trapframe_vm86 *vm86) 143 */ 144ENTRY(vm86_biosret) 145 movl vm86pcb,%edx /* data area */ 146 147 movl 4(%esp),%esi /* source */ 148 movl SCR_ARGFRAME(%edx),%edi /* destination */ 149 movl $VM86_FRAMESIZE/4,%ecx /* size */ 150 cld 151 rep 152 movsl /* copy frame to original frame */ 153 154 movl SCR_STACK(%edx),%esp /* back to old stack */ 155 popl %ebx /* saved va of Idle PTD */ 156 popl %eax 157 movl %eax,0(%ebx) /* restore old pte */ 158 popl %eax 159 movl %eax,%cr3 /* install old page table */ 160 161 movl $0,in_vm86call /* reset trapflag */ 162 163 movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 164 movl SCR_TSS0(%edx),%eax 165 movl %eax,0(%ebx) /* restore first word */ 166 movl SCR_TSS1(%edx),%eax 167 movl %eax,4(%ebx) /* restore second word */ 168 movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 169 ltr %si 170 171 popl PCPU(CURPCB) /* restore curpcb/curproc */ 172 movl SCR_ARGFRAME(%edx),%edx /* original stack frame */ 173 movl TF_TRAPNO(%edx),%eax /* return (trapno) */ 174 175 popl %gs 176 popl %edi 177 popl %esi 178 popl %ebp 179 popl %ebx 180 ret /* back to our normal program */ 181