127 lines
3.5 KiB
C
127 lines
3.5 KiB
C
|
|
#ifndef MANGO_VM_REGION_H_
|
||
|
|
#define MANGO_VM_REGION_H_
|
||
|
|
|
||
|
|
#include <mango/object.h>
|
||
|
|
#include <mango/pmap.h>
|
||
|
|
#include <mango/vm.h>
|
||
|
|
|
||
|
|
#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
|