|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.