[haiku-commits] r35066 - in haiku/trunk: headers/private/kernel/arch headers/private/kernel/arch/ppc headers/private/kernel/arch/x86 headers/private/kernel/vm src/system/kernel/arch/generic ...

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 14 Jan 2010 04:26:13 +0100 (CET)

Author: bonefish
Date: 2010-01-14 04:26:12 +0100 (Thu, 14 Jan 2010)
New Revision: 35066
Changeset: http://dev.haiku-os.org/changeset/35066/haiku

Added:
   haiku/trunk/headers/private/kernel/vm/VMTranslationMap.h
   haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.cpp
   haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.h
   haiku/trunk/src/system/kernel/arch/x86/X86VMTranslationMap.h
   haiku/trunk/src/system/kernel/vm/VMTranslationMap.cpp
Removed:
   haiku/trunk/headers/private/kernel/vm/vm_translation_map.h
Modified:
   haiku/trunk/headers/private/kernel/arch/ppc/arch_vm_translation_map.h
   haiku/trunk/headers/private/kernel/arch/vm_translation_map.h
   haiku/trunk/headers/private/kernel/arch/x86/arch_vm_translation_map.h
   haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h
   haiku/trunk/src/system/kernel/arch/ppc/Jamfile
   haiku/trunk/src/system/kernel/arch/ppc/arch_thread.cpp
   haiku/trunk/src/system/kernel/arch/ppc/arch_vm_translation_map.cpp
   haiku/trunk/src/system/kernel/arch/x86/arch_cpu.cpp
   haiku/trunk/src/system/kernel/arch/x86/arch_thread.cpp
   haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
   haiku/trunk/src/system/kernel/arch/x86/x86_physical_page_mapper.cpp
   haiku/trunk/src/system/kernel/arch/x86/x86_physical_page_mapper.h
   
haiku/trunk/src/system/kernel/arch/x86/x86_physical_page_mapper_large_memory.cpp
   haiku/trunk/src/system/kernel/debug/debug.cpp
   haiku/trunk/src/system/kernel/vm/Jamfile
   haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp
   haiku/trunk/src/system/kernel/vm/vm.cpp
   haiku/trunk/src/system/kernel/vm/vm_page.cpp
Log:
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.


Modified: haiku/trunk/headers/private/kernel/arch/ppc/arch_vm_translation_map.h
===================================================================
--- haiku/trunk/headers/private/kernel/arch/ppc/arch_vm_translation_map.h       
2010-01-13 23:50:53 UTC (rev 35065)
+++ haiku/trunk/headers/private/kernel/arch/ppc/arch_vm_translation_map.h       
2010-01-14 03:26:12 UTC (rev 35066)
@@ -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);

Modified: haiku/trunk/headers/private/kernel/arch/vm_translation_map.h
===================================================================
--- haiku/trunk/headers/private/kernel/arch/vm_translation_map.h        
2010-01-13 23:50:53 UTC (rev 35065)
+++ haiku/trunk/headers/private/kernel/arch/vm_translation_map.h        
2010-01-14 03:26:12 UTC (rev 35066)
@@ -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
 }

Modified: haiku/trunk/headers/private/kernel/arch/x86/arch_vm_translation_map.h
===================================================================
--- haiku/trunk/headers/private/kernel/arch/x86/arch_vm_translation_map.h       
2010-01-13 23:50:53 UTC (rev 35065)
+++ haiku/trunk/headers/private/kernel/arch/x86/arch_vm_translation_map.h       
2010-01-14 03:26:12 UTC (rev 35066)
@@ -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 */

Modified: haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h
===================================================================
--- haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h      2010-01-13 
23:50:53 UTC (rev 35065)
+++ haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h      2010-01-14 
03:26:12 UTC (rev 35066)
@@ -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 @@
                        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 @@
                        int32                           fRefCount;
                        int32                           fFaultCount;
                        int32                           fChangeCount;
-                       vm_translation_map      fTranslationMap;
+                       VMTranslationMap*       fTranslationMap;
                        bool                            fDeleting;
        static  VMAddressSpace*         sKernelAddressSpace;
 };

Added: haiku/trunk/headers/private/kernel/vm/VMTranslationMap.h
===================================================================
--- haiku/trunk/headers/private/kernel/vm/VMTranslationMap.h                    
        (rev 0)
+++ haiku/trunk/headers/private/kernel/vm/VMTranslationMap.h    2010-01-14 
03:26:12 UTC (rev 35066)
@@ -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 */

Added: 
haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.cpp  
                        (rev 0)
+++ haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.cpp  
2010-01-14 03:26:12 UTC (rev 35066)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2010, Ingo Weinhold <ingo_weinhold@xxxxxx>.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "GenericVMPhysicalPageMapper.h"
+
+#include <Errors.h>
+
+#include "generic_vm_physical_page_mapper.h"
+#include "generic_vm_physical_page_ops.h"
+
+
+GenericVMPhysicalPageMapper::GenericVMPhysicalPageMapper()
+{
+}
+
+
+GenericVMPhysicalPageMapper::~GenericVMPhysicalPageMapper()
+{
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::GetPage(addr_t physicalAddress,
+       addr_t* _virtualAddress, void** _handle)
+{
+       return generic_get_physical_page(physicalAddress, _virtualAddress, 0);
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::PutPage(addr_t virtualAddress, void* handle)
+{
+       return generic_put_physical_page(virtualAddress);
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::GetPageCurrentCPU(addr_t physicalAddress,
+       addr_t* _virtualAddress, void** _handle)
+{
+       // TODO:...
+       return B_UNSUPPORTED;
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::PutPageCurrentCPU(addr_t virtualAddress,
+       void* _handle)
+{
+       // TODO:...
+       return B_UNSUPPORTED;
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::GetPageDebug(addr_t physicalAddress,
+       addr_t* _virtualAddress, void** _handle)
+{
+       // TODO:...
+       return B_UNSUPPORTED;
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::PutPageDebug(addr_t virtualAddress, void* handle)
+{
+       // TODO:...
+       return B_UNSUPPORTED;
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::MemsetPhysical(addr_t address, int value,
+       size_t length)
+{
+       return generic_vm_memset_physical(address, value, length);
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::MemcpyFromPhysical(void* to, addr_t from,
+       size_t length, bool user)
+{
+       return generic_vm_memcpy_from_physical(to, from, length, user);
+}
+
+
+status_t
+GenericVMPhysicalPageMapper::MemcpyToPhysical(addr_t to, const void* from,
+       size_t length, bool user)
+{
+       return generic_vm_memcpy_to_physical(to, from, length, user);
+}
+
+
+void
+GenericVMPhysicalPageMapper::MemcpyPhysicalPage(addr_t to, addr_t from)
+{
+       generic_vm_memcpy_physical_page(to, from);
+}

Added: haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.h
===================================================================
--- haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.h    
                        (rev 0)
+++ haiku/trunk/src/system/kernel/arch/generic/GenericVMPhysicalPageMapper.h    
2010-01-14 03:26:12 UTC (rev 35066)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010, Ingo Weinhold <ingo_weinhold@xxxxxx>.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _KERNEL_GENERIC_VM_PHYSICAL_PAGE_MAPPER_CLASS_H
+#define _KERNEL_GENERIC_VM_PHYSICAL_PAGE_MAPPER_CLASS_H
+
+
+#include <vm/VMTranslationMap.h>
+
+
+struct GenericVMPhysicalPageMapper : VMPhysicalPageMapper {
+                                                               
GenericVMPhysicalPageMapper();
+       virtual                                         
~GenericVMPhysicalPageMapper();
+
+       virtual status_t                        GetPage(addr_t physicalAddress,
+                                                                       addr_t* 
_virtualAddress,
+                                                                       void** 
_handle);
+       virtual status_t                        PutPage(addr_t virtualAddress,
+                                                                       void* 
handle);
+
+       virtual status_t                        GetPageCurrentCPU(
+                                                                       addr_t 
physicalAddress,
+                                                                       addr_t* 
_virtualAddress,
+                                                                       void** 
_handle);
+       virtual status_t                        PutPageCurrentCPU(addr_t 
virtualAddress,
+                                                                       void* 
_handle);
+
+       virtual status_t                        GetPageDebug(addr_t 
physicalAddress,
+                                                                       addr_t* 
_virtualAddress,
+                                                                       void** 
_handle);
+       virtual status_t                        PutPageDebug(addr_t 
virtualAddress,
+                                                                       void* 
handle);
+
+       virtual status_t                        MemsetPhysical(addr_t address, 
int value,
+                                                                       size_t 
length);
+       virtual status_t                        MemcpyFromPhysical(void* to, 
addr_t from,
+                                                                       size_t 
length, bool user);
+       virtual status_t                        MemcpyToPhysical(addr_t to, 
const void* from,
+                                                                       size_t 
length, bool user);
+       virtual void                            MemcpyPhysicalPage(addr_t to, 
addr_t from);
+};
+
+
+#endif // _KERNEL_GENERIC_VM_PHYSICAL_PAGE_MAPPER_CLASS_H

Modified: haiku/trunk/src/system/kernel/arch/ppc/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/arch/ppc/Jamfile      2010-01-13 23:50:53 UTC 
(rev 35065)
+++ haiku/trunk/src/system/kernel/arch/ppc/Jamfile      2010-01-14 03:26:12 UTC 
(rev 35066)
@@ -29,6 +29,7 @@
 
        generic_vm_physical_page_mapper.cpp
        generic_vm_physical_page_ops.cpp
+       GenericVMPhysicalPageMapper.cpp
        :
        $(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
 ;

Modified: haiku/trunk/src/system/kernel/arch/ppc/arch_thread.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/ppc/arch_thread.cpp      2010-01-13 
23:50:53 UTC (rev 35065)
+++ haiku/trunk/src/system/kernel/arch/ppc/arch_thread.cpp      2010-01-14 
03:26:12 UTC (rev 35066)
@@ -181,7 +181,7 @@
                if (t_from->team != t_to->team) {
                        // switching to a new address space
                        ppc_translation_map_change_asid(
-                               &t_to->team->address_space->TranslationMap());
+                               t_to->team->address_space->TranslationMap());
                }
        }
 

Modified: haiku/trunk/src/system/kernel/arch/ppc/arch_vm_translation_map.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/ppc/arch_vm_translation_map.cpp  
2010-01-13 23:50:53 UTC (rev 35065)
+++ haiku/trunk/src/system/kernel/arch/ppc/arch_vm_translation_map.cpp  
2010-01-14 03:26:12 UTC (rev 35066)
@@ -53,10 +53,10 @@
        registers (8 - 15) map the kernel addresses, so they remain unchanged.
 
        The range of the virtual address space a team's effective address space
-       is mapped to is defined by its vm_translation_map_arch_info::vsid_base,
+       is mapped to is defined by its PPCVMTranslationMap::fVSIDBase,
        which is the first of the 8 successive VSID values used for the team.
 
-       Which vsid_base values are already taken is defined by the set bits in
+       Which fVSIDBase values are already taken is defined by the set bits in
        the bitmap sVSIDBaseBitmap.
 
 
@@ -85,6 +85,7 @@
 
 #include "generic_vm_physical_page_mapper.h"
 #include "generic_vm_physical_page_ops.h"
+#include "GenericVMPhysicalPageMapper.h"
 
 
 static struct page_table_entry_group *sPageTable;
@@ -92,7 +93,6 @@
 static uint32 sPageTableHashMask;
 static area_id sPageTableArea;
 
-
 // 64 MB of iospace
 #define IOSPACE_SIZE (64*1024*1024)
 // We only have small (4 KB) pages. The only reason for choosing greater chunk
@@ -103,6 +103,7 @@
 
 static addr_t sIOSpaceBase;
 
+static GenericVMPhysicalPageMapper sPhysicalPageMapper;
 
 // The VSID is a 24 bit number. The lower three bits are defined by the
 // (effective) segment number, which leaves us with a 21 bit space of
@@ -112,23 +113,61 @@
 static spinlock sVSIDBaseBitmapLock;
 
 #define VSID_BASE_SHIFT 3
-#define VADDR_TO_VSID(map, vaddr) \
-       ((map)->arch_data->vsid_base + ((vaddr) >> 28))
+#define VADDR_TO_VSID(vsidBase, vaddr) (vsidBase + ((vaddr) >> 28))
 
-// vm_translation object stuff
-typedef struct vm_translation_map_arch_info {
-       int vsid_base;  // used VSIDs are vside_base ... vsid_base + 7
-} vm_translation_map_arch_info;
 
+struct PPCVMTranslationMap : VMTranslationMap {
+                                                               
PPCVMTranslationMap();
+       virtual                                         ~PPCVMTranslationMap();
 
+                       status_t                        Init(bool kernel);
+
+       inline  int                                     VSIDBase() const        
{ return fVSIDBase; }
+
+                       page_table_entry*       LookupPageTableEntry(addr_t 
virtualAddress);
+                       bool                            
RemovePageTableEntry(addr_t virtualAddress);
+
+       virtual status_t                        InitPostSem();
+
+       virtual status_t                        Lock();
+       virtual status_t                        Unlock();
+
+       virtual addr_t                          MappedSize() const;
+       virtual size_t                          MaxPagesNeededToMap(addr_t 
start,
+                                                                       addr_t 
end) const;
+
+       virtual status_t                        Map(addr_t virtualAddress,
+                                                                       addr_t 
physicalAddress,
+                                                                       uint32 
attributes);
+       virtual status_t                        Unmap(addr_t start, addr_t end);
+
+       virtual status_t                        Query(addr_t virtualAddress,
+                                                                       addr_t* 
_physicalAddress,
+                                                                       uint32* 
_flags);
+       virtual status_t                        QueryInterrupt(addr_t 
virtualAddress,
+                                                                       addr_t* 
_physicalAddress,
+                                                                       uint32* 
_flags);
+
+       virtual status_t                        Protect(addr_t base, addr_t top,
+                                                                       uint32 
attributes);
+       virtual status_t                        ClearFlags(addr_t 
virtualAddress,
+                                                                       uint32 
flags);
+
+       virtual void                            Flush();
+
+protected:
+                       int                                     fVSIDBase;
+};
+
+
 void
-ppc_translation_map_change_asid(vm_translation_map *map)
+ppc_translation_map_change_asid(VMTranslationMap *map)
 {
 // this code depends on the kernel being at 0x80000000, fix if we change that
 #if KERNEL_BASE != 0x80000000
 #error fix me
 #endif
-       int vsidBase = map->arch_data->vsid_base;
+       int vsidBase = static_cast<PPCVMTranslationMap*>(map)->VSIDBase();
 
        isync();        // synchronize context
        asm("mtsr       0,%0" : : "g"(vsidBase));
@@ -143,41 +182,7 @@
 }
 
 
-static status_t
-lock_tmap(vm_translation_map *map)
-{
-       recursive_lock_lock(&map->lock);
-       return 0;
-}
-
-
-static status_t
-unlock_tmap(vm_translation_map *map)
-{
-       recursive_lock_unlock(&map->lock);
-       return 0;
-}
-
-
 static void
-destroy_tmap(vm_translation_map *map)
-{
-       if (map->map_count > 0) {
-               panic("vm_translation_map.destroy_tmap: map %p has positive map 
count %ld\n",
-                       map, map->map_count);
-       }
-
-       // mark the vsid base not in use
-       int baseBit = map->arch_data->vsid_base >> VSID_BASE_SHIFT;
-       atomic_and((vint32 *)&sVSIDBaseBitmap[baseBit / 32],
-                       ~(1 << (baseBit % 32)));
-
-       free(map->arch_data);
-       recursive_lock_destroy(&map->lock);
-}
-
-
-static void
 fill_page_table_entry(page_table_entry *entry, uint32 virtualSegmentID,
        addr_t virtualAddress, addr_t physicalAddress, uint8 protection,
        bool secondaryHash)
@@ -207,18 +212,176 @@
 }
 
 
-static size_t
-map_max_pages_need(vm_translation_map *map, addr_t start, addr_t end)
+page_table_entry *
+PPCVMTranslationMap::LookupPageTableEntry(addr_t virtualAddress)
 {
-       return 0;
+       // lookup the vsid based off the va
+       uint32 virtualSegmentID = VADDR_TO_VSID(fVSIDBase, virtualAddress);
+
+//     dprintf("vm_translation_map.lookup_page_table_entry: vsid %ld, va 
0x%lx\n", virtualSegmentID, virtualAddress);
+
+       // Search for the page table entry using the primary hash value
+
+       uint32 hash = page_table_entry::PrimaryHash(virtualSegmentID, 
virtualAddress);
+       page_table_entry_group *group = &sPageTable[hash & sPageTableHashMask];
+
+       for (int i = 0; i < 8; i++) {
+               page_table_entry *entry = &group->entry[i];
+
+               if (entry->virtual_segment_id == virtualSegmentID
+                       && entry->secondary_hash == false
+                       && entry->abbr_page_index == ((virtualAddress >> 22) & 
0x3f))
+                       return entry;
+       }
+
+       // Didn't found it, try the secondary hash value
+
+       hash = page_table_entry::SecondaryHash(hash);
+       group = &sPageTable[hash & sPageTableHashMask];
+
+       for (int i = 0; i < 8; i++) {
+               page_table_entry *entry = &group->entry[i];
+
+               if (entry->virtual_segment_id == virtualSegmentID
+                       && entry->secondary_hash == true
+                       && entry->abbr_page_index == ((virtualAddress >> 22) & 
0x3f))
+                       return entry;
+       }
+
+       return NULL;
 }
 
 
+bool
+PPCVMTranslationMap::RemovePageTableEntry(addr_t virtualAddress)
+{
+       page_table_entry *entry = LookupPageTableEntry(virtualAddress);
+       if (entry) {
+               entry->valid = 0;
+               ppc_sync();
+               tlbie(virtualAddress);
+               eieio();
+               tlbsync();
+               ppc_sync();
+       }
+
+       return entry;
+}
+
+
 static status_t
-map_tmap(vm_translation_map *map, addr_t virtualAddress, addr_t 
physicalAddress, uint32 attributes)
+map_iospace_chunk(addr_t va, addr_t pa, uint32 flags)
 {
+       pa &= ~(B_PAGE_SIZE - 1); // make sure it's page aligned
+       va &= ~(B_PAGE_SIZE - 1); // make sure it's page aligned
+       if (va < sIOSpaceBase || va >= (sIOSpaceBase + IOSPACE_SIZE))
+               panic("map_iospace_chunk: passed invalid va 0x%lx\n", va);
+
+       // map the pages
+       return ppc_map_address_range(va, pa, IOSPACE_CHUNK_SIZE);
+}
+
+
+// #pragma mark -
+
+
+PPCVMTranslationMap::PPCVMTranslationMap()
+{
+}
+
+
+PPCVMTranslationMap::~PPCVMTranslationMap()
+{
+       if (fMapCount > 0) {
+               panic("vm_translation_map.destroy_tmap: map %p has positive map 
count %ld\n",
+                       this, fMapCount);
+       }
+
+       // mark the vsid base not in use
+       int baseBit = fVSIDBase >> VSID_BASE_SHIFT;
+       atomic_and((vint32 *)&sVSIDBaseBitmap[baseBit / 32],
+                       ~(1 << (baseBit % 32)));
+}
+
+
+status_t
+PPCVMTranslationMap::Init(bool kernel)
+{
+       cpu_status state = disable_interrupts();
+       acquire_spinlock(&sVSIDBaseBitmapLock);
+
+       // allocate a VSID base for this one
+       if (kernel) {
+               // The boot loader has set up the segment registers for 
identical
+               // mapping. Two VSID bases are reserved for the kernel: 0 and 
8. The
+               // latter one for mapping the kernel address space 
(0x80000000...), the
+               // former one for the lower addresses required by the Open 
Firmware
+               // services.
+               fVSIDBase = 0;
+               sVSIDBaseBitmap[0] |= 0x3;
+       } else {
+               int i = 0;
+
+               while (i < MAX_VSID_BASES) {
+                       if (sVSIDBaseBitmap[i / 32] == 0xffffffff) {
+                               i += 32;
+                               continue;
+                       }
+                       if ((sVSIDBaseBitmap[i / 32] & (1 << (i % 32))) == 0) {
+                               // we found it
+                               sVSIDBaseBitmap[i / 32] |= 1 << (i % 32);
+                               break;
+                       }
+                       i++;
+               }
+               if (i >= MAX_VSID_BASES)
+                       panic("vm_translation_map_create: out of VSID bases\n");
+               fVSIDBase = i << VSID_BASE_SHIFT;
+       }
+
+       release_spinlock(&sVSIDBaseBitmapLock);
+       restore_interrupts(state);
+
+       return B_OK;
+}
+
+
+status_t
+PPCVMTranslationMap::InitPostSem()
+{
+       return B_OK;
+}
+
+
+status_t
+PPCVMTranslationMap::Lock()
+{
+       recursive_lock_lock(&fLock);
+       return 0;
+}
+
+
+status_t
+PPCVMTranslationMap::Unlock()
+{
+       recursive_lock_unlock(&fLock);
+       return 0;
+}
+
+
+size_t
+PPCVMTranslationMap::MaxPagesNeededToMap(addr_t start, addr_t end) const
+{
+       return 0;
+}
+
+
+status_t
+PPCVMTranslationMap::Map(addr_t virtualAddress, addr_t physicalAddress,
+       uint32 attributes)
+{
        // lookup the vsid based off the va
-       uint32 virtualSegmentID = VADDR_TO_VSID(map, virtualAddress);
+       uint32 virtualSegmentID = VADDR_TO_VSID(fVSIDBase, virtualAddress);
        uint32 protection = 0;
 
        // ToDo: check this
@@ -241,7 +404,7 @@
 
                fill_page_table_entry(entry, virtualSegmentID, virtualAddress, 
physicalAddress,
                        protection, false);
-               map->map_count++;
+               fMapCount++;
                return B_OK;
        }
 
@@ -258,7 +421,7 @@
 
                fill_page_table_entry(entry, virtualSegmentID, virtualAddress, 
physicalAddress,
                        protection, false);
-               map->map_count++;
+               fMapCount++;
                return B_OK;
        }
 
@@ -267,67 +430,9 @@
 }
 
 
-static page_table_entry *
-lookup_page_table_entry(vm_translation_map *map, addr_t virtualAddress)
+status_t
+PPCVMTranslationMap::Unmap(addr_t start, addr_t end)
 {
-       // lookup the vsid based off the va
-       uint32 virtualSegmentID = VADDR_TO_VSID(map, virtualAddress);
-
-//     dprintf("vm_translation_map.lookup_page_table_entry: vsid %ld, va 
0x%lx\n", virtualSegmentID, virtualAddress);
-
-
-       // Search for the page table entry using the primary hash value
-
-       uint32 hash = page_table_entry::PrimaryHash(virtualSegmentID, 
virtualAddress);
-       page_table_entry_group *group = &sPageTable[hash & sPageTableHashMask];
-
-       for (int i = 0; i < 8; i++) {
-               page_table_entry *entry = &group->entry[i];
-
-               if (entry->virtual_segment_id == virtualSegmentID
-                       && entry->secondary_hash == false
-                       && entry->abbr_page_index == ((virtualAddress >> 22) & 
0x3f))
-                       return entry;
-       }
-
-       // Didn't found it, try the secondary hash value
-
-       hash = page_table_entry::SecondaryHash(hash);
-       group = &sPageTable[hash & sPageTableHashMask];
-
-       for (int i = 0; i < 8; i++) {
-               page_table_entry *entry = &group->entry[i];
-
-               if (entry->virtual_segment_id == virtualSegmentID
-                       && entry->secondary_hash == true
-                       && entry->abbr_page_index == ((virtualAddress >> 22) & 
0x3f))
-                       return entry;
-       }
-
-       return NULL;
-}
-
-
-static bool
-remove_page_table_entry(vm_translation_map *map, addr_t virtualAddress)
-{
-       page_table_entry *entry = lookup_page_table_entry(map, virtualAddress);
-       if (entry) {
-               entry->valid = 0;
-               ppc_sync();
-               tlbie(virtualAddress);
-               eieio();
-               tlbsync();
-               ppc_sync();
-       }
-
-       return entry;
-}
-
-
-static status_t
-unmap_tmap(vm_translation_map *map, addr_t start, addr_t end)
-{
        page_table_entry *entry;
 
        start = ROUNDDOWN(start, B_PAGE_SIZE);
@@ -336,8 +441,8 @@
 //     dprintf("vm_translation_map.unmap_tmap: start 0x%lx, end 0x%lx\n", 
start, end);
 
        while (start < end) {
-               if (remove_page_table_entry(map, start))
-                       map->map_count--;
+               if (RemovePageTableEntry(start))
+                       fMapCount--;
 
                start += B_PAGE_SIZE;
        }
@@ -346,8 +451,8 @@
 }
 
 
-static status_t
-query_tmap(vm_translation_map *map, addr_t va, addr_t *_outPhysical, uint32 
*_outFlags)
+status_t
+PPCVMTranslationMap::Query(addr_t va, addr_t *_outPhysical, uint32 *_outFlags)
 {
        page_table_entry *entry;
 
@@ -355,7 +460,7 @@
        *_outFlags = 0;
        *_outPhysical = 0;
 
-       entry = lookup_page_table_entry(map, va);
+       entry = LookupPageTableEntry(va);
        if (entry == NULL)
                return B_NO_ERROR;
 
@@ -375,38 +480,25 @@
 }
 
 
-static status_t
-map_iospace_chunk(addr_t va, addr_t pa, uint32 flags)
+addr_t
+PPCVMTranslationMap::MappedSize() const
 {
-       pa &= ~(B_PAGE_SIZE - 1); // make sure it's page aligned
-       va &= ~(B_PAGE_SIZE - 1); // make sure it's page aligned
-       if (va < sIOSpaceBase || va >= (sIOSpaceBase + IOSPACE_SIZE))
-               panic("map_iospace_chunk: passed invalid va 0x%lx\n", va);
-
-       // map the pages
-       return ppc_map_address_range(va, pa, IOSPACE_CHUNK_SIZE);
+       return fMapCount;
 }
 
 
-static addr_t
-get_mapped_size_tmap(vm_translation_map *map)
+status_t
+PPCVMTranslationMap::Protect(addr_t base, addr_t top, uint32 attributes)
 {
-       return map->map_count;
-}
-
-
-static status_t
-protect_tmap(vm_translation_map *map, addr_t base, addr_t top, uint32 
attributes)
-{
        // XXX finish
        return B_ERROR;
 }
 
 
-static status_t
-clear_flags_tmap(vm_translation_map *map, addr_t virtualAddress, uint32 flags)
+status_t
+PPCVMTranslationMap::ClearFlags(addr_t virtualAddress, uint32 flags)
 {
-       page_table_entry *entry = lookup_page_table_entry(map, virtualAddress);
+       page_table_entry *entry = LookupPageTableEntry(virtualAddress);
        if (entry == NULL)
                return B_NO_ERROR;
 
@@ -434,8 +526,8 @@
 }
 
 
-static void
-flush_tmap(vm_translation_map *map)
+void
+PPCVMTranslationMap::Flush()
 {
 // TODO: arch_cpu_global_TLB_invalidate() is extremely expensive and doesn't
 // even cut it here. We are supposed to invalidate all TLB entries for this
@@ -460,104 +552,32 @@
 }
 
 
-static vm_translation_map_ops tmap_ops = {
-       destroy_tmap,
-       lock_tmap,
-       unlock_tmap,
-       map_max_pages_need,
-       map_tmap,
-       unmap_tmap,
-       query_tmap,
-       query_tmap,
-       get_mapped_size_tmap,
-       protect_tmap,
-       clear_flags_tmap,
-       flush_tmap,
-       get_physical_page_tmap,
-       put_physical_page_tmap,
-       get_physical_page_tmap, // *_current_cpu()
-       put_physical_page_tmap, // *_current_cpu()
-       get_physical_page_tmap, // *_debug()
-       put_physical_page_tmap, // *_debug()
-               // TODO: Replace the *_current_cpu() and *_debug() versions!
-
-       generic_vm_memset_physical,
-       generic_vm_memcpy_from_physical,
-       generic_vm_memcpy_to_physical,
-       generic_vm_memcpy_physical_page
-               // TODO: Verify that this is safe to use!
-};
-
-
 //  #pragma mark -
 //  VM API
 
 
 status_t
-arch_vm_translation_map_init_map(vm_translation_map *map, bool kernel)
+arch_vm_translation_map_create_map(bool kernel, VMTranslationMap** _map)
 {
-       // initialize the new object
-       map->ops = &tmap_ops;
-       map->map_count = 0;
-
-       recursive_lock_init(&map->lock, "translation map");
-
-       map->arch_data = (vm_translation_map_arch_info 
*)malloc(sizeof(vm_translation_map_arch_info));
-       if (map->arch_data == NULL) {
-               if (!kernel)
-                       recursive_lock_destroy(&map->lock);
+       PPCVMTranslationMap* map = new(std::nothrow) PPCVMTranslationMap;
+       if (map == NULL)
                return B_NO_MEMORY;
-       }
 
-       cpu_status state = disable_interrupts();
-       acquire_spinlock(&sVSIDBaseBitmapLock);
-
-       // allocate a VSID base for this one
-       if (kernel) {
-               // The boot loader has set up the segment registers for 
identical
-               // mapping. Two VSID bases are reserved for the kernel: 0 and 
8. The
-               // latter one for mapping the kernel address space 
(0x80000000...), the
-               // former one for the lower addresses required by the Open 
Firmware
-               // services.
-               map->arch_data->vsid_base = 0;
-               sVSIDBaseBitmap[0] |= 0x3;
-       } else {
-               int i = 0;
-
-               while (i < MAX_VSID_BASES) {
-                       if (sVSIDBaseBitmap[i / 32] == 0xffffffff) {
-                               i += 32;
-                               continue;
-                       }
-                       if ((sVSIDBaseBitmap[i / 32] & (1 << (i % 32))) == 0) {
-                               // we found it
-                               sVSIDBaseBitmap[i / 32] |= 1 << (i % 32);
-                               break;
-                       }
-                       i++;
-               }
-               if (i >= MAX_VSID_BASES)
-                       panic("vm_translation_map_create: out of VSID bases\n");
-               map->arch_data->vsid_base = i << VSID_BASE_SHIFT;
+       status_t error = map->Init(kernel);
+       if (error != B_OK) {
+               delete map;

[... truncated: 2523 lines follow ...]

Other related posts:

  • » [haiku-commits] r35066 - in haiku/trunk: headers/private/kernel/arch headers/private/kernel/arch/ppc headers/private/kernel/arch/x86 headers/private/kernel/vm src/system/kernel/arch/generic ... - ingo_weinhold