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