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