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