vm86bios.s revision 39046
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 * 2639046Syokota * $Id: vm86bios.s,v 1.3 1998/07/27 16:45:05 jlemon Exp $ 2734840Sjlemon */ 2834840Sjlemon 2934840Sjlemon#include "opt_vm86.h" 3034840Sjlemon 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 4137889Sjlemon#define SCR_TSS0 PCB_FS 4237889Sjlemon#define SCR_TSS1 PCB_GS 4337889Sjlemon 4434840Sjlemon .data 4534840Sjlemon ALIGN_DATA 4634840Sjlemon 4734840Sjlemon .globl _in_vm86call, _vm86pcb 4834840Sjlemon 4934840Sjlemon_in_vm86call: .long 0 5034840Sjlemon_vm86pcb: .long 0 5134840Sjlemon 5234840Sjlemon .text 5334840Sjlemon 5434840Sjlemon/* 5534840Sjlemon * vm86_bioscall(struct trapframe_vm86 *vm86) 5634840Sjlemon */ 5734840SjlemonENTRY(vm86_bioscall) 5837889Sjlemon movl _vm86pcb,%edx /* scratch data area */ 5934840Sjlemon movl 4(%esp),%eax 6037889Sjlemon movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */ 6134840Sjlemon pushl %ebx 6234840Sjlemon pushl %ebp 6334840Sjlemon pushl %esi 6434840Sjlemon pushl %edi 6534840Sjlemon pushl %fs 6634840Sjlemon pushl %gs 6734840Sjlemon 6834840Sjlemon#ifdef SMP 6934840Sjlemon pushl %edx 7034840Sjlemon ALIGN_LOCK /* Get global lock */ 7134840Sjlemon popl %edx 7234840Sjlemon#endif 7334840Sjlemon movl _curproc,%ecx 7434840Sjlemon pushl %ecx /* save _curproc value */ 7534840Sjlemon testl %ecx,%ecx 7634840Sjlemon je 1f /* no process to save */ 7734840Sjlemon 7834840Sjlemon#if NNPX > 0 7934840Sjlemon cmpl %ecx,_npxproc /* do we need to save fp? */ 8034840Sjlemon jne 1f 8139046Syokota pushl %edx 8234840Sjlemon movl P_ADDR(%ecx),%ecx 8334840Sjlemon addl $PCB_SAVEFPU,%ecx 8439046Syokota pushl %ecx 8534840Sjlemon call _npxsave 8639046Syokota popl %ecx 8734840Sjlemon popl %edx /* recover our pcb */ 8834840Sjlemon#endif 8934840Sjlemon 9034840Sjlemon1: 9137889Sjlemon movl SCR_VMFRAME(%edx),%ebx /* target frame location */ 9234840Sjlemon movl %ebx,%edi /* destination */ 9337889Sjlemon movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */ 9434840Sjlemon movl $21,%ecx /* sizeof(struct vm86frame)/4 */ 9534840Sjlemon cld 9634840Sjlemon rep 9734840Sjlemon movsl /* copy frame to new stack */ 9834840Sjlemon 9934840Sjlemon movl TF_TRAPNO(%ebx),%ebx 10034840Sjlemon cmpl $256,%ebx 10134840Sjlemon jb 1f /* no page frame to map */ 10234840Sjlemon 10334840Sjlemon andl $~PAGE_MASK,%ebx 10434840Sjlemon#if 0 10534840Sjlemon orl $PG_V|PG_RW|PG_U,%ebx /* XXX assembler error?? */ 10634840Sjlemon#endif 10734840Sjlemon orl $0x7,%ebx 10837889Sjlemon movl SCR_PGTABLE(%edx),%eax /* va of vm86 page table */ 10934840Sjlemon movl %ebx,4(%eax) /* set vm86 PTE entry 1 */ 11034840Sjlemon1: 11134840Sjlemon movl _curpcb,%eax 11234840Sjlemon pushl %eax /* save curpcb */ 11334840Sjlemon movl %edx,_curpcb /* set curpcb to vm86pcb */ 11434840Sjlemon movl $0,_curproc /* erase curproc */ 11534840Sjlemon 11634840Sjlemon movl _my_tr,%esi 11734840Sjlemon leal _gdt(,%esi,8),%ebx /* entry in GDT */ 11834840Sjlemon movl 0(%ebx),%eax 11937889Sjlemon movl %eax,SCR_TSS0(%edx) /* save first word */ 12034840Sjlemon movl 4(%ebx),%eax 12134840Sjlemon andl $~0x200, %eax /* flip 386BSY -> 386TSS */ 12237889Sjlemon movl %eax,SCR_TSS1(%edx) /* save second word */ 12334840Sjlemon 12434840Sjlemon movl PCB_EXT(%edx),%edi /* vm86 tssd entry */ 12534840Sjlemon movl 0(%edi),%eax 12634840Sjlemon movl %eax,0(%ebx) 12734840Sjlemon movl 4(%edi),%eax 12834840Sjlemon movl %eax,4(%ebx) 12934840Sjlemon shll $3,%esi /* GSEL(entry, SEL_KPL) */ 13034840Sjlemon ltr %si 13134840Sjlemon 13234840Sjlemon movl %cr3,%eax 13334840Sjlemon pushl %eax /* save address space */ 13434840Sjlemon#ifdef SMP 13534840Sjlemon movl _my_idlePTD,%ecx 13634840Sjlemon#else 13734840Sjlemon movl _IdlePTD,%ecx 13834840Sjlemon#endif 13934840Sjlemon movl %ecx,%ebx 14034840Sjlemon addl $KERNBASE,%ebx /* va of Idle PTD */ 14134840Sjlemon movl 0(%ebx),%eax 14234840Sjlemon pushl %eax /* old ptde != 0 when booting */ 14334840Sjlemon pushl %ebx /* keep for reuse */ 14434840Sjlemon 14537889Sjlemon movl %esp,SCR_STACK(%edx) /* save current stack location */ 14634840Sjlemon 14737889Sjlemon movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */ 14834840Sjlemon movl %eax,0(%ebx) /* ... install as PTD entry 0 */ 14934840Sjlemon 15034840Sjlemon movl %ecx,%cr3 /* new page tables */ 15137889Sjlemon movl SCR_VMFRAME(%edx),%esp /* switch to new stack */ 15234840Sjlemon 15334840Sjlemon call _vm86_prepcall /* finish setup */ 15434840Sjlemon 15534840Sjlemon movl $1,_in_vm86call /* set flag for trap() */ 15634840Sjlemon 15734840Sjlemon /* 15834840Sjlemon * Return via _doreti 15934840Sjlemon */ 16034840Sjlemon#ifdef SMP 16134840Sjlemon ECPL_LOCK 16234840Sjlemon#ifdef CPL_AND_CML 16334840Sjlemon#error Not ready for CPL_AND_CML 16434840Sjlemon#endif 16534840Sjlemon pushl _cpl /* cpl to restore */ 16634840Sjlemon ECPL_UNLOCK 16734840Sjlemon#else 16834840Sjlemon pushl _cpl /* cpl to restore */ 16934840Sjlemon#endif 17034840Sjlemon subl $4,%esp /* dummy unit */ 17134840Sjlemon MPLOCKED incb _intr_nesting_level 17234840Sjlemon MEXITCOUNT 17334840Sjlemon jmp _doreti 17434840Sjlemon 17534840Sjlemon 17634840Sjlemon/* 17734840Sjlemon * vm86_biosret(struct trapframe_vm86 *vm86) 17834840Sjlemon */ 17934840SjlemonENTRY(vm86_biosret) 18034840Sjlemon movl _vm86pcb,%edx /* data area */ 18134840Sjlemon 18234840Sjlemon movl 4(%esp),%esi /* source */ 18337889Sjlemon movl SCR_ARGFRAME(%edx),%edi /* destination */ 18434840Sjlemon movl $21,%ecx /* size */ 18534840Sjlemon cld 18634840Sjlemon rep 18734840Sjlemon movsl /* copy frame to original frame */ 18834840Sjlemon 18937889Sjlemon movl SCR_STACK(%edx),%esp /* back to old stack */ 19034840Sjlemon popl %ebx /* saved va of Idle PTD */ 19134840Sjlemon popl %eax 19234840Sjlemon movl %eax,0(%ebx) /* restore old pte */ 19334840Sjlemon popl %eax 19434840Sjlemon movl %eax,%cr3 /* install old page table */ 19534840Sjlemon 19634840Sjlemon movl $0,_in_vm86call /* reset trapflag */ 19737889Sjlemon movl SCR_PGTABLE(%edx),%ebx /* va of vm86 page table */ 19834840Sjlemon movl $0,4(%ebx) /* ...clear entry 1 */ 19934840Sjlemon 20034840Sjlemon movl _my_tr,%esi 20134840Sjlemon leal _gdt(,%esi,8),%ebx /* entry in GDT */ 20237889Sjlemon movl SCR_TSS0(%edx),%eax 20334840Sjlemon movl %eax,0(%ebx) /* restore first word */ 20437889Sjlemon movl SCR_TSS1(%edx),%eax 20534840Sjlemon movl %eax,4(%ebx) /* restore second word */ 20634840Sjlemon shll $3,%esi /* GSEL(entry, SEL_KPL) */ 20734840Sjlemon ltr %si 20834840Sjlemon 20934840Sjlemon popl _curpcb /* restore curpcb/curproc */ 21034840Sjlemon popl _curproc 21137889Sjlemon movl SCR_ARGFRAME(%edx),%edx /* original stack frame */ 21234840Sjlemon movl TF_TRAPNO(%edx),%eax /* return (trapno) */ 21334840Sjlemon 21434840Sjlemon popl %gs 21534840Sjlemon popl %fs 21634840Sjlemon popl %edi 21734840Sjlemon popl %esi 21834840Sjlemon popl %ebp 21934840Sjlemon popl %ebx 22034840Sjlemon ret /* back to our normal program */ 221