|
|
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: * Mach Operating System ! 27: * Copyright (c) 1987 Carnegie-Mellon University ! 28: * All rights reserved. The CMU software License Agreement specifies ! 29: * the terms and conditions for use and redistribution. ! 30: */ ! 31: /* ! 32: * File: vm/vm_user.c ! 33: * Author: Avadis Tevanian, Jr., Michael Wayne Young ! 34: * ! 35: * Copyright (C) 1985, Avadis Tevanian, Jr., Michael Wayne Young ! 36: * ! 37: * User-exported virtual memory functions. ! 38: */ ! 39: ! 40: #import <mach_xp.h> ! 41: ! 42: #import <sys/types.h> ! 43: ! 44: #import <mach/vm_param.h> ! 45: #import <vm/vm_object.h> ! 46: #import <vm/vm_map.h> ! 47: #import <vm/vm_page.h> ! 48: #import <mach/vm_statistics.h> ! 49: #import <mach/vm_attributes.h> ! 50: ! 51: #import <mach/boolean.h> ! 52: #import <mach/kern_return.h> ! 53: #import <kern/task.h> ! 54: ! 55: #import <mach/mach_types.h> /* to get vm_address_t */ ! 56: ! 57: #import <vm/vm_kern.h> ! 58: ! 59: vm_statistics_data_t vm_stat; ! 60: ! 61: #if MACH_XP ! 62: #else MACH_XP ! 63: #import <kern/lock.h> ! 64: lock_data_t vm_alloc_lock; ! 65: ! 66: /* ! 67: * vm_user_init initializes the vm_alloc lock. XXX ! 68: */ ! 69: void ! 70: vm_user_init() ! 71: { ! 72: lock_init(&vm_alloc_lock, TRUE); ! 73: } ! 74: #endif MACH_XP ! 75: ! 76: /* ! 77: * vm_allocate allocates virtual memory in the specified address ! 78: * map. Newly allocated memory is not yet validated, but will be ! 79: * when page faults occur. ! 80: */ ! 81: kern_return_t vm_allocate_with_pager(map, addr, size, find_space, pager, ! 82: pager_offset) ! 83: register vm_map_t map; ! 84: register vm_offset_t *addr; ! 85: register vm_size_t size; ! 86: boolean_t find_space; ! 87: vm_pager_t pager; ! 88: vm_offset_t pager_offset; ! 89: { ! 90: register vm_object_t object; ! 91: register kern_return_t result; ! 92: ! 93: if (map == VM_MAP_NULL) ! 94: return(KERN_INVALID_ARGUMENT); ! 95: ! 96: *addr = trunc_page(*addr); ! 97: size = round_page(size); ! 98: ! 99: #if MACH_XP ! 100: if ((object = (vm_object_t) vm_object_enter(pager, size, FALSE)) ! 101: == VM_OBJECT_NULL) ! 102: return(KERN_INVALID_ARGUMENT); ! 103: #else MACH_XP ! 104: /* ! 105: * Lookup the pager/paging-space in the object cache. ! 106: * If it's not there, then create a new object and cache ! 107: * it. ! 108: */ ! 109: lock_write(&vm_alloc_lock); ! 110: object = vm_object_lookup(pager); ! 111: vm_stat.lookups++; ! 112: if (object == VM_OBJECT_NULL) { ! 113: /* ! 114: * Need a new object. ! 115: */ ! 116: object = vm_object_allocate(size); ! 117: /* ! 118: * Associate the object with the pager and ! 119: * put it in the cache. ! 120: */ ! 121: if (pager != vm_pager_null) { ! 122: vm_object_setpager(object, pager, ! 123: (vm_offset_t) 0, TRUE); ! 124: vm_object_enter(object, pager); ! 125: } ! 126: } ! 127: else { ! 128: vm_stat.hits++; ! 129: } ! 130: lock_write_done(&vm_alloc_lock); ! 131: object->internal = FALSE; ! 132: #endif MACH_XP ! 133: ! 134: if ((result = vm_map_find(map, object, pager_offset, addr, size, ! 135: find_space)) != KERN_SUCCESS) ! 136: vm_object_deallocate(object); ! 137: return(result); ! 138: } ! 139: ! 140: /* ! 141: * vm_allocate allocates "zero fill" memory in the specfied ! 142: * map. ! 143: */ ! 144: kern_return_t vm_allocate(map, addr, size, anywhere) ! 145: register vm_map_t map; ! 146: register vm_offset_t *addr; ! 147: register vm_size_t size; ! 148: boolean_t anywhere; ! 149: { ! 150: kern_return_t result; ! 151: ! 152: if (map == VM_MAP_NULL) ! 153: return(KERN_INVALID_ARGUMENT); ! 154: if (size == 0) { ! 155: *addr = 0; ! 156: return(KERN_SUCCESS); ! 157: } ! 158: ! 159: if (anywhere) ! 160: *addr = vm_map_min(map); ! 161: else ! 162: *addr = trunc_page(*addr); ! 163: size = round_page(size); ! 164: ! 165: result = vm_map_find(map, VM_OBJECT_NULL, (vm_offset_t) 0, addr, ! 166: size, anywhere); ! 167: ! 168: return(result); ! 169: } ! 170: ! 171: /* ! 172: * vm_deallocate deallocates the specified range of addresses in the ! 173: * specified address map. ! 174: */ ! 175: kern_return_t vm_deallocate(map, start, size) ! 176: register vm_map_t map; ! 177: vm_offset_t start; ! 178: vm_size_t size; ! 179: { ! 180: if (map == VM_MAP_NULL) ! 181: return(KERN_INVALID_ARGUMENT); ! 182: ! 183: if (size == (vm_offset_t) 0) ! 184: return(KERN_SUCCESS); ! 185: ! 186: return(vm_map_remove(map, trunc_page(start), round_page(start+size))); ! 187: } ! 188: ! 189: kern_return_t vm_reallocate(map, start, size) ! 190: register vm_map_t map; ! 191: vm_offset_t start; ! 192: vm_size_t size; ! 193: { ! 194: if (map == VM_MAP_NULL) ! 195: return(KERN_INVALID_ARGUMENT); ! 196: ! 197: if (size == (vm_offset_t) 0) ! 198: return(KERN_SUCCESS); ! 199: ! 200: return(vm_map_reallocate( ! 201: map, trunc_page(start), round_page(start+size))); ! 202: } ! 203: ! 204: /* ! 205: * vm_inherit sets the inheritence of the specified range in the ! 206: * specified map. ! 207: */ ! 208: kern_return_t vm_inherit(map, start, size, new_inheritance) ! 209: register vm_map_t map; ! 210: vm_offset_t start; ! 211: vm_size_t size; ! 212: vm_inherit_t new_inheritance; ! 213: { ! 214: if (map == VM_MAP_NULL) ! 215: return(KERN_INVALID_ARGUMENT); ! 216: ! 217: return(vm_map_inherit(map, trunc_page(start), round_page(start+size), new_inheritance)); ! 218: } ! 219: ! 220: /* ! 221: * vm_protect sets the protection of the specified range in the ! 222: * specified map. ! 223: */ ! 224: ! 225: kern_return_t vm_protect(map, start, size, set_maximum, new_protection) ! 226: register vm_map_t map; ! 227: vm_offset_t start; ! 228: vm_size_t size; ! 229: boolean_t set_maximum; ! 230: vm_prot_t new_protection; ! 231: { ! 232: if (map == VM_MAP_NULL) ! 233: return(KERN_INVALID_ARGUMENT); ! 234: ! 235: return(vm_map_protect(map, trunc_page(start), round_page(start+size), new_protection, set_maximum)); ! 236: } ! 237: ! 238: kern_return_t vm_statistics(map, stat) ! 239: vm_map_t map; ! 240: vm_statistics_data_t *stat; ! 241: { ! 242: if (map == VM_MAP_NULL) ! 243: return(KERN_INVALID_ARGUMENT); ! 244: ! 245: vm_stat.pagesize = PAGE_SIZE; ! 246: vm_stat.free_count = vm_page_free_count; ! 247: vm_stat.active_count = vm_page_active_count; ! 248: vm_stat.inactive_count = vm_page_inactive_count; ! 249: vm_stat.wire_count = vm_page_wire_count; ! 250: ! 251: *stat = vm_stat; ! 252: ! 253: return(KERN_SUCCESS); ! 254: } ! 255: ! 256: /* ! 257: * Handle machine-specific attributes for a mapping, such ! 258: * as cachability, migrability, etc. ! 259: */ ! 260: kern_return_t vm_machine_attribute(map, address, size, attribute, value) ! 261: vm_map_t map; ! 262: vm_address_t address; ! 263: vm_size_t size; ! 264: vm_machine_attribute_t attribute; ! 265: vm_machine_attribute_val_t* value; /* IN/OUT */ ! 266: { ! 267: extern kern_return_t vm_map_machine_attribute(); ! 268: ! 269: if (map == VM_MAP_NULL) ! 270: return(KERN_INVALID_ARGUMENT); ! 271: ! 272: return vm_map_machine_attribute(map, address, size, attribute, value); ! 273: } ! 274: ! 275: kern_return_t vm_read(map, address, size, data, data_size) ! 276: vm_map_t map; ! 277: vm_address_t address; ! 278: vm_size_t size; ! 279: pointer_t *data; ! 280: vm_size_t *data_size; ! 281: { ! 282: kern_return_t error; ! 283: vm_offset_t ipc_address; ! 284: ! 285: if ((round_page(address) != address) || (round_page(size) != size)) ! 286: return(KERN_INVALID_ARGUMENT); ! 287: ! 288: if ((error = vm_allocate(ipc_soft_map, &ipc_address, size, TRUE)) != KERN_SUCCESS) { ! 289: printf("vm_read: kernel error %d\n", error); ! 290: return(KERN_RESOURCE_SHORTAGE); ! 291: } ! 292: ! 293: if ((error = vm_map_copy(ipc_soft_map, map, ipc_address, size, address, FALSE, FALSE)) == KERN_SUCCESS) { ! 294: *data = ipc_address; ! 295: *data_size = size; ! 296: } ! 297: else ! 298: (void) vm_deallocate(ipc_soft_map, ipc_address, size); ! 299: return(error); ! 300: } ! 301: ! 302: kern_return_t vm_write(map, address, data, size) ! 303: vm_map_t map; ! 304: vm_address_t address; ! 305: pointer_t data; ! 306: vm_size_t size; ! 307: { ! 308: if ((round_page(address) != address) || (round_page(size) != size)) ! 309: return(KERN_INVALID_ARGUMENT); ! 310: ! 311: return(vm_map_copy(map, ipc_soft_map, address, size, data, FALSE, TRUE)); ! 312: } ! 313: ! 314: kern_return_t vm_copy(map, source_address, size, dest_address) ! 315: vm_map_t map; ! 316: vm_address_t source_address; ! 317: vm_size_t size; ! 318: vm_address_t dest_address; ! 319: { ! 320: if ( (round_page(source_address) != source_address) || (round_page(dest_address) != dest_address) ! 321: || (round_page(size) != size) ) ! 322: return(KERN_INVALID_ARGUMENT); ! 323: ! 324: return(vm_map_copy(map, map, dest_address, size, source_address, FALSE, FALSE)); ! 325: } ! 326: ! 327: ! 328: ! 329: /* ! 330: * Specify that the range of the virtual address space ! 331: * of the target task must not cause page faults for ! 332: * the indicated accesses. ! 333: * ! 334: * [ To unwire the pages, specify VM_PROT_NONE. ] ! 335: */ ! 336: kern_return_t ! 337: vm_wire( ! 338: host_t host, ! 339: register vm_map_t map, ! 340: vm_offset_t start, ! 341: vm_size_t size, ! 342: vm_prot_t access) ! 343: { ! 344: kern_return_t rc; ! 345: ! 346: if (host == HOST_NULL) ! 347: return KERN_INVALID_HOST; ! 348: ! 349: if (map == VM_MAP_NULL) ! 350: return KERN_INVALID_TASK; ! 351: ! 352: if (access & ~VM_PROT_ALL) ! 353: return KERN_INVALID_ARGUMENT; ! 354: ! 355: if (access != VM_PROT_NONE) { ! 356: rc = vm_map_pageable(map, trunc_page(start), ! 357: round_page(start+size), FALSE); ! 358: } else { ! 359: rc = vm_map_pageable(map, trunc_page(start), ! 360: round_page(start+size), TRUE); ! 361: } ! 362: return rc; ! 363: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.