#ifndef MANGO_VM_REGION_H_ #define MANGO_VM_REGION_H_ #include #include #include #define VM_REGION_NAME_MAX 64 #define VM_REGION_ANY_MAP_ADDRESS ((virt_addr_t) - 1) struct vm_region; struct vm_object; enum vm_region_entry_type { VM_REGION_ENTRY_NONE = 0, VM_REGION_ENTRY_REGION, VM_REGION_ENTRY_MAPPING, }; struct vm_region_entry { struct btree_node e_node; struct vm_region_entry *e_parent; enum vm_region_entry_type e_type; /* absolute virtual address of the entry */ virt_addr_t e_base_address; /* size of the entry in bytes */ size_t e_size; }; struct vm_region_mapping { struct vm_region_entry m_entry; struct vm_object *m_object; /* used to link to vm_object->vo_mappings */ struct queue_entry m_object_entry; enum vm_prot m_prot; /* offset in bytes to the start of the object data that was mapped */ off_t m_object_offset; }; struct vm_region { struct object vr_base; struct vm_region_entry vr_entry; char vr_name[VM_REGION_NAME_MAX]; /* btree of struct vm_region_entry. * sibling entries cannot overlap each other, and child entries must * be entirely contained within their immediate parent entry. */ struct btree vr_entries; /* memory protection restriction mask. * any mapping in this region, or any of its children, cannot use * protection flags that are not set in this mask. * for example, if VM_PROT_EXEC is /not/ set here, no mapping * can be created in this region or any child region with VM_PROT_EXEC * set. */ enum vm_prot vr_prot; /* the physical address space in which mappings in this region (and * its children) are created */ pmap_t vr_pmap; }; extern kern_status_t vm_region_type_init(void); extern kern_status_t vm_region_create( struct vm_region *parent, const char *name, virt_addr_t base, size_t len, enum vm_prot prot, struct vm_region **out); /* find the child region that has jurisdiction over the specified virtual * address. returns the lowest-nested region that covers the specified virtual * address. */ extern struct vm_region *vm_region_find_child( struct vm_region *region, virt_addr_t addr); /* find the child region that has jurisdiction over the specified virtual * address area. returns the lowest-nested region that covers the specified * virtual address area. the area must be fully contained within a region, with * no partial overlaps. if an area is covered by multiple regions, or is only * partially within a region, returns NULL. */ extern struct vm_region *vm_region_find_child_for_area( struct vm_region *region, virt_addr_t addr, size_t len); extern struct vm_region_mapping *vm_region_find_mapping( struct vm_region *region, virt_addr_t addr); extern kern_status_t vm_region_map_object( struct vm_region *region, virt_addr_t map_address, struct vm_object *object, off_t object_offset, size_t length, enum vm_prot prot, virt_addr_t *out); /* returns true if the memory area defined by [base, base+len] contains: * - no child regions * - no vm_object mappings * if any child regions or mappings exist in the memory area, returns false. * if the memory area exceeds the bounds of the region, returns false. */ extern bool vm_region_is_area_free( const struct vm_region *region, virt_addr_t base, size_t len); extern kern_status_t vm_region_demand_map( struct vm_region *region, virt_addr_t addr, enum pmap_fault_flags flags); extern void vm_region_dump(struct vm_region *region, int depth); DEFINE_OBJECT_LOCK_FUNCTION(vm_region, vr_base) #endif