mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-11 14:10:34 +00:00
a5c5d4402c
passed by value (trap frames) as if they were in fact being passed by reference. For better or worse, this incorrect behaviour is no longer present in gcc 4.1. In this patch I convert all trapframe arguments to be explicitly pass by reference. I also remove vm86_initflags, pushing the very little work that it actually does up into vm86_prepcall. Reviewed by: kan Tested by: kan
181 lines
4.7 KiB
ArmAsm
181 lines
4.7 KiB
ArmAsm
/*-
|
|
* Copyright (c) 1998 Jonathan Lemon
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
#include "opt_npx.h"
|
|
|
|
#include <machine/asmacros.h> /* miscellaneous asm macros */
|
|
#include <machine/trap.h>
|
|
|
|
#include "assym.s"
|
|
|
|
#define SCR_NEWPTD PCB_ESI /* readability macros */
|
|
#define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */
|
|
#define SCR_STACK PCB_ESP
|
|
#define SCR_PGTABLE PCB_EBX
|
|
#define SCR_ARGFRAME PCB_EIP
|
|
#define SCR_TSS0 PCB_VM86
|
|
#define SCR_TSS1 (PCB_VM86+4)
|
|
|
|
.data
|
|
ALIGN_DATA
|
|
|
|
.globl vm86pcb
|
|
|
|
vm86pcb: .long 0
|
|
|
|
.text
|
|
|
|
/*
|
|
* vm86_bioscall(struct trapframe_vm86 *vm86)
|
|
*/
|
|
ENTRY(vm86_bioscall)
|
|
movl vm86pcb,%edx /* scratch data area */
|
|
movl 4(%esp),%eax
|
|
movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */
|
|
pushl %ebx
|
|
pushl %ebp
|
|
pushl %esi
|
|
pushl %edi
|
|
pushl %gs
|
|
|
|
#ifdef DEV_NPX
|
|
pushfl
|
|
cli
|
|
movl PCPU(CURTHREAD),%ecx
|
|
cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */
|
|
jne 1f
|
|
testl %ecx,%ecx
|
|
je 1f /* no curproc/npxproc */
|
|
pushl %edx
|
|
movl TD_PCB(%ecx),%ecx
|
|
addl $PCB_SAVEFPU,%ecx
|
|
pushl %ecx
|
|
call npxsave
|
|
popl %ecx
|
|
popl %edx /* recover our pcb */
|
|
1:
|
|
popfl
|
|
#endif
|
|
|
|
movl SCR_VMFRAME(%edx),%ebx /* target frame location */
|
|
movl %ebx,%edi /* destination */
|
|
movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */
|
|
movl $VM86_FRAMESIZE/4,%ecx /* sizeof(struct vm86frame)/4 */
|
|
cld
|
|
rep
|
|
movsl /* copy frame to new stack */
|
|
|
|
movl PCPU(CURPCB),%eax
|
|
pushl %eax /* save curpcb */
|
|
movl %edx,PCPU(CURPCB) /* set curpcb to vm86pcb */
|
|
|
|
movl PCPU(TSS_GDT),%ebx /* entry in GDT */
|
|
movl 0(%ebx),%eax
|
|
movl %eax,SCR_TSS0(%edx) /* save first word */
|
|
movl 4(%ebx),%eax
|
|
andl $~0x200, %eax /* flip 386BSY -> 386TSS */
|
|
movl %eax,SCR_TSS1(%edx) /* save second word */
|
|
|
|
movl PCB_EXT(%edx),%edi /* vm86 tssd entry */
|
|
movl 0(%edi),%eax
|
|
movl %eax,0(%ebx)
|
|
movl 4(%edi),%eax
|
|
movl %eax,4(%ebx)
|
|
movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
|
|
ltr %si
|
|
|
|
movl %cr3,%eax
|
|
pushl %eax /* save address space */
|
|
movl IdlePTD,%ecx
|
|
movl %ecx,%ebx
|
|
addl $KERNBASE,%ebx /* va of Idle PTD */
|
|
movl 0(%ebx),%eax
|
|
pushl %eax /* old ptde != 0 when booting */
|
|
pushl %ebx /* keep for reuse */
|
|
|
|
movl %esp,SCR_STACK(%edx) /* save current stack location */
|
|
|
|
movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */
|
|
movl %eax,0(%ebx) /* ... install as PTD entry 0 */
|
|
|
|
#ifdef PAE
|
|
movl IdlePDPT,%ecx
|
|
#endif
|
|
movl %ecx,%cr3 /* new page tables */
|
|
movl SCR_VMFRAME(%edx),%esp /* switch to new stack */
|
|
|
|
pushl %esp
|
|
call vm86_prepcall /* finish setup */
|
|
add $4, %esp
|
|
|
|
/*
|
|
* Return via doreti
|
|
*/
|
|
MEXITCOUNT
|
|
jmp doreti
|
|
|
|
|
|
/*
|
|
* vm86_biosret(struct trapframe_vm86 *vm86)
|
|
*/
|
|
ENTRY(vm86_biosret)
|
|
movl vm86pcb,%edx /* data area */
|
|
|
|
movl 4(%esp),%esi /* source */
|
|
movl SCR_ARGFRAME(%edx),%edi /* destination */
|
|
movl $VM86_FRAMESIZE/4,%ecx /* size */
|
|
cld
|
|
rep
|
|
movsl /* copy frame to original frame */
|
|
|
|
movl SCR_STACK(%edx),%esp /* back to old stack */
|
|
popl %ebx /* saved va of Idle PTD */
|
|
popl %eax
|
|
movl %eax,0(%ebx) /* restore old pte */
|
|
popl %eax
|
|
movl %eax,%cr3 /* install old page table */
|
|
|
|
movl PCPU(TSS_GDT),%ebx /* entry in GDT */
|
|
movl SCR_TSS0(%edx),%eax
|
|
movl %eax,0(%ebx) /* restore first word */
|
|
movl SCR_TSS1(%edx),%eax
|
|
movl %eax,4(%ebx) /* restore second word */
|
|
movl $GPROC0_SEL*8,%esi /* GSEL(entry, SEL_KPL) */
|
|
ltr %si
|
|
|
|
popl PCPU(CURPCB) /* restore curpcb/curproc */
|
|
movl SCR_ARGFRAME(%edx),%edx /* original stack frame */
|
|
movl TF_TRAPNO(%edx),%eax /* return (trapno) */
|
|
|
|
popl %gs
|
|
popl %edi
|
|
popl %esi
|
|
popl %ebp
|
|
popl %ebx
|
|
ret /* back to our normal program */
|