diff options
author | Liam <byteslice@airmail.cc> | 2024-01-07 19:59:48 +0100 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2024-01-13 00:31:33 +0100 |
commit | f2fed21c1139c8d5c030bc5caee5c612dfe7979f (patch) | |
tree | 4051a2e4e1c34370fa259ecf36783b76ea66a56f /src/core/hle/kernel/k_page_table_base.cpp | |
parent | Merge pull request #12605 from german77/abstract (diff) | |
download | yuzu-f2fed21c1139c8d5c030bc5caee5c612dfe7979f.tar yuzu-f2fed21c1139c8d5c030bc5caee5c612dfe7979f.tar.gz yuzu-f2fed21c1139c8d5c030bc5caee5c612dfe7979f.tar.bz2 yuzu-f2fed21c1139c8d5c030bc5caee5c612dfe7979f.tar.lz yuzu-f2fed21c1139c8d5c030bc5caee5c612dfe7979f.tar.xz yuzu-f2fed21c1139c8d5c030bc5caee5c612dfe7979f.tar.zst yuzu-f2fed21c1139c8d5c030bc5caee5c612dfe7979f.zip |
Diffstat (limited to 'src/core/hle/kernel/k_page_table_base.cpp')
-rw-r--r-- | src/core/hle/kernel/k_page_table_base.cpp | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 73fbda331..f01eaa164 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp @@ -431,9 +431,82 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool m_memory_block_slab_manager)); } +Result KPageTableBase::FinalizeProcess() { + // Only process tables should be finalized. + ASSERT(!this->IsKernel()); + + // HLE processes don't have memory mapped. + R_SUCCEED_IF(m_impl == nullptr); + + // NOTE: Here Nintendo calls an unknown OnFinalize function. + // this->OnFinalize(); + + // NOTE: Here Nintendo calls a second unknown OnFinalize function. + // this->OnFinalize2(); + + // Get implementation objects. + auto& impl = this->GetImpl(); + auto& mm = m_kernel.MemoryManager(); + + // Traverse, freeing all pages. + { + // Get the address space size. + const size_t as_size = this->GetAddressSpaceSize(); + + // Begin the traversal. + TraversalContext context; + TraversalEntry cur_entry = { + .phys_addr = 0, + .block_size = 0, + }; + + bool cur_valid = false; + TraversalEntry next_entry; + bool next_valid; + size_t tot_size = 0; + + next_valid = impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), + this->GetAddressSpaceStart()); + + // Iterate over entries. + while (true) { + if ((!next_valid && !cur_valid) || + (next_valid && cur_valid && + next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size)) { + cur_entry.block_size += next_entry.block_size; + } else { + if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { + mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize); + } + + // Update tracking variables. + tot_size += cur_entry.block_size; + cur_entry = next_entry; + cur_valid = next_valid; + } + + if (cur_entry.block_size + tot_size >= as_size) { + break; + } + + next_valid = + impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)); + } + + // Handle the last block. + if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { + mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize); + } + } + + R_SUCCEED(); +} + void KPageTableBase::Finalize() { + this->FinalizeProcess(); + auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) { - if (Settings::IsFastmemEnabled()) { + if (m_impl->fastmem_arena) { m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size, false); } }; |