summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-04-05 21:03:31 +0200
committerbunnei <bunneidev@gmail.com>2020-04-17 06:59:30 +0200
commitdc720311cc4f4a64a979b14759fb20212ab29b69 (patch)
treebb72b32bfedff00c1720a343eeb43ffa6ae253ac /src/core
parentkernel: memory: Add system_control code, which will be used for ASLR support. (diff)
downloadyuzu-dc720311cc4f4a64a979b14759fb20212ab29b69.tar
yuzu-dc720311cc4f4a64a979b14759fb20212ab29b69.tar.gz
yuzu-dc720311cc4f4a64a979b14759fb20212ab29b69.tar.bz2
yuzu-dc720311cc4f4a64a979b14759fb20212ab29b69.tar.lz
yuzu-dc720311cc4f4a64a979b14759fb20212ab29b69.tar.xz
yuzu-dc720311cc4f4a64a979b14759fb20212ab29b69.tar.zst
yuzu-dc720311cc4f4a64a979b14759fb20212ab29b69.zip
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hle/kernel/memory/page_linked_list.h93
2 files changed, 94 insertions, 0 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 92ed3bdcf..3af325c8e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -158,6 +158,7 @@ add_library(core STATIC
hle/kernel/memory/address_space_info.h
hle/kernel/memory/memory_block.h
hle/kernel/memory/memory_types.h
+ hle/kernel/memory/page_linked_list.h
hle/kernel/memory/slab_heap.h
hle/kernel/memory/system_control.cpp
hle/kernel/memory/system_control.h
diff --git a/src/core/hle/kernel/memory/page_linked_list.h b/src/core/hle/kernel/memory/page_linked_list.h
new file mode 100644
index 000000000..0668d00c6
--- /dev/null
+++ b/src/core/hle/kernel/memory/page_linked_list.h
@@ -0,0 +1,93 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <list>
+
+#include "common/assert.h"
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+#include "core/hle/kernel/memory/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<Node>& Nodes() {
+ return nodes;
+ }
+
+ constexpr const std::list<Node>& 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<Node> nodes;
+};
+
+} // namespace Kernel::Memory