|
|
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.