+ @staticmethod
+ def get_pfn(ptep):
+ pfn_mask = ((1 << TLB.translation_shift_bits(0)) - 1)
+ return ((ptep & pfn_mask) // TLB.pte_size())
+
+ @staticmethod
+ def get_vfn(ptep):
+ vfn_mask = ((1 << TLB.translation_shift_bits(-1)) - 1)
+ return ((ptep & vfn_mask) // TLB.pte_size())
+
+ @staticmethod
+ def mkptep_for(mnt, va):
+ mnt_mask = ~((1 << TLB.translation_shift_bits(0)) - 1)
+ offset = (TLB.physical_pfn(va) * TLB.pte_size()) & ~mnt_mask
+
+ return (mnt & mnt_mask) | offset
+
+ @staticmethod
+ def ptep_infer_level(ptep):
+ l = 0
+ pfn = PageTable.get_pfn(ptep)
+ pfn = pfn << TLB.translation_shift_bits(-1)
+ vfn = (TLB.pgtable_len() - 1)
+ msk = vfn << TLB.translation_shift_bits(l)
+ max_l = TLB.translation_level()
+
+ mnt = ptep & msk
+
+ while (pfn & msk) == msk:
+ l+=1
+ msk = vfn << TLB.translation_shift_bits(l)
+ if l == max_l:
+ break
+
+ return (max_l - l, mnt)
+
+ @staticmethod
+ def va_at(ptep, level):
+ vms_mask = ((1 << TLB.vaddr_width()) - 1)
+
+ ptep = PageTable.get_pfn(ptep) << TLB.translation_shift_bits(level)
+ return ptep & vms_mask
+
+ @staticmethod
+ def get_l0tep(ptep):
+ return PageTable.get_lntep(ptep, 0)
+
+ @staticmethod
+ def get_lntep(ptep, level):
+ lnmask = (1 << TLB.translation_shift_bits(level)) - 1
+ size = (1 << TLB.translation_shift_bits(-1))
+ vpfn = (lnmask * size) & lnmask
+ offset = ((ptep // TLB.pte_size()) * size // (lnmask + 1)) & (size - 1)
+
+ return (ptep & ~lnmask) | vpfn | (offset * TLB.pte_size())
+
+ @staticmethod
+ def mkptep_at(mnt, va, level):
+ lfmask = (1 << TLB.translation_shift_bits(-1)) - 1
+ lsize = (1 << TLB.translation_shift_bits(level))
+ offset = (va // lsize) * TLB.pte_size()
+
+ return mnt | ((lsize - 1) & ~lfmask) | offset
+
+ @staticmethod
+ def shift_ptep_nextlevel(ptep):
+ mnt_mask = ~((1 << TLB.translation_shift_bits(0)) - 1)
+ size = (1 << TLB.translation_shift_bits(-1))
+ mnt = ptep & mnt_mask
+ vpfn = ((ptep // TLB.pte_size()) * size) & ~mnt_mask
+
+ return mnt | vpfn
+
+ @staticmethod
+ def shift_ptep_prevlevel(ptep):
+ mnt_mask = ~((1 << TLB.translation_shift_bits(0)) - 1)
+ self_mnt = (TLB.pgtable_len() - 1) * (~mnt_mask + 1)
+ unshifted = PageTable.get_pfn(ptep) << TLB.translation_shift_bits(-1)
+ unshifted = PageTable.mkptep_for(self_mnt, unshifted)
+ return PageTable.mkptep_for(ptep & mnt_mask, unshifted)