Annotation of kernel/machdep/ppc/PseudoKernel.c, revision 1.1.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.