|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.