private static unsafe Addr AllocateGlobalPages(uint pages, AllocatePageOptions options = default) { if (AddProtectedRegions) { pages += 2; } //lock (lockObj) //{ // LockCount++; var physHead = PhysicalPageManager.AllocatePages(pages, options); if (physHead == null) { return(Addr.Zero); } var virtHead = GlobalAllocator.AllocatePages(pages, options); var p = physHead; var v = virtHead; for (var i = 0; i < pages; i++) { var map = true; if (AddProtectedRegions && (i == 0 || i == pages - 1)) { map = false; } if (map) { PageTable.KernelTable.Map(GlobalAllocator.GetAddress(v), PhysicalPageManager.GetAddress(p)); } p = PhysicalPageManager.NextCompoundPage(p); v = GlobalAllocator.NextCompoundPage(v); } PageTable.KernelTable.Flush(); if (AddProtectedRegions) { virtHead = GlobalAllocator.NextCompoundPage(virtHead); } //LockCount--; return(GlobalAllocator.GetAddress(virtHead)); //} }
public static MemoryRegion AllocateRegion(this IPageFrameAllocator allocator, USize size, AllocatePageOptions options = default) { var pages = KMath.DivCeil(size, 4096); var p = allocator.AllocatePages(pages, options); return(new MemoryRegion(allocator.GetAddress(p), pages * 4096)); }
public static unsafe void Map(this IPageTable table, Addr virtAddr, Addr physAddr, IPageFrameAllocator physAllocator, bool present = true, bool flush = false) { var page = physAllocator.GetPageByAddress(physAddr); var pAddr = physAllocator.GetAddress(page); while (true) { table.Map(virtAddr, pAddr, present, flush); page = physAllocator.NextCompoundPage(page); pAddr = physAllocator.GetAddress(page); if (page == null || pAddr == physAddr) { break; } virtAddr += 4096; } }
/// <summary> /// Returns pages, where virtAddr equals physAddr. /// </summary> private static unsafe Addr AllocateIdentityMappedPages(uint pages, AllocatePageOptions options = default) { if (AddProtectedRegions) { pages += 2; } var virtHead = IdentityAllocator.AllocatePages(pages, options); var v = virtHead; for (var i = 0; i < pages; i++) { var addr = IdentityAllocator.GetAddress(v); var map = true; if (AddProtectedRegions && (i == 0 || i == pages - 1)) { map = false; } if (map) { PageTable.KernelTable.Map(addr, addr); } v = IdentityAllocator.NextCompoundPage(v); } PageTable.KernelTable.Flush(); if (AddProtectedRegions) { virtHead = IdentityAllocator.NextCompoundPage(virtHead); } return(IdentityAllocator.GetAddress(virtHead)); }
public static void SelfTest() { if (SelfTestDump) { Default.DumpPages(); } KernelMessage.WriteLine("Begin SelfTest"); var ptrPages = ((BootInfo.Header->InstalledPhysicalMemory / 4096) * 4) / 4096; var ptrList = (Addr *)AllocatePageAddr(ptrPages); // pointers for 4GB of pages var ptrListMapped = (Addr *)0x3000; PageTable.KernelTable.Map(ptrListMapped, ptrList, ptrPages * 4096, true, true); var checkPageCount = Default.FreePages; checkPageCount -= Default.CriticalLowPages; //checkPageCount = 32; var mapAddr = 0x2000u; for (var i = 0; i < checkPageCount; i++) { if (SelfTestDump) { KernelMessage.Write("."); } var testPage = Default.AllocatePage(); var testAddr = Default.GetAddress(testPage); ptrListMapped[i] = testAddr; PageTable.KernelTable.Map(mapAddr, testAddr, 4096, true, true); var mapPtr = (uint *)mapAddr; for (var pos = 0; pos < 1024; pos++) { *mapPtr = 0xEBFEEBFE; mapPtr += 1; } PageTable.KernelTable.UnMap(mapAddr, 4096, true); //Default.Free(testPage); } if (SelfTestDump) { Default.DumpPages(); } KernelMessage.WriteLine("Free Pages now"); for (var i = 0; i < checkPageCount; i++) { if (SelfTestDump) { KernelMessage.Write(":"); } var testAddr = ptrListMapped[i]; Default.FreeAddr(testAddr); } Default.FreeAddr(ptrList); KernelMessage.WriteLine("SelfTest Done"); if (SelfTestDump) { Default.DumpPages(); KernelMessage.WriteLine("Final Dump"); } }
public static Addr AllocatePageAddr(this IPageFrameAllocator allocator, AllocatePageOptions options = default) { return(allocator.GetAddress(allocator.AllocatePage(options))); }
public static void DumpPages(this IPageFrameAllocator allocator) { var sb = new StringBuffer(); sb.Append("Allocator Dump of {0}. TotalPages={1} Free={2}", allocator.DebugName, allocator.TotalPages, allocator.FreePages); for (uint i = 0; i < allocator.TotalPages; i++) { var p = allocator.GetPageByIndex(i); if (i % 64 == 0) { sb.Append("\nIndex={0} Page {1} at {2:X8}, PageStructAddr={3:X8}: ", i, allocator.GetPageNum(p), allocator.GetAddress(p), (uint)p); sb.WriteTo(DeviceManager.Serial1); sb.Clear(); } sb.Append((int)p->Status); sb.WriteTo(DeviceManager.Serial1); sb.Clear(); } DeviceManager.Serial1.Write('\n'); }
public static void DumpPage(this IPageFrameAllocator allocator, Page *p) { KernelMessage.WriteLine("pNum {0}, phys {1:X8} status {2} struct {3:X8} structPage {4}", allocator.GetPageNum(p), allocator.GetAddress(p), (uint)p->Status, (uint)p, (uint)p / 4096); }