Annotation of Gnu-Mach/i386/pc/rv86/rv86_trap_handler.S, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Copyright (c) 1995-1994 The University of Utah and
        !             3:  * the Computer Systems Laboratory at the University of Utah (CSL).
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Permission to use, copy, modify and distribute this software is hereby
        !             7:  * granted provided that (1) source code retains these copyright, permission,
        !             8:  * and disclaimer notices, and (2) redistributions including binaries
        !             9:  * reproduce the notices in supporting documentation, and (3) all advertising
        !            10:  * materials mentioning features or use of this software display the following
        !            11:  * acknowledgement: ``This product includes software developed by the
        !            12:  * Computer Systems Laboratory at the University of Utah.''
        !            13:  *
        !            14:  * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
        !            15:  * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
        !            16:  * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            17:  *
        !            18:  * CSL requests users of this software to return to [email protected] any
        !            19:  * improvements that they make and grant CSL redistribution rights.
        !            20:  *
        !            21:  *      Author: Bryan Ford, University of Utah CSL
        !            22:  */
        !            23: 
        !            24: #include <mach/machine/asm.h>
        !            25: #include <mach/machine/eflags.h>
        !            26: 
        !            27: #include "i386_asm.h"
        !            28: #include "trap.h"
        !            29: #include "trap_asm.h"
        !            30: 
        !            31:        .text
        !            32: 
        !            33: ENTRY(rv86_trap_handler)
        !            34:        cmpl    $T_GENERAL_PROTECTION,TR_TRAPNO(%esp)
        !            35:        jz      gpf_from_v86
        !            36: 
        !            37:        UNEXPECTED_TRAP
        !            38: 
        !            39: gpf_from_v86:
        !            40: 
        !            41:        /* Load the linear/physical-address data segment,
        !            42:           for easy access to real-mode memory.  */
        !            43:        movl    $LINEAR_DS,%eax
        !            44:        movw    %ax,%ds
        !            45: 
        !            46:        /* Find the physical address of the trapping instruction (ebx).  */
        !            47:        movzwl  TR_CS(%esp),%ebx
        !            48:        shll    $4,%ebx
        !            49:        addl    TR_EIP(%esp),%ebx
        !            50: 
        !            51:        /* See if we're just trying to get out of v86 mode.  */
        !            52:        cmpl    %ss:EXT(rv86_return_int_pa),%ebx
        !            53:        je      EXT(rv86_return)
        !            54: 
        !            55:        /* Check the instruction (al).  */
        !            56:        movb    (%ebx),%al
        !            57:        cmpb    $0xcd,%al
        !            58:        je      gpf_int_n
        !            59: 
        !            60:        UNEXPECTED_TRAP
        !            61: 
        !            62: 
        !            63: gpf_int_n:
        !            64: 
        !            65:        /* Bump the ip past the int instruction.  */
        !            66:        addw    $2,TR_EIP(%esp)
        !            67: 
        !            68:        /* Find the real mode interrupt vector number (esi).  */
        !            69:        movzbl  1(%ebx),%esi
        !            70: 
        !            71:        /* See if it's a copy-extended-memory interrupt request;
        !            72:           if so, just handle it here.  */
        !            73:        cmpl    $0x15,%esi
        !            74:        jne     1f
        !            75:        cmpb    $0x87,TR_EAX+1(%esp)
        !            76:        je      copy_ext_mem
        !            77: 1:
        !            78: 
        !            79:        /* XXX The stuff down here is essentially the same as in moss.  */
        !            80: 
        !            81: reflect_v86_intr:
        !            82: 
        !            83:        /* Find the address of the real mode interrupt vector (esi).  */
        !            84:        shll    $2,%esi
        !            85: 
        !            86:        /* Make room for the real-mode interrupt stack frame.  */
        !            87:        subw    $6,TR_ESP(%esp)
        !            88: 
        !            89:        /* Find the physical address of the v86 stack (ebx).  */
        !            90:        movzwl  TR_SS(%esp),%ebx
        !            91:        shll    $4,%ebx
        !            92:        addl    TR_ESP(%esp),%ebx
        !            93: 
        !            94:        /* Store the return information into the v86 stack frame.  */
        !            95:        movl    TR_EIP(%esp),%eax
        !            96:        movw    %ax,(%ebx)
        !            97:        movl    TR_CS(%esp),%eax
        !            98:        movw    %ax,2(%ebx)
        !            99:        movl    TR_EFLAGS(%esp),%eax
        !           100:        movw    %ax,4(%ebx)
        !           101: 
        !           102:        /* Find the real-mode interrupt vector to invoke,
        !           103:           and set up the real_call_thread's kernel stack frame
        !           104:           to point to it.  */
        !           105:        movl    (%esi),%eax
        !           106:        movw    %ax,TR_EIP(%esp)
        !           107:        shrl    $16,%eax
        !           108:        movw    %ax,TR_CS(%esp)
        !           109:        andl    $-1-EFL_IF-EFL_TF,TR_EFLAGS(%esp)
        !           110: 
        !           111:        /* Restore saved state and return.  */
        !           112:        addl    $4*4,%esp
        !           113:        popa
        !           114:        addl    $4*2,%esp
        !           115:        iret
        !           116: 
        !           117: 
        !           118: 
        !           119: /* We intercepted a copy-extended-memory software interrupt
        !           120:    (int 0x15 function 0x87).
        !           121:    This is used by HIMEM.SYS, for example, to manage extended memory.
        !           122:    The BIOS's routine isn't going to work in v86 mode,
        !           123:    so do it ourselves.  */
        !           124: copy_ext_mem:
        !           125: 
        !           126:        /* Find the parameter block provided by the caller (ebx).  */
        !           127:        movzwl  TR_V86_ES(%esp),%ebx
        !           128:        movzwl  TR_ESI(%esp),%eax
        !           129:        shll    $4,%ebx
        !           130:        addl    %eax,%ebx
        !           131: 
        !           132:        /* Source address (esi).  */
        !           133:        movl    0x12(%ebx),%esi
        !           134:        andl    $0x00ffffff,%esi
        !           135: 
        !           136:        /* Destination address (edi).  */
        !           137:        movl    0x1a(%ebx),%edi
        !           138:        andl    $0x00ffffff,%edi
        !           139: 
        !           140:        /* Number of bytes (ecx).  */
        !           141:        movzwl  TR_ECX(%esp),%ecx
        !           142:        addl    %ecx,%ecx
        !           143: 
        !           144:        /* Use the standard i386 bcopy routine to copy the data.
        !           145:           This assumes it's "friendly" in its use of segment registers
        !           146:           (i.e. always uses ss for stack data and ds/es for the data to copy).
        !           147:           The bcopy is simple enough that this should always be true.  */
        !           148:        movw    %ds,%ax
        !           149:        movw    %ax,%es
        !           150:        cld
        !           151:        pushl   %ecx
        !           152:        pushl   %edi
        !           153:        pushl   %esi
        !           154:        call    EXT(bcopy)
        !           155:        addl    $3*4,%esp
        !           156: 
        !           157:        /* Clear the carry flag to indicate that the copy was successful.
        !           158:           AH is also cleared, below.  */
        !           159:        andl    $-1-EFL_CF,TR_EFLAGS(%esp)
        !           160: 
        !           161:        /* Restore saved state and return.  */
        !           162:        addl    $4*4,%esp
        !           163:        popa
        !           164:        xorb    %ah,%ah
        !           165:        addl    $4*2,%esp
        !           166:        iret
        !           167: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.