Annotation of XNU/osfmk/device/iokit_rpc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: #include <mach_kdb.h>
                     23: #include <zone_debug.h>
                     24: #include <mach_kdb.h>
                     25: 
                     26: #include <mach/boolean.h>
                     27: #include <mach/kern_return.h>
                     28: #include <mach/mig_errors.h>
                     29: #include <mach/port.h>
                     30: #include <mach/vm_param.h>
                     31: #include <mach/notify.h>
                     32: #include <mach/mach_host_server.h>
                     33: #include <mach/mach_types.h>
                     34: 
                     35: #include <machine/machparam.h>         /* spl definitions */
                     36: 
                     37: #include <ipc/ipc_port.h>
                     38: #include <ipc/ipc_space.h>
                     39: 
                     40: #include <kern/clock.h>
                     41: #include <kern/spl.h>
                     42: #include <kern/ast.h>
                     43: #include <kern/counters.h>
                     44: #include <kern/queue.h>
                     45: #include <kern/zalloc.h>
                     46: #include <kern/thread.h>
                     47: #include <kern/thread_swap.h>
                     48: #include <kern/task.h>
                     49: #include <kern/sched_prim.h>
                     50: #include <kern/misc_protos.h>
                     51: 
                     52: #include <vm/pmap.h>
                     53: #include <vm/vm_map.h>
                     54: #include <vm/vm_kern.h>
                     55: 
                     56: #include <device/device_types.h>
                     57: #include <device/device_port.h>
                     58: #include <device/device_server.h>
                     59: 
                     60: #include <sys/ioctl.h>
                     61: 
                     62: #include <machine/machparam.h>
                     63: 
                     64: #ifdef __ppc__
                     65: #include <ppc/mappings.h>
                     66: #include <ppc/pmap_internals.h>
                     67: #endif
                     68: #include <IOKit/IOTypes.h>
                     69: 
                     70: #undef DEBUG
                     71: #define DEBUG
                     72: #define EXTERN
                     73: #define MIGEXTERN
                     74: 
                     75: /*
                     76:  * Functions in iokit:IOUserClient.cpp
                     77:  */
                     78: 
                     79: extern void iokit_add_reference( io_object_t obj );
                     80: 
                     81: extern void iokit_remove_reference( io_object_t obj );
                     82: 
                     83: extern ipc_port_t iokit_port_for_object( io_object_t obj,
                     84:                        ipc_kobject_type_t type );
                     85: 
                     86: extern kern_return_t iokit_client_died( io_object_t obj,
                     87:                         ipc_port_t port, ipc_kobject_type_t type );
                     88: 
                     89: extern kern_return_t
                     90: iokit_client_memory_for_type(
                     91:        io_object_t     connect,
                     92:        unsigned int    type,
                     93:        unsigned int *  flags,
                     94:        vm_address_t *  address,
                     95:        vm_size_t    *  size );
                     96: 
                     97: /*
                     98:  * Lookup a device by its port.
                     99:  * Doesn't consume the naked send right; produces a device reference.
                    100:  */
                    101: MIGEXTERN io_object_t
                    102: iokit_lookup_object_port(
                    103:        ipc_port_t      port)
                    104: {
                    105:        register io_object_t    obj;
                    106: 
                    107:        if (!IP_VALID(port))
                    108:            return (NULL);
                    109: 
                    110:        ip_lock(port);
                    111:        if (ip_active(port) && (ip_kotype(port) == IKOT_IOKIT_OBJECT)) {
                    112:            obj = (io_object_t) port->ip_kobject;
                    113:            iokit_add_reference( obj );
                    114:        }
                    115:        else
                    116:            obj = NULL;
                    117: 
                    118:        ip_unlock(port);
                    119: 
                    120:        return( obj );
                    121: }
                    122: 
                    123: MIGEXTERN io_object_t
                    124: iokit_lookup_connect_port(
                    125:        ipc_port_t      port)
                    126: {
                    127:        register io_object_t    obj;
                    128: 
                    129:        if (!IP_VALID(port))
                    130:            return (NULL);
                    131: 
                    132:        ip_lock(port);
                    133:        if (ip_active(port) && (ip_kotype(port) == IKOT_IOKIT_CONNECT)) {
                    134:            obj = (io_object_t) port->ip_kobject;
                    135:            iokit_add_reference( obj );
                    136:        }
                    137:        else
                    138:            obj = NULL;
                    139: 
                    140:        ip_unlock(port);
                    141: 
                    142:        return( obj );
                    143: }
                    144: 
                    145: /*
                    146:  * Get the port for a device.
                    147:  * Consumes a device reference; produces a naked send right.
                    148:  */
                    149: MIGEXTERN ipc_port_t
                    150: iokit_make_object_port(
                    151:        io_object_t     obj )
                    152: {
                    153:     register ipc_port_t        port;
                    154: 
                    155:     if( obj == NULL)
                    156:         return IP_NULL;
                    157: 
                    158:     port = iokit_port_for_object( obj, IKOT_IOKIT_OBJECT );
                    159:     if( port)
                    160:        port = ipc_port_make_send( port);
                    161: 
                    162:     iokit_remove_reference( obj );
                    163: 
                    164:     return( port);
                    165: }
                    166: 
                    167: MIGEXTERN ipc_port_t
                    168: iokit_make_connect_port(
                    169:        io_object_t     obj )
                    170: {
                    171:     register ipc_port_t        port;
                    172: 
                    173:     if( obj == NULL)
                    174:         return IP_NULL;
                    175: 
                    176:     port = iokit_port_for_object( obj, IKOT_IOKIT_CONNECT );
                    177:     if( port)
                    178:         port = ipc_port_make_send( port);
                    179: 
                    180:     iokit_remove_reference( obj );
                    181: 
                    182:     return( port);
                    183: }
                    184: 
                    185: 
                    186: EXTERN ipc_port_t
                    187: iokit_alloc_object_port( io_object_t obj, ipc_kobject_type_t type );
                    188: 
                    189: int gIOKitPortCount;
                    190: 
                    191: EXTERN ipc_port_t
                    192: iokit_alloc_object_port( io_object_t obj, ipc_kobject_type_t type )
                    193: {
                    194:     ipc_port_t         notify;
                    195:     ipc_port_t         port;
                    196: 
                    197:     do {
                    198: 
                    199:        /* Allocate port, keeping a reference for it. */
                    200:         port = ipc_port_alloc_kernel();
                    201:         if( port == IP_NULL)
                    202:             continue;
                    203: 
                    204:         /* set kobject & type */
                    205: //     iokit_add_reference( obj );
                    206:        ipc_kobject_set( port, (ipc_kobject_t) obj, type);
                    207: 
                    208:         /* Request no-senders notifications on the port. */
                    209:         notify = ipc_port_make_sonce( port);
                    210:         ip_lock( port);
                    211:         ipc_port_nsrequest( port, 1, notify, &notify);
                    212:         assert( notify == IP_NULL);
                    213:        gIOKitPortCount++;
                    214: 
                    215:     } while( FALSE);
                    216: 
                    217:     return( port );
                    218: }
                    219: 
                    220: 
                    221: EXTERN kern_return_t
                    222: iokit_destroy_object_port( ipc_port_t port )
                    223: {
                    224:     ipc_kobject_set( port, IKO_NULL, IKOT_NONE);
                    225: 
                    226: //    iokit_remove_reference( obj );
                    227: 
                    228:     ipc_port_dealloc_kernel( port);
                    229:     gIOKitPortCount--;
                    230: 
                    231:     return( KERN_SUCCESS);
                    232: }
                    233: 
                    234: EXTERN mach_port_name_t
                    235: iokit_make_send_right( task_t task, io_object_t obj, ipc_kobject_type_t type )
                    236: {
                    237:     kern_return_t      kr;
                    238:     ipc_port_t         port;
                    239:     mach_port_name_t   name;
                    240: 
                    241:     if( obj == NULL)
                    242:         return MACH_PORT_NULL;
                    243: 
                    244:     port = iokit_port_for_object( obj, type );
                    245:     if( port)
                    246:         port = ipc_port_make_send( port);
                    247:     if( port == IP_NULL)
                    248:         return MACH_PORT_NULL;
                    249: 
                    250:     kr = ipc_object_copyout( task->itk_space, (ipc_object_t) port,
                    251:                                MACH_MSG_TYPE_PORT_SEND, TRUE, &name);
                    252: 
                    253:     if( kr != KERN_SUCCESS)
                    254:        name = MACH_PORT_NULL;
                    255: 
                    256:     iokit_remove_reference( obj );
                    257: 
                    258:     return( name );
                    259: }
                    260: 
                    261: EXTERN vm_map_t
                    262: iokit_task_map( task_t task )
                    263: {
                    264:     return( task->map );
                    265: }
                    266: 
                    267: EXTERN pmap_t
                    268: iokit_map_pmap( vm_map_t map )
                    269: {
                    270:     return( map->pmap );
                    271: }
                    272: 
                    273: /*
                    274:  * Handle the No-More_Senders notification generated from a device port destroy.
                    275:  * Since there are no longer any tasks which hold a send right to this device
                    276:  * port a NMS notification has been generated. 
                    277:  */
                    278: 
                    279: static void
                    280: iokit_no_senders( mach_no_senders_notification_t * notification )
                    281: {
                    282:     ipc_port_t         port;
                    283:     io_object_t                obj;
                    284:     ipc_kobject_type_t type;
                    285: 
                    286:     port = (ipc_port_t) notification->not_header.msgh_remote_port;
                    287: 
                    288:     // convert a port to io_object_t.
                    289:     if( IP_VALID(port)) {
                    290:         ip_lock(port);
                    291:         if( ip_active(port)) {
                    292:             obj = (io_object_t) port->ip_kobject;
                    293:            type = ip_kotype( port );
                    294:             if( (IKOT_IOKIT_OBJECT  == type)
                    295:             || (IKOT_IOKIT_CONNECT == type))
                    296:                 iokit_add_reference( obj );
                    297:            else
                    298:                 obj = NULL;
                    299:        }
                    300:         ip_unlock(port);
                    301: 
                    302:         if( obj ) {
                    303:             (void) iokit_client_died( obj, port, type );
                    304:             iokit_remove_reference( obj );
                    305:         }
                    306:     }
                    307: }
                    308: 
                    309: 
                    310: EXTERN
                    311: boolean_t
                    312: iokit_notify( mach_msg_header_t * msg )
                    313: {
                    314:     switch (msg->msgh_id) {
                    315:         case MACH_NOTIFY_NO_SENDERS:
                    316:             iokit_no_senders((mach_no_senders_notification_t *) msg);
                    317:             return TRUE;
                    318: 
                    319:         case MACH_NOTIFY_PORT_DELETED:
                    320:         case MACH_NOTIFY_PORT_DESTROYED:
                    321:         case MACH_NOTIFY_SEND_ONCE:
                    322:         case MACH_NOTIFY_DEAD_NAME:
                    323:         default:
                    324:             printf("iokit_notify: strange notification %ld\n", msg->msgh_id);
                    325:             return FALSE;
                    326:     }
                    327: }
                    328: 
                    329: static void IOMapPage(vm_map_t map, vm_offset_t va, vm_offset_t pa,
                    330:                        int mapFlags)
                    331: 
                    332: {
                    333: #ifdef __ppc__
                    334:     struct phys_entry * pp;
                    335:     spl_t              spl;
                    336:     int                        memattr;
                    337: #endif
                    338:     vm_prot_t          prot;
                    339:     pmap_t             pmap = map->pmap;
                    340: 
                    341:     prot = (mapFlags & kIOMapReadOnly)
                    342:                ? VM_PROT_READ : (VM_PROT_READ|VM_PROT_WRITE);
                    343: 
                    344: #if __ppc__
                    345: 
                    346:     /* Get the physent for this physical page */
                    347:     pp = pmap_find_physentry(pa);
                    348:     spl = splhigh();
                    349: 
                    350:     /* Remove any other mapping at this address */
                    351:     mapping_remove(pmap->space, va);
                    352: 
                    353:     switch( mapFlags & kIOMapCacheMask ) {
                    354: 
                    355:        case kIOMapDefaultCache:
                    356:        default:
                    357:            if( pp )
                    358:                memattr = ((pp->pte1 & 0x00000078) >> 3);
                    359:            else
                    360:                 memattr = PTE_WIMG_UNCACHED_COHERENT_GUARDED;
                    361:            break;
                    362: 
                    363:        case kIOMapInhibitCache:
                    364:             memattr = PTE_WIMG_UNCACHED_COHERENT_GUARDED;
                    365:            break;
                    366: 
                    367:        case kIOMapWriteThruCache:
                    368:             memattr = PTE_WIMG_WT_CACHED_COHERENT_GUARDED;
                    369:            break;
                    370:        case kIOMapCopybackCache:
                    371: //            memattr = PTE_WIMG_CB_CACHED_COHERENT;
                    372:             memattr = PTE_WIMG_CB_CACHED;
                    373:            break;
                    374:     }
                    375: 
                    376:     /* Make the address mapping */
                    377:     mapping_make(pmap, pmap->space, 0, va, pa, prot, memattr);
                    378: 
                    379:     splx(spl);
                    380: #else
                    381:     pmap_enter( pmap, va, pa, prot, TRUE);
                    382: #endif
                    383: }
                    384: 
                    385: kern_return_t IOMapPages(vm_map_t map, vm_offset_t va, vm_offset_t pa,
                    386:                        vm_size_t length, unsigned int options)
                    387: {
                    388:     vm_size_t  off;
                    389: 
                    390: #if __ppc__
                    391:     /* TEMPORARY - make sure there are enough free mappings */
                    392:     mapping_prealloc( length );
                    393: #endif
                    394: 
                    395:     // enter each page's physical address in the target map
                    396:     for ( off = 0; off < length; off += page_size ) {
                    397:         IOMapPage( map, va + off, pa + off, options );
                    398:     }
                    399: 
                    400: #ifdef __ppc__
                    401:     /* TEMPORARY - make sure there are enough free mappings */
                    402:     mapping_relpre();
                    403: #endif
                    404: 
                    405:     return( KERN_SUCCESS );
                    406: }
                    407: 
                    408: void IOGetTime( mach_timespec_t * clock_time);
                    409: void IOGetTime( mach_timespec_t * clock_time)
                    410: {
                    411:        *clock_time = clock_get_system_value();
                    412: }

unix.superglobalmegacorp.com

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