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: stable/11/sys/i386/i386/vm86bios.s 331759 2018-03-30 10:36:54Z kib $
2734840Sjlemon */
2834840Sjlemon
2934840Sjlemon#include <machine/asmacros.h>		/* miscellaneous asm macros */
3034840Sjlemon#include <machine/trap.h>
3134840Sjlemon
3234840Sjlemon#include "assym.s"
3334840Sjlemon
3437889Sjlemon#define SCR_NEWPTD	PCB_ESI		/* readability macros */
3537889Sjlemon#define SCR_VMFRAME	PCB_EBP		/* see vm86.c for explanation */
3637889Sjlemon#define SCR_STACK	PCB_ESP
3737889Sjlemon#define SCR_PGTABLE	PCB_EBX
3837889Sjlemon#define SCR_ARGFRAME	PCB_EIP
39145025Speter#define SCR_TSS0	PCB_VM86
40145025Speter#define SCR_TSS1	(PCB_VM86+4)
4137889Sjlemon
4234840Sjlemon	.data
4334840Sjlemon	ALIGN_DATA
4434840Sjlemon
45106542Sdavidxu	.globl	vm86pcb
4634840Sjlemon
4773011Sjakevm86pcb:		.long	0
4834840Sjlemon
4934840Sjlemon	.text
5034840Sjlemon
5134840Sjlemon/*
5234840Sjlemon * vm86_bioscall(struct trapframe_vm86 *vm86)
5334840Sjlemon */
5434840SjlemonENTRY(vm86_bioscall)
5573011Sjake	movl	vm86pcb,%edx		/* scratch data area */
5634840Sjlemon	movl	4(%esp),%eax
5737889Sjlemon	movl	%eax,SCR_ARGFRAME(%edx)	/* save argument pointer */
5834840Sjlemon	pushl	%ebx
5934840Sjlemon	pushl	%ebp
6034840Sjlemon	pushl	%esi
6134840Sjlemon	pushl	%edi
6234840Sjlemon	pushl	%gs
6334840Sjlemon
6483366Sjulian	movl	PCPU(CURTHREAD),%ecx
6587702Sjhb	cmpl	%ecx,PCPU(FPCURTHREAD)	/* do we need to save fp? */
6634840Sjlemon	jne	1f
6739046Syokota	pushl	%edx
6883366Sjulian	movl	TD_PCB(%ecx),%ecx
69217587Sjkim	pushl	PCB_SAVEFPU(%ecx)
7073011Sjake	call	npxsave
71217587Sjkim	addl	$4,%esp
7234840Sjlemon	popl	%edx			/* recover our pcb */
7376904Sbde1:
7437889Sjlemon	movl	SCR_VMFRAME(%edx),%ebx	/* target frame location */
7534840Sjlemon	movl	%ebx,%edi		/* destination */
7637889Sjlemon	movl    SCR_ARGFRAME(%edx),%esi	/* source (set on entry) */
7747080Sluoqi	movl	$VM86_FRAMESIZE/4,%ecx	/* sizeof(struct vm86frame)/4 */
7834840Sjlemon	cld
7934840Sjlemon	rep
8034840Sjlemon	movsl				/* copy frame to new stack */
8134840Sjlemon
8269971Sjake	movl	PCPU(CURPCB),%eax
8334840Sjlemon	pushl	%eax			/* save curpcb */
8469971Sjake	movl	%edx,PCPU(CURPCB)	/* set curpcb to vm86pcb */
8534840Sjlemon
8669971Sjake	movl	PCPU(TSS_GDT),%ebx	/* entry in GDT */
8734840Sjlemon	movl	0(%ebx),%eax
8837889Sjlemon	movl	%eax,SCR_TSS0(%edx)	/* save first word */
8934840Sjlemon	movl	4(%ebx),%eax
9034840Sjlemon	andl    $~0x200, %eax		/* flip 386BSY -> 386TSS */
9137889Sjlemon	movl	%eax,SCR_TSS1(%edx)	/* save second word */
9234840Sjlemon
9334840Sjlemon	movl	PCB_EXT(%edx),%edi	/* vm86 tssd entry */
9434840Sjlemon	movl	0(%edi),%eax
9534840Sjlemon	movl	%eax,0(%ebx)
9634840Sjlemon	movl	4(%edi),%eax
9734840Sjlemon	movl	%eax,4(%ebx)
9847081Sluoqi	movl	$GPROC0_SEL*8,%esi	/* GSEL(entry, SEL_KPL) */
9934840Sjlemon	ltr	%si
10034840Sjlemon
10134840Sjlemon	movl	%cr3,%eax
10234840Sjlemon	pushl	%eax			/* save address space */
10373011Sjake	movl	IdlePTD,%ecx
10434840Sjlemon	movl	%ecx,%ebx
10534840Sjlemon	addl	$KERNBASE,%ebx		/* va of Idle PTD */
10634840Sjlemon	movl	0(%ebx),%eax
10734840Sjlemon	pushl	%eax			/* old ptde != 0 when booting */
10834840Sjlemon	pushl	%ebx			/* keep for reuse */
10934840Sjlemon
11037889Sjlemon	movl	%esp,SCR_STACK(%edx)	/* save current stack location */
11134840Sjlemon
11237889Sjlemon	movl	SCR_NEWPTD(%edx),%eax	/* mapping for vm86 page table */
11334840Sjlemon	movl	%eax,0(%ebx)		/* ... install as PTD entry 0 */
11434840Sjlemon
115281495Skib#if defined(PAE) || defined(PAE_TABLES)
116112841Sjake	movl	IdlePDPT,%ecx
117112841Sjake#endif
11834840Sjlemon	movl	%ecx,%cr3		/* new page tables */
11937889Sjlemon	movl	SCR_VMFRAME(%edx),%esp	/* switch to new stack */
120165302Skmacy
121165302Skmacy	pushl	%esp
122165302Skmacy	call	vm86_prepcall		/* finish setup */
123165302Skmacy	add	$4, %esp
12434840Sjlemon
12534840Sjlemon	/*
12673011Sjake	 * Return via doreti
12734840Sjlemon	 */
12834840Sjlemon	MEXITCOUNT
12973011Sjake	jmp	doreti
13034840Sjlemon
13134840Sjlemon
13234840Sjlemon/*
13334840Sjlemon * vm86_biosret(struct trapframe_vm86 *vm86)
13434840Sjlemon */
13534840SjlemonENTRY(vm86_biosret)
13673011Sjake	movl	vm86pcb,%edx		/* data area */
13734840Sjlemon
13834840Sjlemon	movl	4(%esp),%esi		/* source */
13937889Sjlemon	movl	SCR_ARGFRAME(%edx),%edi	/* destination */
14047080Sluoqi	movl	$VM86_FRAMESIZE/4,%ecx	/* size */
14134840Sjlemon	cld
14234840Sjlemon	rep
14334840Sjlemon	movsl				/* copy frame to original frame */
14434840Sjlemon
14537889Sjlemon	movl	SCR_STACK(%edx),%esp	/* back to old stack */
14634840Sjlemon	popl	%ebx			/* saved va of Idle PTD */
14734840Sjlemon	popl	%eax
14834840Sjlemon	movl	%eax,0(%ebx)		/* restore old pte */
14934840Sjlemon	popl	%eax
15034840Sjlemon	movl	%eax,%cr3		/* install old page table */
15134840Sjlemon
15269971Sjake	movl	PCPU(TSS_GDT),%ebx		/* entry in GDT */
15337889Sjlemon	movl	SCR_TSS0(%edx),%eax
15434840Sjlemon	movl	%eax,0(%ebx)		/* restore first word */
15537889Sjlemon	movl	SCR_TSS1(%edx),%eax
15634840Sjlemon	movl	%eax,4(%ebx)		/* restore second word */
15747081Sluoqi	movl	$GPROC0_SEL*8,%esi	/* GSEL(entry, SEL_KPL) */
15834840Sjlemon	ltr	%si
15934840Sjlemon
16069971Sjake	popl	PCPU(CURPCB)		/* restore curpcb/curproc */
16137889Sjlemon	movl	SCR_ARGFRAME(%edx),%edx	/* original stack frame */
16234840Sjlemon	movl	TF_TRAPNO(%edx),%eax	/* return (trapno) */
16334840Sjlemon
16434840Sjlemon	popl	%gs
16534840Sjlemon	popl	%edi
16634840Sjlemon	popl	%esi
16734840Sjlemon	popl	%ebp
16834840Sjlemon	popl	%ebx
16934840Sjlemon	ret				/* back to our normal program */
170