From 93109c870e957d495d24d61d94f7761c72f5624f Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 12 Feb 2021 17:26:01 -0800 Subject: hle: kernel: Migrate PageLinkedList to KPageLinkedList. --- src/core/CMakeLists.txt | 2 +- src/core/hle/kernel/k_page_linked_list.h | 92 +++++++++++++++++++++++++++ src/core/hle/kernel/k_shared_memory.cpp | 2 +- src/core/hle/kernel/k_shared_memory.h | 6 +- src/core/hle/kernel/memory/memory_manager.cpp | 6 +- src/core/hle/kernel/memory/memory_manager.h | 10 +-- src/core/hle/kernel/memory/page_linked_list.h | 92 --------------------------- src/core/hle/kernel/memory/page_table.cpp | 30 ++++----- src/core/hle/kernel/memory/page_table.h | 11 ++-- 9 files changed, 127 insertions(+), 124 deletions(-) create mode 100644 src/core/hle/kernel/k_page_linked_list.h delete mode 100644 src/core/hle/kernel/memory/page_linked_list.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a304dd935..70dab3f74 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -171,6 +171,7 @@ add_library(core STATIC hle/kernel/k_memory_block_manager.h hle/kernel/k_memory_layout.h hle/kernel/k_page_bitmap.h + hle/kernel/k_page_linked_list.h hle/kernel/k_priority_queue.h hle/kernel/k_readable_event.cpp hle/kernel/k_readable_event.h @@ -201,7 +202,6 @@ add_library(core STATIC hle/kernel/memory_types.h hle/kernel/memory/memory_manager.cpp hle/kernel/memory/memory_manager.h - hle/kernel/memory/page_linked_list.h hle/kernel/memory/page_heap.cpp hle/kernel/memory/page_heap.h hle/kernel/memory/page_table.cpp diff --git a/src/core/hle/kernel/k_page_linked_list.h b/src/core/hle/kernel/k_page_linked_list.h new file mode 100644 index 000000000..64024d01f --- /dev/null +++ b/src/core/hle/kernel/k_page_linked_list.h @@ -0,0 +1,92 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/assert.h" +#include "common/common_types.h" +#include "core/hle/kernel/memory_types.h" +#include "core/hle/result.h" + +namespace Kernel { + +class KPageLinkedList final { +public: + class Node final { + public: + constexpr Node(u64 addr, std::size_t num_pages) : addr{addr}, num_pages{num_pages} {} + + constexpr u64 GetAddress() const { + return addr; + } + + constexpr std::size_t GetNumPages() const { + return num_pages; + } + + private: + u64 addr{}; + std::size_t num_pages{}; + }; + +public: + KPageLinkedList() = default; + KPageLinkedList(u64 address, u64 num_pages) { + ASSERT(AddBlock(address, num_pages).IsSuccess()); + } + + constexpr std::list& Nodes() { + return nodes; + } + + constexpr const std::list& Nodes() const { + return nodes; + } + + std::size_t GetNumPages() const { + std::size_t num_pages = 0; + for (const Node& node : nodes) { + num_pages += node.GetNumPages(); + } + return num_pages; + } + + bool IsEqual(KPageLinkedList& other) const { + auto this_node = nodes.begin(); + auto other_node = other.nodes.begin(); + while (this_node != nodes.end() && other_node != other.nodes.end()) { + if (this_node->GetAddress() != other_node->GetAddress() || + this_node->GetNumPages() != other_node->GetNumPages()) { + return false; + } + this_node = std::next(this_node); + other_node = std::next(other_node); + } + + return this_node == nodes.end() && other_node == other.nodes.end(); + } + + ResultCode AddBlock(u64 address, u64 num_pages) { + if (!num_pages) { + return RESULT_SUCCESS; + } + if (!nodes.empty()) { + const auto node = nodes.back(); + if (node.GetAddress() + node.GetNumPages() * PageSize == address) { + address = node.GetAddress(); + num_pages += node.GetNumPages(); + nodes.pop_back(); + } + } + nodes.push_back({address, num_pages}); + return RESULT_SUCCESS; + } + +private: + std::list nodes; +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index eb48afe9d..aade52764 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp @@ -20,7 +20,7 @@ KSharedMemory::~KSharedMemory() { std::shared_ptr KSharedMemory::Create( KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, - Memory::PageLinkedList&& page_list, KMemoryPermission owner_permission, + KPageLinkedList&& page_list, KMemoryPermission owner_permission, KMemoryPermission user_permission, PAddr physical_address, std::size_t size, std::string name) { diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 1ecb4f7dd..016e34be5 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h @@ -10,7 +10,7 @@ #include "common/common_types.h" #include "core/device_memory.h" #include "core/hle/kernel/k_memory_block.h" -#include "core/hle/kernel/memory/page_linked_list.h" +#include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/result.h" @@ -26,7 +26,7 @@ public: static std::shared_ptr Create( KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, - Memory::PageLinkedList&& page_list, KMemoryPermission owner_permission, + KPageLinkedList&& page_list, KMemoryPermission owner_permission, KMemoryPermission user_permission, PAddr physical_address, std::size_t size, std::string name); @@ -76,7 +76,7 @@ public: private: Core::DeviceMemory& device_memory; Process* owner_process{}; - Memory::PageLinkedList page_list; + KPageLinkedList page_list; KMemoryPermission owner_permission{}; KMemoryPermission user_permission{}; PAddr physical_address{}; diff --git a/src/core/hle/kernel/memory/memory_manager.cpp b/src/core/hle/kernel/memory/memory_manager.cpp index ffda77374..00d5b15f3 100644 --- a/src/core/hle/kernel/memory/memory_manager.cpp +++ b/src/core/hle/kernel/memory/memory_manager.cpp @@ -8,8 +8,8 @@ #include "common/assert.h" #include "common/common_types.h" #include "common/scope_exit.h" +#include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/memory/memory_manager.h" -#include "core/hle/kernel/memory/page_linked_list.h" #include "core/hle/kernel/svc_results.h" namespace Kernel::Memory { @@ -80,7 +80,7 @@ VAddr MemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_ return allocated_block; } -ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pages, Pool pool, +ResultCode MemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, Direction dir) { ASSERT(page_list.GetNumPages() == 0); @@ -149,7 +149,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa return RESULT_SUCCESS; } -ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, Pool pool, +ResultCode MemoryManager::Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, Direction dir) { // Early return if we're freeing no pages if (!num_pages) { diff --git a/src/core/hle/kernel/memory/memory_manager.h b/src/core/hle/kernel/memory/memory_manager.h index 80dfbc8c2..d090979bd 100644 --- a/src/core/hle/kernel/memory/memory_manager.h +++ b/src/core/hle/kernel/memory/memory_manager.h @@ -13,9 +13,11 @@ #include "core/hle/kernel/memory/page_heap.h" #include "core/hle/result.h" -namespace Kernel::Memory { +namespace Kernel { +class KPageLinkedList; +} -class PageLinkedList; +namespace Kernel::Memory { class MemoryManager final : NonCopyable { public: @@ -48,9 +50,9 @@ public: void InitializeManager(Pool pool, u64 start_address, u64 end_address); VAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); - ResultCode Allocate(PageLinkedList& page_list, std::size_t num_pages, Pool pool, + ResultCode Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, Direction dir = Direction::FromFront); - ResultCode Free(PageLinkedList& page_list, std::size_t num_pages, Pool pool, + ResultCode Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, Direction dir = Direction::FromFront); static constexpr std::size_t MaxManagerCount = 10; diff --git a/src/core/hle/kernel/memory/page_linked_list.h b/src/core/hle/kernel/memory/page_linked_list.h deleted file mode 100644 index 9b871f15b..000000000 --- a/src/core/hle/kernel/memory/page_linked_list.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2020 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include - -#include "common/assert.h" -#include "common/common_types.h" -#include "core/hle/kernel/memory_types.h" -#include "core/hle/result.h" - -namespace Kernel::Memory { - -class PageLinkedList final { -public: - class Node final { - public: - constexpr Node(u64 addr, std::size_t num_pages) : addr{addr}, num_pages{num_pages} {} - - constexpr u64 GetAddress() const { - return addr; - } - - constexpr std::size_t GetNumPages() const { - return num_pages; - } - - private: - u64 addr{}; - std::size_t num_pages{}; - }; - -public: - PageLinkedList() = default; - PageLinkedList(u64 address, u64 num_pages) { - ASSERT(AddBlock(address, num_pages).IsSuccess()); - } - - constexpr std::list& Nodes() { - return nodes; - } - - constexpr const std::list& Nodes() const { - return nodes; - } - - std::size_t GetNumPages() const { - std::size_t num_pages = 0; - for (const Node& node : nodes) { - num_pages += node.GetNumPages(); - } - return num_pages; - } - - bool IsEqual(PageLinkedList& other) const { - auto this_node = nodes.begin(); - auto other_node = other.nodes.begin(); - while (this_node != nodes.end() && other_node != other.nodes.end()) { - if (this_node->GetAddress() != other_node->GetAddress() || - this_node->GetNumPages() != other_node->GetNumPages()) { - return false; - } - this_node = std::next(this_node); - other_node = std::next(other_node); - } - - return this_node == nodes.end() && other_node == other.nodes.end(); - } - - ResultCode AddBlock(u64 address, u64 num_pages) { - if (!num_pages) { - return RESULT_SUCCESS; - } - if (!nodes.empty()) { - const auto node = nodes.back(); - if (node.GetAddress() + node.GetNumPages() * PageSize == address) { - address = node.GetAddress(); - num_pages += node.GetNumPages(); - nodes.pop_back(); - } - } - nodes.push_back({address, num_pages}); - return RESULT_SUCCESS; - } - -private: - std::list nodes; -}; - -} // namespace Kernel::Memory diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 183482648..c1efc23de 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -9,11 +9,11 @@ #include "core/hle/kernel/k_address_space_info.h" #include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_memory_block_manager.h" +#include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_system_control.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/memory/page_linked_list.h" #include "core/hle/kernel/memory/page_table.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" @@ -285,7 +285,7 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemoryS return ResultInvalidCurrentMemory; } - PageLinkedList page_linked_list; + KPageLinkedList page_linked_list; CASCADE_CODE( system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)); @@ -311,7 +311,7 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: return ResultInvalidCurrentMemory; } - PageLinkedList page_linked_list; + KPageLinkedList page_linked_list; AddRegionToPages(src_addr, num_pages, page_linked_list); { @@ -363,7 +363,7 @@ ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std return RESULT_SUCCESS; } -void PageTable::MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, VAddr end) { +void PageTable::MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end) { auto node{page_linked_list.Nodes().begin()}; PAddr map_addr{node->GetAddress()}; std::size_t src_num_pages{node->GetNumPages()}; @@ -423,7 +423,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { return ResultResourceLimitedExceeded; } - PageLinkedList page_linked_list; + KPageLinkedList page_linked_list; CASCADE_CODE( system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, memory_pool)); @@ -485,7 +485,7 @@ ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) { const VAddr end_addr{addr + size}; ResultCode result{RESULT_SUCCESS}; - PageLinkedList page_linked_list; + KPageLinkedList page_linked_list; // Unmap each region within the range block_manager->IterateForRange(addr, end_addr, [&](const KMemoryInfo& info) { @@ -529,7 +529,7 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { return ResultInvalidCurrentMemory; } - PageLinkedList page_linked_list; + KPageLinkedList page_linked_list; const std::size_t num_pages{size / PageSize}; AddRegionToPages(src_addr, num_pages, page_linked_list); @@ -570,8 +570,8 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { KMemoryPermission::None, KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); - PageLinkedList src_pages; - PageLinkedList dst_pages; + KPageLinkedList src_pages; + KPageLinkedList dst_pages; const std::size_t num_pages{size / PageSize}; AddRegionToPages(src_addr, num_pages, src_pages); @@ -597,7 +597,7 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { return RESULT_SUCCESS; } -ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_list, +ResultCode PageTable::MapPages(VAddr addr, const KPageLinkedList& page_linked_list, KMemoryPermission perm) { VAddr cur_addr{addr}; @@ -619,7 +619,7 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis return RESULT_SUCCESS; } -ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, KMemoryState state, +ResultCode PageTable::MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, KMemoryPermission perm) { std::lock_guard lock{page_table_lock}; @@ -793,7 +793,7 @@ ResultVal PageTable::SetHeapSize(std::size_t size) { return ResultResourceLimitedExceeded; } - PageLinkedList page_linked_list; + KPageLinkedList page_linked_list; const std::size_t num_pages{delta / PageSize}; CASCADE_CODE( @@ -841,7 +841,7 @@ ResultVal PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s if (is_map_only) { CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); } else { - PageLinkedList page_group; + KPageLinkedList page_group; CASCADE_CODE( system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool)); CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)); @@ -924,7 +924,7 @@ bool PageTable::IsRegionContiguous(VAddr addr, u64 size) const { } void PageTable::AddRegionToPages(VAddr start, std::size_t num_pages, - PageLinkedList& page_linked_list) { + KPageLinkedList& page_linked_list) { VAddr addr{start}; while (addr < start + (num_pages * PageSize)) { const PAddr paddr{GetPhysicalAddr(addr)}; @@ -945,7 +945,7 @@ VAddr PageTable::AllocateVirtualMemory(VAddr start, std::size_t region_num_pages IsKernel() ? 1 : 4); } -ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, const PageLinkedList& page_group, +ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, const KPageLinkedList& page_group, OperationType operation) { std::lock_guard lock{page_table_lock}; diff --git a/src/core/hle/kernel/memory/page_table.h b/src/core/hle/kernel/memory/page_table.h index a4914d050..736583b81 100644 --- a/src/core/hle/kernel/memory/page_table.h +++ b/src/core/hle/kernel/memory/page_table.h @@ -40,7 +40,7 @@ public: ResultCode UnmapMemory(VAddr addr, std::size_t size); ResultCode Map(VAddr dst_addr, VAddr src_addr, std::size_t size); ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size); - ResultCode MapPages(VAddr addr, PageLinkedList& page_linked_list, KMemoryState state, + ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, KMemoryPermission perm); ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); KMemoryInfo QueryInfo(VAddr addr); @@ -79,15 +79,16 @@ private: KMemoryAttribute::DeviceShared; ResultCode InitializeMemoryLayout(VAddr start, VAddr end); - ResultCode MapPages(VAddr addr, const PageLinkedList& page_linked_list, KMemoryPermission perm); - void MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, VAddr end); + ResultCode MapPages(VAddr addr, const KPageLinkedList& page_linked_list, + KMemoryPermission perm); + void MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end); bool IsRegionMapped(VAddr address, u64 size); bool IsRegionContiguous(VAddr addr, u64 size) const; - void AddRegionToPages(VAddr start, std::size_t num_pages, PageLinkedList& page_linked_list); + void AddRegionToPages(VAddr start, std::size_t num_pages, KPageLinkedList& page_linked_list); KMemoryInfo QueryInfoImpl(VAddr addr); VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages, std::size_t align); - ResultCode Operate(VAddr addr, std::size_t num_pages, const PageLinkedList& page_group, + ResultCode Operate(VAddr addr, std::size_t num_pages, const KPageLinkedList& page_group, OperationType operation); ResultCode Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm, OperationType operation, PAddr map_addr = 0); -- cgit v1.2.3