public static PageAttributes GetPageAttributes (void* page, uint granularity, PageAllocator.Errors* ret_err) { return Pager.GetPageAttributes (page, granularity, ret_err); }
public static PageAttributes GetPageAttributes (void* page, uint granularity, PageAllocator.Errors* ret_err) { uint pde = 0, pte = 0; uint* table = null; if (granularity < 0 || granularity > 1) { *ret_err = PageAllocator.Errors.UnsupportedGranularity; return PageAttributes.None; } Diagnostics.Assert(ADC.Pager.GetPointerGranularity(page) == granularity, "X86.Pager.GetPageAttributes(): bad page pointer alignment!"); PagePtrToTables(page, &pde, &pte); table = PageDirectory; if (granularity == 0) table = (uint*)(table[pde] & (uint)PageAttr.FrameMask); *ret_err = PageAllocator.Errors.Success; return GetAbstractPMA((PageAttr)(table[pde] & (uint)PageAttr.AttributeMask)); }
public static PageAllocator.Errors Setup(uint totalMem, byte* pagemap, uint pagemapLen, PageAllocator.Errors* error) { if (pagemap == null || pagemapLen < ComputeControlReq(totalMem)) { *error = PageAllocator.Errors.UnusablePageControlBuffer; return *error; } uint totalBytes = totalMem * 1024; // more intuitive to think in bytes than in kibibytes PageDirectory = (uint*)pagemap; PageTables = (uint*)(((byte*)PageDirectory) + 4096); uint addr = 0; uint* table = (uint*)PageTables; // Page directory needs to span all 4 GBs // FIXME: What about PAE support might different implementation // uint totalPages = UInt32.MaxValue / 4096; // Each page spans of memory 4MB uint totalTables = 1024; // 1024 * 4MB = 4GB MemoryUtil.MemSet32(0, (uint)PageDirectory, 1024); for (int x = 0; x < totalTables; ++x) { bool needsDirectoryPresent = false; for (int i = 0; i < 1024; ++i) { uint val = (addr & (uint)PageAttr.FrameMask) | (uint)(PageAttr.ReadWrite); if (addr <= totalBytes) { val |= (uint)PageAttr.Present; needsDirectoryPresent = true; } table[i] = val; addr += 4096; } // top-level page directory (level-1) uint pageAddress = (uint)table & (uint)PageAttr.FrameMask; // Make direcory read/write enabled pageAddress |= (uint)PageAttr.ReadWrite; if (needsDirectoryPresent) { // Make directory present if its point to a physical memory already pageAddress |= (uint)PageAttr.Present; } PageDirectory[x] = pageAddress; table += 1024; // 1024 x sizeof(int) = 4k } DMA.Setup((byte*)((uint)pagemap) + pagemapLen); *error = PageAllocator.Errors.Success; return *error; }
public static PageAllocator.Errors Enable(PageAllocator.Errors* error) { if (PageDirectory == null) { *error = PageAllocator.Errors.UnusablePageControlBuffer; return *error; } SetDirectory((uint)PageDirectory); *error = PageAllocator.Errors.Success; return *error; }
public static uint GetGranularitySize(uint granularity, PageAllocator.Errors* ret_err) { if (granularity < 0 || granularity > 1) { *ret_err = PageAllocator.Errors.UnsupportedGranularity; return 0; } *ret_err = PageAllocator.Errors.Success; switch (granularity) { case 0: return 4096; case 1: return 131072; default: *ret_err = PageAllocator.Errors.UnsupportedGranularity; return 0xFFFFFFFF; } }