vm86bios.s revision 87702
1121572Sume/*- 262583Sitojun * Copyright (c) 1998 Jonathan Lemon 355505Sshin * All rights reserved. 455505Sshin * 555505Sshin * Redistribution and use in source and binary forms, with or without 655505Sshin * modification, are permitted provided that the following conditions 755505Sshin * are met: 855505Sshin * 1. Redistributions of source code must retain the above copyright 955505Sshin * notice, this list of conditions and the following disclaimer. 1055505Sshin * 2. Redistributions in binary form must reproduce the above copyright 1155505Sshin * notice, this list of conditions and the following disclaimer in the 1255505Sshin * documentation and/or other materials provided with the distribution. 1355505Sshin * 1455505Sshin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1555505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1655505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1755505Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1855505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1955505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2055505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2155505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2255505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2355505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2455505Sshin * SUCH DAMAGE. 2555505Sshin * 2655505Sshin * $FreeBSD: head/sys/i386/i386/vm86bios.s 87702 2001-12-11 23:33:44Z jhb $ 2755505Sshin */ 2855505Sshin 2955505Sshin#include "opt_npx.h" 3055505Sshin 3155505Sshin#include <machine/asmacros.h> /* miscellaneous asm macros */ 3284208Sdillon#include <machine/trap.h> 3384208Sdillon 3484208Sdillon#include "assym.s" 3555505Sshin 3655505Sshin#define SCR_NEWPTD PCB_ESI /* readability macros */ 3755505Sshin#define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */ 3855505Sshin#define SCR_STACK PCB_ESP 3955505Sshin#define SCR_PGTABLE PCB_EBX 4057855Sshin#define SCR_ARGFRAME PCB_EIP 41171135Sgnn#define SCR_TSS0 PCB_SPARE 42171135Sgnn#define SCR_TSS1 (PCB_SPARE+4) 4355505Sshin 4455505Sshin .data 4555505Sshin ALIGN_DATA 4655505Sshin 4755505Sshin .globl in_vm86call, vm86pcb 4862583Sitojun 4955505Sshinin_vm86call: .long 0 5055505Sshinvm86pcb: .long 0 5178064Sume 5278064Sume .text 5362583Sitojun 5462583Sitojun/* 5562583Sitojun * vm86_bioscall(struct trapframe_vm86 *vm86) 5662583Sitojun */ 5762583SitojunENTRY(vm86_bioscall) 5862583Sitojun movl vm86pcb,%edx /* scratch data area */ 5962583Sitojun movl 4(%esp),%eax 6062583Sitojun movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */ 6162583Sitojun pushl %ebx 6262583Sitojun pushl %ebp 6362583Sitojun pushl %esi 6462583Sitojun pushl %edi 6562583Sitojun pushl %gs 6662583Sitojun 6762583Sitojun#ifdef DEV_NPX 6862583Sitojun pushfl 6962583Sitojun cli 7062583Sitojun movl PCPU(CURTHREAD),%ecx 7162583Sitojun cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */ 7262583Sitojun jne 1f 7362583Sitojun testl %ecx,%ecx 7462583Sitojun je 1f /* no curproc/npxproc */ 7562583Sitojun pushl %edx 7662583Sitojun movl TD_PCB(%ecx),%ecx 7762583Sitojun addl $PCB_SAVEFPU,%ecx 78248314Sglebius pushl %ecx 79248314Sglebius call npxsave 80248314Sglebius popl %ecx 81248314Sglebius popl %edx /* recover our pcb */ 82248314Sglebius1: 83248314Sglebius popfl 84248314Sglebius#endif 8562583Sitojun 8655505Sshin movl SCR_VMFRAME(%edx),%ebx /* target frame location */ 8755505Sshin movl %ebx,%edi /* destination */ 8892917Sobrien movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */ 8992917Sobrien movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */ 9092917Sobrien cld 9192917Sobrien rep 9292917Sobrien movsl /* copy frame to new stack */ 9355505Sshin 9455505Sshin movl PCPU(CURPCB),%eax 9555505Sshin pushl %eax /* save curpcb */ 9655505Sshin movl %edx,PCPU(CURPCB) /* set curpcb to vm86pcb */ 9755505Sshin 9855505Sshin movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 9962583Sitojun movl 0(%ebx),%eax 10062583Sitojun movl %eax,SCR_TSS0(%edx) /* save first word */ 10162583Sitojun movl 4(%ebx),%eax 10262583Sitojun andl $~0x200, %eax /* flip 386BSY -> 386TSS */ 10362583Sitojun movl %eax,SCR_TSS1(%edx) /* save second word */ 10462583Sitojun 10562583Sitojun movl PCB_EXT(%edx),%edi /* vm86 tssd entry */ 10662583Sitojun movl 0(%edi),%eax 10762583Sitojun movl %eax,0(%ebx) 10855505Sshin movl 4(%edi),%eax 10962583Sitojun movl %eax,4(%ebx) 11055505Sshin movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 11162583Sitojun ltr %si 11262583Sitojun 11362583Sitojun movl %cr3,%eax 11455505Sshin pushl %eax /* save address space */ 11562583Sitojun movl IdlePTD,%ecx 11662583Sitojun movl %ecx,%ebx 117121572Sume addl $KERNBASE,%ebx /* va of Idle PTD */ 11862583Sitojun movl 0(%ebx),%eax 119121572Sume pushl %eax /* old ptde != 0 when booting */ 12055505Sshin pushl %ebx /* keep for reuse */ 12162583Sitojun 12255505Sshin movl %esp,SCR_STACK(%edx) /* save current stack location */ 12362583Sitojun 12462583Sitojun movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */ 12555505Sshin movl %eax,0(%ebx) /* ... install as PTD entry 0 */ 12662583Sitojun 12762583Sitojun movl %ecx,%cr3 /* new page tables */ 12862583Sitojun movl SCR_VMFRAME(%edx),%esp /* switch to new stack */ 12962583Sitojun 13062583Sitojun call vm86_prepcall /* finish setup */ 13155505Sshin 13262583Sitojun movl $1,in_vm86call /* set flag for trap() */ 13362583Sitojun 13462583Sitojun /* 13562583Sitojun * Return via doreti 13662583Sitojun */ 13762583Sitojun MEXITCOUNT 13862583Sitojun jmp doreti 13962583Sitojun 14055505Sshin 14162583Sitojun/* 14255505Sshin * vm86_biosret(struct trapframe_vm86 *vm86) 14362583Sitojun */ 14462583SitojunENTRY(vm86_biosret) 14562583Sitojun movl vm86pcb,%edx /* data area */ 14655505Sshin 14762583Sitojun movl 4(%esp),%esi /* source */ 14855505Sshin movl SCR_ARGFRAME(%edx),%edi /* destination */ 14955505Sshin movl $VM86_FRAMESIZE/4,%ecx /* size */ 15055505Sshin cld 15155505Sshin rep 15262583Sitojun movsl /* copy frame to original frame */ 15355505Sshin 15455505Sshin movl SCR_STACK(%edx),%esp /* back to old stack */ 15555505Sshin popl %ebx /* saved va of Idle PTD */ 15662583Sitojun popl %eax 15762583Sitojun movl %eax,0(%ebx) /* restore old pte */ 15855505Sshin popl %eax 15955505Sshin movl %eax,%cr3 /* install old page table */ 16055505Sshin 16155505Sshin movl $0,in_vm86call /* reset trapflag */ 16255505Sshin 16355505Sshin movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 16455505Sshin movl SCR_TSS0(%edx),%eax 16555505Sshin movl %eax,0(%ebx) /* restore first word */ 16655505Sshin movl SCR_TSS1(%edx),%eax 16755505Sshin movl %eax,4(%ebx) /* restore second word */ 16855505Sshin movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 16955505Sshin ltr %si 17055505Sshin 17155505Sshin popl PCPU(CURPCB) /* restore curpcb/curproc */ 17255505Sshin movl SCR_ARGFRAME(%edx),%edx /* original stack frame */ 17355505Sshin movl TF_TRAPNO(%edx),%eax /* return (trapno) */ 17455505Sshin 17555505Sshin popl %gs 17662583Sitojun popl %edi 17762583Sitojun popl %esi 17862583Sitojun popl %ebp 17962583Sitojun popl %ebx 18055505Sshin ret /* back to our normal program */ 18162583Sitojun