Annotation of kernel/bsd/dev/ev.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: /*     Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved. 
                     26:  *
                     27:  * ev.c - Machine dependent code needed to support the Event Driver.
                     28:  *
                     29:  * HISTORY
                     30:  * 22 Sep 92   Joe Pasqua 
                     31:  *      Created. 
                     32:  */
                     33:  
                     34: #import <mach/mach_types.h>
                     35:  
                     36: #import <mach/kern_return.h>
                     37: #import <kern/kern_port.h>
                     38: #import <vm/vm_kern.h>
                     39: #import <driverkit/return.h>
                     40: 
                     41: #ifndef        NULL
                     42: #define NULL ((void *)0)
                     43: #endif
                     44: 
                     45: /*
                     46:  * NULL terminated list of event source classes that should be attached
                     47:  * to the Event Driver when the Window Server starts up.
                     48:  * The list is machine dependent.
                     49:  */
                     50: static const char *defaultEventSrc[] = 
                     51: {
                     52:        "EventSrcPCPointer",
                     53:        "EventSrcPCKeyboard",
                     54:        NULL
                     55: };
                     56: 
                     57: /*
                     58:  * Return a NULL terminated list of event sources that should be attached
                     59:  * to the Event Driver when the Window Server starts up.
                     60:  */
                     61: const char **
                     62: defaultEventSources()
                     63: {
                     64:        return defaultEventSrc;
                     65: }
                     66: 
                     67: /*
                     68:  * Set up the shared memory area between the Window Server and the kernel.
                     69:  *
                     70:  *     Obtain page aligned wired kernel memory for 'size' bytes using
                     71:  *     kmem_alloc().
                     72:  *     Find a similar sized region in the Window Server task VM map using
                     73:  *     vm_map_find().  This function will find an appropriately sized region,
                     74:  *     create a memory object, and insert it in the VM map.
                     75:  *     For each physical page in the kernel's wired memory we got from
                     76:  *     kmem_alloc(), enter that page at the appropriate location in the page
                     77:  *     map for the Window Server, in the address range we allocated using
                     78:  *     vm_map_find().  
                     79:  */
                     80:  kern_return_t
                     81: createEventShmem(      port_t task,                    // in
                     82:                        vm_size_t size,                 // in
                     83:                        struct vm_map **owner,          // out
                     84:                        vm_offset_t *owner_addr,        // out
                     85:                        vm_offset_t *shmem_addr )       // out
                     86: {
                     87:        vm_offset_t     off;
                     88:        vm_offset_t     phys_addr;
                     89:        kern_return_t   krtn;
                     90:        vm_map_t        task_map;
                     91:        kern_port_t     task_port;
                     92:        vm_size_t       shmem_size;
                     93:        extern vm_map_t convert_port_to_map(kern_port_t);
                     94: 
                     95:        *owner = VM_MAP_NULL;
                     96:        // Get the task map
                     97:        if ( (task_port = (kern_port_t)IOGetKernPort(task)) == KERN_PORT_NULL )
                     98:            return KERN_INVALID_ARGUMENT;
                     99:        if ( (task_map = convert_port_to_map(task_port)) == VM_MAP_NULL )
                    100:        {
                    101:            port_release(task_port);    // Decrement ref cnt
                    102:            return KERN_INVALID_ARGUMENT;
                    103:        }
                    104:        port_release(task_port);        // Decrement ref cnt
                    105: 
                    106:        shmem_size = round_page(size);  // Round up to page boundry.
                    107: 
                    108:        /* Find some memory of a suitable size in the kernel VM map. */
                    109:        if ( kmem_alloc_wired( kernel_map, shmem_addr, shmem_size ) )
                    110:        {
                    111:            vm_map_deallocate(task_map);        // discard our reference
                    112:            return KERN_NO_SPACE;
                    113:        }
                    114:        /* Find some memory of the same size in 'task'.  We use vm_map_find()
                    115:           to do this. vm_map_find inserts the found memory object in the
                    116:           target task's map as a side effect. */
                    117:        *owner_addr = vm_map_min(task_map);
                    118:        krtn = vm_map_find( task_map,
                    119:                VM_OBJECT_NULL,
                    120:                0,                              // offset
                    121:                owner_addr,
                    122:                shmem_size,
                    123:                TRUE );                         // Find first fit
                    124:        if(krtn)
                    125:        {
                    126:            IOLog("createEventShmem: vm_map_find() returned %d\n", krtn);
                    127:            vm_map_deallocate(task_map);        // discard our reference
                    128:            return KERN_NO_SPACE;
                    129:        }
                    130:        /* For each page in the area allocated from the kernel map,
                    131:                find the physical address of the page.
                    132:                Enter the page in the target task's pmap, at the
                    133:                appropriate target task virtual address. */
                    134:        for ( off = 0; off < shmem_size; off += PAGE_SIZE )
                    135:        {
                    136:            phys_addr = pmap_extract( kernel_pmap, (*shmem_addr) + off );
                    137:            if ( phys_addr == 0 )
                    138:            {
                    139:                IOLog("createEventShmem: no paddr for vaddr 0x%x\n",
                    140:                        (*shmem_addr) + off );
                    141:                kmem_free( kernel_map, *shmem_addr, size );
                    142:                vm_map_deallocate(task_map);    // discard our reference
                    143:                return KERN_NO_SPACE;
                    144:            }
                    145:            pmap_enter(
                    146:                task_map->pmap,
                    147:                *owner_addr + off,
                    148:                phys_addr,
                    149:                VM_PROT_READ|VM_PROT_WRITE,
                    150:                TRUE);
                    151:        }
                    152:        *owner = task_map;
                    153: 
                    154:        return KERN_SUCCESS;
                    155: }
                    156: 
                    157: 
                    158: // 
                    159: // Unmap the shared memory area and release the wired memory.
                    160: //
                    161: kern_return_t
                    162: destroyEventShmem(     port_t task,
                    163:                        struct vm_map *owner,
                    164:                        vm_size_t size,
                    165:                        vm_offset_t owner_addr,
                    166:                        vm_offset_t shmem_addr )
                    167: {
                    168:        vm_offset_t off;
                    169:        kern_return_t krtn;
                    170:        vm_size_t shmem_size;
                    171: 
                    172:        if ( owner == VM_MAP_NULL )
                    173:                return KERN_INVALID_ARGUMENT;
                    174:        shmem_size = round_page(size);
                    175: 
                    176:        // Pull the shared pages out of the task map
                    177:        for ( off = 0; off < shmem_size; off += PAGE_SIZE )
                    178:        {
                    179:                pmap_remove(
                    180:                    owner->pmap,
                    181:                    owner_addr + off,
                    182:                    owner_addr + off + PAGE_SIZE);
                    183:        }
                    184:        // Free the former shmem area in the task
                    185:        krtn = vm_map_remove(owner,
                    186:                owner_addr,
                    187:                owner_addr + shmem_size );
                    188:        if(krtn) {
                    189:                IOLog("destroyEventShmem: vm_map_remove() returned %d\n",
                    190:                        krtn);
                    191:        }
                    192:        // finally, free the memory back to the kernel map.
                    193:        kmem_free( kernel_map, shmem_addr, shmem_size );
                    194:        
                    195:        vm_map_deallocate(owner);       // discard our reference
                    196:        return krtn;
                    197: }

unix.superglobalmegacorp.com

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