vm86bios.s revision 281495
134840Sjlemon/*- 234840Sjlemon * Copyright (c) 1998 Jonathan Lemon 334840Sjlemon * All rights reserved. 434840Sjlemon * 534840Sjlemon * Redistribution and use in source and binary forms, with or without 634840Sjlemon * modification, are permitted provided that the following conditions 734840Sjlemon * are met: 834840Sjlemon * 1. Redistributions of source code must retain the above copyright 934840Sjlemon * notice, this list of conditions and the following disclaimer. 1034840Sjlemon * 2. Redistributions in binary form must reproduce the above copyright 1134840Sjlemon * notice, this list of conditions and the following disclaimer in the 1234840Sjlemon * documentation and/or other materials provided with the distribution. 1334840Sjlemon * 1434840Sjlemon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1534840Sjlemon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1634840Sjlemon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1734840Sjlemon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1834840Sjlemon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1934840Sjlemon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2034840Sjlemon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2134840Sjlemon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2234840Sjlemon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2334840Sjlemon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2434840Sjlemon * SUCH DAMAGE. 2534840Sjlemon * 2650477Speter * $FreeBSD: head/sys/i386/i386/vm86bios.s 281495 2015-04-13 15:22:45Z kib $ 2734840Sjlemon */ 2834840Sjlemon 2971257Speter#include "opt_npx.h" 3071256Speter 3134840Sjlemon#include <machine/asmacros.h> /* miscellaneous asm macros */ 3234840Sjlemon#include <machine/trap.h> 3334840Sjlemon 3434840Sjlemon#include "assym.s" 3534840Sjlemon 3637889Sjlemon#define SCR_NEWPTD PCB_ESI /* readability macros */ 3737889Sjlemon#define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */ 3837889Sjlemon#define SCR_STACK PCB_ESP 3937889Sjlemon#define SCR_PGTABLE PCB_EBX 4037889Sjlemon#define SCR_ARGFRAME PCB_EIP 41145025Speter#define SCR_TSS0 PCB_VM86 42145025Speter#define SCR_TSS1 (PCB_VM86+4) 4337889Sjlemon 4434840Sjlemon .data 4534840Sjlemon ALIGN_DATA 4634840Sjlemon 47106542Sdavidxu .globl vm86pcb 4834840Sjlemon 4973011Sjakevm86pcb: .long 0 5034840Sjlemon 5134840Sjlemon .text 5234840Sjlemon 5334840Sjlemon/* 5434840Sjlemon * vm86_bioscall(struct trapframe_vm86 *vm86) 5534840Sjlemon */ 5634840SjlemonENTRY(vm86_bioscall) 5773011Sjake movl vm86pcb,%edx /* scratch data area */ 5834840Sjlemon movl 4(%esp),%eax 5937889Sjlemon movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */ 6034840Sjlemon pushl %ebx 6134840Sjlemon pushl %ebp 6234840Sjlemon pushl %esi 6334840Sjlemon pushl %edi 6434840Sjlemon pushl %gs 6534840Sjlemon 6671257Speter#ifdef DEV_NPX 6776904Sbde pushfl 6876904Sbde cli 6983366Sjulian movl PCPU(CURTHREAD),%ecx 7087702Sjhb cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */ 7134840Sjlemon jne 1f 7239046Syokota pushl %edx 7383366Sjulian movl TD_PCB(%ecx),%ecx 74217587Sjkim pushl PCB_SAVEFPU(%ecx) 7573011Sjake call npxsave 76217587Sjkim addl $4,%esp 7734840Sjlemon popl %edx /* recover our pcb */ 7876904Sbde1: 7976904Sbde popfl 8034840Sjlemon#endif 8134840Sjlemon 8237889Sjlemon movl SCR_VMFRAME(%edx),%ebx /* target frame location */ 8334840Sjlemon movl %ebx,%edi /* destination */ 8437889Sjlemon movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */ 8547080Sluoqi movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */ 8634840Sjlemon cld 8734840Sjlemon rep 8834840Sjlemon movsl /* copy frame to new stack */ 8934840Sjlemon 9069971Sjake movl PCPU(CURPCB),%eax 9134840Sjlemon pushl %eax /* save curpcb */ 9269971Sjake movl %edx,PCPU(CURPCB) /* set curpcb to vm86pcb */ 9334840Sjlemon 9469971Sjake movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 9534840Sjlemon movl 0(%ebx),%eax 9637889Sjlemon movl %eax,SCR_TSS0(%edx) /* save first word */ 9734840Sjlemon movl 4(%ebx),%eax 9834840Sjlemon andl $~0x200, %eax /* flip 386BSY -> 386TSS */ 9937889Sjlemon movl %eax,SCR_TSS1(%edx) /* save second word */ 10034840Sjlemon 10134840Sjlemon movl PCB_EXT(%edx),%edi /* vm86 tssd entry */ 10234840Sjlemon movl 0(%edi),%eax 10334840Sjlemon movl %eax,0(%ebx) 10434840Sjlemon movl 4(%edi),%eax 10534840Sjlemon movl %eax,4(%ebx) 10647081Sluoqi movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 10734840Sjlemon ltr %si 10834840Sjlemon 10934840Sjlemon movl %cr3,%eax 11034840Sjlemon pushl %eax /* save address space */ 11173011Sjake movl IdlePTD,%ecx 11234840Sjlemon movl %ecx,%ebx 11334840Sjlemon addl $KERNBASE,%ebx /* va of Idle PTD */ 11434840Sjlemon movl 0(%ebx),%eax 11534840Sjlemon pushl %eax /* old ptde != 0 when booting */ 11634840Sjlemon pushl %ebx /* keep for reuse */ 11734840Sjlemon 11837889Sjlemon movl %esp,SCR_STACK(%edx) /* save current stack location */ 11934840Sjlemon 12037889Sjlemon movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */ 12134840Sjlemon movl %eax,0(%ebx) /* ... install as PTD entry 0 */ 12234840Sjlemon 123281495Skib#if defined(PAE) || defined(PAE_TABLES) 124112841Sjake movl IdlePDPT,%ecx 125112841Sjake#endif 12634840Sjlemon movl %ecx,%cr3 /* new page tables */ 12737889Sjlemon movl SCR_VMFRAME(%edx),%esp /* switch to new stack */ 128165302Skmacy 129165302Skmacy pushl %esp 130165302Skmacy call vm86_prepcall /* finish setup */ 131165302Skmacy add $4, %esp 13234840Sjlemon 13334840Sjlemon /* 13473011Sjake * Return via doreti 13534840Sjlemon */ 13634840Sjlemon MEXITCOUNT 13773011Sjake jmp doreti 13834840Sjlemon 13934840Sjlemon 14034840Sjlemon/* 14134840Sjlemon * vm86_biosret(struct trapframe_vm86 *vm86) 14234840Sjlemon */ 14334840SjlemonENTRY(vm86_biosret) 14473011Sjake movl vm86pcb,%edx /* data area */ 14534840Sjlemon 14634840Sjlemon movl 4(%esp),%esi /* source */ 14737889Sjlemon movl SCR_ARGFRAME(%edx),%edi /* destination */ 14847080Sluoqi movl $VM86_FRAMESIZE/4,%ecx /* size */ 14934840Sjlemon cld 15034840Sjlemon rep 15134840Sjlemon movsl /* copy frame to original frame */ 15234840Sjlemon 15337889Sjlemon movl SCR_STACK(%edx),%esp /* back to old stack */ 15434840Sjlemon popl %ebx /* saved va of Idle PTD */ 15534840Sjlemon popl %eax 15634840Sjlemon movl %eax,0(%ebx) /* restore old pte */ 15734840Sjlemon popl %eax 15834840Sjlemon movl %eax,%cr3 /* install old page table */ 15934840Sjlemon 16069971Sjake movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 16137889Sjlemon movl SCR_TSS0(%edx),%eax 16234840Sjlemon movl %eax,0(%ebx) /* restore first word */ 16337889Sjlemon movl SCR_TSS1(%edx),%eax 16434840Sjlemon movl %eax,4(%ebx) /* restore second word */ 16547081Sluoqi movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 16634840Sjlemon ltr %si 16734840Sjlemon 16869971Sjake popl PCPU(CURPCB) /* restore curpcb/curproc */ 16937889Sjlemon movl SCR_ARGFRAME(%edx),%edx /* original stack frame */ 17034840Sjlemon movl TF_TRAPNO(%edx),%eax /* return (trapno) */ 17134840Sjlemon 17234840Sjlemon popl %gs 17334840Sjlemon popl %edi 17434840Sjlemon popl %esi 17534840Sjlemon popl %ebp 17634840Sjlemon popl %ebx 17734840Sjlemon ret /* back to our normal program */ 178