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