|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1993 NeXT Computer, Inc.
27: *
28: * PC support primatives.
29: *
30: * HISTORY
31: *
32: * 22 Mar 1993 ? at NeXT
33: * Created.
34: */
35:
36: #import <mach/mach_types.h>
37:
38: #import <machdep/i386/sel_inline.h>
39: #import <machdep/i386/cpu_inline.h>
40:
41: #import "PCprivate.h"
42:
43: kern_return_t
44: PCresume(void)
45: {
46: thread_t thread = current_thread();
47: thread_saved_state_t *saved_state = USER_REGS(thread);
48: PCshared_t shared = threadPCShared(thread);
49: PCcontext_t context;
50: _PCcpuState_t * cpuState;
51:
52: if (shared == 0)
53: return (KERN_FAILURE);
54:
55: cpuState = &shared->cpuState;
56:
57: if (cpuState->cr0.pe && cpuState->cs.ti != SEL_LDT)
58: return (KERN_FAILURE);
59:
60: context = currentContext(shared);
61:
62: context->IF_flag = (cpuState->eflags & EFL_IF) != 0;
63: context->EM_bit = cpuState->cr0.em;
64: context->X_flags = (cpuState->eflags & (EFL_NT | EFL_IOPL));
65:
66: PCscheduleTimers(context);
67:
68: context->running = TRUE;
69:
70: setts();
71:
72: saved_state->regs.eax = cpuState->eax;
73: saved_state->regs.ebx = cpuState->ebx;
74: saved_state->regs.ecx = cpuState->ecx;
75: saved_state->regs.edx = cpuState->edx;
76: saved_state->regs.edi = cpuState->edi;
77: saved_state->regs.esi = cpuState->esi;
78: saved_state->regs.ebp = cpuState->ebp;
79: saved_state->frame.esp = cpuState->esp;
80: saved_state->frame.ss = cpuState->ss;
81: saved_state->frame.eflags = cpuState->eflags;
82: saved_state->frame.eflags &= ~( EFL_VM | EFL_NT | EFL_IOPL | EFL_CLR );
83: saved_state->frame.eflags |= ( EFL_IF | EFL_SET );
84: saved_state->frame.eip = cpuState->eip;
85: saved_state->frame.cs = cpuState->cs;
86:
87: if (cpuState->cr0.pe) {
88: saved_state->regs.ds = cpuState->ds;
89: saved_state->regs.es = cpuState->es;
90: saved_state->regs.fs = cpuState->fs;
91: saved_state->regs.gs = cpuState->gs;
92: }
93: else {
94: saved_state->frame.eflags |= EFL_VM;
95:
96: saved_state->regs.ds = NULL_SEL;
97: saved_state->regs.es = NULL_SEL;
98: saved_state->regs.fs = NULL_SEL;
99: saved_state->regs.gs = NULL_SEL;
100: saved_state->frame.v_ds = sel_to_selector(cpuState->ds);
101: saved_state->frame.v_es = sel_to_selector(cpuState->es);
102: saved_state->frame.v_fs = sel_to_selector(cpuState->fs);
103: saved_state->frame.v_gs = sel_to_selector(cpuState->gs);
104: }
105:
106: thread_exception_return();
107: /* NOTREACHED */
108: }
109:
110: void
111: PCcallMonitor(
112: thread_t thread,
113: thread_saved_state_t *saved_state
114: )
115: {
116: PCshared_t shared = threadPCShared(thread);
117: PCcontext_t context = currentContext(shared);
118: _PCcpuState_t * cpuState;
119:
120: cpuState = &shared->cpuState;
121:
122: cpuState->cr0 = (cr0_t) { 0 }; // XXX
123:
124: if (context->EM_bit)
125: cpuState->cr0.em = TRUE;
126:
127: if (saved_state->frame.eflags & EFL_VM) {
128: cpuState->cr0.pe = FALSE;
129: cpuState->ds = selector_to_sel(saved_state->frame.v_ds);
130: cpuState->es = selector_to_sel(saved_state->frame.v_es);
131: cpuState->fs = selector_to_sel(saved_state->frame.v_fs);
132: cpuState->gs = selector_to_sel(saved_state->frame.v_gs);
133: }
134: else {
135: cpuState->cr0.pe = TRUE;
136: cpuState->ds = saved_state->regs.ds;
137: cpuState->es = saved_state->regs.es;
138: cpuState->fs = saved_state->regs.fs;
139: cpuState->gs = saved_state->regs.gs;
140: }
141:
142: cpuState->eflags = saved_state->frame.eflags;
143: if (context->IF_flag)
144: cpuState->eflags |= EFL_IF;
145: else
146: cpuState->eflags &= ~EFL_IF;
147:
148: cpuState->eflags |= (context->X_flags & (EFL_NT | EFL_IOPL));
149:
150: cpuState->cs = saved_state->frame.cs;
151: cpuState->eip = saved_state->frame.eip;
152:
153: cpuState->ss = saved_state->frame.ss;
154: cpuState->esp = saved_state->frame.esp;
155:
156: cpuState->ebp = saved_state->regs.ebp;
157: cpuState->esi = saved_state->regs.esi;
158: cpuState->edi = saved_state->regs.edi;
159: cpuState->edx = saved_state->regs.edx;
160: cpuState->ecx = saved_state->regs.ecx;
161: cpuState->ebx = saved_state->regs.ebx;
162: cpuState->eax = saved_state->regs.eax;
163:
164: context->running = FALSE;
165:
166: setts();
167:
168: PCdeliverTimers(context);
169:
170: saved_state->regs.ds = UDATA_SEL;
171: saved_state->regs.es = UDATA_SEL;
172: saved_state->regs.fs = NULL_SEL;
173: saved_state->regs.gs = NULL_SEL;
174:
175: saved_state->frame.cs = UCODE_SEL;
176: saved_state->frame.eip = (unsigned int)shared->callbackHelper;
177:
178: saved_state->frame.ss = UDATA_SEL;
179: saved_state->frame.esp = context->runState.sc_esp;
180: saved_state->regs.ebp = 0;
181:
182: saved_state->frame.eflags &= ~(EFL_VM | EFL_DF | EFL_TF);
183:
184: thread_exception_return();
185: /* NOTREACHED */
186: }
187:
188: boolean_t
189: PCbopFA(
190: thread_t thread,
191: thread_saved_state_t *state,
192: PCbopFA_t *args
193: )
194: {
195: if (args->cs.ti != SEL_LDT)
196: return (FALSE);
197:
198: state->frame.eip = args->eip;
199: state->frame.cs = args->cs;
200: state->frame.eflags = args->eflags;
201: state->frame.eflags &= ~( EFL_VM | EFL_NT | EFL_IOPL | EFL_CLR );
202: state->frame.eflags |= ( EFL_IF | EFL_SET );
203: state->frame.esp = args->esp;
204: state->frame.ss = args->ss;
205:
206: thread_exception_return();
207: /* NOTREACHED*/
208: }
209:
210: boolean_t
211: PCbopFC(
212: thread_t thread,
213: thread_saved_state_t *state,
214: PCbopFC_t *args
215: )
216: {
217: if (args->cs.ti != SEL_LDT)
218: return (FALSE);
219:
220: state->frame.eip = args->ip;
221: state->frame.cs = args->cs;
222: state->frame.eflags = args->flags;
223: state->frame.eflags &= ~( EFL_VM | EFL_NT | EFL_IOPL | EFL_CLR );
224: state->frame.eflags |= ( EFL_IF | EFL_SET );
225: state->frame.esp = args->sp;
226: state->frame.ss = args->ss;
227:
228: thread_exception_return();
229: /* NOTREACHED*/
230: }
231:
232: void
233: PCbopFD(
234: thread_t thread,
235: thread_saved_state_t *state,
236: PCbopFD_t *args
237: )
238: {
239: state->frame.eip = args->eip;
240: state->frame.cs = args->cs;
241: state->frame.eflags = args->eflags;
242: state->frame.eflags &= ~( EFL_NT | EFL_IOPL | EFL_CLR );
243: state->frame.eflags |= ( EFL_VM | EFL_IF | EFL_SET );
244: state->frame.esp = args->esp;
245: state->frame.ss = args->ss;
246:
247: state->regs.ds = NULL_SEL;
248: state->regs.es = NULL_SEL;
249: state->regs.fs = NULL_SEL;
250: state->regs.gs = NULL_SEL;
251:
252: thread_exception_return();
253: /* NOTREACHED*/
254: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.