diff --git a/zion/lib/memory_mapping_tree.cpp b/zion/lib/memory_mapping_tree.cpp index ead2ff6..91259ff 100644 --- a/zion/lib/memory_mapping_tree.cpp +++ b/zion/lib/memory_mapping_tree.cpp @@ -55,9 +55,6 @@ glcr::ErrorCode MemoryMappingTree::FreeMemoryRange(uint64_t vaddr_base, auto find_or = mapping_tree_.Find(vaddr_base); if (find_or) { - dbgln("Mem addr {x} refcnt {}", - (uint64_t)find_or.value().get().mem_object.get(), - find_or.value().get().mem_object->ref_count()); mapping_tree_.Delete(vaddr_base); } while (true) { diff --git a/zion/loader/init_loader.cpp b/zion/loader/init_loader.cpp index 5a7fa3e..c7157eb 100644 --- a/zion/loader/init_loader.cpp +++ b/zion/loader/init_loader.cpp @@ -130,8 +130,8 @@ void WriteInitProgram(glcr::RefPtr port, glcr::String name, uint64_t id) { glcr::ErrorCode WritePciVmmo(glcr::RefPtr port, uint64_t id) { ASSIGN_OR_RETURN(PcieConfiguration config, GetPciExtendedConfiguration()); - auto vmmo = - glcr::MakeRefCounted(config.base, config.offset); + auto vmmo = glcr::MakeRefCounted(config.base, + config.offset, false); port->WriteKernel(id, MakeRefCounted(vmmo)); diff --git a/zion/memory/physical_memory.cpp b/zion/memory/physical_memory.cpp index a833c52..526c09f 100644 --- a/zion/memory/physical_memory.cpp +++ b/zion/memory/physical_memory.cpp @@ -4,6 +4,7 @@ #include "boot/boot_info.h" #include "debug/debug.h" +#include "memory/constants.h" #define K_PHYS_DEBUG 0 @@ -49,7 +50,7 @@ class PhysicalMemoryManager { #endif size -= bootstrap_used; } - AddMemoryRegion(base, size); + AddMemoryRegion(base, size / kPageSize); } } } @@ -65,7 +66,7 @@ class PhysicalMemoryManager { MemBlock& block = memory_blocks.PeekFront(); uint64_t page = block.base; - block.base += 0x1000; + block.base += kPageSize; block.num_pages--; if (block.num_pages == 0) { memory_blocks.PopFront(); @@ -97,7 +98,7 @@ class PhysicalMemoryManager { } uint64_t page = iter->base; - iter->base += num_pages * 0x1000; + iter->base += num_pages * kPageSize; iter->num_pages -= num_pages; #if K_PHYS_DEBUG dbgln("Continuous {x}:{}", page, num_pages); @@ -105,11 +106,17 @@ class PhysicalMemoryManager { allocated_pages_ += num_pages; return page; } + void FreePage(uint64_t page) { - AddMemoryRegion(page, 0x1000); + AddMemoryRegion(page, 1); allocated_pages_--; } + void FreePages(uint64_t page, uint64_t num_pages) { + AddMemoryRegion(page, num_pages); + allocated_pages_ -= num_pages; + } + uint64_t AllocatedPages() { return allocated_pages_; } uint64_t AvailablePages() { @@ -130,10 +137,10 @@ class PhysicalMemoryManager { uint64_t allocated_pages_ = 0; - void AddMemoryRegion(uint64_t base, uint64_t size) { + void AddMemoryRegion(uint64_t base, uint64_t num_pages) { MemBlock block{ .base = base, - .num_pages = size >> 12, + .num_pages = num_pages, }; memory_blocks.PushFront(block); } @@ -232,8 +239,22 @@ uint64_t AllocateContinuous(uint64_t num_continuous) { return gPmm->AllocateContinuous(num_continuous); } +void FreePage(uint64_t page) { + if (gPmm == nullptr) { + panic("No physical memory manager!"); + } + gPmm->FreePage(page); +} + +void FreePages(uint64_t page, uint64_t num_pages) { + if (gPmm == nullptr) { + panic("No physical memory manager!"); + } + gPmm->FreePages(page, num_pages); +} + void DumpPhysicalMemoryUsage() { - dbgln("Pages used: {} MiB, avail: {} MiB", gPmm->AllocatedPages() / 256, + dbgln("Pages used: {} KiB, avail: {} MiB", gPmm->AllocatedPages() * 4, gPmm->AvailablePages() / 256); } diff --git a/zion/memory/physical_memory.h b/zion/memory/physical_memory.h index 02d932b..cd5106c 100644 --- a/zion/memory/physical_memory.h +++ b/zion/memory/physical_memory.h @@ -19,7 +19,9 @@ uint64_t AllocatePage(); uint64_t AllocateAndZeroPage(); uint64_t AllocateContinuous(uint64_t num_pages); + void FreePage(uint64_t page); +void FreePages(uint64_t page, uint64_t num_pages); void DumpPhysicalMemoryUsage(); diff --git a/zion/object/address_space.cpp b/zion/object/address_space.cpp index 171904c..7299118 100644 --- a/zion/object/address_space.cpp +++ b/zion/object/address_space.cpp @@ -14,7 +14,7 @@ glcr::RefPtr AddressSpace::ForRoot() { } AddressSpace::AddressSpace() { - cr3_ = phys_mem::AllocatePage(); + cr3_ = phys_mem::AllocateAndZeroPage(); InitializePml4(cr3_); } diff --git a/zion/object/memory_object.cpp b/zion/object/memory_object.cpp index 62d6520..bfc775a 100644 --- a/zion/object/memory_object.cpp +++ b/zion/object/memory_object.cpp @@ -20,7 +20,13 @@ MemoryObject::MemoryObject(uint64_t size) : size_(size) { } } -MemoryObject::~MemoryObject() { dbgln("Memory Object Freed"); } +MemoryObject::~MemoryObject() { + for (uint64_t page : phys_page_list_) { + if (page != 0) { + phys_mem::FreePage(page); + } + } +} uint64_t MemoryObject::PhysicalPageAtOffset(uint64_t offset) { if (offset > size_) { @@ -70,6 +76,12 @@ uint64_t MemoryObject::PageNumberToPhysAddr(uint64_t page_num) { return *iter; } +FixedMemoryObject::~FixedMemoryObject() { + if (should_free_) { + phys_mem::FreePages(physical_addr_, num_pages()); + } +} + glcr::ErrorOr> FixedMemoryObject::Duplicate( uint64_t offset, uint64_t length) { if (offset + length > size()) { @@ -77,5 +89,6 @@ glcr::ErrorOr> FixedMemoryObject::Duplicate( } return glcr::StaticCastRefPtr( - glcr::MakeRefCounted(physical_addr_ + offset, length)); + glcr::MakeRefCounted(physical_addr_ + offset, length, + false)); } diff --git a/zion/object/memory_object.h b/zion/object/memory_object.h index e7bdcdc..fc4f653 100644 --- a/zion/object/memory_object.h +++ b/zion/object/memory_object.h @@ -31,7 +31,7 @@ class MemoryObject : public KernelObject { ~MemoryObject(); uint64_t size() { return size_; } - uint64_t num_pages() { return size_ / 0x1000; } + uint64_t num_pages() { return ((size_ - 1) / 0x1000) + 1; } uint64_t PhysicalPageAtOffset(uint64_t offset); @@ -58,14 +58,20 @@ class MemoryObject : public KernelObject { class FixedMemoryObject : public MemoryObject { public: // FIXME: Validate that this is 4k aligned. - FixedMemoryObject(uint64_t physical_addr, uint64_t size) - : MemoryObject(size, true), physical_addr_(physical_addr) {} + // Create a new class object for should free. + FixedMemoryObject(uint64_t physical_addr, uint64_t size, bool should_free) + : MemoryObject(size, true), + physical_addr_(physical_addr), + should_free_(should_free) {} + + ~FixedMemoryObject(); virtual glcr::ErrorOr> Duplicate( uint64_t offset, uint64_t length) override; private: uint64_t physical_addr_; + bool should_free_; uint64_t PageNumberToPhysAddr(uint64_t page_num) override { return physical_addr_ + (0x1000 * page_num); diff --git a/zion/syscall/memory_object.cpp b/zion/syscall/memory_object.cpp index 5457cb6..b358ee8 100644 --- a/zion/syscall/memory_object.cpp +++ b/zion/syscall/memory_object.cpp @@ -14,7 +14,8 @@ z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req) { z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); uint64_t paddr = req->paddr; - auto vmmo_ref = glcr::MakeRefCounted(paddr, req->size); + auto vmmo_ref = + glcr::MakeRefCounted(paddr, req->size, false); *req->vmmo_cap = curr_proc.AddNewCapability(StaticCastRefPtr(vmmo_ref)); return glcr::OK; @@ -22,8 +23,10 @@ z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) { z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); - uint64_t paddr = phys_mem::AllocateContinuous(((req->size - 1) / 0x1000) + 1); - auto vmmo_ref = glcr::MakeRefCounted(paddr, req->size); + uint64_t num_pages = ((req->size - 1) / 0x1000) + 1; + uint64_t paddr = phys_mem::AllocateContinuous(num_pages); + auto vmmo_ref = + glcr::MakeRefCounted(paddr, req->size, true); *req->vmmo_cap = curr_proc.AddNewCapability(StaticCastRefPtr(vmmo_ref)); *req->paddr = paddr;