]> git.buserror.net Git - polintos/scott/priv.git/blob - kernel/include/kern/pagetable.h
a1cd84b391fc08751ac6caef3cc95523212ed8e0
[polintos/scott/priv.git] / kernel / include / kern / pagetable.h
1 // This is a generic pagetable implementation that most architectures
2 // should be able to use as is, though architectures with weird paging
3 // hardware can provide their own implementation.  It corresponds to
4 // mem/pagetable.cc.
5
6 #ifndef _KERN_PAGETABLE_H
7 #define _KERN_PAGETABLE_H
8
9 #include <kern/mem.h>
10 #include <util/lock.h>
11 #include <arch/pagetable.h>
12
13 namespace Mem {
14         template<typename PTE>
15         class PageTableImpl : public PageTable {
16         public:
17                 typedef Mem::PTEFlags Flags;
18                 typedef System::Mem::Region Region;
19                 typedef System::Mem::RegionWithOffset RegionWithOffset;
20                 typedef typename PTE::VirtAddr VirtAddr;
21                 typedef typename PTE::DirPTE DirPTE;
22
23         private:
24                 // The lock of any page table may nest in the lock of any
25                 // aspace.
26                 
27                 Lock::Lock lock;
28                 
29                 // For non-process aspaces, the number of levels may be more or
30                 // less than what the hardware provides (in particular, large file
31                 // mappings on 32-bit targets will need more levels).  For process
32                 // aspaces, num_levels must equal PTE::num_levels.  Levels for
33                 // non-process address spaces can be added dynamically as needed. 
34                 // Non-proc aspaces may also use a different PTE format.
35                 
36                 int num_levels;
37                 int toplevel_shift, lastlevel_shift;
38
39                 static uint pages_per_table()
40                 {
41                         return 1 << PTE::shift_per_level;
42                 }
43                 
44                 static uint pages_per_dtable()
45                 {
46                         return 1 << DirPTE::shift_per_level;
47                 }
48                 
49                 void end_map(RegionWithOffset region, PTE flags, void *table);
50                 
51                 void end_unmap(Region region, void *table);
52
53                 void end_set_flags(Region region, PTE flags, PTE mask, void *table);
54
55                 void rec_map(RegionWithOffset region, PTE flags,
56                              void *table, int shift);
57                 
58                 void rec_unmap(Region region, void *table, int shift);
59
60                 void rec_set_flags(Region region, PTE flags,
61                                    PTE mask, void *table, int shift);
62
63         public:
64                 PageTableImpl(bool process);
65                 PageTableImpl(void *table);
66                 
67                 virtual ~PageTableImpl();
68
69                 virtual void map(RegionWithOffset region, Flags flags);
70                 virtual void unmap(Region region);
71                 virtual void set_flags(Region region, Flags flags, Flags mask);
72                 virtual void get_entry(u64 addr, u64 *phys, Flags *flags);
73
74                 virtual void get_size(u64 *size)
75                 {
76                         if (is_process)
77                                 *size = 1ULL << (PTE::num_levels * PTE::shift_per_level);
78                         else
79                                 *size = 1ULL << (64 - PTE::page_shift);
80                 }
81         };
82 }
83
84 #endif