|
|
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: File: PseudoKernel.c
27:
28: Contains: BlueBox PseudoKernel calls
29:
30: Copyright: 1997 by Apple Computer, Inc., all rights reserved
31:
32: File Ownership:
33:
34: DRI: Thomas Mason
35:
36: Other Contact: Brett Halle
37:
38: Technology: Kernel/IO
39:
40: Writers:
41:
42: (tjm) Thomas Mason
43:
44: Change History (most recent first):
45: */
46:
47: #include <mach/mach_types.h>
48:
49: #include <machdep/ppc/PseudoKernel.h>
50:
51: #define printf kprintf
52:
53: int debugNotify = 0;
54:
55: /*
56: ** Function: NotifyInterruption
57: **
58: ** Inputs: port - mach_port for Blue thread
59: ** ppcInterrupHandler - interrupt handler to execute
60: ** interruptStatePtr - current interrupt state
61: ** emulatorDescriptor - where in emulator to notify
62: ** originalPC - where the emulator was executing
63: ** originalR2 - new R2
64: **
65: ** Outputs:
66: **
67: ** Notes:
68: **
69: */
70: void NotifyInterruption ( void * port_thread,
71: UInt32 ppcInterruptHandler,
72: UInt32 * interruptStatePtr,
73: EmulatorDescriptor * emulatorDescriptor,
74: void ** originalPC,
75: void ** originalR2,
76: thread_t *othread )
77: {
78: pcb_t bluePCB;
79: UInt32 interruptState;
80: thread_t thread, cur_thread;
81: task_t task;
82: ipc_port_t sright;
83: ipc_space_t space;
84: mach_port_t port, name;
85: queue_head_t *list;
86: spl_t s;
87:
88:
89: if (debugNotify > 5) {
90: printf("\nNotifyInterruption: %X, %X, %X, %X, %X, %X\n",
91: port_thread, ppcInterruptHandler, interruptStatePtr,
92: emulatorDescriptor, originalPC, originalR2 );
93: }
94:
95: if (othread != 0) {
96: port = (mach_port_t)port_thread;
97: cur_thread = current_thread();
98: task = cur_thread->task;
99: space = task->itk_space;
100: list = &task->thread_list;
101:
102: /* find the thread */
103: queue_iterate(list, thread, thread_t, thread_list) {
104:
105: sright = retrieve_thread_self(thread);
106: name = ipc_port_copyout_send_compat(sright, space);
107:
108: if (debugNotify > 5) {
109: printf("NotifyInterruption: port = %x\n", port);
110: printf(" th->ith_sself = %x\n",thread->ith_sself);
111: printf(" th->ith_self = %x\n",thread->ith_self);
112: printf(" task = %x\n",task);
113: printf(" sright = %x\n",sright);
114: printf(" space = %x\n",space);
115: printf(" name = %x\n",name);
116: }
117: if (name == port) {
118: if (debugNotify > 1)
119: printf(" thread = %x\n",thread);
120: break;
121: }
122: else {
123: if (debugNotify > 5) {
124: printf("NotifyInterruption: looking for port = %x\n", port);
125: if (name == MACH_PORT_NULL)
126: printf("Error from ipc_port_copyout_send_compat\n");
127: printf(" got name = %x\n",name);
128: printf(" task = %x\n",task);
129: printf(" thread = %x\n",thread);
130: }
131: }
132: }
133: if (queue_end(list, (queue_entry_t)(thread))) {
134: if (name != port) {
135: printf("COULD NOT FIND the thread!!!\n");
136: while (1)
137: ;
138: }
139: }
140: *othread = thread;
141: }
142: else {
143: if (debugNotify > 1)
144: printf(" thread = %x\n",thread);
145: thread = (thread_t)port_thread;
146: }
147:
148: s=splsched();
149: thread_lock(thread);
150: interruptState = (*interruptStatePtr & kInterruptStateMask) >> kInterruptStateShift;
151: bluePCB = thread->pcb;
152:
153: switch (interruptState)
154: {
155: case kInUninitialized:
156: if (debugNotify > 2)
157: printf("NotifyInterrupt: kInUninitialized\n");
158: break;
159:
160: case kInPseudoKernel:
161: case kOutsideBlue:
162: if (debugNotify > 2)
163: printf("NotifyInterrupt: kInPseudoKernel/kOutsideBlue\n");
164: *interruptStatePtr = *interruptStatePtr
165: | ((emulatorDescriptor->postIntMask >> kCR2ToBackupShift)
166: & kBackupCR2Mask);
167: break;
168:
169: case kInSystemContext:
170: if (debugNotify > 2)
171: printf("NotifyInterrupt: kInSystemContext\n");
172: bluePCB->ss.cr |= emulatorDescriptor->postIntMask;
173: break;
174:
175: case kInAlternateContext:
176: if (debugNotify > 2)
177: printf("NotifyInterrupt: kInAlternateContext\n");
178: *interruptStatePtr = *interruptStatePtr
179: | ((emulatorDescriptor->postIntMask >> kCR2ToBackupShift)
180: & kBackupCR2Mask);
181: *interruptStatePtr = (*interruptStatePtr & ~kInterruptStateMask) | (kInPseudoKernel << kInterruptStateShift);
182:
183: *originalPC = (void *)bluePCB->ss.srr0;
184: bluePCB->ss.srr0 = ppcInterruptHandler;
185: *originalR2 = (void *)bluePCB->ss.r2;
186: break;
187:
188: case kInExceptionHandler:
189: if (debugNotify > 2)
190: printf("NotifyInterrupt: kInExceptionHandler\n");
191: *interruptStatePtr = *interruptStatePtr
192: | ((emulatorDescriptor->postIntMask >> kCR2ToBackupShift)
193: & kBackupCR2Mask);
194: break;
195:
196: default:
197: if (debugNotify)
198: printf("NotifyInterrupt: default ");
199: printf("Interruption while running in unknown state\n");
200: printf("interruptState = 0x%X\n",interruptState);
201: break;
202: }
203: thread_unlock(thread);
204: (void) splx(s);
205: }
206:
207: #import <driverkit/return.h>
208:
209: #ifndef NULL
210: #define NULL ((void *)0)
211: #endif
212:
213: static void *Blueowner = NULL;
214: static vm_offset_t Blueowner_addr;
215: static port_t Blueowner_task = PORT_NULL;
216: static vm_size_t Blueshmem_size;
217: static vm_offset_t *Blueshmem_addr;
218:
219: /*
220: * Set up the shared memory area between the BlueBox and the kernel.
221: *
222: * Obtain page aligned wired kernel memory for 'size' bytes using
223: * kmem_alloc().
224: * Find a similar sized region in the BlueBox task VM map using
225: * vm_map_find(). This function will find an appropriately sized region,
226: * create a memory object, and insert it in the VM map.
227: * For each physical page in the kernel's wired memory we got from
228: * kmem_alloc(), enter that page at the appropriate location in the page
229: * map for the BlueBox, in the address range we allocated using
230: * vm_map_find().
231: */
232: int
233: mapBlueBoxShmem ( port_t task, // in
234: vm_size_t size, // in
235: vm_offset_t * addr) // out
236: {
237: vm_offset_t off;
238: vm_offset_t phys_addr;
239: IOReturn krtn;
240: void * task_map;
241: vm_offset_t task_addr;
242:
243: if ( task == PORT_NULL || size == 0 ) // malformed request
244: return IO_R_INVALID_ARG;
245: if ( Blueowner_task != PORT_NULL || Blueowner != NULL )
246: return IO_R_INVALID_ARG; // Mapping set up already
247:
248: krtn = createEventShmem(task,size,&task_map,&task_addr,&Blueshmem_addr);
249: if ( krtn != KERN_SUCCESS )
250: {
251: printf("mapEventShmem: createEventShmem fails (%d).\n",krtn);
252: return krtn;
253: }
254:
255: Blueshmem_size = size;
256: Blueowner_task = task;
257: Blueowner_addr = task_addr;
258: *addr = task_addr;
259: Blueowner = task_map;
260:
261: return IO_R_SUCCESS;
262: }
263:
264: /*
265: * Unmap the shared memory area and release the wired memory.
266: */
267: int
268: unmapBlueBoxShmem (void)
269: {
270: vm_offset_t off;
271: IOReturn r;
272:
273: r=destroyEventShmem(Blueowner_task,Blueowner,Blueshmem_size,Blueowner_addr,Blueshmem_addr);
274: if ( r != KERN_SUCCESS )
275: {
276: printf("unmapBlueBoxShmem: destroyEventShmem fails (%d).\n", r);
277: }
278: Blueshmem_addr = Blueowner_addr = (vm_offset_t)0;
279: Blueshmem_size = 0;
280: Blueowner = NULL;
281: Blueowner_task = PORT_NULL;
282: return r;
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.