2002-07-09 16:24:59 +04:00
|
|
|
/*
|
2007-03-11 16:27:42 +03:00
|
|
|
* Copyright 2002-2007, Haiku. All rights reserved.
|
2006-04-30 21:45:33 +04: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.
|
|
|
|
*/
|
2003-05-03 20:03:26 +04:00
|
|
|
#ifndef KERNEL_VM_TRANSLATION_MAP_H
|
|
|
|
#define KERNEL_VM_TRANSLATION_MAP_H
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
#include <kernel.h>
|
|
|
|
#include <lock.h>
|
|
|
|
|
2003-10-29 00:10:00 +03:00
|
|
|
|
2003-05-03 20:03:26 +04:00
|
|
|
struct kernel_args;
|
|
|
|
|
|
|
|
|
2004-10-20 03:19:10 +04:00
|
|
|
typedef struct vm_translation_map {
|
|
|
|
struct vm_translation_map *next;
|
|
|
|
struct vm_translation_map_ops *ops;
|
|
|
|
recursive_lock lock;
|
|
|
|
int32 map_count;
|
|
|
|
struct vm_translation_map_arch_info *arch_data;
|
2002-07-09 16:24:59 +04:00
|
|
|
} vm_translation_map;
|
|
|
|
|
2003-10-29 00:10:00 +03:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
// table of operations the vm may want to do to this mapping
|
2004-10-20 03:19:10 +04:00
|
|
|
typedef struct vm_translation_map_ops {
|
2006-04-30 21:45:33 +04:00
|
|
|
void (*destroy)(vm_translation_map *map);
|
|
|
|
status_t (*lock)(vm_translation_map *map);
|
|
|
|
status_t (*unlock)(vm_translation_map *map);
|
2007-10-06 15:18:21 +04:00
|
|
|
size_t (*map_max_pages_need)(vm_translation_map *map, addr_t start, addr_t end);
|
2007-03-11 16:27:42 +03:00
|
|
|
status_t (*map)(vm_translation_map *map, addr_t va, addr_t pa,
|
|
|
|
uint32 attributes);
|
2004-06-17 17:22:05 +04:00
|
|
|
status_t (*unmap)(vm_translation_map *map, addr_t start, addr_t end);
|
2007-03-11 16:27:42 +03:00
|
|
|
status_t (*query)(vm_translation_map *map, addr_t va, addr_t *_outPhysical,
|
|
|
|
uint32 *_outFlags);
|
|
|
|
status_t (*query_interrupt)(vm_translation_map *map, addr_t va,
|
|
|
|
addr_t *_outPhysical, uint32 *_outFlags);
|
2004-06-17 17:22:05 +04:00
|
|
|
addr_t (*get_mapped_size)(vm_translation_map*);
|
2007-03-11 16:27:42 +03:00
|
|
|
status_t (*protect)(vm_translation_map *map, addr_t base, addr_t top,
|
|
|
|
uint32 attributes);
|
2004-06-17 17:22:05 +04:00
|
|
|
status_t (*clear_flags)(vm_translation_map *map, addr_t va, uint32 flags);
|
2002-07-09 16:24:59 +04:00
|
|
|
void (*flush)(vm_translation_map *map);
|
* Prefixed memset_physical() and memcpy_to_physical() with "vm_",
added vm_memcpy_from_physical() and vm_memcpy_physical_page(), and
added respective functions to the vm_translation_map operations. The
architecture specific implementation can now decide how to implement
them most efficiently. Added generic implementations that can be used,
though.
* Changed vm_{get,put}_physical_page(). The former no longer accepts
flags (the only flag PHYSICAL_PAGE_DONT_WAIT wasn't needed anymore).
Instead it returns an implementation-specific handle that has to be
passed to the latter. Added vm_{get,put}_physical_page_current_cpu()
and *_debug() variants, that work only for the current CPU,
respectively when in the kernel debugger. Also adjusted the
vm_translation_map operations accordingly.
* Made consequent use of the physical memory operations in the source
tree.
* Also adjusted the m68k and ppc implementations with respect to the
vm_translation_map operation changes, but they are probably broken,
nevertheless.
* For x86 the generic physical page mapper isn't used anymore. It is
suboptimal in any case. For systems with small memory it is too much
overhead, since one can just map the complete physical memory (that's
not done yet, though). For systems with large memory it counteracts
the VM strategy to reuse the least recently used pages. Since those
pages will most likely not be mapped by the page mapper anymore, it
will keep remapping chunks. This was also the reason why building
Haiku in Haiku was significantly faster with only 256 MB RAM (since
that much could be kept mapped all the time).
Now we're using a different strategy: We have small pools of virtual
page slots per CPU that are used for the physical page operations
(memset_physical(), memcpy_*_physical()) with CPU-pinned thread.
Furthermore we have four slots per translation map, which are used to
map page tables.
These changes speed up the Haiku image build in Haiku significantly. On
my Core2 Duo 2.2 GHz 2 GB machine about 40% to 20 min 40 s (KDEBUG
disabled, block cache debug disabled). Still more than factor 3 slower
than FreeBSD and Linux, though.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28244 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-10-20 04:06:09 +04:00
|
|
|
|
|
|
|
// get/put virtual address for physical page -- will be usuable on all CPUs
|
|
|
|
// (usually more expensive than the *_current_cpu() versions)
|
2007-03-11 16:27:42 +03:00
|
|
|
status_t (*get_physical_page)(addr_t physicalAddress,
|
* Prefixed memset_physical() and memcpy_to_physical() with "vm_",
added vm_memcpy_from_physical() and vm_memcpy_physical_page(), and
added respective functions to the vm_translation_map operations. The
architecture specific implementation can now decide how to implement
them most efficiently. Added generic implementations that can be used,
though.
* Changed vm_{get,put}_physical_page(). The former no longer accepts
flags (the only flag PHYSICAL_PAGE_DONT_WAIT wasn't needed anymore).
Instead it returns an implementation-specific handle that has to be
passed to the latter. Added vm_{get,put}_physical_page_current_cpu()
and *_debug() variants, that work only for the current CPU,
respectively when in the kernel debugger. Also adjusted the
vm_translation_map operations accordingly.
* Made consequent use of the physical memory operations in the source
tree.
* Also adjusted the m68k and ppc implementations with respect to the
vm_translation_map operation changes, but they are probably broken,
nevertheless.
* For x86 the generic physical page mapper isn't used anymore. It is
suboptimal in any case. For systems with small memory it is too much
overhead, since one can just map the complete physical memory (that's
not done yet, though). For systems with large memory it counteracts
the VM strategy to reuse the least recently used pages. Since those
pages will most likely not be mapped by the page mapper anymore, it
will keep remapping chunks. This was also the reason why building
Haiku in Haiku was significantly faster with only 256 MB RAM (since
that much could be kept mapped all the time).
Now we're using a different strategy: We have small pools of virtual
page slots per CPU that are used for the physical page operations
(memset_physical(), memcpy_*_physical()) with CPU-pinned thread.
Furthermore we have four slots per translation map, which are used to
map page tables.
These changes speed up the Haiku image build in Haiku significantly. On
my Core2 Duo 2.2 GHz 2 GB machine about 40% to 20 min 40 s (KDEBUG
disabled, block cache debug disabled). Still more than factor 3 slower
than FreeBSD and Linux, though.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28244 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-10-20 04:06:09 +04:00
|
|
|
addr_t *_virtualAddress, void **handle);
|
|
|
|
status_t (*put_physical_page)(addr_t virtualAddress, void *handle);
|
|
|
|
|
|
|
|
// get/put virtual address for physical page -- thread must be pinned the
|
|
|
|
// whole time
|
|
|
|
status_t (*get_physical_page_current_cpu)(addr_t physicalAddress,
|
|
|
|
addr_t *_virtualAddress, void **handle);
|
|
|
|
status_t (*put_physical_page_current_cpu)(addr_t virtualAddress,
|
|
|
|
void *handle);
|
|
|
|
|
|
|
|
// get/put virtual address for physical in KDL
|
|
|
|
status_t (*get_physical_page_debug)(addr_t physicalAddress,
|
|
|
|
addr_t *_virtualAddress, void **handle);
|
|
|
|
status_t (*put_physical_page_debug)(addr_t virtualAddress, void *handle);
|
|
|
|
|
|
|
|
// memory operations on pages
|
|
|
|
status_t (*memset_physical)(addr_t address, int value, size_t length);
|
|
|
|
status_t (*memcpy_from_physical)(void* to, addr_t from, size_t length,
|
|
|
|
bool user);
|
|
|
|
status_t (*memcpy_to_physical)(addr_t to, const void* from, size_t length,
|
|
|
|
bool user);
|
|
|
|
void (*memcpy_physical_page)(addr_t to, addr_t from);
|
2002-07-09 16:24:59 +04:00
|
|
|
} vm_translation_map_ops;
|
|
|
|
|
2003-10-29 00:10:00 +03:00
|
|
|
#include <arch/vm_translation_map.h>
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-05-03 20:03:26 +04:00
|
|
|
#endif /* KERNEL_VM_TRANSLATION_MAP_H */
|