/* * ReactOS kernel * Copyright (C) 2000 David Welch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * FILE: ntoskrnl/ke/i386/vm86_sup.S * PURPOSE: V86 mode support * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 09/10/00 */ #include #include #include .globl _Ki386RetToV86Mode .globl _KiV86Complete /* * VOID Ki386RetToV86Mode(KV86M_REGISTERS* InRegs, * KV86M_REGISTERS* OutRegs); * * Starts in v86 mode with the registers set to the * specified values. */ _Ki386RetToV86Mode: /* * Setup a stack frame */ pushl %ebp movl %esp, %ebp /* * Save registers */ pusha /* * Get a pointer to IN_REGS */ movl 8(%ebp), %ebx /* * Save ebp */ pushl %ebp /* * Save a pointer to IN_REGS which the v86m exception handler will * use to handle exceptions */ pushl %ebx /* * The stack used for handling exceptions from v86 mode in this thread * will be the current stack adjusted so we don't overwrite the * existing stack frames */ movl %esp, KTSS_ESP0(%esi) /* * Create the stack frame for an iret to v86 mode */ pushl KV86M_REGISTERS_GS(%ebx) pushl KV86M_REGISTERS_FS(%ebx) pushl KV86M_REGISTERS_DS(%ebx) pushl KV86M_REGISTERS_ES(%ebx) pushl KV86M_REGISTERS_SS(%ebx) pushl KV86M_REGISTERS_ESP(%ebx) pushl KV86M_REGISTERS_EFLAGS(%ebx) pushl KV86M_REGISTERS_CS(%ebx) pushl KV86M_REGISTERS_EIP(%ebx) /* * Setup the CPU registers */ movl KV86M_REGISTERS_EAX(%ebx), %eax movl KV86M_REGISTERS_ECX(%ebx), %ecx movl KV86M_REGISTERS_EDX(%ebx), %edx movl KV86M_REGISTERS_ESI(%ebx), %esi movl KV86M_REGISTERS_EDI(%ebx), %edi movl KV86M_REGISTERS_EBP(%ebx), %ebp movl KV86M_REGISTERS_EBX(%ebx), %ebx /* * Go to v86 mode */ iret /* * Handle the completion of a vm86 routine. We are called from * an exception handler with the registers at the point of the * exception on the stack. */ _KiV86Complete: addl $4, %esp /* Ignore pointer to trap frame */ /* Restore the original ebp */ movl TF_ORIG_EBP(%esp), %ebp /* Get a pointer to the OUT_REGS structure */ movl 12(%ebp), %ebx /* Save the vm86 registers into the OUT_REGS structure */ popl KV86M_REGISTERS_EDI(%ebx) popl KV86M_REGISTERS_ESI(%ebx) popl KV86M_REGISTERS_EBP(%ebx) popl KV86M_REGISTERS_EBX(%ebx) popl KV86M_REGISTERS_EDX(%ebx) popl KV86M_REGISTERS_ECX(%ebx) popl KV86M_REGISTERS_EAX(%ebx) addl $16, %esp /* Ignore 32-bit segment registers */ addl $4, %esp /* Ignore error code */ popl KV86M_REGISTERS_EIP(%ebx) popl KV86M_REGISTERS_CS(%ebx) popl KV86M_REGISTERS_EFLAGS(%ebx) popl KV86M_REGISTERS_ESP(%ebx) popl KV86M_REGISTERS_SS(%ebx) popl KV86M_REGISTERS_ES(%ebx) popl KV86M_REGISTERS_DS(%ebx) popl KV86M_REGISTERS_FS(%ebx) popl KV86M_REGISTERS_GS(%ebx) /* Ignore IN_REGS pointer */ addl $4, %esp /* Ignore ebp restored above */ addl $4, %esp /* Return to caller */ popa movl %ebp, %esp popl %ebp ret