xref: /freebsd/sys/i386/i386/vm86bios.S (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1*ccd9b49fSElliott Mitchell/*-
2*ccd9b49fSElliott Mitchell * Copyright (c) 1998 Jonathan Lemon
3*ccd9b49fSElliott Mitchell * All rights reserved.
4*ccd9b49fSElliott Mitchell *
5*ccd9b49fSElliott Mitchell * Redistribution and use in source and binary forms, with or without
6*ccd9b49fSElliott Mitchell * modification, are permitted provided that the following conditions
7*ccd9b49fSElliott Mitchell * are met:
8*ccd9b49fSElliott Mitchell * 1. Redistributions of source code must retain the above copyright
9*ccd9b49fSElliott Mitchell *    notice, this list of conditions and the following disclaimer.
10*ccd9b49fSElliott Mitchell * 2. Redistributions in binary form must reproduce the above copyright
11*ccd9b49fSElliott Mitchell *    notice, this list of conditions and the following disclaimer in the
12*ccd9b49fSElliott Mitchell *    documentation and/or other materials provided with the distribution.
13*ccd9b49fSElliott Mitchell *
14*ccd9b49fSElliott Mitchell * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*ccd9b49fSElliott Mitchell * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*ccd9b49fSElliott Mitchell * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*ccd9b49fSElliott Mitchell * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*ccd9b49fSElliott Mitchell * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*ccd9b49fSElliott Mitchell * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*ccd9b49fSElliott Mitchell * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*ccd9b49fSElliott Mitchell * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*ccd9b49fSElliott Mitchell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*ccd9b49fSElliott Mitchell * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*ccd9b49fSElliott Mitchell * SUCH DAMAGE.
25*ccd9b49fSElliott Mitchell */
26*ccd9b49fSElliott Mitchell
27*ccd9b49fSElliott Mitchell#include <machine/asmacros.h>		/* miscellaneous asm macros */
28*ccd9b49fSElliott Mitchell#include <machine/trap.h>
29*ccd9b49fSElliott Mitchell
30*ccd9b49fSElliott Mitchell#include "assym.inc"
31*ccd9b49fSElliott Mitchell
32*ccd9b49fSElliott Mitchell#define SCR_NEWPTD	PCB_ESI		/* readability macros */
33*ccd9b49fSElliott Mitchell#define SCR_VMFRAME	PCB_EBP		/* see vm86.c for explanation */
34*ccd9b49fSElliott Mitchell#define SCR_STACK	PCB_ESP
35*ccd9b49fSElliott Mitchell#define SCR_PGTABLE	PCB_EBX
36*ccd9b49fSElliott Mitchell#define SCR_ARGFRAME	PCB_EIP
37*ccd9b49fSElliott Mitchell#define SCR_TSS0	PCB_VM86
38*ccd9b49fSElliott Mitchell#define SCR_TSS1	(PCB_VM86+4)
39*ccd9b49fSElliott Mitchell
40*ccd9b49fSElliott Mitchell	.data
41*ccd9b49fSElliott Mitchell	ALIGN_DATA
42*ccd9b49fSElliott Mitchell
43*ccd9b49fSElliott Mitchell	.globl	vm86pcb
44*ccd9b49fSElliott Mitchell
45*ccd9b49fSElliott Mitchellvm86pcb:		.long	0
46*ccd9b49fSElliott Mitchell
47*ccd9b49fSElliott Mitchell	.text
48*ccd9b49fSElliott Mitchell
49*ccd9b49fSElliott Mitchell/*
50*ccd9b49fSElliott Mitchell * vm86_bioscall(struct trapframe_vm86 *vm86)
51*ccd9b49fSElliott Mitchell */
52*ccd9b49fSElliott MitchellENTRY(vm86_bioscall)
53*ccd9b49fSElliott Mitchell	movl	vm86pcb,%edx		/* scratch data area */
54*ccd9b49fSElliott Mitchell	movl	4(%esp),%eax
55*ccd9b49fSElliott Mitchell	movl	%eax,SCR_ARGFRAME(%edx)	/* save argument pointer */
56*ccd9b49fSElliott Mitchell	pushl	%ebx
57*ccd9b49fSElliott Mitchell	pushl	%ebp
58*ccd9b49fSElliott Mitchell	pushl	%esi
59*ccd9b49fSElliott Mitchell	pushl	%edi
60*ccd9b49fSElliott Mitchell	pushl	%gs
61*ccd9b49fSElliott Mitchell
62*ccd9b49fSElliott Mitchell	movl	PCPU(CURTHREAD),%ecx
63*ccd9b49fSElliott Mitchell	cmpl	%ecx,PCPU(FPCURTHREAD)	/* do we need to save fp? */
64*ccd9b49fSElliott Mitchell	jne	1f
65*ccd9b49fSElliott Mitchell	pushl	%edx
66*ccd9b49fSElliott Mitchell	movl	TD_PCB(%ecx),%ecx
67*ccd9b49fSElliott Mitchell	pushl	PCB_SAVEFPU(%ecx)
68*ccd9b49fSElliott Mitchell	movl	$npxsave,%eax
69*ccd9b49fSElliott Mitchell	call	*%eax
70*ccd9b49fSElliott Mitchell	addl	$4,%esp
71*ccd9b49fSElliott Mitchell	popl	%edx			/* recover our pcb */
72*ccd9b49fSElliott Mitchell1:
73*ccd9b49fSElliott Mitchell	movl	SCR_VMFRAME(%edx),%ebx	/* target frame location */
74*ccd9b49fSElliott Mitchell	movl	%ebx,%edi		/* destination */
75*ccd9b49fSElliott Mitchell	movl    SCR_ARGFRAME(%edx),%esi	/* source (set on entry) */
76*ccd9b49fSElliott Mitchell	movl	$VM86_FRAMESIZE/4,%ecx	/* sizeof(struct vm86frame)/4 */
77*ccd9b49fSElliott Mitchell	cld
78*ccd9b49fSElliott Mitchell	rep
79*ccd9b49fSElliott Mitchell	movsl				/* copy frame to new stack */
80*ccd9b49fSElliott Mitchell
81*ccd9b49fSElliott Mitchell	movl	PCPU(CURPCB),%eax
82*ccd9b49fSElliott Mitchell	pushl	%eax			/* save curpcb */
83*ccd9b49fSElliott Mitchell	movl	%edx,PCPU(CURPCB)	/* set curpcb to vm86pcb */
84*ccd9b49fSElliott Mitchell
85*ccd9b49fSElliott Mitchell	movl	PCPU(TSS_GDT),%ebx	/* entry in GDT */
86*ccd9b49fSElliott Mitchell	movl	0(%ebx),%eax
87*ccd9b49fSElliott Mitchell	movl	%eax,SCR_TSS0(%edx)	/* save first word */
88*ccd9b49fSElliott Mitchell	movl	4(%ebx),%eax
89*ccd9b49fSElliott Mitchell	andl    $~0x200, %eax		/* flip 386BSY -> 386TSS */
90*ccd9b49fSElliott Mitchell	movl	%eax,SCR_TSS1(%edx)	/* save second word */
91*ccd9b49fSElliott Mitchell
92*ccd9b49fSElliott Mitchell	movl	PCB_EXT(%edx),%edi	/* vm86 tssd entry */
93*ccd9b49fSElliott Mitchell	movl	0(%edi),%eax
94*ccd9b49fSElliott Mitchell	movl	%eax,0(%ebx)
95*ccd9b49fSElliott Mitchell	movl	4(%edi),%eax
96*ccd9b49fSElliott Mitchell	movl	%eax,4(%ebx)
97*ccd9b49fSElliott Mitchell	movl	$GPROC0_SEL*8,%esi	/* GSEL(entry, SEL_KPL) */
98*ccd9b49fSElliott Mitchell	ltr	%si
99*ccd9b49fSElliott Mitchell
100*ccd9b49fSElliott Mitchell	movl	%cr3,%eax
101*ccd9b49fSElliott Mitchell	pushl	%eax			/* save address space */
102*ccd9b49fSElliott Mitchell	cmpb	$0,pae_mode
103*ccd9b49fSElliott Mitchell	jne	2f
104*ccd9b49fSElliott Mitchell	movl	IdlePTD_nopae,%ecx	/* va (and pa) of Idle PTD */
105*ccd9b49fSElliott Mitchell	jmp	3f
106*ccd9b49fSElliott Mitchell2:	movl	IdlePTD_pae,%ecx
107*ccd9b49fSElliott Mitchell3:	movl	%ecx,%ebx
108*ccd9b49fSElliott Mitchell	movl	0(%ebx),%eax
109*ccd9b49fSElliott Mitchell	pushl	%eax			/* old ptde != 0 when booting */
110*ccd9b49fSElliott Mitchell	pushl	%ebx			/* keep for reuse */
111*ccd9b49fSElliott Mitchell
112*ccd9b49fSElliott Mitchell	movl	%esp,SCR_STACK(%edx)	/* save current stack location */
113*ccd9b49fSElliott Mitchell
114*ccd9b49fSElliott Mitchell	movl	SCR_NEWPTD(%edx),%eax	/* mapping for vm86 page table */
115*ccd9b49fSElliott Mitchell	movl	%eax,0(%ebx)		/* ... install as PTD entry 0 */
116*ccd9b49fSElliott Mitchell
117*ccd9b49fSElliott Mitchell	cmpb	$0,pae_mode
118*ccd9b49fSElliott Mitchell	je	4f
119*ccd9b49fSElliott Mitchell	movl	IdlePDPT,%ecx
120*ccd9b49fSElliott Mitchell4:	movl	%ecx,%cr3		/* new page tables */
121*ccd9b49fSElliott Mitchell	movl	SCR_VMFRAME(%edx),%esp	/* switch to new stack */
122*ccd9b49fSElliott Mitchell
123*ccd9b49fSElliott Mitchell	pushl	%esp
124*ccd9b49fSElliott Mitchell	movl	$vm86_prepcall, %eax
125*ccd9b49fSElliott Mitchell	call	*%eax			/* finish setup */
126*ccd9b49fSElliott Mitchell	add	$4, %esp
127*ccd9b49fSElliott Mitchell
128*ccd9b49fSElliott Mitchell	/*
129*ccd9b49fSElliott Mitchell	 * Return via doreti
130*ccd9b49fSElliott Mitchell	 */
131*ccd9b49fSElliott Mitchell	jmp	doreti
132*ccd9b49fSElliott Mitchell
133*ccd9b49fSElliott Mitchell
134*ccd9b49fSElliott Mitchell/*
135*ccd9b49fSElliott Mitchell * vm86_biosret(struct trapframe_vm86 *vm86)
136*ccd9b49fSElliott Mitchell */
137*ccd9b49fSElliott MitchellENTRY(vm86_biosret)
138*ccd9b49fSElliott Mitchell	movl	vm86pcb,%edx		/* data area */
139*ccd9b49fSElliott Mitchell
140*ccd9b49fSElliott Mitchell	movl	4(%esp),%esi		/* source */
141*ccd9b49fSElliott Mitchell	movl	SCR_ARGFRAME(%edx),%edi	/* destination */
142*ccd9b49fSElliott Mitchell	movl	$VM86_FRAMESIZE/4,%ecx	/* size */
143*ccd9b49fSElliott Mitchell	cld
144*ccd9b49fSElliott Mitchell	rep
145*ccd9b49fSElliott Mitchell	movsl				/* copy frame to original frame */
146*ccd9b49fSElliott Mitchell
147*ccd9b49fSElliott Mitchell	movl	SCR_STACK(%edx),%esp	/* back to old stack */
148*ccd9b49fSElliott Mitchell	popl	%ebx			/* saved va of Idle PTD */
149*ccd9b49fSElliott Mitchell	popl	%eax
150*ccd9b49fSElliott Mitchell	movl	%eax,0(%ebx)		/* restore old pte */
151*ccd9b49fSElliott Mitchell	popl	%eax
152*ccd9b49fSElliott Mitchell	movl	%eax,%cr3		/* install old page table */
153*ccd9b49fSElliott Mitchell
154*ccd9b49fSElliott Mitchell	movl	PCPU(TSS_GDT),%ebx		/* entry in GDT */
155*ccd9b49fSElliott Mitchell	movl	SCR_TSS0(%edx),%eax
156*ccd9b49fSElliott Mitchell	movl	%eax,0(%ebx)		/* restore first word */
157*ccd9b49fSElliott Mitchell	movl	SCR_TSS1(%edx),%eax
158*ccd9b49fSElliott Mitchell	movl	%eax,4(%ebx)		/* restore second word */
159*ccd9b49fSElliott Mitchell	movl	$GPROC0_SEL*8,%esi	/* GSEL(entry, SEL_KPL) */
160*ccd9b49fSElliott Mitchell	ltr	%si
161*ccd9b49fSElliott Mitchell
162*ccd9b49fSElliott Mitchell	popl	PCPU(CURPCB)		/* restore curpcb/curproc */
163*ccd9b49fSElliott Mitchell	movl	SCR_ARGFRAME(%edx),%edx	/* original stack frame */
164*ccd9b49fSElliott Mitchell	movl	TF_TRAPNO(%edx),%eax	/* return (trapno) */
165*ccd9b49fSElliott Mitchell
166*ccd9b49fSElliott Mitchell	popl	%gs
167*ccd9b49fSElliott Mitchell	popl	%edi
168*ccd9b49fSElliott Mitchell	popl	%esi
169*ccd9b49fSElliott Mitchell	popl	%ebp
170*ccd9b49fSElliott Mitchell	popl	%ebx
171*ccd9b49fSElliott Mitchell	ret				/* back to our normal program */
172