1*ccd9b49fSElliott Mitchell/*- 2*ccd9b49fSElliott Mitchell * Copyright (c) 1998 Jonathan Lemon 3*ccd9b49fSElliott Mitchell * All rights reserved. 4*ccd9b49fSElliott Mitchell * 5*ccd9b49fSElliott Mitchell * Redistribution and use in source and binary forms, with or without 6*ccd9b49fSElliott Mitchell * modification, are permitted provided that the following conditions 7*ccd9b49fSElliott Mitchell * are met: 8*ccd9b49fSElliott Mitchell * 1. Redistributions of source code must retain the above copyright 9*ccd9b49fSElliott Mitchell * notice, this list of conditions and the following disclaimer. 10*ccd9b49fSElliott Mitchell * 2. Redistributions in binary form must reproduce the above copyright 11*ccd9b49fSElliott Mitchell * notice, this list of conditions and the following disclaimer in the 12*ccd9b49fSElliott Mitchell * documentation and/or other materials provided with the distribution. 13*ccd9b49fSElliott Mitchell * 14*ccd9b49fSElliott Mitchell * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*ccd9b49fSElliott Mitchell * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*ccd9b49fSElliott Mitchell * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*ccd9b49fSElliott Mitchell * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*ccd9b49fSElliott Mitchell * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*ccd9b49fSElliott Mitchell * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*ccd9b49fSElliott Mitchell * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*ccd9b49fSElliott Mitchell * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*ccd9b49fSElliott Mitchell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*ccd9b49fSElliott Mitchell * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*ccd9b49fSElliott Mitchell * SUCH DAMAGE. 25*ccd9b49fSElliott Mitchell */ 26*ccd9b49fSElliott Mitchell 27*ccd9b49fSElliott Mitchell#include <machine/asmacros.h> /* miscellaneous asm macros */ 28*ccd9b49fSElliott Mitchell#include <machine/trap.h> 29*ccd9b49fSElliott Mitchell 30*ccd9b49fSElliott Mitchell#include "assym.inc" 31*ccd9b49fSElliott Mitchell 32*ccd9b49fSElliott Mitchell#define SCR_NEWPTD PCB_ESI /* readability macros */ 33*ccd9b49fSElliott Mitchell#define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */ 34*ccd9b49fSElliott Mitchell#define SCR_STACK PCB_ESP 35*ccd9b49fSElliott Mitchell#define SCR_PGTABLE PCB_EBX 36*ccd9b49fSElliott Mitchell#define SCR_ARGFRAME PCB_EIP 37*ccd9b49fSElliott Mitchell#define SCR_TSS0 PCB_VM86 38*ccd9b49fSElliott Mitchell#define SCR_TSS1 (PCB_VM86+4) 39*ccd9b49fSElliott Mitchell 40*ccd9b49fSElliott Mitchell .data 41*ccd9b49fSElliott Mitchell ALIGN_DATA 42*ccd9b49fSElliott Mitchell 43*ccd9b49fSElliott Mitchell .globl vm86pcb 44*ccd9b49fSElliott Mitchell 45*ccd9b49fSElliott Mitchellvm86pcb: .long 0 46*ccd9b49fSElliott Mitchell 47*ccd9b49fSElliott Mitchell .text 48*ccd9b49fSElliott Mitchell 49*ccd9b49fSElliott Mitchell/* 50*ccd9b49fSElliott Mitchell * vm86_bioscall(struct trapframe_vm86 *vm86) 51*ccd9b49fSElliott Mitchell */ 52*ccd9b49fSElliott MitchellENTRY(vm86_bioscall) 53*ccd9b49fSElliott Mitchell movl vm86pcb,%edx /* scratch data area */ 54*ccd9b49fSElliott Mitchell movl 4(%esp),%eax 55*ccd9b49fSElliott Mitchell movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */ 56*ccd9b49fSElliott Mitchell pushl %ebx 57*ccd9b49fSElliott Mitchell pushl %ebp 58*ccd9b49fSElliott Mitchell pushl %esi 59*ccd9b49fSElliott Mitchell pushl %edi 60*ccd9b49fSElliott Mitchell pushl %gs 61*ccd9b49fSElliott Mitchell 62*ccd9b49fSElliott Mitchell movl PCPU(CURTHREAD),%ecx 63*ccd9b49fSElliott Mitchell cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */ 64*ccd9b49fSElliott Mitchell jne 1f 65*ccd9b49fSElliott Mitchell pushl %edx 66*ccd9b49fSElliott Mitchell movl TD_PCB(%ecx),%ecx 67*ccd9b49fSElliott Mitchell pushl PCB_SAVEFPU(%ecx) 68*ccd9b49fSElliott Mitchell movl $npxsave,%eax 69*ccd9b49fSElliott Mitchell call *%eax 70*ccd9b49fSElliott Mitchell addl $4,%esp 71*ccd9b49fSElliott Mitchell popl %edx /* recover our pcb */ 72*ccd9b49fSElliott Mitchell1: 73*ccd9b49fSElliott Mitchell movl SCR_VMFRAME(%edx),%ebx /* target frame location */ 74*ccd9b49fSElliott Mitchell movl %ebx,%edi /* destination */ 75*ccd9b49fSElliott Mitchell movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */ 76*ccd9b49fSElliott Mitchell movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */ 77*ccd9b49fSElliott Mitchell cld 78*ccd9b49fSElliott Mitchell rep 79*ccd9b49fSElliott Mitchell movsl /* copy frame to new stack */ 80*ccd9b49fSElliott Mitchell 81*ccd9b49fSElliott Mitchell movl PCPU(CURPCB),%eax 82*ccd9b49fSElliott Mitchell pushl %eax /* save curpcb */ 83*ccd9b49fSElliott Mitchell movl %edx,PCPU(CURPCB) /* set curpcb to vm86pcb */ 84*ccd9b49fSElliott Mitchell 85*ccd9b49fSElliott Mitchell movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 86*ccd9b49fSElliott Mitchell movl 0(%ebx),%eax 87*ccd9b49fSElliott Mitchell movl %eax,SCR_TSS0(%edx) /* save first word */ 88*ccd9b49fSElliott Mitchell movl 4(%ebx),%eax 89*ccd9b49fSElliott Mitchell andl $~0x200, %eax /* flip 386BSY -> 386TSS */ 90*ccd9b49fSElliott Mitchell movl %eax,SCR_TSS1(%edx) /* save second word */ 91*ccd9b49fSElliott Mitchell 92*ccd9b49fSElliott Mitchell movl PCB_EXT(%edx),%edi /* vm86 tssd entry */ 93*ccd9b49fSElliott Mitchell movl 0(%edi),%eax 94*ccd9b49fSElliott Mitchell movl %eax,0(%ebx) 95*ccd9b49fSElliott Mitchell movl 4(%edi),%eax 96*ccd9b49fSElliott Mitchell movl %eax,4(%ebx) 97*ccd9b49fSElliott Mitchell movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 98*ccd9b49fSElliott Mitchell ltr %si 99*ccd9b49fSElliott Mitchell 100*ccd9b49fSElliott Mitchell movl %cr3,%eax 101*ccd9b49fSElliott Mitchell pushl %eax /* save address space */ 102*ccd9b49fSElliott Mitchell cmpb $0,pae_mode 103*ccd9b49fSElliott Mitchell jne 2f 104*ccd9b49fSElliott Mitchell movl IdlePTD_nopae,%ecx /* va (and pa) of Idle PTD */ 105*ccd9b49fSElliott Mitchell jmp 3f 106*ccd9b49fSElliott Mitchell2: movl IdlePTD_pae,%ecx 107*ccd9b49fSElliott Mitchell3: movl %ecx,%ebx 108*ccd9b49fSElliott Mitchell movl 0(%ebx),%eax 109*ccd9b49fSElliott Mitchell pushl %eax /* old ptde != 0 when booting */ 110*ccd9b49fSElliott Mitchell pushl %ebx /* keep for reuse */ 111*ccd9b49fSElliott Mitchell 112*ccd9b49fSElliott Mitchell movl %esp,SCR_STACK(%edx) /* save current stack location */ 113*ccd9b49fSElliott Mitchell 114*ccd9b49fSElliott Mitchell movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */ 115*ccd9b49fSElliott Mitchell movl %eax,0(%ebx) /* ... install as PTD entry 0 */ 116*ccd9b49fSElliott Mitchell 117*ccd9b49fSElliott Mitchell cmpb $0,pae_mode 118*ccd9b49fSElliott Mitchell je 4f 119*ccd9b49fSElliott Mitchell movl IdlePDPT,%ecx 120*ccd9b49fSElliott Mitchell4: movl %ecx,%cr3 /* new page tables */ 121*ccd9b49fSElliott Mitchell movl SCR_VMFRAME(%edx),%esp /* switch to new stack */ 122*ccd9b49fSElliott Mitchell 123*ccd9b49fSElliott Mitchell pushl %esp 124*ccd9b49fSElliott Mitchell movl $vm86_prepcall, %eax 125*ccd9b49fSElliott Mitchell call *%eax /* finish setup */ 126*ccd9b49fSElliott Mitchell add $4, %esp 127*ccd9b49fSElliott Mitchell 128*ccd9b49fSElliott Mitchell /* 129*ccd9b49fSElliott Mitchell * Return via doreti 130*ccd9b49fSElliott Mitchell */ 131*ccd9b49fSElliott Mitchell jmp doreti 132*ccd9b49fSElliott Mitchell 133*ccd9b49fSElliott Mitchell 134*ccd9b49fSElliott Mitchell/* 135*ccd9b49fSElliott Mitchell * vm86_biosret(struct trapframe_vm86 *vm86) 136*ccd9b49fSElliott Mitchell */ 137*ccd9b49fSElliott MitchellENTRY(vm86_biosret) 138*ccd9b49fSElliott Mitchell movl vm86pcb,%edx /* data area */ 139*ccd9b49fSElliott Mitchell 140*ccd9b49fSElliott Mitchell movl 4(%esp),%esi /* source */ 141*ccd9b49fSElliott Mitchell movl SCR_ARGFRAME(%edx),%edi /* destination */ 142*ccd9b49fSElliott Mitchell movl $VM86_FRAMESIZE/4,%ecx /* size */ 143*ccd9b49fSElliott Mitchell cld 144*ccd9b49fSElliott Mitchell rep 145*ccd9b49fSElliott Mitchell movsl /* copy frame to original frame */ 146*ccd9b49fSElliott Mitchell 147*ccd9b49fSElliott Mitchell movl SCR_STACK(%edx),%esp /* back to old stack */ 148*ccd9b49fSElliott Mitchell popl %ebx /* saved va of Idle PTD */ 149*ccd9b49fSElliott Mitchell popl %eax 150*ccd9b49fSElliott Mitchell movl %eax,0(%ebx) /* restore old pte */ 151*ccd9b49fSElliott Mitchell popl %eax 152*ccd9b49fSElliott Mitchell movl %eax,%cr3 /* install old page table */ 153*ccd9b49fSElliott Mitchell 154*ccd9b49fSElliott Mitchell movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 155*ccd9b49fSElliott Mitchell movl SCR_TSS0(%edx),%eax 156*ccd9b49fSElliott Mitchell movl %eax,0(%ebx) /* restore first word */ 157*ccd9b49fSElliott Mitchell movl SCR_TSS1(%edx),%eax 158*ccd9b49fSElliott Mitchell movl %eax,4(%ebx) /* restore second word */ 159*ccd9b49fSElliott Mitchell movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 160*ccd9b49fSElliott Mitchell ltr %si 161*ccd9b49fSElliott Mitchell 162*ccd9b49fSElliott Mitchell popl PCPU(CURPCB) /* restore curpcb/curproc */ 163*ccd9b49fSElliott Mitchell movl SCR_ARGFRAME(%edx),%edx /* original stack frame */ 164*ccd9b49fSElliott Mitchell movl TF_TRAPNO(%edx),%eax /* return (trapno) */ 165*ccd9b49fSElliott Mitchell 166*ccd9b49fSElliott Mitchell popl %gs 167*ccd9b49fSElliott Mitchell popl %edi 168*ccd9b49fSElliott Mitchell popl %esi 169*ccd9b49fSElliott Mitchell popl %ebp 170*ccd9b49fSElliott Mitchell popl %ebx 171*ccd9b49fSElliott Mitchell ret /* back to our normal program */ 172