#ifndef KERNEL_VM_OBJECT_H_ #define KERNEL_VM_OBJECT_H_ #include #include #define VM_OBJECT_NAME_MAX 64 struct vm_controller; enum vm_object_flags { /* the memory behind this vm-object wasn't allocated by us, and * therefore shouldn't be freed by us */ VMO_IN_PLACE = 0x01u, /* this vm-object is/was attached to a vm-controller */ VMO_CONTROLLER = 0x02u, /* when a vm-object is attached to a controller, and the ref-count of * the object falls to one (i.e. the last reference is the handle to * the object held by the server that created it), the object will * be detached, allowing the server to close the last handle to the * object and dispose of it. */ VMO_AUTO_DETACH = 0x04u, /* this vmo is a duplicate of a vmo that is attached to a vm-controller. * the duplicate vmo is scheduled to be attached to the same controller, * but this won't actually happen until the controller is needed to * fulfill a page request. once the duplicate vmo has been attached to * the controller, this flag will be cleared. */ VMO_LAZY_ATTACH = 0x08u, /* these flags are for use with vm_object_get_page */ /**************************************************/ /* if the relevant page hasn't been allocated yet, it will be allocated * and returned. if this flag isn't specified, NULL will be returned. */ VMO_ALLOCATE_MISSING_PAGE = 0x0100u, /* if the vm-object is attached to a vm-controller, and the relevant * page is uncommitted, send a request to the vm-controller to provide * the missing page. will result in the vm-object being unlocked and * the current thread sleeping until the request is fulfilled. the * vm-object will be re-locked before the function returns. */ VMO_REQUEST_MISSING_PAGE = 0x0200u, }; struct vm_object { struct object vo_base; char vo_name[VM_OBJECT_NAME_MAX]; enum vm_object_flags vo_flags; /* queue of struct vm_region_mapping */ struct queue vo_mappings; struct vm_controller *vo_ctrl; equeue_key_t vo_key; struct btree_node vo_ctrl_node; /* memory protection flags. mappings of this vm_object can only * use a subset of the flags set in this mask. */ vm_prot_t vo_prot; /* btree of vm_pages that have been allocated to this vm_object. * vm_page->p_vmo_offset and the size of each page is the bst key. */ struct btree vo_pages; /* total length of the vm_object in bytes. */ size_t vo_size; }; extern kern_status_t vm_object_type_init(void); extern struct vm_object *vm_object_cast(struct object *obj); /* create a vm_object with the specified length in bytes and protection flags. * the length will be automatically rounded up to the nearest vm_object page * order size. the actual page frames themselves won't be allocated until * they are mapped and accessed. */ extern struct vm_object *vm_object_create( const char *name, size_t name_len, size_t data_len, vm_prot_t prot); /* create a vm_object that represents the specified range of physical memory. * the length will be automatically rounded up to the nearest vm_object page * order size. * NOTE this function assumes that the physical memory has already been * reserved, and is not in use by any other kernel component. */ extern struct vm_object *vm_object_create_in_place( const char *name, size_t name_len, phys_addr_t base, size_t data_len, vm_prot_t prot); /* create a copy-on-write duplicate of a vm-object */ extern struct vm_object *vm_object_duplicate_cow(struct vm_object *vmo); /* attach a copy-on-write duplicate of a vm-object to the vm-controller that * controlled the original vm-object */ extern kern_status_t vm_object_attach_cow( struct vm_object *vmo, unsigned long *irq_flags); /* prefetch any missing pages in the specified range of a vm-object. * any lazy-allocated pages will be allocated. * any missing pages will be requested from the vm-controller, if one is * attached. */ extern kern_status_t vm_object_prefetch( struct vm_object *vo, off_t offset, size_t length, unsigned long *irq_flags); extern struct vm_page *vm_object_get_page( struct vm_object *vo, off_t offset, enum vm_object_flags flags, unsigned long *irq_flags); extern kern_status_t vm_object_put_page( struct vm_object *vo, off_t offset, struct vm_page *pg); extern kern_status_t vm_object_read( struct vm_object *vo, void *dst, off_t offset, size_t count, size_t *nr_read); extern kern_status_t vm_object_write( struct vm_object *vo, const void *dst, off_t offset, size_t count, size_t *nr_written); extern kern_status_t vm_object_copy( struct vm_object *dst, off_t dst_offset, struct vm_object *src, off_t src_offset, size_t count, size_t *nr_copied); extern kern_status_t vm_object_transfer( struct vm_object *dst, off_t dst_offset, struct vm_object *src, off_t src_offset, size_t count, size_t *nr_moved); DEFINE_OBJECT_LOCK_FUNCTION(vm_object, vo_base) #endif