Refactored vm_translation_map:
* Pulled the physical page mapping functions out of vm_translation_map into a new interface VMPhysicalPageMapper. * Renamed vm_translation_map to VMTranslationMap and made it a proper C++ class. The functions in the operations vector have become methods. * Added class GenericVMPhysicalPageMapper implementing VMPhysicalPageMapper as far as possible (without actually writing new code). * Adjusted the x86 and the PPC specifics accordingly (untested for the latter). For the other architectures the build is, I'm afraid, seriously broken. The next steps will modify and extend the VMTranslationMap interface, so that it will be possible to fix the bugs in vm_unmap_page[s]() and employ architecture specific optimizations. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35066 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ppc_translation_map_change_asid(vm_translation_map *map);
|
||||
void ppc_translation_map_change_asid(VMTranslationMap *map);
|
||||
|
||||
status_t ppc_map_address_range(addr_t virtualAddress, addr_t physicalAddress,
|
||||
size_t size);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright 2002-2004, The Haiku Team. All rights reserved.
|
||||
** Copyright 2002-2010, The Haiku Team. All rights reserved.
|
||||
** Distributed under the terms of the Haiku License.
|
||||
**
|
||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@@ -9,27 +9,28 @@
|
||||
#define KERNEL_ARCH_VM_TRANSLATION_MAP_H
|
||||
|
||||
|
||||
#include <vm/vm_translation_map.h>
|
||||
#include <vm/VMTranslationMap.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t arch_vm_translation_map_init_map(vm_translation_map *map, bool kernel);
|
||||
status_t arch_vm_translation_map_init_kernel_map_post_sem(vm_translation_map *map);
|
||||
status_t arch_vm_translation_map_create_map(bool kernel,
|
||||
VMTranslationMap** _map);
|
||||
|
||||
status_t arch_vm_translation_map_init(struct kernel_args *args);
|
||||
status_t arch_vm_translation_map_init(struct kernel_args *args,
|
||||
VMPhysicalPageMapper** _physicalPageMapper);
|
||||
status_t arch_vm_translation_map_init_post_area(struct kernel_args *args);
|
||||
status_t arch_vm_translation_map_init_post_sem(struct kernel_args *args);
|
||||
|
||||
// Quick function to map a page in regardless of map context. Used in VM
|
||||
// initialization before most vm data structures exist.
|
||||
status_t arch_vm_translation_map_early_map(struct kernel_args *args, addr_t va, addr_t pa,
|
||||
uint8 attributes, addr_t (*get_free_page)(struct kernel_args *));
|
||||
status_t arch_vm_translation_map_early_map(struct kernel_args *args, addr_t va,
|
||||
addr_t pa, uint8 attributes, addr_t (*get_free_page)(struct kernel_args *));
|
||||
|
||||
bool arch_vm_translation_map_is_kernel_page_accessible(addr_t virtualAddress,
|
||||
uint32 protection);
|
||||
uint32 protection);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void *i386_translation_map_get_pgdir(vm_translation_map *map);
|
||||
void *i386_translation_map_get_pgdir(VMTranslationMap *map);
|
||||
|
||||
#endif /* _KERNEL_ARCH_x86_VM_TRANSLATION_MAP_H */
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#include <OS.h>
|
||||
|
||||
#include <vm/vm_priv.h>
|
||||
#include <vm/vm_translation_map.h>
|
||||
#include <vm/VMArea.h>
|
||||
#include <vm/VMTranslationMap.h>
|
||||
|
||||
|
||||
struct VMAddressSpace {
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
size_t FreeSpace() const { return fFreeSpace; }
|
||||
bool IsBeingDeleted() const { return fDeleting; }
|
||||
|
||||
vm_translation_map& TranslationMap() { return fTranslationMap; }
|
||||
VMTranslationMap* TranslationMap() { return fTranslationMap; }
|
||||
|
||||
status_t ReadLock()
|
||||
{ return rw_lock_read_lock(&fLock); }
|
||||
@@ -129,7 +129,7 @@ protected:
|
||||
int32 fRefCount;
|
||||
int32 fFaultCount;
|
||||
int32 fChangeCount;
|
||||
vm_translation_map fTranslationMap;
|
||||
VMTranslationMap* fTranslationMap;
|
||||
bool fDeleting;
|
||||
static VMAddressSpace* sKernelAddressSpace;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2002-2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef KERNEL_VM_VM_TRANSLATION_MAP_H
|
||||
#define KERNEL_VM_VM_TRANSLATION_MAP_H
|
||||
|
||||
|
||||
#include <kernel.h>
|
||||
#include <lock.h>
|
||||
|
||||
|
||||
struct kernel_args;
|
||||
|
||||
|
||||
struct VMTranslationMap {
|
||||
VMTranslationMap();
|
||||
virtual ~VMTranslationMap();
|
||||
|
||||
virtual status_t InitPostSem() = 0;
|
||||
|
||||
virtual status_t Lock() = 0;
|
||||
virtual status_t Unlock() = 0;
|
||||
|
||||
virtual addr_t MappedSize() const = 0;
|
||||
virtual size_t MaxPagesNeededToMap(addr_t start,
|
||||
addr_t end) const = 0;
|
||||
|
||||
virtual status_t Map(addr_t virtualAddress,
|
||||
addr_t physicalAddress,
|
||||
uint32 attributes) = 0;
|
||||
virtual status_t Unmap(addr_t start, addr_t end) = 0;
|
||||
|
||||
virtual status_t Query(addr_t virtualAddress,
|
||||
addr_t* _physicalAddress,
|
||||
uint32* _flags) = 0;
|
||||
virtual status_t QueryInterrupt(addr_t virtualAddress,
|
||||
addr_t* _physicalAddress,
|
||||
uint32* _flags) = 0;
|
||||
|
||||
virtual status_t Protect(addr_t base, addr_t top,
|
||||
uint32 attributes) = 0;
|
||||
virtual status_t ClearFlags(addr_t virtualAddress,
|
||||
uint32 flags) = 0;
|
||||
|
||||
virtual void Flush() = 0;
|
||||
|
||||
protected:
|
||||
recursive_lock fLock;
|
||||
int32 fMapCount;
|
||||
};
|
||||
|
||||
|
||||
struct VMPhysicalPageMapper {
|
||||
VMPhysicalPageMapper();
|
||||
virtual ~VMPhysicalPageMapper();
|
||||
|
||||
// get/put virtual address for physical page -- will be usuable on all CPUs
|
||||
// (usually more expensive than the *_current_cpu() versions)
|
||||
virtual status_t GetPage(addr_t physicalAddress,
|
||||
addr_t* _virtualAddress,
|
||||
void** _handle) = 0;
|
||||
virtual status_t PutPage(addr_t virtualAddress,
|
||||
void* handle) = 0;
|
||||
|
||||
// get/put virtual address for physical page -- thread must be pinned the
|
||||
// whole time
|
||||
virtual status_t GetPageCurrentCPU(
|
||||
addr_t physicalAddress,
|
||||
addr_t* _virtualAddress,
|
||||
void** _handle) = 0;
|
||||
virtual status_t PutPageCurrentCPU(addr_t virtualAddress,
|
||||
void* _handle) = 0;
|
||||
|
||||
// get/put virtual address for physical in KDL
|
||||
virtual status_t GetPageDebug(addr_t physicalAddress,
|
||||
addr_t* _virtualAddress,
|
||||
void** _handle) = 0;
|
||||
virtual status_t PutPageDebug(addr_t virtualAddress,
|
||||
void* handle) = 0;
|
||||
|
||||
// memory operations on pages
|
||||
virtual status_t MemsetPhysical(addr_t address, int value,
|
||||
size_t length) = 0;
|
||||
virtual status_t MemcpyFromPhysical(void* to, addr_t from,
|
||||
size_t length, bool user) = 0;
|
||||
virtual status_t MemcpyToPhysical(addr_t to, const void* from,
|
||||
size_t length, bool user) = 0;
|
||||
virtual void MemcpyPhysicalPage(addr_t to, addr_t from) = 0;
|
||||
};
|
||||
|
||||
|
||||
#include <arch/vm_translation_map.h>
|
||||
|
||||
#endif /* KERNEL_VM_VM_TRANSLATION_MAP_H */
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2007, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef KERNEL_VM_VM_TRANSLATION_MAP_H
|
||||
#define KERNEL_VM_VM_TRANSLATION_MAP_H
|
||||
|
||||
|
||||
#include <kernel.h>
|
||||
#include <lock.h>
|
||||
|
||||
|
||||
struct kernel_args;
|
||||
|
||||
|
||||
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;
|
||||
} vm_translation_map;
|
||||
|
||||
|
||||
// table of operations the vm may want to do to this mapping
|
||||
typedef struct vm_translation_map_ops {
|
||||
void (*destroy)(vm_translation_map *map);
|
||||
status_t (*lock)(vm_translation_map *map);
|
||||
status_t (*unlock)(vm_translation_map *map);
|
||||
size_t (*map_max_pages_need)(vm_translation_map *map, addr_t start, addr_t end);
|
||||
status_t (*map)(vm_translation_map *map, addr_t va, addr_t pa,
|
||||
uint32 attributes);
|
||||
status_t (*unmap)(vm_translation_map *map, addr_t start, addr_t end);
|
||||
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);
|
||||
addr_t (*get_mapped_size)(vm_translation_map*);
|
||||
status_t (*protect)(vm_translation_map *map, addr_t base, addr_t top,
|
||||
uint32 attributes);
|
||||
status_t (*clear_flags)(vm_translation_map *map, addr_t va, uint32 flags);
|
||||
void (*flush)(vm_translation_map *map);
|
||||
|
||||
// get/put virtual address for physical page -- will be usuable on all CPUs
|
||||
// (usually more expensive than the *_current_cpu() versions)
|
||||
status_t (*get_physical_page)(addr_t physicalAddress,
|
||||
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);
|
||||
} vm_translation_map_ops;
|
||||
|
||||
#include <arch/vm_translation_map.h>
|
||||
|
||||
#endif /* KERNEL_VM_VM_TRANSLATION_MAP_H */
|
||||
Reference in New Issue
Block a user