]> git.buserror.net Git - polintos/scott/priv.git/blobdiff - kernel/include/kern/pagetable.h
update
[polintos/scott/priv.git] / kernel / include / kern / pagetable.h
index 436a81c23fd49c6094883e190140f84a537323d2..691ada0271c9c37311ad48e98d37778ba56c106b 100644 (file)
@@ -1,83 +1,55 @@
-// This is a generic pagetable implementation that most architectures
-// should be able to use as is, though architectures with weird paging
-// hardware can provide their own implementation.  It corresponds to
-// mem/pagetable.cc.
-
 #ifndef _KERN_PAGETABLE_H
 #define _KERN_PAGETABLE_H
 
 #include <kern/mem.h>
-#include <util/lock.h>
-#include <arch/pagetable.h>
+#include <kern/rmap.h>
 
 namespace Mem {
-       template<typename PTE>
-       class PageTableImpl : public PageTable {
+       class PageTable {
        public:
+               void *toplevel;
+               RMapTable rmap_table;
+               const bool is_process;
+
                typedef Mem::PTEFlags Flags;
                typedef System::Mem::Region Region;
                typedef System::Mem::RegionWithOffset RegionWithOffset;
-               typedef typename PTE::VirtAddr VirtAddr;
-               typedef typename PTE::DirPTE DirPTE;
-
-       private:
-               // The lock of any page table may nest in the lock of any
-               // aspace.
                
-               Lock::Lock lock;
-               
-               // For non-process aspaces, the number of levels may be more or
-               // less than what the hardware provides (in particular, large file
-               // mappings on 32-bit targets will need more levels).  For process
-               // aspaces, num_levels must equal PTE::num_levels.  Levels for
-               // non-process address spaces can be added dynamically as needed. 
-               // Non-proc aspaces may also use a different PTE format.
-               
-               int num_levels;
-               int toplevel_shift, lastlevel_shift;
-
-               static uint pages_per_table()
+               PageTable(bool process) : is_process(process)
                {
-                       return 1 << PTE::shift_per_level;
                }
-               
-               static uint pages_per_dtable()
+
+               virtual ~PageTable()
                {
-                       return 1 << DirPTE::shift_per_level;
                }
                
-               void end_map(RegionWithOffset region, PTE flags, void *table);
-               
-               void end_unmap(Region region, void *table);
+               // Region is virtual, offset is physical
+               virtual void map(RegionWithOffset region, Flags flags) = 0;
+               virtual void unmap(Region region) = 0;
 
-               void end_set_flags(Region region, PTE flags, PTE mask, void *table);
-
-               void rec_map(RegionWithOffset region, PTE flags,
-                            void *table, int shift);
+               // Sets the flags which are set in mask to their value in flags.
+               // Flags not set in mask are untouched.
                
-               void rec_unmap(Region region, void *table, int shift);
-
-               void rec_set_flags(Region region, PTE flags,
-                                  PTE mask, void *table, int shift);
-
-       public:
-               PageTableImpl(bool process);
-               PageTableImpl(void *table);
+               virtual void set_flags(Region region, Flags flags, Flags mask) = 0;
                
-               virtual ~PageTableImpl();
-
-               virtual void map(RegionWithOffset region, Flags flags);
-               virtual void unmap(Region region);
-               virtual void set_flags(Region region, Flags flags, Flags mask);
-               virtual void get_mapping(u64 addr, u64 *phys, Flags *flags);
-
-               virtual void get_size(u64 *size)
-               {
-                       if (is_process)
-                               *size = 1ULL << (PTE::num_levels * PTE::shift_per_level);
-                       else
-                               *size = 1ULL << (64 - PTE::page_shift);
-               }
+               // Returns the physical address and flags associated with a given
+               // virtual address.  If flags.Valid is not set, then phys and all
+               // other flags are undefined.  This function is mainly used for
+               // propagating stacked aspace PTEs.
+               
+               virtual void get_mapping(u64 vaddr, u64 *phys, Flags *flags) = 0;
+               
+               virtual void get_size(u64 *size) = 0;
+               
+               // This is called when a PTE is replaced.  It handles refcounting,
+               // dirty page queueing, and TLB invalidation.  vaddr is only
+               // valid for process address spaces, so it doesn't need to be
+               // 64-bit (except on 64-bit hardware, of course).  When it is
+               // known that only flags are changing, set no_release so that
+               // the page refcount is not decremented.
+               
+               void kill_pte(ulong vaddr, u64 physaddr, bool dirty, bool valid,
+                             bool no_release);
        };
 }