2002-07-09 16:24:59 +04:00
|
|
|
/*
|
2008-03-25 14:51:45 +03:00
|
|
|
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
2004-12-14 01:04:26 +03:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
|
|
* Distributed under the terms of the NewOS License.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
#ifndef _KERNEL_VM_H
|
|
|
|
#define _KERNEL_VM_H
|
|
|
|
|
2003-05-03 20:03:26 +04:00
|
|
|
|
2005-12-21 15:38:31 +03:00
|
|
|
#include <arch/vm.h>
|
2007-09-27 16:21:33 +04:00
|
|
|
|
|
|
|
#include <OS.h>
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-05-03 20:03:26 +04:00
|
|
|
struct kernel_args;
|
2005-12-20 18:54:45 +03:00
|
|
|
struct team;
|
2007-09-27 16:21:33 +04:00
|
|
|
struct vm_page;
|
|
|
|
struct vm_cache;
|
|
|
|
struct vm_area;
|
|
|
|
struct vm_address_space;
|
2007-09-26 04:20:23 +04:00
|
|
|
struct vnode;
|
2003-05-03 20:03:26 +04:00
|
|
|
|
|
|
|
|
2007-09-27 17:01:18 +04:00
|
|
|
// additional protection flags
|
|
|
|
// Note: the VM probably won't support all combinations - it will try
|
|
|
|
// its best, but create_area() will fail if it has to.
|
|
|
|
// Of course, the exact behaviour will be documented somewhere...
|
|
|
|
#define B_EXECUTE_AREA 0x04
|
|
|
|
#define B_STACK_AREA 0x08
|
|
|
|
// "stack" protection is not available on most platforms - it's used
|
|
|
|
// to only commit memory as needed, and have guard pages at the
|
|
|
|
// bottom of the stack.
|
|
|
|
// "execute" protection is currently ignored, but nevertheless, you
|
|
|
|
// should use it if you require to execute code in that area.
|
|
|
|
|
|
|
|
#define B_KERNEL_EXECUTE_AREA 0x40
|
|
|
|
#define B_KERNEL_STACK_AREA 0x80
|
|
|
|
|
|
|
|
#define B_USER_PROTECTION \
|
|
|
|
(B_READ_AREA | B_WRITE_AREA | B_EXECUTE_AREA | B_STACK_AREA)
|
|
|
|
#define B_KERNEL_PROTECTION \
|
|
|
|
(B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_EXECUTE_AREA \
|
|
|
|
| B_KERNEL_STACK_AREA)
|
|
|
|
|
|
|
|
#define B_OVERCOMMITTING_AREA 0x1000
|
2008-04-14 02:52:11 +04:00
|
|
|
#define B_SHARED_AREA 0x2000
|
|
|
|
// TODO: These aren't really a protection flags, but since the "protection"
|
2007-09-27 17:01:18 +04:00
|
|
|
// field is the only flag field, we currently use it for this.
|
|
|
|
// A cleaner approach would be appreciated - maybe just an official generic
|
|
|
|
// flags region in the protection field.
|
|
|
|
|
2008-04-14 02:52:11 +04:00
|
|
|
|
2007-09-27 17:01:18 +04:00
|
|
|
#define B_USER_AREA_FLAGS (B_USER_PROTECTION)
|
|
|
|
#define B_KERNEL_AREA_FLAGS \
|
2008-04-14 02:52:11 +04:00
|
|
|
(B_KERNEL_PROTECTION | B_USER_CLONEABLE_AREA | B_OVERCOMMITTING_AREA \
|
|
|
|
| B_SHARED_AREA)
|
2007-09-27 17:01:18 +04:00
|
|
|
|
|
|
|
// flags for vm_get_physical_page()
|
|
|
|
enum {
|
|
|
|
PHYSICAL_PAGE_NO_WAIT = 0,
|
|
|
|
PHYSICAL_PAGE_CAN_WAIT,
|
|
|
|
};
|
|
|
|
|
|
|
|
// mapping argument for several internal VM functions
|
|
|
|
enum {
|
|
|
|
REGION_NO_PRIVATE_MAP = 0,
|
|
|
|
REGION_PRIVATE_MAP
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
// ToDo: these are here only temporarily - it's a private
|
|
|
|
// addition to the BeOS create_area() lock flags
|
|
|
|
B_ALREADY_WIRED = 6,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MEMORY_TYPE_SHIFT 28
|
|
|
|
|
|
|
|
|
2003-06-27 06:27:43 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2007-02-27 22:26:40 +03:00
|
|
|
// startup only
|
2007-09-27 16:21:33 +04:00
|
|
|
status_t vm_init(struct kernel_args *args);
|
2004-10-20 03:19:10 +04:00
|
|
|
status_t vm_init_post_sem(struct kernel_args *args);
|
|
|
|
status_t vm_init_post_thread(struct kernel_args *args);
|
The short story: we now have MTRR support on Intel and AMD CPUs (the latter
has not yet been tested, though - I'll do this after this commit):
* Removed the arch_memory_type stuff from vm_area; since there are only 8 memory
ranges on x86, it's simply overkill. The MTRR code now remembers the area ID
and finds the MTRR that way (it could also iterate over the existing MTRRs).
* Introduced some post_modules() init functions.
* If the other x86 CPUs out there don't differ a lot, MTRR functionality might
be put back into the kernel.
* x86_write_msr() was broken, it wrote the 64 bit number with the 32 bit words
switched - it took me some time (and lots of #GPs) to figure that one out.
* Removed the macro read_ebp() and introduced a function x86_read_ebp()
(it's not really a time critical call).
* Followed the Intel docs on how to change MTRRs (symmetrically on all CPUs
with caches turned off).
* Asking for memory types will automatically change the requested length to
a power of two - note that BeOS seems to behave in the same, although that's
not really very clean.
* fixed MTRRs are ignored for now - we should make sure at least, though,
that they are identical on all CPUs (or turn them off, even though I'd
prefer the BIOS stuff to be uncacheable, which we don't enforce yet, though).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15528 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-12-13 19:34:29 +03:00
|
|
|
status_t vm_init_post_modules(struct kernel_args *args);
|
2007-09-27 16:21:33 +04:00
|
|
|
void vm_free_kernel_args(struct kernel_args *args);
|
2004-10-20 03:19:10 +04:00
|
|
|
void vm_free_unused_boot_loader_range(addr_t start, addr_t end);
|
2007-09-27 16:21:33 +04:00
|
|
|
addr_t vm_allocate_early(struct kernel_args *args, size_t virtualSize,
|
2007-02-27 22:26:40 +03:00
|
|
|
size_t physicalSize, uint32 attributes);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-04-30 02:58:46 +04:00
|
|
|
void slab_init(struct kernel_args *args, addr_t initialBase,
|
|
|
|
size_t initialSize);
|
2007-04-29 06:23:37 +04:00
|
|
|
void slab_init_post_sem();
|
|
|
|
|
2005-12-20 18:54:45 +03:00
|
|
|
// to protect code regions with interrupts turned on
|
|
|
|
void permit_page_faults(void);
|
|
|
|
void forbid_page_faults(void);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-08-19 18:11:58 +04:00
|
|
|
// private kernel only extension (should be moved somewhere else):
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id create_area_etc(struct team *team, const char *name, void **address,
|
2005-05-15 19:56:55 +04:00
|
|
|
uint32 addressSpec, uint32 size, uint32 lock, uint32 protection);
|
2003-08-19 21:22:47 +04:00
|
|
|
status_t delete_area_etc(struct team *team, area_id area);
|
2003-08-19 18:11:58 +04:00
|
|
|
|
2005-12-20 18:54:45 +03:00
|
|
|
status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);
|
2008-04-02 16:30:06 +04:00
|
|
|
status_t vm_reserve_address_range(team_id team, void **_address,
|
2005-05-15 19:56:55 +04:00
|
|
|
uint32 addressSpec, addr_t size, uint32 flags);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id vm_create_anonymous_area(team_id team, const char *name, void **address,
|
2008-04-14 02:52:11 +04:00
|
|
|
uint32 addressSpec, addr_t size, uint32 wiring, uint32 protection,
|
|
|
|
bool unmapAddressRange);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id vm_map_physical_memory(team_id team, const char *name, void **address,
|
2005-05-15 19:56:55 +04:00
|
|
|
uint32 addressSpec, addr_t size, uint32 protection, addr_t phys_addr);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id vm_map_file(team_id aid, const char *name, void **address,
|
|
|
|
uint32 addressSpec, addr_t size, uint32 protection, uint32 mapping,
|
2008-04-14 02:52:11 +04:00
|
|
|
int fd, off_t offset);
|
2007-09-27 16:21:33 +04:00
|
|
|
struct vm_cache *vm_area_get_locked_cache(struct vm_area *area);
|
|
|
|
void vm_area_put_locked_cache(struct vm_cache *cache);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id vm_create_null_area(team_id team, const char *name, void **address,
|
2005-05-15 19:56:55 +04:00
|
|
|
uint32 addressSpec, addr_t size);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id vm_copy_area(team_id team, const char *name, void **_address,
|
2005-05-15 19:56:55 +04:00
|
|
|
uint32 addressSpec, uint32 protection, area_id sourceID);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id vm_clone_area(team_id team, const char *name, void **address,
|
|
|
|
uint32 addressSpec, uint32 protection, uint32 mapping,
|
2005-05-15 19:56:55 +04:00
|
|
|
area_id sourceArea);
|
2007-09-27 16:21:33 +04:00
|
|
|
status_t vm_delete_area(team_id teamID, area_id areaID);
|
|
|
|
status_t vm_create_vnode_cache(struct vnode *vnode, struct vm_cache **_cache);
|
|
|
|
struct vm_area *vm_area_lookup(struct vm_address_space *addressSpace,
|
|
|
|
addr_t address);
|
2005-12-13 03:06:52 +03:00
|
|
|
status_t vm_set_area_memory_type(area_id id, addr_t physicalBase, uint32 type);
|
2005-12-20 18:54:45 +03:00
|
|
|
status_t vm_get_page_mapping(team_id team, addr_t vaddr, addr_t *paddr);
|
2007-09-28 19:50:26 +04:00
|
|
|
bool vm_test_map_modification(struct vm_page *page);
|
2007-09-27 16:21:33 +04:00
|
|
|
int32 vm_test_map_activation(struct vm_page *page, bool *_modified);
|
2007-09-28 19:50:26 +04:00
|
|
|
void vm_clear_map_flags(struct vm_page *page, uint32 flags);
|
2007-10-04 20:36:35 +04:00
|
|
|
void vm_remove_all_page_mappings(struct vm_page *page, uint32 *_flags);
|
2007-10-09 15:05:50 +04:00
|
|
|
status_t vm_unmap_pages(struct vm_area *area, addr_t base, size_t length,
|
|
|
|
bool preserveModified);
|
2007-09-27 16:21:33 +04:00
|
|
|
status_t vm_map_page(struct vm_area *area, struct vm_page *page, addr_t address,
|
2007-02-28 16:24:53 +03:00
|
|
|
uint32 protection);
|
2005-12-20 18:54:45 +03:00
|
|
|
status_t vm_get_physical_page(addr_t paddr, addr_t *vaddr, uint32 flags);
|
2004-10-20 04:33:06 +04:00
|
|
|
status_t vm_put_physical_page(addr_t vaddr);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-04-02 16:30:06 +04:00
|
|
|
off_t vm_available_memory(void);
|
2008-03-25 14:51:45 +03:00
|
|
|
|
2005-12-20 18:54:45 +03:00
|
|
|
// user syscalls
|
2003-08-19 18:11:58 +04:00
|
|
|
area_id _user_create_area(const char *name, void **address, uint32 addressSpec,
|
2003-08-20 19:47:52 +04:00
|
|
|
size_t size, uint32 lock, uint32 protection);
|
2003-08-19 18:11:58 +04:00
|
|
|
status_t _user_delete_area(area_id area);
|
2008-04-14 02:52:11 +04:00
|
|
|
area_id _user_map_file(const char *uname, void **uaddress, int addressSpec,
|
|
|
|
addr_t size, int protection, int mapping, int fd, off_t offset);
|
|
|
|
status_t _user_unmap_memory(void *address, addr_t size);
|
2003-08-20 19:47:52 +04:00
|
|
|
area_id _user_area_for(void *address);
|
|
|
|
area_id _user_find_area(const char *name);
|
|
|
|
status_t _user_get_area_info(area_id area, area_info *info);
|
|
|
|
status_t _user_get_next_area_info(team_id team, int32 *cookie, area_info *info);
|
|
|
|
status_t _user_resize_area(area_id area, size_t newSize);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id _user_transfer_area(area_id area, void **_address, uint32 addressSpec,
|
2005-05-15 19:56:55 +04:00
|
|
|
team_id target);
|
2003-08-20 19:47:52 +04:00
|
|
|
status_t _user_set_area_protection(area_id area, uint32 newProtection);
|
2008-04-02 16:30:06 +04:00
|
|
|
area_id _user_clone_area(const char *name, void **_address, uint32 addressSpec,
|
2003-08-20 19:47:52 +04:00
|
|
|
uint32 protection, area_id sourceArea);
|
2006-03-18 15:52:01 +03:00
|
|
|
status_t _user_reserve_heap_address_range(addr_t* userAddress, uint32 addressSpec,
|
|
|
|
addr_t size);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-06-27 06:27:43 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
#endif
|
|
|
|
|
2003-06-27 06:27:43 +04:00
|
|
|
#endif /* _KERNEL_VM_H */
|