Annotation of kernel/bsd/dev/ev.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: /*     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.