|
|
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.