vm86bios.s revision 145025
1234027Sstas/*- 2234027Sstas * Copyright (c) 1998 Jonathan Lemon 3234027Sstas * All rights reserved. 4234027Sstas * 5234027Sstas * Redistribution and use in source and binary forms, with or without 6234027Sstas * modification, are permitted provided that the following conditions 7234027Sstas * are met: 8234027Sstas * 1. Redistributions of source code must retain the above copyright 9234027Sstas * notice, this list of conditions and the following disclaimer. 10234027Sstas * 2. Redistributions in binary form must reproduce the above copyright 11234027Sstas * notice, this list of conditions and the following disclaimer in the 12234027Sstas * documentation and/or other materials provided with the distribution. 13234027Sstas * 14233294Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24233294Sstas * SUCH DAMAGE. 25233294Sstas * 26233294Sstas * $FreeBSD: head/sys/i386/i386/vm86bios.s 145025 2005-04-13 18:13:40Z peter $ 27233294Sstas */ 28233294Sstas 29233294Sstas#include "opt_npx.h" 30233294Sstas 31233294Sstas#include <machine/asmacros.h> /* miscellaneous asm macros */ 32233294Sstas#include <machine/trap.h> 33233294Sstas 34233294Sstas#include "assym.s" 35233294Sstas 36233294Sstas#define SCR_NEWPTD PCB_ESI /* readability macros */ 37233294Sstas#define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */ 38233294Sstas#define SCR_STACK PCB_ESP 39233294Sstas#define SCR_PGTABLE PCB_EBX 40233294Sstas#define SCR_ARGFRAME PCB_EIP 41233294Sstas#define SCR_TSS0 PCB_VM86 42233294Sstas#define SCR_TSS1 (PCB_VM86+4) 43233294Sstas 44233294Sstas .data 45233294Sstas ALIGN_DATA 46233294Sstas 47233294Sstas .globl vm86pcb 48233294Sstas 49233294Sstasvm86pcb: .long 0 50233294Sstas 51233294Sstas .text 52233294Sstas 53233294Sstas/* 54233294Sstas * vm86_bioscall(struct trapframe_vm86 *vm86) 55233294Sstas */ 56233294SstasENTRY(vm86_bioscall) 57233294Sstas movl vm86pcb,%edx /* scratch data area */ 58233294Sstas movl 4(%esp),%eax 59233294Sstas movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */ 60233294Sstas pushl %ebx 61233294Sstas pushl %ebp 62233294Sstas pushl %esi 63233294Sstas pushl %edi 64233294Sstas pushl %gs 65233294Sstas 66233294Sstas#ifdef DEV_NPX 67233294Sstas pushfl 68233294Sstas cli 69233294Sstas movl PCPU(CURTHREAD),%ecx 70233294Sstas cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */ 71233294Sstas jne 1f 72233294Sstas testl %ecx,%ecx 73233294Sstas je 1f /* no curproc/npxproc */ 74233294Sstas pushl %edx 75233294Sstas movl TD_PCB(%ecx),%ecx 76233294Sstas addl $PCB_SAVEFPU,%ecx 77233294Sstas pushl %ecx 78233294Sstas call npxsave 79233294Sstas popl %ecx 80233294Sstas popl %edx /* recover our pcb */ 81233294Sstas1: 82233294Sstas popfl 83233294Sstas#endif 84233294Sstas 85233294Sstas movl SCR_VMFRAME(%edx),%ebx /* target frame location */ 86233294Sstas movl %ebx,%edi /* destination */ 87233294Sstas movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */ 88233294Sstas movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */ 89233294Sstas cld 90233294Sstas rep 91233294Sstas movsl /* copy frame to new stack */ 92233294Sstas 93233294Sstas movl PCPU(CURPCB),%eax 94233294Sstas pushl %eax /* save curpcb */ 95233294Sstas movl %edx,PCPU(CURPCB) /* set curpcb to vm86pcb */ 96233294Sstas 97233294Sstas movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 98233294Sstas movl 0(%ebx),%eax 99233294Sstas movl %eax,SCR_TSS0(%edx) /* save first word */ 100233294Sstas movl 4(%ebx),%eax 101233294Sstas andl $~0x200, %eax /* flip 386BSY -> 386TSS */ 102233294Sstas movl %eax,SCR_TSS1(%edx) /* save second word */ 103233294Sstas 104233294Sstas movl PCB_EXT(%edx),%edi /* vm86 tssd entry */ 105233294Sstas movl 0(%edi),%eax 106233294Sstas movl %eax,0(%ebx) 107233294Sstas movl 4(%edi),%eax 108233294Sstas movl %eax,4(%ebx) 109233294Sstas movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 110233294Sstas ltr %si 111233294Sstas 112233294Sstas movl %cr3,%eax 113233294Sstas pushl %eax /* save address space */ 114233294Sstas movl IdlePTD,%ecx 115233294Sstas movl %ecx,%ebx 116233294Sstas addl $KERNBASE,%ebx /* va of Idle PTD */ 117233294Sstas movl 0(%ebx),%eax 118233294Sstas pushl %eax /* old ptde != 0 when booting */ 119233294Sstas pushl %ebx /* keep for reuse */ 120233294Sstas 121233294Sstas movl %esp,SCR_STACK(%edx) /* save current stack location */ 122233294Sstas 123233294Sstas movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */ 124233294Sstas movl %eax,0(%ebx) /* ... install as PTD entry 0 */ 125233294Sstas 126233294Sstas#ifdef PAE 127233294Sstas movl IdlePDPT,%ecx 128233294Sstas#endif 129233294Sstas movl %ecx,%cr3 /* new page tables */ 130233294Sstas movl SCR_VMFRAME(%edx),%esp /* switch to new stack */ 131233294Sstas 132233294Sstas call vm86_prepcall /* finish setup */ 133233294Sstas 134233294Sstas /* 135233294Sstas * Return via doreti 136233294Sstas */ 137233294Sstas MEXITCOUNT 138233294Sstas jmp doreti 139233294Sstas 140233294Sstas 141233294Sstas/* 142233294Sstas * vm86_biosret(struct trapframe_vm86 *vm86) 143233294Sstas */ 144233294SstasENTRY(vm86_biosret) 145233294Sstas movl vm86pcb,%edx /* data area */ 146233294Sstas 147233294Sstas movl 4(%esp),%esi /* source */ 148233294Sstas movl SCR_ARGFRAME(%edx),%edi /* destination */ 149233294Sstas movl $VM86_FRAMESIZE/4,%ecx /* size */ 150233294Sstas cld 151233294Sstas rep 152233294Sstas movsl /* copy frame to original frame */ 153233294Sstas 154233294Sstas movl SCR_STACK(%edx),%esp /* back to old stack */ 155233294Sstas popl %ebx /* saved va of Idle PTD */ 156233294Sstas popl %eax 157233294Sstas movl %eax,0(%ebx) /* restore old pte */ 158233294Sstas popl %eax 159233294Sstas movl %eax,%cr3 /* install old page table */ 160233294Sstas 161233294Sstas movl PCPU(TSS_GDT),%ebx /* entry in GDT */ 162233294Sstas movl SCR_TSS0(%edx),%eax 163233294Sstas movl %eax,0(%ebx) /* restore first word */ 164233294Sstas movl SCR_TSS1(%edx),%eax 165233294Sstas movl %eax,4(%ebx) /* restore second word */ 166233294Sstas movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */ 167233294Sstas ltr %si 168233294Sstas 169233294Sstas popl PCPU(CURPCB) /* restore curpcb/curproc */ 170233294Sstas movl SCR_ARGFRAME(%edx),%edx /* original stack frame */ 171233294Sstas movl TF_TRAPNO(%edx),%eax /* return (trapno) */ 172233294Sstas 173178825Sdfr popl %gs 174178825Sdfr popl %edi 175178825Sdfr popl %esi 176178825Sdfr popl %ebp 177178825Sdfr popl %ebx 178178825Sdfr ret /* back to our normal program */ 179178825Sdfr