Annotation of kernel/machdep/ppc/PseudoKernel.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.