X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=kernel%2Finclude%2Fkern%2Fpagetable.h;h=691ada0271c9c37311ad48e98d37778ba56c106b;hp=a1cd84b391fc08751ac6caef3cc95523212ed8e0;hb=1ac390fe1e18444008857b056c947710be9621a8;hpb=7da27a216a7f4bb3331fe315cdbec69bfcf2c762 diff --git a/kernel/include/kern/pagetable.h b/kernel/include/kern/pagetable.h index a1cd84b..691ada0 100644 --- a/kernel/include/kern/pagetable.h +++ b/kernel/include/kern/pagetable.h @@ -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 -#include -#include +#include namespace Mem { - template - 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_entry(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); }; }