|
|
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) 1993-1987 Carnegie Mellon University
28: * All Rights Reserved.
29: *
30: * Permission to use, copy, modify and distribute this software and its
31: * documentation is hereby granted, provided that both the copyright
32: * notice and this permission notice appear in all copies of the
33: * software, derivative works or modified versions, and any portions
34: * thereof, and that both notices appear in supporting documentation.
35: *
36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39: *
40: * Carnegie Mellon requests users of this software to return to
41: *
42: * Software Distribution Coordinator or [email protected]
43: * School of Computer Science
44: * Carnegie Mellon University
45: * Pittsburgh PA 15213-3890
46: *
47: * any improvements or extensions that they make and grant Carnegie Mellon
48: * the rights to redistribute these changes.
49: */
50: /*
51: * File: vm/vm_map.h
52: * Author: Avadis Tevanian, Jr., Michael Wayne Young
53: * Date: 1985
54: *
55: * Virtual memory map module definitions.
56: *
57: * Contributors:
58: * avie, dlb, mwyoung
59: */
60:
61: #ifndef _VM_VM_MAP_H_
62: #define _VM_VM_MAP_H_
63:
64: #import <mach/features.h>
65:
66: #include <mach/kern_return.h>
67: #include <mach/boolean.h>
68: #include <mach/machine/vm_types.h>
69: #include <mach/vm_prot.h>
70: #include <mach/vm_inherit.h>
71: #include <vm/pmap.h>
72: #include <vm/vm_object.h>
73: #include <vm/vm_page.h>
74: #include <kern/lock.h>
75: #include <kern/macro_help.h>
76:
77: /*
78: * Types defined:
79: *
80: * vm_map_t the high-level address map data structure.
81: * vm_map_entry_t an entry in an address map.
82: * vm_map_version_t a timestamp of a map, for use with vm_map_lookup
83: * vm_map_copy_t represents memory copied from an address map,
84: * used for inter-map copy operations
85: */
86:
87: /*
88: * Type: vm_map_object_t [internal use only]
89: *
90: * Description:
91: * The target of an address mapping, either a virtual
92: * memory object or a sub map (of the kernel map).
93: */
94: typedef union vm_map_object {
95: struct vm_object *vm_object; /* object object */
96: #if OLD_VM_CODE
97: struct vm_map *share_map; /* share map */
98: #endif
99: struct vm_map *sub_map; /* belongs to another map */
100: } vm_map_object_t;
101:
102: /*
103: * Type: vm_map_entry_t [internal use only]
104: *
105: * Description:
106: * A single mapping within an address map.
107: *
108: * Implementation:
109: * Address map entries consist of start and end addresses,
110: * a VM object (or sub map) and offset into that object,
111: * and user-exported inheritance and protection information.
112: * Control information for virtual copy operations is also
113: * stored in the address map entry.
114: */
115: struct vm_map_links {
116: struct vm_map_entry *prev; /* previous entry */
117: struct vm_map_entry *next; /* next entry */
118: vm_offset_t start; /* start address */
119: vm_offset_t end; /* end address */
120: };
121:
122: struct vm_map_entry {
123: struct vm_map_links links; /* links to other entries */
124: #define vme_prev links.prev
125: #define vme_next links.next
126: #define vme_start links.start
127: #define vme_end links.end
128: union vm_map_object object; /* object I point to */
129: vm_offset_t offset; /* offset into object */
130: unsigned int
131: #if OLD_VM_CODE
132: /* boolean_t */ is_a_map:1, /* Is "object" a map? */
133: #endif
134: /* boolean_t */ is_shared:1, /* region is shared */
135: /* boolean_t */ is_sub_map:1, /* Is "object" a submap? */
136: #if OLD_VM_CODE
137: /* Only in sharing maps: */
138: /* boolean_t */ copy_on_write:1,/* is data copy-on-write */
139: #endif
140: /* boolean_t */ in_transition:1, /* Entry being changed */
141: /* boolean_t */ needs_wakeup:1, /* Waiters on in_transition */
142: /* Only used when object is a vm_object: */
143: /* boolean_t */ needs_copy:1; /* does object need to be copied */
144:
145: /* Only in task maps: */
146: vm_prot_t protection; /* protection code */
147: vm_prot_t max_protection; /* maximum protection */
148: vm_inherit_t inheritance; /* inheritance */
149: unsigned short wired_count; /* can be paged if = 0 */
150: unsigned short user_wired_count; /* for vm_wire */
151: };
152:
153: typedef struct vm_map_entry *vm_map_entry_t;
154:
155: #define VM_MAP_ENTRY_NULL ((vm_map_entry_t) 0)
156:
157: /*
158: * Type: struct vm_map_header
159: *
160: * Description:
161: * Header for a vm_map and a vm_map_copy.
162: */
163: struct vm_map_header {
164: struct vm_map_links links; /* first, last, min, max */
165: int nentries; /* Number of entries */
166: boolean_t entries_pageable;
167: /* are map entries pageable? */
168: };
169:
170: /*
171: * Type: vm_map_t [exported; contents invisible]
172: *
173: * Description:
174: * An address map -- a directory relating valid
175: * regions of a task's address space to the corresponding
176: * virtual memory objects.
177: *
178: * Implementation:
179: * Maps are doubly-linked lists of map entries, sorted
180: * by address. One hint is used to start
181: * searches again from the last successful search,
182: * insertion, or removal. Another hint is used to
183: * quickly find free space.
184: */
185: typedef struct vm_map {
186: lock_data_t lock; /* Lock for map data */
187: struct vm_map_header hdr; /* Map entry header */
188: #define min_offset hdr.links.start /* start of range */
189: #define max_offset hdr.links.end /* end of range */
190: pmap_t pmap; /* Physical map */
191: vm_size_t size; /* virtual size */
192: #if OLD_VM_CODE
193: boolean_t is_main_map; /* Am I a main map? */
194: #endif
195: int ref_count; /* Reference count */
196: decl_simple_lock_data(, ref_lock) /* Lock for ref_count field */
197: vm_map_entry_t hint; /* hint for quick lookups */
198: decl_simple_lock_data(, hint_lock) /* lock for hint storage */
199: vm_map_entry_t first_free; /* First free space hint */
200: boolean_t wait_for_space; /* Should callers wait
201: for space? */
202: boolean_t wiring_required;/* All memory wired? */
203: unsigned int timestamp; /* Version number */
204: } *vm_map_t;
205:
206: #define VM_MAP_NULL ((vm_map_t) 0)
207:
208: #define vm_map_to_entry(map) ((struct vm_map_entry *) &(map)->hdr.links)
209: #define vm_map_first_entry(map) ((map)->hdr.links.next)
210: #define vm_map_last_entry(map) ((map)->hdr.links.prev)
211:
212: /*
213: * Type: vm_map_version_t [exported; contents invisible]
214: *
215: * Description:
216: * Map versions may be used to quickly validate a previous
217: * lookup operation.
218: *
219: * Usage note:
220: * Because they are bulky objects, map versions are usually
221: * passed by reference.
222: *
223: * Implementation:
224: * Just a timestamp for the main map.
225: */
226: typedef struct vm_map_version {
227: unsigned int main_timestamp;
228: #if OLD_VM_CODE
229: vm_map_t share_map;
230: int share_timestamp;
231: #endif
232: } vm_map_version_t;
233:
234: /*
235: * Type: vm_map_copy_t [exported; contents invisible]
236: *
237: * Description:
238: * A map copy object represents a region of virtual memory
239: * that has been copied from an address map but is still
240: * in transit.
241: *
242: * A map copy object may only be used by a single thread
243: * at a time.
244: *
245: * Implementation:
246: * There are three formats for map copy objects.
247: * The first is very similar to the main
248: * address map in structure, and as a result, some
249: * of the internal maintenance functions/macros can
250: * be used with either address maps or map copy objects.
251: *
252: * The map copy object contains a header links
253: * entry onto which the other entries that represent
254: * the region are chained.
255: *
256: * The second format is a single vm object. This is used
257: * primarily in the pageout path. The third format is a
258: * list of vm pages. An optional continuation provides
259: * a hook to be called to obtain more of the memory,
260: * or perform other operations. The continuation takes 3
261: * arguments, a saved arg buffer, a pointer to a new vm_map_copy
262: * (returned) and an abort flag (abort if TRUE).
263: */
264:
265: #define VM_MAP_COPY_PAGE_LIST_MAX 8
266:
267: typedef struct vm_map_copy {
268: int type;
269: #define VM_MAP_COPY_ENTRY_LIST 1
270: #define VM_MAP_COPY_OBJECT 2
271: #define VM_MAP_COPY_PAGE_LIST 3
272: vm_offset_t offset;
273: vm_size_t size;
274: union {
275: struct vm_map_header hdr; /* ENTRY_LIST */
276: struct { /* OBJECT */
277: vm_object_t object;
278: } c_o;
279: struct { /* PAGE_LIST */
280: vm_page_t page_list[VM_MAP_COPY_PAGE_LIST_MAX];
281: int npages;
282: kern_return_t (*cont)();
283: char *cont_args;
284: } c_p;
285: } c_u;
286: } *vm_map_copy_t;
287:
288: #define cpy_hdr c_u.hdr
289:
290: #define cpy_object c_u.c_o.object
291:
292: #define cpy_page_list c_u.c_p.page_list
293: #define cpy_npages c_u.c_p.npages
294: #define cpy_cont c_u.c_p.cont
295: #define cpy_cont_args c_u.c_p.cont_args
296:
297: #define VM_MAP_COPY_NULL ((vm_map_copy_t) 0)
298:
299: /*
300: * Useful macros for entry list copy objects
301: */
302:
303: #define vm_map_copy_to_entry(copy) \
304: ((struct vm_map_entry *) &(copy)->cpy_hdr.links)
305: #define vm_map_copy_first_entry(copy) \
306: ((copy)->cpy_hdr.links.next)
307: #define vm_map_copy_last_entry(copy) \
308: ((copy)->cpy_hdr.links.prev)
309:
310: /*
311: * Continuation macros for page list copy objects
312: */
313:
314: #define vm_map_copy_invoke_cont(old_copy, new_copy, result) \
315: MACRO_BEGIN \
316: vm_map_copy_page_discard(old_copy); \
317: *result = (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \
318: new_copy); \
319: (old_copy)->cpy_cont = (kern_return_t (*)()) 0; \
320: MACRO_END
321:
322: #define vm_map_copy_invoke_extend_cont(old_copy, new_copy, result) \
323: MACRO_BEGIN \
324: *result = (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \
325: new_copy); \
326: (old_copy)->cpy_cont = (kern_return_t (*)()) 0; \
327: MACRO_END
328:
329: #define vm_map_copy_abort_cont(old_copy) \
330: MACRO_BEGIN \
331: vm_map_copy_page_discard(old_copy); \
332: (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \
333: (vm_map_copy_t *) 0); \
334: (old_copy)->cpy_cont = (kern_return_t (*)()) 0; \
335: (old_copy)->cpy_cont_args = (char *) 0; \
336: MACRO_END
337:
338: #define vm_map_copy_has_cont(copy) \
339: (((copy)->cpy_cont) != (kern_return_t (*)()) 0)
340:
341: /*
342: * Continuation structures for vm_map_copyin_page_list.
343: */
344:
345: typedef struct {
346: vm_map_t map;
347: vm_offset_t src_addr;
348: vm_size_t src_len;
349: vm_offset_t destroy_addr;
350: vm_size_t destroy_len;
351: boolean_t steal_pages;
352: } vm_map_copyin_args_data_t, *vm_map_copyin_args_t;
353:
354: #define VM_MAP_COPYIN_ARGS_NULL ((vm_map_copyin_args_t) 0)
355:
356: /*
357: * Macros: vm_map_lock, etc. [internal use only]
358: * Description:
359: * Perform locking on the data portion of a map.
360: */
361:
362: #define vm_map_lock_init(map) \
363: MACRO_BEGIN \
364: lock_init(&(map)->lock, TRUE); \
365: (map)->timestamp = 0; \
366: MACRO_END
367:
368: #define vm_map_lock(map) \
369: MACRO_BEGIN \
370: lock_write(&(map)->lock); \
371: (map)->timestamp++; \
372: MACRO_END
373:
374: #define vm_map_unlock(map) lock_write_done(&(map)->lock)
375: #define vm_map_lock_read(map) lock_read(&(map)->lock)
376: #define vm_map_unlock_read(map) lock_read_done(&(map)->lock)
377: #define vm_map_lock_write_to_read(map) \
378: lock_write_to_read(&(map)->lock)
379: #define vm_map_lock_read_to_write(map) \
380: (lock_read_to_write(&(map)->lock) || (((map)->timestamp++), 0))
381: #define vm_map_lock_set_recursive(map) \
382: lock_set_recursive(&(map)->lock)
383: #define vm_map_lock_clear_recursive(map) \
384: lock_clear_recursive(&(map)->lock)
385:
386: /*
387: * Exported procedures that operate on vm_map_t.
388: */
389:
390: extern vm_offset_t kentry_data;
391: extern vm_offset_t kentry_data_size;
392: extern int kentry_count;
393: extern void vm_map_init(); /* Initialize the module */
394:
395: extern vm_map_t vm_map_create(); /* Create an empty map */
396: extern vm_map_t vm_map_fork(); /* Create a map in the image
397: * of an existing map */
398:
399: extern void vm_map_reference(); /* Gain a reference to
400: * an existing map */
401: extern void vm_map_deallocate(); /* Lose a reference */
402:
403: extern kern_return_t vm_map_enter(); /* Enter a mapping */
404: extern kern_return_t vm_map_find_entry(); /* Enter a mapping primitive */
405: extern kern_return_t vm_map_remove(); /* Deallocate a region */
406: extern kern_return_t vm_map_reallocate(); /* *private* (BlueBox) */
407: extern kern_return_t vm_map_protect(); /* Change protection */
408: extern kern_return_t vm_map_inherit(); /* Change inheritance */
409:
410: extern void vm_map_print(); /* Debugging: print a map */
411:
412: extern kern_return_t vm_map_lookup(); /* Look up an address */
413: extern boolean_t vm_map_verify(); /* Verify that a previous
414: * lookup is still valid */
415: /* vm_map_verify_done is now a macro -- see below */
416: extern kern_return_t vm_map_copyin(); /* Make a copy of a region */
417: extern kern_return_t vm_map_copyin_page_list();/* Make a copy of a region
418: * using a page list copy */
419: extern kern_return_t vm_map_copyout(); /* Place a copy into a map */
420: extern kern_return_t vm_map_copy_overwrite();/* Overwrite existing memory
421: * with a copy */
422: extern void vm_map_copy_discard(); /* Discard a copy without
423: * using it */
424: extern kern_return_t vm_map_copy_discard_cont();/* Page list continuation
425: * version of previous */
426:
427: extern kern_return_t vm_map_machine_attribute();
428: /* Add or remove machine-
429: dependent attributes from
430: map regions */
431:
432: /*
433: * Functions implemented as macros
434: */
435: #define vm_map_min(map) ((map)->min_offset)
436: /* Lowest valid address in
437: * a map */
438:
439: #define vm_map_max(map) ((map)->max_offset)
440: /* Highest valid address */
441:
442: #define vm_map_pmap(map) ((map)->pmap)
443: /* Physical map associated
444: * with this address map */
445:
446: #if NEW_VM_CODE
447: #define vm_map_verify_done(map, version) (vm_map_unlock_read(map))
448: /* Operation that required
449: * a verified lookup is
450: * now complete */
451: /*
452: * Pageability functions. Includes macro to preserve old interface.
453: */
454: extern kern_return_t vm_map_pageable_common();
455:
456: #define vm_map_pageable(map, s, e, access) \
457: vm_map_pageable_common(map, s, e, access, FALSE)
458:
459: #define vm_map_pageable_user(map, s, e, access) \
460: vm_map_pageable_common(map, s, e, access, TRUE)
461: #endif
462:
463: /*
464: * Submap object. Must be used to create memory to be put
465: * in a submap by vm_map_submap.
466: */
467: extern vm_object_t vm_submap_object;
468:
469: /*
470: * Wait and wakeup macros for in_transition map entries.
471: */
472: #define vm_map_entry_wait(map, interruptible) \
473: MACRO_BEGIN \
474: assert_wait((event_t)&(map)->hdr, interruptible); \
475: vm_map_unlock(map); \
476: thread_block((void (*)()) 0); \
477: MACRO_END
478:
479: #define vm_map_entry_wakeup(map) thread_wakeup((event_t)&(map)->hdr)
480:
481: #endif /* _VM_VM_MAP_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.