--- Gnu-Mach/vm/vm_map.h 2020/09/02 04:42:55 1.1.1.2 +++ Gnu-Mach/vm/vm_map.h 2020/09/02 04:45:27 1.1.1.3 @@ -43,18 +43,23 @@ #include #include #include +#include #include #include #include #include #include +#include #include +#include #include +/* TODO: make it dynamic */ +#define KENTRY_DATA_SIZE (64*PAGE_SIZE) + /* * Types defined: * - * vm_map_t the high-level address map data structure. * vm_map_entry_t an entry in an address map. * vm_map_version_t a timestamp of a map, for use with vm_map_lookup * vm_map_copy_t represents memory copied from an address map, @@ -99,6 +104,7 @@ struct vm_map_entry { #define vme_next links.next #define vme_start links.start #define vme_end links.end + struct rbtree_node tree_node; /* links to other entries in tree */ union vm_map_object object; /* object I point to */ vm_offset_t offset; /* offset into object */ unsigned int @@ -134,6 +140,7 @@ typedef struct vm_map_entry *vm_map_entr */ struct vm_map_header { struct vm_map_links links; /* first, last, min, max */ + struct rbtree tree; /* Sorted tree of entries */ int nentries; /* Number of entries */ boolean_t entries_pageable; /* are map entries pageable? */ @@ -149,9 +156,11 @@ struct vm_map_header { * * Implementation: * Maps are doubly-linked lists of map entries, sorted - * by address. One hint is used to start - * searches again from the last successful search, - * insertion, or removal. Another hint is used to + * by address. They're also contained in a red-black tree. + * One hint is used to start searches again at the last + * successful search, insertion, or removal. If the hint + * lookup failed (i.e. the hint didn't refer to the requested + * entry), a BST lookup is performed. Another hint is used to * quickly find free space. */ struct vm_map { @@ -171,9 +180,6 @@ struct vm_map { boolean_t wiring_required;/* All memory wired? */ unsigned int timestamp; /* Version number */ }; -typedef struct vm_map *vm_map_t; - -#define VM_MAP_NULL ((vm_map_t) 0) #define vm_map_to_entry(map) ((struct vm_map_entry *) &(map)->hdr.links) #define vm_map_first_entry(map) ((map)->hdr.links.next) @@ -228,11 +234,7 @@ typedef struct vm_map_version { * (returned) and an abort flag (abort if TRUE). */ -#if iPSC386 || iPSC860 #define VM_MAP_COPY_PAGE_LIST_MAX 64 -#else /* iPSC386 || iPSC860 */ -#define VM_MAP_COPY_PAGE_LIST_MAX 8 -#endif /* iPSC386 || iPSC860 */ typedef struct vm_map_copy { int type; @@ -358,45 +360,82 @@ MACRO_END */ extern vm_offset_t kentry_data; -extern vm_offset_t kentry_data_size; +extern vm_size_t kentry_data_size; extern int kentry_count; -extern void vm_map_init(); /* Initialize the module */ +/* Initialize the module */ +extern void vm_map_init(void); -extern vm_map_t vm_map_create(); /* Create an empty map */ -extern vm_map_t vm_map_fork(); /* Create a map in the image - * of an existing map */ - -extern void vm_map_reference(); /* Gain a reference to - * an existing map */ -extern void vm_map_deallocate(); /* Lose a reference */ - -extern kern_return_t vm_map_enter(); /* Enter a mapping */ -extern kern_return_t vm_map_find_entry(); /* Enter a mapping primitive */ -extern kern_return_t vm_map_remove(); /* Deallocate a region */ -extern kern_return_t vm_map_protect(); /* Change protection */ -extern kern_return_t vm_map_inherit(); /* Change inheritance */ - -extern void vm_map_print(); /* Debugging: print a map */ - -extern kern_return_t vm_map_lookup(); /* Look up an address */ -extern boolean_t vm_map_verify(); /* Verify that a previous - * lookup is still valid */ +/* Initialize an empty map */ +extern void vm_map_setup(vm_map_t, pmap_t, vm_offset_t, vm_offset_t, + boolean_t); +/* Create an empty map */ +extern vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t, + boolean_t); +/* Create a map in the image of an existing map */ +extern vm_map_t vm_map_fork(vm_map_t); + +/* Gain a reference to an existing map */ +extern void vm_map_reference(vm_map_t); +/* Lose a reference */ +extern void vm_map_deallocate(vm_map_t); + +/* Enter a mapping */ +extern kern_return_t vm_map_enter(vm_map_t, vm_offset_t *, vm_size_t, + vm_offset_t, boolean_t, vm_object_t, + vm_offset_t, boolean_t, vm_prot_t, + vm_prot_t, vm_inherit_t); +/* Enter a mapping primitive */ +extern kern_return_t vm_map_find_entry(vm_map_t, vm_offset_t *, vm_size_t, + vm_offset_t, vm_object_t, + vm_map_entry_t *); +/* Deallocate a region */ +extern kern_return_t vm_map_remove(vm_map_t, vm_offset_t, vm_offset_t); +/* Change protection */ +extern kern_return_t vm_map_protect(vm_map_t, vm_offset_t, vm_offset_t, + vm_prot_t, boolean_t); +/* Change inheritance */ +extern kern_return_t vm_map_inherit(vm_map_t, vm_offset_t, vm_offset_t, + vm_inherit_t); + +/* Look up an address */ +extern kern_return_t vm_map_lookup(vm_map_t *, vm_offset_t, vm_prot_t, + vm_map_version_t *, vm_object_t *, + vm_offset_t *, vm_prot_t *, boolean_t *); +/* Find a map entry */ +extern boolean_t vm_map_lookup_entry(vm_map_t, vm_offset_t, + vm_map_entry_t *); +/* Verify that a previous lookup is still valid */ +extern boolean_t vm_map_verify(vm_map_t, vm_map_version_t *); /* vm_map_verify_done is now a macro -- see below */ -extern kern_return_t vm_map_copyin(); /* Make a copy of a region */ -extern kern_return_t vm_map_copyin_page_list();/* Make a copy of a region - * using a page list copy */ -extern kern_return_t vm_map_copyout(); /* Place a copy into a map */ -extern kern_return_t vm_map_copy_overwrite();/* Overwrite existing memory - * with a copy */ -extern void vm_map_copy_discard(); /* Discard a copy without - * using it */ -extern kern_return_t vm_map_copy_discard_cont();/* Page list continuation - * version of previous */ - -extern kern_return_t vm_map_machine_attribute(); - /* Add or remove machine- - dependent attributes from - map regions */ +/* Make a copy of a region */ +extern kern_return_t vm_map_copyin(vm_map_t, vm_offset_t, vm_size_t, + boolean_t, vm_map_copy_t *); +/* Make a copy of a region using a page list copy */ +extern kern_return_t vm_map_copyin_page_list(vm_map_t, vm_offset_t, + vm_size_t, boolean_t, + boolean_t, vm_map_copy_t *, + boolean_t); +/* Place a copy into a map */ +extern kern_return_t vm_map_copyout(vm_map_t, vm_offset_t *, vm_map_copy_t); +/* Overwrite existing memory with a copy */ +extern kern_return_t vm_map_copy_overwrite(vm_map_t, vm_offset_t, + vm_map_copy_t, boolean_t); +/* Discard a copy without using it */ +extern void vm_map_copy_discard(vm_map_copy_t); +extern void vm_map_copy_page_discard(vm_map_copy_t); +extern vm_map_copy_t vm_map_copy_copy(vm_map_copy_t); +/* Page list continuation version of previous */ +extern kern_return_t vm_map_copy_discard_cont(vm_map_copyin_args_t, + vm_map_copy_t *); + +/* Add or remove machine- dependent attributes from map regions */ +extern kern_return_t vm_map_machine_attribute(vm_map_t, vm_offset_t, + vm_size_t, + vm_machine_attribute_t, + vm_machine_attribute_val_t *); + +/* Delete entry from map */ +extern void vm_map_entry_delete(vm_map_t, vm_map_entry_t); /* * Functions implemented as macros @@ -419,7 +458,9 @@ extern kern_return_t vm_map_machine_attr /* * Pageability functions. Includes macro to preserve old interface. */ -extern kern_return_t vm_map_pageable_common(); +extern kern_return_t vm_map_pageable_common(vm_map_t, vm_offset_t, + vm_offset_t, vm_prot_t, + boolean_t); #define vm_map_pageable(map, s, e, access) \ vm_map_pageable_common(map, s, e, access, FALSE) @@ -434,6 +475,42 @@ extern kern_return_t vm_map_pageable_com extern vm_object_t vm_submap_object; /* + * vm_map_copyin_object: + * + * Create a copy object from an object. + * Our caller donates an object reference. + */ +extern kern_return_t vm_map_copyin_object( + vm_object_t object, + vm_offset_t offset, /* offset of region in object */ + vm_size_t size, /* size of region in object */ + vm_map_copy_t *copy_result); /* OUT */ + +/* + * vm_map_submap: [ kernel use only ] + * + * Mark the given range as handled by a subordinate map. + * + * This range must have been created with vm_map_find using + * the vm_submap_object, and no other operations may have been + * performed on this range prior to calling vm_map_submap. + * + * Only a limited number of operations can be performed + * within this rage after calling vm_map_submap: + * vm_fault + * [Don't try vm_map_copyin!] + * + * To remove a submapping, one must first remove the + * range from the superior map, and then destroy the + * submap (if desired). [Better yet, don't try it.] + */ +extern kern_return_t vm_map_submap( + vm_map_t map, + vm_offset_t start, + vm_offset_t end, + vm_map_t submap); + +/* * Wait and wakeup macros for in_transition map entries. */ #define vm_map_entry_wait(map, interruptible) \ @@ -445,4 +522,22 @@ extern vm_object_t vm_submap_object; #define vm_map_entry_wakeup(map) thread_wakeup((event_t)&(map)->hdr) +/* + * This routine is called only when it is known that + * the entry must be split. + */ +extern void _vm_map_clip_start( + struct vm_map_header *map_header, + vm_map_entry_t entry, + vm_offset_t start); + +/* + * vm_map_clip_end: [ internal use only ] + * + * Asserts that the given entry ends at or before + * the specified address; if necessary, + * it splits the entry into two. + */ +void _vm_map_clip_end(); + #endif /* _VM_VM_MAP_H_ */