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
6 #ifndef _KERN_PAGETABLE_H
7 #define _KERN_PAGETABLE_H
10 #include <util/lock.h>
11 #include <arch/pagetable.h>
14 template<typename PTE>
15 class PageTableImpl : public PageTable {
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;
24 // The lock of any page table may nest in the lock of any
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.
37 int toplevel_shift, lastlevel_shift;
39 static uint pages_per_table()
41 return 1 << PTE::shift_per_level;
44 static uint pages_per_dtable()
46 return 1 << DirPTE::shift_per_level;
49 void end_map(RegionWithOffset region, PTE flags, void *table);
51 void end_unmap(Region region, void *table);
53 void end_set_flags(Region region, PTE flags, PTE mask, void *table);
55 void rec_map(RegionWithOffset region, PTE flags,
56 void *table, int shift);
58 void rec_unmap(Region region, void *table, int shift);
60 void rec_set_flags(Region region, PTE flags,
61 PTE mask, void *table, int shift);
64 PageTableImpl(bool process);
65 PageTableImpl(void *table);
67 virtual ~PageTableImpl();
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_mapping(u64 addr, u64 *phys, Flags *flags);
74 virtual void get_size(u64 *size)
77 *size = 1ULL << (PTE::num_levels * PTE::shift_per_level);
79 *size = 1ULL << (64 - PTE::page_shift);