aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/memory
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2021-02-12 17:38:40 -0800
committerbunnei <bunneidev@gmail.com>2021-02-18 16:16:25 -0800
commitb1e27890e8728c19ceef404aa6352cd6f2913ded (patch)
tree6579ee15eeea8f2ce339a264bef80e5adc5a4dc8 /src/core/hle/kernel/memory
parent93109c870e957d495d24d61d94f7761c72f5624f (diff)
hle: kernel: Migrate MemoryManager to KMemoryManager.
Diffstat (limited to 'src/core/hle/kernel/memory')
-rw-r--r--src/core/hle/kernel/memory/memory_manager.cpp176
-rw-r--r--src/core/hle/kernel/memory/memory_manager.h121
-rw-r--r--src/core/hle/kernel/memory/page_table.cpp2
-rw-r--r--src/core/hle/kernel/memory/page_table.h6
4 files changed, 4 insertions, 301 deletions
diff --git a/src/core/hle/kernel/memory/memory_manager.cpp b/src/core/hle/kernel/memory/memory_manager.cpp
deleted file mode 100644
index 00d5b15f3..000000000
--- a/src/core/hle/kernel/memory/memory_manager.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2020 yuzu Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-
-#include "common/alignment.h"
-#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/svc_results.h"
-
-namespace Kernel::Memory {
-
-std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) {
- const auto size{end_address - start_address};
-
- // Calculate metadata sizes
- const auto ref_count_size{(size / PageSize) * sizeof(u16)};
- const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)};
- const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)};
- const auto page_heap_size{PageHeap::CalculateManagementOverheadSize(size)};
- const auto total_metadata_size{manager_size + page_heap_size};
- ASSERT(manager_size <= total_metadata_size);
- ASSERT(Common::IsAligned(total_metadata_size, PageSize));
-
- // Setup region
- pool = new_pool;
-
- // Initialize the manager's KPageHeap
- heap.Initialize(start_address, size, page_heap_size);
-
- // Free the memory to the heap
- heap.Free(start_address, size / PageSize);
-
- // Update the heap's used size
- heap.UpdateUsedSize();
-
- return total_metadata_size;
-}
-
-void MemoryManager::InitializeManager(Pool pool, u64 start_address, u64 end_address) {
- ASSERT(pool < Pool::Count);
- managers[static_cast<std::size_t>(pool)].Initialize(pool, start_address, end_address);
-}
-
-VAddr MemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_t align_pages,
- u32 option) {
- // Early return if we're allocating no pages
- if (num_pages == 0) {
- return {};
- }
-
- // Lock the pool that we're allocating from
- const auto [pool, dir] = DecodeOption(option);
- const auto pool_index{static_cast<std::size_t>(pool)};
- std::lock_guard lock{pool_locks[pool_index]};
-
- // Choose a heap based on our page size request
- const s32 heap_index{PageHeap::GetAlignedBlockIndex(num_pages, align_pages)};
-
- // Loop, trying to iterate from each block
- // TODO (bunnei): Support multiple managers
- Impl& chosen_manager{managers[pool_index]};
- VAddr allocated_block{chosen_manager.AllocateBlock(heap_index, false)};
-
- // If we failed to allocate, quit now
- if (!allocated_block) {
- return {};
- }
-
- // If we allocated more than we need, free some
- const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)};
- if (allocated_pages > num_pages) {
- chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages);
- }
-
- return allocated_block;
-}
-
-ResultCode MemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
- Direction dir) {
- ASSERT(page_list.GetNumPages() == 0);
-
- // Early return if we're allocating no pages
- if (num_pages == 0) {
- return RESULT_SUCCESS;
- }
-
- // Lock the pool that we're allocating from
- const auto pool_index{static_cast<std::size_t>(pool)};
- std::lock_guard lock{pool_locks[pool_index]};
-
- // Choose a heap based on our page size request
- const s32 heap_index{PageHeap::GetBlockIndex(num_pages)};
- if (heap_index < 0) {
- return ResultOutOfMemory;
- }
-
- // TODO (bunnei): Support multiple managers
- Impl& chosen_manager{managers[pool_index]};
-
- // Ensure that we don't leave anything un-freed
- auto group_guard = detail::ScopeExit([&] {
- for (const auto& it : page_list.Nodes()) {
- const auto min_num_pages{std::min<size_t>(
- it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)};
- chosen_manager.Free(it.GetAddress(), min_num_pages);
- }
- });
-
- // Keep allocating until we've allocated all our pages
- for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) {
- const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)};
-
- while (num_pages >= pages_per_alloc) {
- // Allocate a block
- VAddr allocated_block{chosen_manager.AllocateBlock(index, false)};
- if (!allocated_block) {
- break;
- }
-
- // Safely add it to our group
- {
- auto block_guard = detail::ScopeExit(
- [&] { chosen_manager.Free(allocated_block, pages_per_alloc); });
-
- if (const ResultCode result{page_list.AddBlock(allocated_block, pages_per_alloc)};
- result.IsError()) {
- return result;
- }
-
- block_guard.Cancel();
- }
-
- num_pages -= pages_per_alloc;
- }
- }
-
- // Only succeed if we allocated as many pages as we wanted
- if (num_pages) {
- return ResultOutOfMemory;
- }
-
- // We succeeded!
- group_guard.Cancel();
- return RESULT_SUCCESS;
-}
-
-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) {
- return RESULT_SUCCESS;
- }
-
- // Lock the pool that we're freeing from
- const auto pool_index{static_cast<std::size_t>(pool)};
- std::lock_guard lock{pool_locks[pool_index]};
-
- // TODO (bunnei): Support multiple managers
- Impl& chosen_manager{managers[pool_index]};
-
- // Free all of the pages
- for (const auto& it : page_list.Nodes()) {
- const auto min_num_pages{std::min<size_t>(
- it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)};
- chosen_manager.Free(it.GetAddress(), min_num_pages);
- }
-
- return RESULT_SUCCESS;
-}
-
-} // namespace Kernel::Memory
diff --git a/src/core/hle/kernel/memory/memory_manager.h b/src/core/hle/kernel/memory/memory_manager.h
deleted file mode 100644
index d090979bd..000000000
--- a/src/core/hle/kernel/memory/memory_manager.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2020 yuzu Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <array>
-#include <mutex>
-#include <tuple>
-
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-#include "core/hle/kernel/memory/page_heap.h"
-#include "core/hle/result.h"
-
-namespace Kernel {
-class KPageLinkedList;
-}
-
-namespace Kernel::Memory {
-
-class MemoryManager final : NonCopyable {
-public:
- enum class Pool : u32 {
- Application = 0,
- Applet = 1,
- System = 2,
- SystemNonSecure = 3,
-
- Count,
-
- Shift = 4,
- Mask = (0xF << Shift),
- };
-
- enum class Direction : u32 {
- FromFront = 0,
- FromBack = 1,
-
- Shift = 0,
- Mask = (0xF << Shift),
- };
-
- MemoryManager() = default;
-
- constexpr std::size_t GetSize(Pool pool) const {
- return managers[static_cast<std::size_t>(pool)].GetSize();
- }
-
- void InitializeManager(Pool pool, u64 start_address, u64 end_address);
-
- VAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option);
- ResultCode Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
- Direction dir = Direction::FromFront);
- ResultCode Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
- Direction dir = Direction::FromFront);
-
- static constexpr std::size_t MaxManagerCount = 10;
-
-public:
- static constexpr u32 EncodeOption(Pool pool, Direction dir) {
- return (static_cast<u32>(pool) << static_cast<u32>(Pool::Shift)) |
- (static_cast<u32>(dir) << static_cast<u32>(Direction::Shift));
- }
-
- static constexpr Pool GetPool(u32 option) {
- return static_cast<Pool>((static_cast<u32>(option) & static_cast<u32>(Pool::Mask)) >>
- static_cast<u32>(Pool::Shift));
- }
-
- static constexpr Direction GetDirection(u32 option) {
- return static_cast<Direction>(
- (static_cast<u32>(option) & static_cast<u32>(Direction::Mask)) >>
- static_cast<u32>(Direction::Shift));
- }
-
- static constexpr std::tuple<Pool, Direction> DecodeOption(u32 option) {
- return std::make_tuple(GetPool(option), GetDirection(option));
- }
-
-private:
- class Impl final : NonCopyable {
- private:
- using RefCount = u16;
-
- private:
- PageHeap heap;
- Pool pool{};
-
- public:
- Impl() = default;
-
- std::size_t Initialize(Pool new_pool, u64 start_address, u64 end_address);
-
- VAddr AllocateBlock(s32 index, bool random) {
- return heap.AllocateBlock(index, random);
- }
-
- void Free(VAddr addr, std::size_t num_pages) {
- heap.Free(addr, num_pages);
- }
-
- constexpr std::size_t GetSize() const {
- return heap.GetSize();
- }
-
- constexpr VAddr GetAddress() const {
- return heap.GetAddress();
- }
-
- constexpr VAddr GetEndAddress() const {
- return heap.GetEndAddress();
- }
- };
-
-private:
- std::array<std::mutex, static_cast<std::size_t>(Pool::Count)> pool_locks;
- std::array<Impl, MaxManagerCount> managers;
-};
-
-} // namespace Kernel::Memory
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp
index c1efc23de..ef9d97413 100644
--- a/src/core/hle/kernel/memory/page_table.cpp
+++ b/src/core/hle/kernel/memory/page_table.cpp
@@ -62,7 +62,7 @@ PageTable::PageTable(Core::System& system) : system{system} {}
ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type,
bool enable_aslr, VAddr code_addr, std::size_t code_size,
- Memory::MemoryManager::Pool pool) {
+ KMemoryManager::Pool pool) {
const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
return KAddressSpaceInfo::GetAddressSpaceStart(address_space_width, type);
diff --git a/src/core/hle/kernel/memory/page_table.h b/src/core/hle/kernel/memory/page_table.h
index 736583b81..a9e850e01 100644
--- a/src/core/hle/kernel/memory/page_table.h
+++ b/src/core/hle/kernel/memory/page_table.h
@@ -11,7 +11,7 @@
#include "common/page_table.h"
#include "core/file_sys/program_metadata.h"
#include "core/hle/kernel/k_memory_block.h"
-#include "core/hle/kernel/memory/memory_manager.h"
+#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/result.h"
namespace Core {
@@ -30,7 +30,7 @@ public:
ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
VAddr code_addr, std::size_t code_size,
- Memory::MemoryManager::Pool pool);
+ KMemoryManager::Pool pool);
ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state,
KMemoryPermission perm);
ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size);
@@ -271,7 +271,7 @@ private:
bool is_kernel{};
bool is_aslr_enabled{};
- MemoryManager::Pool memory_pool{MemoryManager::Pool::Application};
+ KMemoryManager::Pool memory_pool{KMemoryManager::Pool::Application};
Common::PageTable page_table_impl;