summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2021-02-27 12:48:35 -0700
committerGravatar GitHub2021-02-27 12:48:35 -0700
commit09f7c355c6d7e3c7845ba96d9704489d2d5853f4 (patch)
treeb12127263c0e4999f0a6e9edfe7f8f25adef9d37
parentMerge pull request #5944 from Morph1984/gc-vibrations (diff)
parenthle: kernel: Migrate PageHeap/PageTable to KPageHeap/KPageTable. (diff)
downloadyuzu-09f7c355c6d7e3c7845ba96d9704489d2d5853f4.tar.gz
yuzu-09f7c355c6d7e3c7845ba96d9704489d2d5853f4.tar.xz
yuzu-09f7c355c6d7e3c7845ba96d9704489d2d5853f4.zip
Merge pull request #5953 from bunnei/memory-refactor-1
Kernel Rework: Memory updates and refactoring (Part 1)
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/alignment.h5
-rw-r--r--src/common/tiny_mt.h250
-rw-r--r--src/core/CMakeLists.txt41
-rw-r--r--src/core/hle/kernel/k_address_space_info.cpp (renamed from src/core/hle/kernel/memory/address_space_info.cpp)60
-rw-r--r--src/core/hle/kernel/k_address_space_info.h (renamed from src/core/hle/kernel/memory/address_space_info.h)15
-rw-r--r--src/core/hle/kernel/k_memory_block.h (renamed from src/core/hle/kernel/memory/memory_block.h)149
-rw-r--r--src/core/hle/kernel/k_memory_block_manager.cpp (renamed from src/core/hle/kernel/memory/memory_block_manager.cpp)60
-rw-r--r--src/core/hle/kernel/k_memory_block_manager.h (renamed from src/core/hle/kernel/memory/memory_block_manager.h)33
-rw-r--r--src/core/hle/kernel/k_memory_layout.h (renamed from src/core/hle/kernel/memory/memory_layout.h)34
-rw-r--r--src/core/hle/kernel/k_memory_manager.cpp (renamed from src/core/hle/kernel/memory/memory_manager.cpp)39
-rw-r--r--src/core/hle/kernel/k_memory_manager.h (renamed from src/core/hle/kernel/memory/memory_manager.h)49
-rw-r--r--src/core/hle/kernel/k_page_bitmap.h279
-rw-r--r--src/core/hle/kernel/k_page_heap.cpp (renamed from src/core/hle/kernel/memory/page_heap.cpp)23
-rw-r--r--src/core/hle/kernel/k_page_heap.h193
-rw-r--r--src/core/hle/kernel/k_page_linked_list.h (renamed from src/core/hle/kernel/memory/page_linked_list.h)14
-rw-r--r--src/core/hle/kernel/k_page_table.cpp (renamed from src/core/hle/kernel/memory/page_table.cpp)592
-rw-r--r--src/core/hle/kernel/k_page_table.h (renamed from src/core/hle/kernel/memory/page_table.h)98
-rw-r--r--src/core/hle/kernel/k_shared_memory.cpp (renamed from src/core/hle/kernel/shared_memory.cpp)29
-rw-r--r--src/core/hle/kernel/k_shared_memory.h (renamed from src/core/hle/kernel/shared_memory.h)24
-rw-r--r--src/core/hle/kernel/k_slab_heap.h (renamed from src/core/hle/kernel/memory/slab_heap.h)21
-rw-r--r--src/core/hle/kernel/k_spin_lock.cpp54
-rw-r--r--src/core/hle/kernel/k_spin_lock.h33
-rw-r--r--src/core/hle/kernel/k_system_control.cpp (renamed from src/core/hle/kernel/memory/system_control.cpp)18
-rw-r--r--src/core/hle/kernel/k_system_control.h19
-rw-r--r--src/core/hle/kernel/k_thread.cpp8
-rw-r--r--src/core/hle/kernel/kernel.cpp88
-rw-r--r--src/core/hle/kernel/kernel.h44
-rw-r--r--src/core/hle/kernel/memory/page_heap.h370
-rw-r--r--src/core/hle/kernel/memory/system_control.h13
-rw-r--r--src/core/hle/kernel/memory_types.h (renamed from src/core/hle/kernel/memory/memory_types.h)4
-rw-r--r--src/core/hle/kernel/process.cpp58
-rw-r--r--src/core/hle/kernel/process.h11
-rw-r--r--src/core/hle/kernel/process_capability.cpp14
-rw-r--r--src/core/hle/kernel/process_capability.h16
-rw-r--r--src/core/hle/kernel/svc.cpp51
-rw-r--r--src/core/hle/kernel/transfer_memory.cpp4
-rw-r--r--src/core/hle/kernel/transfer_memory.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/core/hle/service/hid/hid.h4
-rw-r--r--src/core/hle/service/hid/irs.cpp2
-rw-r--r--src/core/hle/service/hid/irs.h4
-rw-r--r--src/core/hle/service/ldr/ldr.cpp30
-rw-r--r--src/core/hle/service/ns/pl_u.cpp4
-rw-r--r--src/core/hle/service/time/time_sharedmemory.cpp2
-rw-r--r--src/core/hle/service/time/time_sharedmemory.h6
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp2
-rw-r--r--src/core/loader/elf.cpp2
-rw-r--r--src/core/loader/kip.cpp2
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/memory.cpp2
-rw-r--r--src/core/memory.h10
-rw-r--r--src/core/memory/cheat_engine.cpp2
-rw-r--r--src/core/reporter.cpp2
-rw-r--r--src/video_core/memory_manager.cpp2
56 files changed, 1690 insertions, 1212 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index b657506b1..788516ded 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -167,6 +167,7 @@ add_library(common STATIC
167 threadsafe_queue.h 167 threadsafe_queue.h
168 time_zone.cpp 168 time_zone.cpp
169 time_zone.h 169 time_zone.h
170 tiny_mt.h
170 tree.h 171 tree.h
171 uint128.h 172 uint128.h
172 uuid.cpp 173 uuid.cpp
diff --git a/src/common/alignment.h b/src/common/alignment.h
index fb81f10d8..32d796ffa 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -42,6 +42,11 @@ requires std::is_integral_v<T>[[nodiscard]] constexpr bool IsAligned(T value, si
42 return (value & mask) == 0; 42 return (value & mask) == 0;
43} 43}
44 44
45template <typename T, typename U>
46requires std::is_integral_v<T>[[nodiscard]] constexpr T DivideUp(T x, U y) {
47 return (x + (y - 1)) / y;
48}
49
45template <typename T, size_t Align = 16> 50template <typename T, size_t Align = 16>
46class AlignmentAllocator { 51class AlignmentAllocator {
47public: 52public:
diff --git a/src/common/tiny_mt.h b/src/common/tiny_mt.h
new file mode 100644
index 000000000..19ae5b7d6
--- /dev/null
+++ b/src/common/tiny_mt.h
@@ -0,0 +1,250 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8
9#include "common/alignment.h"
10#include "common/common_types.h"
11
12namespace Common {
13
14// Implementation of TinyMT (mersenne twister RNG).
15// Like Nintendo, we will use the sample parameters.
16class TinyMT {
17public:
18 static constexpr std::size_t NumStateWords = 4;
19
20 struct State {
21 std::array<u32, NumStateWords> data{};
22 };
23
24private:
25 static constexpr u32 ParamMat1 = 0x8F7011EE;
26 static constexpr u32 ParamMat2 = 0xFC78FF1F;
27 static constexpr u32 ParamTmat = 0x3793FDFF;
28
29 static constexpr u32 ParamMult = 0x6C078965;
30 static constexpr u32 ParamPlus = 0x0019660D;
31 static constexpr u32 ParamXor = 0x5D588B65;
32
33 static constexpr u32 TopBitmask = 0x7FFFFFFF;
34
35 static constexpr int MinimumInitIterations = 8;
36 static constexpr int NumDiscardedInitOutputs = 8;
37
38 static constexpr u32 XorByShifted27(u32 value) {
39 return value ^ (value >> 27);
40 }
41
42 static constexpr u32 XorByShifted30(u32 value) {
43 return value ^ (value >> 30);
44 }
45
46private:
47 State state{};
48
49private:
50 // Internal API.
51 void FinalizeInitialization() {
52 const u32 state0 = this->state.data[0] & TopBitmask;
53 const u32 state1 = this->state.data[1];
54 const u32 state2 = this->state.data[2];
55 const u32 state3 = this->state.data[3];
56
57 if (state0 == 0 && state1 == 0 && state2 == 0 && state3 == 0) {
58 this->state.data[0] = 'T';
59 this->state.data[1] = 'I';
60 this->state.data[2] = 'N';
61 this->state.data[3] = 'Y';
62 }
63
64 for (int i = 0; i < NumDiscardedInitOutputs; i++) {
65 this->GenerateRandomU32();
66 }
67 }
68
69 u32 GenerateRandomU24() {
70 return (this->GenerateRandomU32() >> 8);
71 }
72
73 static void GenerateInitialValuePlus(TinyMT::State* state, int index, u32 value) {
74 u32& state0 = state->data[(index + 0) % NumStateWords];
75 u32& state1 = state->data[(index + 1) % NumStateWords];
76 u32& state2 = state->data[(index + 2) % NumStateWords];
77 u32& state3 = state->data[(index + 3) % NumStateWords];
78
79 const u32 x = XorByShifted27(state0 ^ state1 ^ state3) * ParamPlus;
80 const u32 y = x + index + value;
81
82 state0 = y;
83 state1 += x;
84 state2 += y;
85 }
86
87 static void GenerateInitialValueXor(TinyMT::State* state, int index) {
88 u32& state0 = state->data[(index + 0) % NumStateWords];
89 u32& state1 = state->data[(index + 1) % NumStateWords];
90 u32& state2 = state->data[(index + 2) % NumStateWords];
91 u32& state3 = state->data[(index + 3) % NumStateWords];
92
93 const u32 x = XorByShifted27(state0 + state1 + state3) * ParamXor;
94 const u32 y = x - index;
95
96 state0 = y;
97 state1 ^= x;
98 state2 ^= y;
99 }
100
101public:
102 constexpr TinyMT() = default;
103
104 // Public API.
105
106 // Initialization.
107 void Initialize(u32 seed) {
108 this->state.data[0] = seed;
109 this->state.data[1] = ParamMat1;
110 this->state.data[2] = ParamMat2;
111 this->state.data[3] = ParamTmat;
112
113 for (int i = 1; i < MinimumInitIterations; i++) {
114 const u32 mixed = XorByShifted30(this->state.data[(i - 1) % NumStateWords]);
115 this->state.data[i % NumStateWords] ^= mixed * ParamMult + i;
116 }
117
118 this->FinalizeInitialization();
119 }
120
121 void Initialize(const u32* seed, int seed_count) {
122 this->state.data[0] = 0;
123 this->state.data[1] = ParamMat1;
124 this->state.data[2] = ParamMat2;
125 this->state.data[3] = ParamTmat;
126
127 {
128 const int num_init_iterations = std::max(seed_count + 1, MinimumInitIterations) - 1;
129
130 GenerateInitialValuePlus(&this->state, 0, seed_count);
131
132 for (int i = 0; i < num_init_iterations; i++) {
133 GenerateInitialValuePlus(&this->state, (i + 1) % NumStateWords,
134 (i < seed_count) ? seed[i] : 0);
135 }
136
137 for (int i = 0; i < static_cast<int>(NumStateWords); i++) {
138 GenerateInitialValueXor(&this->state,
139 (i + 1 + num_init_iterations) % NumStateWords);
140 }
141 }
142
143 this->FinalizeInitialization();
144 }
145
146 // State management.
147 void GetState(TinyMT::State& out) const {
148 out.data = this->state.data;
149 }
150
151 void SetState(const TinyMT::State& state_) {
152 this->state.data = state_.data;
153 }
154
155 // Random generation.
156 void GenerateRandomBytes(void* dst, std::size_t size) {
157 const uintptr_t start = reinterpret_cast<uintptr_t>(dst);
158 const uintptr_t end = start + size;
159 const uintptr_t aligned_start = Common::AlignUp(start, 4);
160 const uintptr_t aligned_end = Common::AlignDown(end, 4);
161
162 // Make sure we're aligned.
163 if (start < aligned_start) {
164 const u32 rnd = this->GenerateRandomU32();
165 std::memcpy(dst, &rnd, aligned_start - start);
166 }
167
168 // Write as many aligned u32s as we can.
169 {
170 u32* cur_dst = reinterpret_cast<u32*>(aligned_start);
171 u32* const end_dst = reinterpret_cast<u32*>(aligned_end);
172
173 while (cur_dst < end_dst) {
174 *(cur_dst++) = this->GenerateRandomU32();
175 }
176 }
177
178 // Handle any leftover unaligned data.
179 if (aligned_end < end) {
180 const u32 rnd = this->GenerateRandomU32();
181 std::memcpy(reinterpret_cast<void*>(aligned_end), &rnd, end - aligned_end);
182 }
183 }
184
185 u32 GenerateRandomU32() {
186 // Advance state.
187 const u32 x0 =
188 (this->state.data[0] & TopBitmask) ^ this->state.data[1] ^ this->state.data[2];
189 const u32 y0 = this->state.data[3];
190 const u32 x1 = x0 ^ (x0 << 1);
191 const u32 y1 = y0 ^ (y0 >> 1) ^ x1;
192
193 const u32 state0 = this->state.data[1];
194 u32 state1 = this->state.data[2];
195 u32 state2 = x1 ^ (y1 << 10);
196 const u32 state3 = y1;
197
198 if ((y1 & 1) != 0) {
199 state1 ^= ParamMat1;
200 state2 ^= ParamMat2;
201 }
202
203 this->state.data[0] = state0;
204 this->state.data[1] = state1;
205 this->state.data[2] = state2;
206 this->state.data[3] = state3;
207
208 // Temper.
209 const u32 t1 = state0 + (state2 >> 8);
210 u32 t0 = state3 ^ t1;
211
212 if ((t1 & 1) != 0) {
213 t0 ^= ParamTmat;
214 }
215
216 return t0;
217 }
218
219 u64 GenerateRandomU64() {
220 const u32 lo = this->GenerateRandomU32();
221 const u32 hi = this->GenerateRandomU32();
222 return (u64{hi} << 32) | u64{lo};
223 }
224
225 float GenerateRandomF32() {
226 // Floats have 24 bits of mantissa.
227 constexpr u32 MantissaBits = 24;
228 return static_cast<float>(GenerateRandomU24()) * (1.0f / (1U << MantissaBits));
229 }
230
231 double GenerateRandomF64() {
232 // Doubles have 53 bits of mantissa.
233 // The smart way to generate 53 bits of random would be to use 32 bits
234 // from the first rnd32() call, and then 21 from the second.
235 // Nintendo does not. They use (32 - 5) = 27 bits from the first rnd32()
236 // call, and (32 - 6) bits from the second. We'll do what they do, but
237 // There's not a clear reason why.
238 constexpr u32 MantissaBits = 53;
239 constexpr u32 Shift1st = (64 - MantissaBits) / 2;
240 constexpr u32 Shift2nd = (64 - MantissaBits) - Shift1st;
241
242 const u32 first = (this->GenerateRandomU32() >> Shift1st);
243 const u32 second = (this->GenerateRandomU32() >> Shift2nd);
244
245 return (1.0 * first * (u64{1} << (32 - Shift2nd)) + second) *
246 (1.0 / (u64{1} << MantissaBits));
247 }
248};
249
250} // namespace Common
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index c6bdf72ec..17f251c37 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -156,6 +156,8 @@ add_library(core STATIC
156 hle/kernel/hle_ipc.h 156 hle/kernel/hle_ipc.h
157 hle/kernel/k_address_arbiter.cpp 157 hle/kernel/k_address_arbiter.cpp
158 hle/kernel/k_address_arbiter.h 158 hle/kernel/k_address_arbiter.h
159 hle/kernel/k_address_space_info.cpp
160 hle/kernel/k_address_space_info.h
159 hle/kernel/k_affinity_mask.h 161 hle/kernel/k_affinity_mask.h
160 hle/kernel/k_condition_variable.cpp 162 hle/kernel/k_condition_variable.cpp
161 hle/kernel/k_condition_variable.h 163 hle/kernel/k_condition_variable.h
@@ -164,6 +166,18 @@ add_library(core STATIC
164 hle/kernel/k_light_condition_variable.h 166 hle/kernel/k_light_condition_variable.h
165 hle/kernel/k_light_lock.cpp 167 hle/kernel/k_light_lock.cpp
166 hle/kernel/k_light_lock.h 168 hle/kernel/k_light_lock.h
169 hle/kernel/k_memory_block.h
170 hle/kernel/k_memory_block_manager.cpp
171 hle/kernel/k_memory_block_manager.h
172 hle/kernel/k_memory_layout.h
173 hle/kernel/k_memory_manager.cpp
174 hle/kernel/k_memory_manager.h
175 hle/kernel/k_page_bitmap.h
176 hle/kernel/k_page_heap.cpp
177 hle/kernel/k_page_heap.h
178 hle/kernel/k_page_linked_list.h
179 hle/kernel/k_page_table.cpp
180 hle/kernel/k_page_table.h
167 hle/kernel/k_priority_queue.h 181 hle/kernel/k_priority_queue.h
168 hle/kernel/k_readable_event.cpp 182 hle/kernel/k_readable_event.cpp
169 hle/kernel/k_readable_event.h 183 hle/kernel/k_readable_event.h
@@ -175,8 +189,15 @@ add_library(core STATIC
175 hle/kernel/k_scoped_lock.h 189 hle/kernel/k_scoped_lock.h
176 hle/kernel/k_scoped_resource_reservation.h 190 hle/kernel/k_scoped_resource_reservation.h
177 hle/kernel/k_scoped_scheduler_lock_and_sleep.h 191 hle/kernel/k_scoped_scheduler_lock_and_sleep.h
192 hle/kernel/k_shared_memory.cpp
193 hle/kernel/k_shared_memory.h
194 hle/kernel/k_slab_heap.h
195 hle/kernel/k_spin_lock.cpp
196 hle/kernel/k_spin_lock.h
178 hle/kernel/k_synchronization_object.cpp 197 hle/kernel/k_synchronization_object.cpp
179 hle/kernel/k_synchronization_object.h 198 hle/kernel/k_synchronization_object.h
199 hle/kernel/k_system_control.cpp
200 hle/kernel/k_system_control.h
180 hle/kernel/k_thread.cpp 201 hle/kernel/k_thread.cpp
181 hle/kernel/k_thread.h 202 hle/kernel/k_thread.h
182 hle/kernel/k_thread_queue.h 203 hle/kernel/k_thread_queue.h
@@ -184,23 +205,7 @@ add_library(core STATIC
184 hle/kernel/k_writable_event.h 205 hle/kernel/k_writable_event.h
185 hle/kernel/kernel.cpp 206 hle/kernel/kernel.cpp
186 hle/kernel/kernel.h 207 hle/kernel/kernel.h
187 hle/kernel/memory/address_space_info.cpp 208 hle/kernel/memory_types.h
188 hle/kernel/memory/address_space_info.h
189 hle/kernel/memory/memory_block.h
190 hle/kernel/memory/memory_block_manager.cpp
191 hle/kernel/memory/memory_block_manager.h
192 hle/kernel/memory/memory_layout.h
193 hle/kernel/memory/memory_manager.cpp
194 hle/kernel/memory/memory_manager.h
195 hle/kernel/memory/memory_types.h
196 hle/kernel/memory/page_linked_list.h
197 hle/kernel/memory/page_heap.cpp
198 hle/kernel/memory/page_heap.h
199 hle/kernel/memory/page_table.cpp
200 hle/kernel/memory/page_table.h
201 hle/kernel/memory/slab_heap.h
202 hle/kernel/memory/system_control.cpp
203 hle/kernel/memory/system_control.h
204 hle/kernel/object.cpp 209 hle/kernel/object.cpp
205 hle/kernel/object.h 210 hle/kernel/object.h
206 hle/kernel/physical_core.cpp 211 hle/kernel/physical_core.cpp
@@ -218,8 +223,6 @@ add_library(core STATIC
218 hle/kernel/service_thread.h 223 hle/kernel/service_thread.h
219 hle/kernel/session.cpp 224 hle/kernel/session.cpp
220 hle/kernel/session.h 225 hle/kernel/session.h
221 hle/kernel/shared_memory.cpp
222 hle/kernel/shared_memory.h
223 hle/kernel/svc.cpp 226 hle/kernel/svc.cpp
224 hle/kernel/svc.h 227 hle/kernel/svc.h
225 hle/kernel/svc_common.h 228 hle/kernel/svc_common.h
diff --git a/src/core/hle/kernel/memory/address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp
index 6cf43ba24..24944d15b 100644
--- a/src/core/hle/kernel/memory/address_space_info.cpp
+++ b/src/core/hle/kernel/k_address_space_info.cpp
@@ -2,15 +2,12 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#include <array> 5#include <array>
9 6
10#include "common/assert.h" 7#include "common/assert.h"
11#include "core/hle/kernel/memory/address_space_info.h" 8#include "core/hle/kernel/k_address_space_info.h"
12 9
13namespace Kernel::Memory { 10namespace Kernel {
14 11
15namespace { 12namespace {
16 13
@@ -28,20 +25,20 @@ enum : u64 {
28}; 25};
29 26
30// clang-format off 27// clang-format off
31constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{ 28constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{
32 { .bit_width = 32, .address = Size_2_MB , .size = Size_1_GB - Size_2_MB , .type = AddressSpaceInfo::Type::Is32Bit, }, 29 { .bit_width = 32, .address = Size_2_MB , .size = Size_1_GB - Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, },
33 { .bit_width = 32, .address = Size_1_GB , .size = Size_4_GB - Size_1_GB , .type = AddressSpaceInfo::Type::Small64Bit, }, 30 { .bit_width = 32, .address = Size_1_GB , .size = Size_4_GB - Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
34 { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = AddressSpaceInfo::Type::Heap, }, 31 { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, },
35 { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = AddressSpaceInfo::Type::Alias, }, 32 { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, },
36 { .bit_width = 36, .address = Size_128_MB, .size = Size_2_GB - Size_128_MB, .type = AddressSpaceInfo::Type::Is32Bit, }, 33 { .bit_width = 36, .address = Size_128_MB, .size = Size_2_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, },
37 { .bit_width = 36, .address = Size_2_GB , .size = Size_64_GB - Size_2_GB , .type = AddressSpaceInfo::Type::Small64Bit, }, 34 { .bit_width = 36, .address = Size_2_GB , .size = Size_64_GB - Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
38 { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = AddressSpaceInfo::Type::Heap, }, 35 { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
39 { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = AddressSpaceInfo::Type::Alias, }, 36 { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, },
40 { .bit_width = 39, .address = Size_128_MB, .size = Size_512_GB - Size_128_MB, .type = AddressSpaceInfo::Type::Large64Bit, }, 37 { .bit_width = 39, .address = Size_128_MB, .size = Size_512_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, },
41 { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = AddressSpaceInfo::Type::Is32Bit }, 38 { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall },
42 { .bit_width = 39, .address = Invalid , .size = Size_6_GB , .type = AddressSpaceInfo::Type::Heap, }, 39 { .bit_width = 39, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
43 { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = AddressSpaceInfo::Type::Alias, }, 40 { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, },
44 { .bit_width = 39, .address = Invalid , .size = Size_2_GB , .type = AddressSpaceInfo::Type::Stack, }, 41 { .bit_width = 39, .address = Invalid , .size = Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, },
45}}; 42}};
46// clang-format on 43// clang-format on
47 44
@@ -49,7 +46,8 @@ constexpr bool IsAllowedIndexForAddress(std::size_t index) {
49 return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Invalid; 46 return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Invalid;
50} 47}
51 48
52using IndexArray = std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)>; 49using IndexArray =
50 std::array<std::size_t, static_cast<std::size_t>(KAddressSpaceInfo::Type::Count)>;
53 51
54constexpr IndexArray AddressSpaceIndices32Bit{ 52constexpr IndexArray AddressSpaceIndices32Bit{
55 0, 1, 0, 2, 0, 3, 53 0, 1, 0, 2, 0, 3,
@@ -63,23 +61,23 @@ constexpr IndexArray AddressSpaceIndices39Bit{
63 9, 8, 8, 10, 12, 11, 61 9, 8, 8, 10, 12, 11,
64}; 62};
65 63
66constexpr bool IsAllowed32BitType(AddressSpaceInfo::Type type) { 64constexpr bool IsAllowed32BitType(KAddressSpaceInfo::Type type) {
67 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit && 65 return type < KAddressSpaceInfo::Type::Count && type != KAddressSpaceInfo::Type::Map39Bit &&
68 type != AddressSpaceInfo::Type::Stack; 66 type != KAddressSpaceInfo::Type::Stack;
69} 67}
70 68
71constexpr bool IsAllowed36BitType(AddressSpaceInfo::Type type) { 69constexpr bool IsAllowed36BitType(KAddressSpaceInfo::Type type) {
72 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit && 70 return type < KAddressSpaceInfo::Type::Count && type != KAddressSpaceInfo::Type::Map39Bit &&
73 type != AddressSpaceInfo::Type::Stack; 71 type != KAddressSpaceInfo::Type::Stack;
74} 72}
75 73
76constexpr bool IsAllowed39BitType(AddressSpaceInfo::Type type) { 74constexpr bool IsAllowed39BitType(KAddressSpaceInfo::Type type) {
77 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Small64Bit; 75 return type < KAddressSpaceInfo::Type::Count && type != KAddressSpaceInfo::Type::MapLarge;
78} 76}
79 77
80} // namespace 78} // namespace
81 79
82u64 AddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) { 80u64 KAddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) {
83 const std::size_t index{static_cast<std::size_t>(type)}; 81 const std::size_t index{static_cast<std::size_t>(type)};
84 switch (width) { 82 switch (width) {
85 case 32: 83 case 32:
@@ -99,7 +97,7 @@ u64 AddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) {
99 return 0; 97 return 0;
100} 98}
101 99
102std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type) { 100std::size_t KAddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type) {
103 const std::size_t index{static_cast<std::size_t>(type)}; 101 const std::size_t index{static_cast<std::size_t>(type)};
104 switch (width) { 102 switch (width) {
105 case 32: 103 case 32:
@@ -116,4 +114,4 @@ std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type)
116 return 0; 114 return 0;
117} 115}
118 116
119} // namespace Kernel::Memory 117} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/address_space_info.h b/src/core/hle/kernel/k_address_space_info.h
index a4e6e91e5..06f31c6d5 100644
--- a/src/core/hle/kernel/memory/address_space_info.h
+++ b/src/core/hle/kernel/k_address_space_info.h
@@ -2,20 +2,17 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once 5#pragma once
9 6
10#include "common/common_types.h" 7#include "common/common_types.h"
11 8
12namespace Kernel::Memory { 9namespace Kernel {
13 10
14struct AddressSpaceInfo final { 11struct KAddressSpaceInfo final {
15 enum class Type : u32 { 12 enum class Type : u32 {
16 Is32Bit = 0, 13 MapSmall = 0,
17 Small64Bit = 1, 14 MapLarge = 1,
18 Large64Bit = 2, 15 Map39Bit = 2,
19 Heap = 3, 16 Heap = 3,
20 Stack = 4, 17 Stack = 4,
21 Alias = 5, 18 Alias = 5,
@@ -31,4 +28,4 @@ struct AddressSpaceInfo final {
31 const Type type{}; 28 const Type type{};
32}; 29};
33 30
34} // namespace Kernel::Memory 31} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/memory_block.h b/src/core/hle/kernel/k_memory_block.h
index 83acece1e..c5b9c5e85 100644
--- a/src/core/hle/kernel/memory/memory_block.h
+++ b/src/core/hle/kernel/k_memory_block.h
@@ -2,20 +2,17 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once 5#pragma once
9 6
10#include "common/alignment.h" 7#include "common/alignment.h"
11#include "common/assert.h" 8#include "common/assert.h"
12#include "common/common_types.h" 9#include "common/common_types.h"
13#include "core/hle/kernel/memory/memory_types.h" 10#include "core/hle/kernel/memory_types.h"
14#include "core/hle/kernel/svc_types.h" 11#include "core/hle/kernel/svc_types.h"
15 12
16namespace Kernel::Memory { 13namespace Kernel {
17 14
18enum class MemoryState : u32 { 15enum class KMemoryState : u32 {
19 None = 0, 16 None = 0,
20 Mask = 0xFF, 17 Mask = 0xFF,
21 All = ~None, 18 All = ~None,
@@ -97,31 +94,31 @@ enum class MemoryState : u32 {
97 FlagReferenceCounted | FlagCanDebug, 94 FlagReferenceCounted | FlagCanDebug,
98 CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted, 95 CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted,
99}; 96};
100DECLARE_ENUM_FLAG_OPERATORS(MemoryState); 97DECLARE_ENUM_FLAG_OPERATORS(KMemoryState);
101 98
102static_assert(static_cast<u32>(MemoryState::Free) == 0x00000000); 99static_assert(static_cast<u32>(KMemoryState::Free) == 0x00000000);
103static_assert(static_cast<u32>(MemoryState::Io) == 0x00002001); 100static_assert(static_cast<u32>(KMemoryState::Io) == 0x00002001);
104static_assert(static_cast<u32>(MemoryState::Static) == 0x00042002); 101static_assert(static_cast<u32>(KMemoryState::Static) == 0x00042002);
105static_assert(static_cast<u32>(MemoryState::Code) == 0x00DC7E03); 102static_assert(static_cast<u32>(KMemoryState::Code) == 0x00DC7E03);
106static_assert(static_cast<u32>(MemoryState::CodeData) == 0x03FEBD04); 103static_assert(static_cast<u32>(KMemoryState::CodeData) == 0x03FEBD04);
107static_assert(static_cast<u32>(MemoryState::Normal) == 0x037EBD05); 104static_assert(static_cast<u32>(KMemoryState::Normal) == 0x037EBD05);
108static_assert(static_cast<u32>(MemoryState::Shared) == 0x00402006); 105static_assert(static_cast<u32>(KMemoryState::Shared) == 0x00402006);
109static_assert(static_cast<u32>(MemoryState::AliasCode) == 0x00DD7E08); 106static_assert(static_cast<u32>(KMemoryState::AliasCode) == 0x00DD7E08);
110static_assert(static_cast<u32>(MemoryState::AliasCodeData) == 0x03FFBD09); 107static_assert(static_cast<u32>(KMemoryState::AliasCodeData) == 0x03FFBD09);
111static_assert(static_cast<u32>(MemoryState::Ipc) == 0x005C3C0A); 108static_assert(static_cast<u32>(KMemoryState::Ipc) == 0x005C3C0A);
112static_assert(static_cast<u32>(MemoryState::Stack) == 0x005C3C0B); 109static_assert(static_cast<u32>(KMemoryState::Stack) == 0x005C3C0B);
113static_assert(static_cast<u32>(MemoryState::ThreadLocal) == 0x0040200C); 110static_assert(static_cast<u32>(KMemoryState::ThreadLocal) == 0x0040200C);
114static_assert(static_cast<u32>(MemoryState::Transferred) == 0x015C3C0D); 111static_assert(static_cast<u32>(KMemoryState::Transferred) == 0x015C3C0D);
115static_assert(static_cast<u32>(MemoryState::SharedTransferred) == 0x005C380E); 112static_assert(static_cast<u32>(KMemoryState::SharedTransferred) == 0x005C380E);
116static_assert(static_cast<u32>(MemoryState::SharedCode) == 0x0040380F); 113static_assert(static_cast<u32>(KMemoryState::SharedCode) == 0x0040380F);
117static_assert(static_cast<u32>(MemoryState::Inaccessible) == 0x00000010); 114static_assert(static_cast<u32>(KMemoryState::Inaccessible) == 0x00000010);
118static_assert(static_cast<u32>(MemoryState::NonSecureIpc) == 0x005C3811); 115static_assert(static_cast<u32>(KMemoryState::NonSecureIpc) == 0x005C3811);
119static_assert(static_cast<u32>(MemoryState::NonDeviceIpc) == 0x004C2812); 116static_assert(static_cast<u32>(KMemoryState::NonDeviceIpc) == 0x004C2812);
120static_assert(static_cast<u32>(MemoryState::Kernel) == 0x00002013); 117static_assert(static_cast<u32>(KMemoryState::Kernel) == 0x00002013);
121static_assert(static_cast<u32>(MemoryState::GeneratedCode) == 0x00402214); 118static_assert(static_cast<u32>(KMemoryState::GeneratedCode) == 0x00402214);
122static_assert(static_cast<u32>(MemoryState::CodeOut) == 0x00402015); 119static_assert(static_cast<u32>(KMemoryState::CodeOut) == 0x00402015);
123 120
124enum class MemoryPermission : u8 { 121enum class KMemoryPermission : u8 {
125 None = 0, 122 None = 0,
126 Mask = static_cast<u8>(~None), 123 Mask = static_cast<u8>(~None),
127 124
@@ -135,9 +132,9 @@ enum class MemoryPermission : u8 {
135 UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write | 132 UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write |
136 Svc::MemoryPermission::Execute), 133 Svc::MemoryPermission::Execute),
137}; 134};
138DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission); 135DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission);
139 136
140enum class MemoryAttribute : u8 { 137enum class KMemoryAttribute : u8 {
141 None = 0x00, 138 None = 0x00,
142 Mask = 0x7F, 139 Mask = 0x7F,
143 All = Mask, 140 All = Mask,
@@ -152,18 +149,18 @@ enum class MemoryAttribute : u8 {
152 LockedAndIpcLocked = Locked | IpcLocked, 149 LockedAndIpcLocked = Locked | IpcLocked,
153 DeviceSharedAndUncached = DeviceShared | Uncached 150 DeviceSharedAndUncached = DeviceShared | Uncached
154}; 151};
155DECLARE_ENUM_FLAG_OPERATORS(MemoryAttribute); 152DECLARE_ENUM_FLAG_OPERATORS(KMemoryAttribute);
156 153
157static_assert((static_cast<u8>(MemoryAttribute::Mask) & 154static_assert((static_cast<u8>(KMemoryAttribute::Mask) &
158 static_cast<u8>(MemoryAttribute::DontCareMask)) == 0); 155 static_cast<u8>(KMemoryAttribute::DontCareMask)) == 0);
159 156
160struct MemoryInfo { 157struct KMemoryInfo {
161 VAddr addr{}; 158 VAddr addr{};
162 std::size_t size{}; 159 std::size_t size{};
163 MemoryState state{}; 160 KMemoryState state{};
164 MemoryPermission perm{}; 161 KMemoryPermission perm{};
165 MemoryAttribute attribute{}; 162 KMemoryAttribute attribute{};
166 MemoryPermission original_perm{}; 163 KMemoryPermission original_perm{};
167 u16 ipc_lock_count{}; 164 u16 ipc_lock_count{};
168 u16 device_use_count{}; 165 u16 device_use_count{};
169 166
@@ -171,9 +168,9 @@ struct MemoryInfo {
171 return { 168 return {
172 addr, 169 addr,
173 size, 170 size,
174 static_cast<Svc::MemoryState>(state & MemoryState::Mask), 171 static_cast<Svc::MemoryState>(state & KMemoryState::Mask),
175 static_cast<Svc::MemoryAttribute>(attribute & MemoryAttribute::Mask), 172 static_cast<Svc::MemoryAttribute>(attribute & KMemoryAttribute::Mask),
176 static_cast<Svc::MemoryPermission>(perm & MemoryPermission::UserMask), 173 static_cast<Svc::MemoryPermission>(perm & KMemoryPermission::UserMask),
177 ipc_lock_count, 174 ipc_lock_count,
178 device_use_count, 175 device_use_count,
179 }; 176 };
@@ -196,21 +193,21 @@ struct MemoryInfo {
196 } 193 }
197}; 194};
198 195
199class MemoryBlock final { 196class KMemoryBlock final {
200 friend class MemoryBlockManager; 197 friend class KMemoryBlockManager;
201 198
202private: 199private:
203 VAddr addr{}; 200 VAddr addr{};
204 std::size_t num_pages{}; 201 std::size_t num_pages{};
205 MemoryState state{MemoryState::None}; 202 KMemoryState state{KMemoryState::None};
206 u16 ipc_lock_count{}; 203 u16 ipc_lock_count{};
207 u16 device_use_count{}; 204 u16 device_use_count{};
208 MemoryPermission perm{MemoryPermission::None}; 205 KMemoryPermission perm{KMemoryPermission::None};
209 MemoryPermission original_perm{MemoryPermission::None}; 206 KMemoryPermission original_perm{KMemoryPermission::None};
210 MemoryAttribute attribute{MemoryAttribute::None}; 207 KMemoryAttribute attribute{KMemoryAttribute::None};
211 208
212public: 209public:
213 static constexpr int Compare(const MemoryBlock& lhs, const MemoryBlock& rhs) { 210 static constexpr int Compare(const KMemoryBlock& lhs, const KMemoryBlock& rhs) {
214 if (lhs.GetAddress() < rhs.GetAddress()) { 211 if (lhs.GetAddress() < rhs.GetAddress()) {
215 return -1; 212 return -1;
216 } else if (lhs.GetAddress() <= rhs.GetLastAddress()) { 213 } else if (lhs.GetAddress() <= rhs.GetLastAddress()) {
@@ -221,9 +218,9 @@ public:
221 } 218 }
222 219
223public: 220public:
224 constexpr MemoryBlock() = default; 221 constexpr KMemoryBlock() = default;
225 constexpr MemoryBlock(VAddr addr_, std::size_t num_pages_, MemoryState state_, 222 constexpr KMemoryBlock(VAddr addr_, std::size_t num_pages_, KMemoryState state_,
226 MemoryPermission perm_, MemoryAttribute attribute_) 223 KMemoryPermission perm_, KMemoryAttribute attribute_)
227 : addr{addr_}, num_pages(num_pages_), state{state_}, perm{perm_}, attribute{attribute_} {} 224 : addr{addr_}, num_pages(num_pages_), state{state_}, perm{perm_}, attribute{attribute_} {}
228 225
229 constexpr VAddr GetAddress() const { 226 constexpr VAddr GetAddress() const {
@@ -246,40 +243,40 @@ public:
246 return GetEndAddress() - 1; 243 return GetEndAddress() - 1;
247 } 244 }
248 245
249 constexpr MemoryInfo GetMemoryInfo() const { 246 constexpr KMemoryInfo GetMemoryInfo() const {
250 return { 247 return {
251 GetAddress(), GetSize(), state, perm, 248 GetAddress(), GetSize(), state, perm,
252 attribute, original_perm, ipc_lock_count, device_use_count, 249 attribute, original_perm, ipc_lock_count, device_use_count,
253 }; 250 };
254 } 251 }
255 252
256 void ShareToDevice(MemoryPermission /*new_perm*/) { 253 void ShareToDevice(KMemoryPermission /*new_perm*/) {
257 ASSERT((attribute & MemoryAttribute::DeviceShared) == MemoryAttribute::DeviceShared || 254 ASSERT((attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared ||
258 device_use_count == 0); 255 device_use_count == 0);
259 attribute |= MemoryAttribute::DeviceShared; 256 attribute |= KMemoryAttribute::DeviceShared;
260 const u16 new_use_count{++device_use_count}; 257 const u16 new_use_count{++device_use_count};
261 ASSERT(new_use_count > 0); 258 ASSERT(new_use_count > 0);
262 } 259 }
263 260
264 void UnshareToDevice(MemoryPermission /*new_perm*/) { 261 void UnshareToDevice(KMemoryPermission /*new_perm*/) {
265 ASSERT((attribute & MemoryAttribute::DeviceShared) == MemoryAttribute::DeviceShared); 262 ASSERT((attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared);
266 const u16 prev_use_count{device_use_count--}; 263 const u16 prev_use_count{device_use_count--};
267 ASSERT(prev_use_count > 0); 264 ASSERT(prev_use_count > 0);
268 if (prev_use_count == 1) { 265 if (prev_use_count == 1) {
269 attribute &= ~MemoryAttribute::DeviceShared; 266 attribute &= ~KMemoryAttribute::DeviceShared;
270 } 267 }
271 } 268 }
272 269
273private: 270private:
274 constexpr bool HasProperties(MemoryState s, MemoryPermission p, MemoryAttribute a) const { 271 constexpr bool HasProperties(KMemoryState s, KMemoryPermission p, KMemoryAttribute a) const {
275 constexpr MemoryAttribute AttributeIgnoreMask{MemoryAttribute::DontCareMask | 272 constexpr KMemoryAttribute AttributeIgnoreMask{KMemoryAttribute::DontCareMask |
276 MemoryAttribute::IpcLocked | 273 KMemoryAttribute::IpcLocked |
277 MemoryAttribute::DeviceShared}; 274 KMemoryAttribute::DeviceShared};
278 return state == s && perm == p && 275 return state == s && perm == p &&
279 (attribute | AttributeIgnoreMask) == (a | AttributeIgnoreMask); 276 (attribute | AttributeIgnoreMask) == (a | AttributeIgnoreMask);
280 } 277 }
281 278
282 constexpr bool HasSameProperties(const MemoryBlock& rhs) const { 279 constexpr bool HasSameProperties(const KMemoryBlock& rhs) const {
283 return state == rhs.state && perm == rhs.perm && original_perm == rhs.original_perm && 280 return state == rhs.state && perm == rhs.perm && original_perm == rhs.original_perm &&
284 attribute == rhs.attribute && ipc_lock_count == rhs.ipc_lock_count && 281 attribute == rhs.attribute && ipc_lock_count == rhs.ipc_lock_count &&
285 device_use_count == rhs.device_use_count; 282 device_use_count == rhs.device_use_count;
@@ -296,25 +293,25 @@ private:
296 num_pages += count; 293 num_pages += count;
297 } 294 }
298 295
299 constexpr void Update(MemoryState new_state, MemoryPermission new_perm, 296 constexpr void Update(KMemoryState new_state, KMemoryPermission new_perm,
300 MemoryAttribute new_attribute) { 297 KMemoryAttribute new_attribute) {
301 ASSERT(original_perm == MemoryPermission::None); 298 ASSERT(original_perm == KMemoryPermission::None);
302 ASSERT((attribute & MemoryAttribute::IpcLocked) == MemoryAttribute::None); 299 ASSERT((attribute & KMemoryAttribute::IpcLocked) == KMemoryAttribute::None);
303 300
304 state = new_state; 301 state = new_state;
305 perm = new_perm; 302 perm = new_perm;
306 303
307 attribute = static_cast<MemoryAttribute>( 304 attribute = static_cast<KMemoryAttribute>(
308 new_attribute | 305 new_attribute |
309 (attribute & (MemoryAttribute::IpcLocked | MemoryAttribute::DeviceShared))); 306 (attribute & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)));
310 } 307 }
311 308
312 constexpr MemoryBlock Split(VAddr split_addr) { 309 constexpr KMemoryBlock Split(VAddr split_addr) {
313 ASSERT(GetAddress() < split_addr); 310 ASSERT(GetAddress() < split_addr);
314 ASSERT(Contains(split_addr)); 311 ASSERT(Contains(split_addr));
315 ASSERT(Common::IsAligned(split_addr, PageSize)); 312 ASSERT(Common::IsAligned(split_addr, PageSize));
316 313
317 MemoryBlock block; 314 KMemoryBlock block;
318 block.addr = addr; 315 block.addr = addr;
319 block.num_pages = (split_addr - GetAddress()) / PageSize; 316 block.num_pages = (split_addr - GetAddress()) / PageSize;
320 block.state = state; 317 block.state = state;
@@ -330,6 +327,6 @@ private:
330 return block; 327 return block;
331 } 328 }
332}; 329};
333static_assert(std::is_trivially_destructible<MemoryBlock>::value); 330static_assert(std::is_trivially_destructible<KMemoryBlock>::value);
334 331
335} // namespace Kernel::Memory 332} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/memory_block_manager.cpp b/src/core/hle/kernel/k_memory_block_manager.cpp
index 0732fa5a1..4a2d88008 100644
--- a/src/core/hle/kernel/memory/memory_block_manager.cpp
+++ b/src/core/hle/kernel/k_memory_block_manager.cpp
@@ -2,19 +2,19 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/kernel/memory/memory_block_manager.h" 5#include "core/hle/kernel/k_memory_block_manager.h"
6#include "core/hle/kernel/memory/memory_types.h" 6#include "core/hle/kernel/memory_types.h"
7 7
8namespace Kernel::Memory { 8namespace Kernel {
9 9
10MemoryBlockManager::MemoryBlockManager(VAddr start_addr, VAddr end_addr) 10KMemoryBlockManager::KMemoryBlockManager(VAddr start_addr, VAddr end_addr)
11 : start_addr{start_addr}, end_addr{end_addr} { 11 : start_addr{start_addr}, end_addr{end_addr} {
12 const u64 num_pages{(end_addr - start_addr) / PageSize}; 12 const u64 num_pages{(end_addr - start_addr) / PageSize};
13 memory_block_tree.emplace_back(start_addr, num_pages, MemoryState::Free, MemoryPermission::None, 13 memory_block_tree.emplace_back(start_addr, num_pages, KMemoryState::Free,
14 MemoryAttribute::None); 14 KMemoryPermission::None, KMemoryAttribute::None);
15} 15}
16 16
17MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) { 17KMemoryBlockManager::iterator KMemoryBlockManager::FindIterator(VAddr addr) {
18 auto node{memory_block_tree.begin()}; 18 auto node{memory_block_tree.begin()};
19 while (node != end()) { 19 while (node != end()) {
20 const VAddr end_addr{node->GetNumPages() * PageSize + node->GetAddress()}; 20 const VAddr end_addr{node->GetNumPages() * PageSize + node->GetAddress()};
@@ -26,9 +26,9 @@ MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) {
26 return end(); 26 return end();
27} 27}
28 28
29VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_num_pages, 29VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_num_pages,
30 std::size_t num_pages, std::size_t align, std::size_t offset, 30 std::size_t num_pages, std::size_t align,
31 std::size_t guard_pages) { 31 std::size_t offset, std::size_t guard_pages) {
32 if (num_pages == 0) { 32 if (num_pages == 0) {
33 return {}; 33 return {};
34 } 34 }
@@ -41,7 +41,7 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu
41 break; 41 break;
42 } 42 }
43 43
44 if (info.state != MemoryState::Free) { 44 if (info.state != KMemoryState::Free) {
45 continue; 45 continue;
46 } 46 }
47 47
@@ -63,17 +63,17 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu
63 return {}; 63 return {};
64} 64}
65 65
66void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState prev_state, 66void KMemoryBlockManager::Update(VAddr addr, std::size_t num_pages, KMemoryState prev_state,
67 MemoryPermission prev_perm, MemoryAttribute prev_attribute, 67 KMemoryPermission prev_perm, KMemoryAttribute prev_attribute,
68 MemoryState state, MemoryPermission perm, 68 KMemoryState state, KMemoryPermission perm,
69 MemoryAttribute attribute) { 69 KMemoryAttribute attribute) {
70 const VAddr end_addr{addr + num_pages * PageSize}; 70 const VAddr end_addr{addr + num_pages * PageSize};
71 iterator node{memory_block_tree.begin()}; 71 iterator node{memory_block_tree.begin()};
72 72
73 prev_attribute |= MemoryAttribute::IpcAndDeviceMapped; 73 prev_attribute |= KMemoryAttribute::IpcAndDeviceMapped;
74 74
75 while (node != memory_block_tree.end()) { 75 while (node != memory_block_tree.end()) {
76 MemoryBlock* block{&(*node)}; 76 KMemoryBlock* block{&(*node)};
77 iterator next_node{std::next(node)}; 77 iterator next_node{std::next(node)};
78 const VAddr cur_addr{block->GetAddress()}; 78 const VAddr cur_addr{block->GetAddress()};
79 const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; 79 const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr};
@@ -106,13 +106,13 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState p
106 } 106 }
107} 107}
108 108
109void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState state, 109void KMemoryBlockManager::Update(VAddr addr, std::size_t num_pages, KMemoryState state,
110 MemoryPermission perm, MemoryAttribute attribute) { 110 KMemoryPermission perm, KMemoryAttribute attribute) {
111 const VAddr end_addr{addr + num_pages * PageSize}; 111 const VAddr end_addr{addr + num_pages * PageSize};
112 iterator node{memory_block_tree.begin()}; 112 iterator node{memory_block_tree.begin()};
113 113
114 while (node != memory_block_tree.end()) { 114 while (node != memory_block_tree.end()) {
115 MemoryBlock* block{&(*node)}; 115 KMemoryBlock* block{&(*node)};
116 iterator next_node{std::next(node)}; 116 iterator next_node{std::next(node)};
117 const VAddr cur_addr{block->GetAddress()}; 117 const VAddr cur_addr{block->GetAddress()};
118 const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; 118 const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr};
@@ -141,13 +141,13 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState s
141 } 141 }
142} 142}
143 143
144void MemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, 144void KMemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func,
145 MemoryPermission perm) { 145 KMemoryPermission perm) {
146 const VAddr end_addr{addr + num_pages * PageSize}; 146 const VAddr end_addr{addr + num_pages * PageSize};
147 iterator node{memory_block_tree.begin()}; 147 iterator node{memory_block_tree.begin()};
148 148
149 while (node != memory_block_tree.end()) { 149 while (node != memory_block_tree.end()) {
150 MemoryBlock* block{&(*node)}; 150 KMemoryBlock* block{&(*node)};
151 iterator next_node{std::next(node)}; 151 iterator next_node{std::next(node)};
152 const VAddr cur_addr{block->GetAddress()}; 152 const VAddr cur_addr{block->GetAddress()};
153 const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; 153 const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr};
@@ -176,9 +176,9 @@ void MemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&
176 } 176 }
177} 177}
178 178
179void MemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& func) { 179void KMemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& func) {
180 const_iterator it{FindIterator(start)}; 180 const_iterator it{FindIterator(start)};
181 MemoryInfo info{}; 181 KMemoryInfo info{};
182 do { 182 do {
183 info = it->GetMemoryInfo(); 183 info = it->GetMemoryInfo();
184 func(info); 184 func(info);
@@ -186,8 +186,8 @@ void MemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& f
186 } while (info.addr + info.size - 1 < end - 1 && it != cend()); 186 } while (info.addr + info.size - 1 < end - 1 && it != cend());
187} 187}
188 188
189void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) { 189void KMemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) {
190 MemoryBlock* block{&(*it)}; 190 KMemoryBlock* block{&(*it)};
191 191
192 auto EraseIt = [&](const iterator it_to_erase) { 192 auto EraseIt = [&](const iterator it_to_erase) {
193 if (next_it == it_to_erase) { 193 if (next_it == it_to_erase) {
@@ -197,7 +197,7 @@ void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) {
197 }; 197 };
198 198
199 if (it != memory_block_tree.begin()) { 199 if (it != memory_block_tree.begin()) {
200 MemoryBlock* prev{&(*std::prev(it))}; 200 KMemoryBlock* prev{&(*std::prev(it))};
201 201
202 if (block->HasSameProperties(*prev)) { 202 if (block->HasSameProperties(*prev)) {
203 const iterator prev_it{std::prev(it)}; 203 const iterator prev_it{std::prev(it)};
@@ -211,7 +211,7 @@ void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) {
211 } 211 }
212 212
213 if (it != cend()) { 213 if (it != cend()) {
214 const MemoryBlock* const next{&(*std::next(it))}; 214 const KMemoryBlock* const next{&(*std::next(it))};
215 215
216 if (block->HasSameProperties(*next)) { 216 if (block->HasSameProperties(*next)) {
217 block->Add(next->GetNumPages()); 217 block->Add(next->GetNumPages());
@@ -220,4 +220,4 @@ void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) {
220 } 220 }
221} 221}
222 222
223} // namespace Kernel::Memory 223} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/memory_block_manager.h b/src/core/hle/kernel/k_memory_block_manager.h
index f57d1bbcc..e11cc70c8 100644
--- a/src/core/hle/kernel/memory/memory_block_manager.h
+++ b/src/core/hle/kernel/k_memory_block_manager.h
@@ -8,18 +8,18 @@
8#include <list> 8#include <list>
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/kernel/memory/memory_block.h" 11#include "core/hle/kernel/k_memory_block.h"
12 12
13namespace Kernel::Memory { 13namespace Kernel {
14 14
15class MemoryBlockManager final { 15class KMemoryBlockManager final {
16public: 16public:
17 using MemoryBlockTree = std::list<MemoryBlock>; 17 using MemoryBlockTree = std::list<KMemoryBlock>;
18 using iterator = MemoryBlockTree::iterator; 18 using iterator = MemoryBlockTree::iterator;
19 using const_iterator = MemoryBlockTree::const_iterator; 19 using const_iterator = MemoryBlockTree::const_iterator;
20 20
21public: 21public:
22 MemoryBlockManager(VAddr start_addr, VAddr end_addr); 22 KMemoryBlockManager(VAddr start_addr, VAddr end_addr);
23 23
24 iterator end() { 24 iterator end() {
25 return memory_block_tree.end(); 25 return memory_block_tree.end();
@@ -36,21 +36,22 @@ public:
36 VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages, 36 VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages,
37 std::size_t align, std::size_t offset, std::size_t guard_pages); 37 std::size_t align, std::size_t offset, std::size_t guard_pages);
38 38
39 void Update(VAddr addr, std::size_t num_pages, MemoryState prev_state, 39 void Update(VAddr addr, std::size_t num_pages, KMemoryState prev_state,
40 MemoryPermission prev_perm, MemoryAttribute prev_attribute, MemoryState state, 40 KMemoryPermission prev_perm, KMemoryAttribute prev_attribute, KMemoryState state,
41 MemoryPermission perm, MemoryAttribute attribute); 41 KMemoryPermission perm, KMemoryAttribute attribute);
42 42
43 void Update(VAddr addr, std::size_t num_pages, MemoryState state, 43 void Update(VAddr addr, std::size_t num_pages, KMemoryState state,
44 MemoryPermission perm = MemoryPermission::None, 44 KMemoryPermission perm = KMemoryPermission::None,
45 MemoryAttribute attribute = MemoryAttribute::None); 45 KMemoryAttribute attribute = KMemoryAttribute::None);
46 46
47 using LockFunc = std::function<void(iterator, MemoryPermission)>; 47 using LockFunc = std::function<void(iterator, KMemoryPermission)>;
48 void UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, MemoryPermission perm); 48 void UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func,
49 KMemoryPermission perm);
49 50
50 using IterateFunc = std::function<void(const MemoryInfo&)>; 51 using IterateFunc = std::function<void(const KMemoryInfo&)>;
51 void IterateForRange(VAddr start, VAddr end, IterateFunc&& func); 52 void IterateForRange(VAddr start, VAddr end, IterateFunc&& func);
52 53
53 MemoryBlock& FindBlock(VAddr addr) { 54 KMemoryBlock& FindBlock(VAddr addr) {
54 return *FindIterator(addr); 55 return *FindIterator(addr);
55 } 56 }
56 57
@@ -63,4 +64,4 @@ private:
63 MemoryBlockTree memory_block_tree; 64 MemoryBlockTree memory_block_tree;
64}; 65};
65 66
66} // namespace Kernel::Memory 67} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/memory_layout.h b/src/core/hle/kernel/k_memory_layout.h
index c7c0b2f49..0821d2d8c 100644
--- a/src/core/hle/kernel/memory/memory_layout.h
+++ b/src/core/hle/kernel/k_memory_layout.h
@@ -7,7 +7,7 @@
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/device_memory.h" 8#include "core/device_memory.h"
9 9
10namespace Kernel::Memory { 10namespace Kernel {
11 11
12constexpr std::size_t KernelAslrAlignment = 2 * 1024 * 1024; 12constexpr std::size_t KernelAslrAlignment = 2 * 1024 * 1024;
13constexpr std::size_t KernelVirtualAddressSpaceWidth = 1ULL << 39; 13constexpr std::size_t KernelVirtualAddressSpaceWidth = 1ULL << 39;
@@ -27,8 +27,8 @@ constexpr bool IsKernelAddress(VAddr address) {
27 return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; 27 return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd;
28} 28}
29 29
30class MemoryRegion final { 30class KMemoryRegion final {
31 friend class MemoryLayout; 31 friend class KMemoryLayout;
32 32
33public: 33public:
34 constexpr PAddr StartAddress() const { 34 constexpr PAddr StartAddress() const {
@@ -40,29 +40,29 @@ public:
40 } 40 }
41 41
42private: 42private:
43 constexpr MemoryRegion() = default; 43 constexpr KMemoryRegion() = default;
44 constexpr MemoryRegion(PAddr start_address, PAddr end_address) 44 constexpr KMemoryRegion(PAddr start_address, PAddr end_address)
45 : start_address{start_address}, end_address{end_address} {} 45 : start_address{start_address}, end_address{end_address} {}
46 46
47 const PAddr start_address{}; 47 const PAddr start_address{};
48 const PAddr end_address{}; 48 const PAddr end_address{};
49}; 49};
50 50
51class MemoryLayout final { 51class KMemoryLayout final {
52public: 52public:
53 constexpr const MemoryRegion& Application() const { 53 constexpr const KMemoryRegion& Application() const {
54 return application; 54 return application;
55 } 55 }
56 56
57 constexpr const MemoryRegion& Applet() const { 57 constexpr const KMemoryRegion& Applet() const {
58 return applet; 58 return applet;
59 } 59 }
60 60
61 constexpr const MemoryRegion& System() const { 61 constexpr const KMemoryRegion& System() const {
62 return system; 62 return system;
63 } 63 }
64 64
65 static constexpr MemoryLayout GetDefaultLayout() { 65 static constexpr KMemoryLayout GetDefaultLayout() {
66 constexpr std::size_t application_size{0xcd500000}; 66 constexpr std::size_t application_size{0xcd500000};
67 constexpr std::size_t applet_size{0x1fb00000}; 67 constexpr std::size_t applet_size{0x1fb00000};
68 constexpr PAddr application_start_address{Core::DramMemoryMap::End - application_size}; 68 constexpr PAddr application_start_address{Core::DramMemoryMap::End - application_size};
@@ -76,15 +76,15 @@ public:
76 } 76 }
77 77
78private: 78private:
79 constexpr MemoryLayout(PAddr application_start_address, std::size_t application_size, 79 constexpr KMemoryLayout(PAddr application_start_address, std::size_t application_size,
80 PAddr applet_start_address, std::size_t applet_size, 80 PAddr applet_start_address, std::size_t applet_size,
81 PAddr system_start_address, std::size_t system_size) 81 PAddr system_start_address, std::size_t system_size)
82 : application{application_start_address, application_size}, 82 : application{application_start_address, application_size},
83 applet{applet_start_address, applet_size}, system{system_start_address, system_size} {} 83 applet{applet_start_address, applet_size}, system{system_start_address, system_size} {}
84 84
85 const MemoryRegion application; 85 const KMemoryRegion application;
86 const MemoryRegion applet; 86 const KMemoryRegion applet;
87 const MemoryRegion system; 87 const KMemoryRegion system;
88}; 88};
89 89
90} // namespace Kernel::Memory 90} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index 77f135cdc..9027602bf 100644
--- a/src/core/hle/kernel/memory/memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -8,20 +8,20 @@
8#include "common/assert.h" 8#include "common/assert.h"
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/scope_exit.h" 10#include "common/scope_exit.h"
11#include "core/hle/kernel/memory/memory_manager.h" 11#include "core/hle/kernel/k_memory_manager.h"
12#include "core/hle/kernel/memory/page_linked_list.h" 12#include "core/hle/kernel/k_page_linked_list.h"
13#include "core/hle/kernel/svc_results.h" 13#include "core/hle/kernel/svc_results.h"
14 14
15namespace Kernel::Memory { 15namespace Kernel {
16 16
17std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { 17std::size_t KMemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) {
18 const auto size{end_address - start_address}; 18 const auto size{end_address - start_address};
19 19
20 // Calculate metadata sizes 20 // Calculate metadata sizes
21 const auto ref_count_size{(size / PageSize) * sizeof(u16)}; 21 const auto ref_count_size{(size / PageSize) * sizeof(u16)};
22 const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)}; 22 const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)};
23 const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; 23 const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)};
24 const auto page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)}; 24 const auto page_heap_size{KPageHeap::CalculateManagementOverheadSize(size)};
25 const auto total_metadata_size{manager_size + page_heap_size}; 25 const auto total_metadata_size{manager_size + page_heap_size};
26 ASSERT(manager_size <= total_metadata_size); 26 ASSERT(manager_size <= total_metadata_size);
27 ASSERT(Common::IsAligned(total_metadata_size, PageSize)); 27 ASSERT(Common::IsAligned(total_metadata_size, PageSize));
@@ -41,29 +41,30 @@ std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u6
41 return total_metadata_size; 41 return total_metadata_size;
42} 42}
43 43
44void MemoryManager::InitializeManager(Pool pool, u64 start_address, u64 end_address) { 44void KMemoryManager::InitializeManager(Pool pool, u64 start_address, u64 end_address) {
45 ASSERT(pool < Pool::Count); 45 ASSERT(pool < Pool::Count);
46 managers[static_cast<std::size_t>(pool)].Initialize(pool, start_address, end_address); 46 managers[static_cast<std::size_t>(pool)].Initialize(pool, start_address, end_address);
47} 47}
48 48
49VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align_pages, Pool pool, 49VAddr KMemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_t align_pages,
50 Direction dir) { 50 u32 option) {
51 // Early return if we're allocating no pages 51 // Early return if we're allocating no pages
52 if (num_pages == 0) { 52 if (num_pages == 0) {
53 return {}; 53 return {};
54 } 54 }
55 55
56 // Lock the pool that we're allocating from 56 // Lock the pool that we're allocating from
57 const auto [pool, dir] = DecodeOption(option);
57 const auto pool_index{static_cast<std::size_t>(pool)}; 58 const auto pool_index{static_cast<std::size_t>(pool)};
58 std::lock_guard lock{pool_locks[pool_index]}; 59 std::lock_guard lock{pool_locks[pool_index]};
59 60
60 // Choose a heap based on our page size request 61 // Choose a heap based on our page size request
61 const s32 heap_index{PageHeap::GetAlignedBlockIndex(num_pages, align_pages)}; 62 const s32 heap_index{KPageHeap::GetAlignedBlockIndex(num_pages, align_pages)};
62 63
63 // Loop, trying to iterate from each block 64 // Loop, trying to iterate from each block
64 // TODO (bunnei): Support multiple managers 65 // TODO (bunnei): Support multiple managers
65 Impl& chosen_manager{managers[pool_index]}; 66 Impl& chosen_manager{managers[pool_index]};
66 VAddr allocated_block{chosen_manager.AllocateBlock(heap_index)}; 67 VAddr allocated_block{chosen_manager.AllocateBlock(heap_index, false)};
67 68
68 // If we failed to allocate, quit now 69 // If we failed to allocate, quit now
69 if (!allocated_block) { 70 if (!allocated_block) {
@@ -71,7 +72,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align
71 } 72 }
72 73
73 // If we allocated more than we need, free some 74 // If we allocated more than we need, free some
74 const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; 75 const auto allocated_pages{KPageHeap::GetBlockNumPages(heap_index)};
75 if (allocated_pages > num_pages) { 76 if (allocated_pages > num_pages) {
76 chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages); 77 chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages);
77 } 78 }
@@ -79,8 +80,8 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align
79 return allocated_block; 80 return allocated_block;
80} 81}
81 82
82ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pages, Pool pool, 83ResultCode KMemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
83 Direction dir) { 84 Direction dir) {
84 ASSERT(page_list.GetNumPages() == 0); 85 ASSERT(page_list.GetNumPages() == 0);
85 86
86 // Early return if we're allocating no pages 87 // Early return if we're allocating no pages
@@ -93,7 +94,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
93 std::lock_guard lock{pool_locks[pool_index]}; 94 std::lock_guard lock{pool_locks[pool_index]};
94 95
95 // Choose a heap based on our page size request 96 // Choose a heap based on our page size request
96 const s32 heap_index{PageHeap::GetBlockIndex(num_pages)}; 97 const s32 heap_index{KPageHeap::GetBlockIndex(num_pages)};
97 if (heap_index < 0) { 98 if (heap_index < 0) {
98 return ResultOutOfMemory; 99 return ResultOutOfMemory;
99 } 100 }
@@ -112,11 +113,11 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
112 113
113 // Keep allocating until we've allocated all our pages 114 // Keep allocating until we've allocated all our pages
114 for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) { 115 for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) {
115 const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)}; 116 const auto pages_per_alloc{KPageHeap::GetBlockNumPages(index)};
116 117
117 while (num_pages >= pages_per_alloc) { 118 while (num_pages >= pages_per_alloc) {
118 // Allocate a block 119 // Allocate a block
119 VAddr allocated_block{chosen_manager.AllocateBlock(index)}; 120 VAddr allocated_block{chosen_manager.AllocateBlock(index, false)};
120 if (!allocated_block) { 121 if (!allocated_block) {
121 break; 122 break;
122 } 123 }
@@ -148,8 +149,8 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
148 return RESULT_SUCCESS; 149 return RESULT_SUCCESS;
149} 150}
150 151
151ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, Pool pool, 152ResultCode KMemoryManager::Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
152 Direction dir) { 153 Direction dir) {
153 // Early return if we're freeing no pages 154 // Early return if we're freeing no pages
154 if (!num_pages) { 155 if (!num_pages) {
155 return RESULT_SUCCESS; 156 return RESULT_SUCCESS;
@@ -172,4 +173,4 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages,
172 return RESULT_SUCCESS; 173 return RESULT_SUCCESS;
173} 174}
174 175
175} // namespace Kernel::Memory 176} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/memory_manager.h b/src/core/hle/kernel/k_memory_manager.h
index 3cf444857..ae9f683b8 100644
--- a/src/core/hle/kernel/memory/memory_manager.h
+++ b/src/core/hle/kernel/k_memory_manager.h
@@ -6,16 +6,18 @@
6 6
7#include <array> 7#include <array>
8#include <mutex> 8#include <mutex>
9#include <tuple>
9 10
11#include "common/common_funcs.h"
10#include "common/common_types.h" 12#include "common/common_types.h"
11#include "core/hle/kernel/memory/page_heap.h" 13#include "core/hle/kernel/k_page_heap.h"
12#include "core/hle/result.h" 14#include "core/hle/result.h"
13 15
14namespace Kernel::Memory { 16namespace Kernel {
15 17
16class PageLinkedList; 18class KPageLinkedList;
17 19
18class MemoryManager final : NonCopyable { 20class KMemoryManager final : NonCopyable {
19public: 21public:
20 enum class Pool : u32 { 22 enum class Pool : u32 {
21 Application = 0, 23 Application = 0,
@@ -37,29 +39,50 @@ public:
37 Mask = (0xF << Shift), 39 Mask = (0xF << Shift),
38 }; 40 };
39 41
40 MemoryManager() = default; 42 KMemoryManager() = default;
41 43
42 constexpr std::size_t GetSize(Pool pool) const { 44 constexpr std::size_t GetSize(Pool pool) const {
43 return managers[static_cast<std::size_t>(pool)].GetSize(); 45 return managers[static_cast<std::size_t>(pool)].GetSize();
44 } 46 }
45 47
46 void InitializeManager(Pool pool, u64 start_address, u64 end_address); 48 void InitializeManager(Pool pool, u64 start_address, u64 end_address);
47 VAddr AllocateContinuous(std::size_t num_pages, std::size_t align_pages, Pool pool, 49
48 Direction dir = Direction::FromFront); 50 VAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option);
49 ResultCode Allocate(PageLinkedList& page_list, std::size_t num_pages, Pool pool, 51 ResultCode Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
50 Direction dir = Direction::FromFront); 52 Direction dir = Direction::FromFront);
51 ResultCode Free(PageLinkedList& page_list, std::size_t num_pages, Pool pool, 53 ResultCode Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
52 Direction dir = Direction::FromFront); 54 Direction dir = Direction::FromFront);
53 55
54 static constexpr std::size_t MaxManagerCount = 10; 56 static constexpr std::size_t MaxManagerCount = 10;
55 57
58public:
59 static constexpr u32 EncodeOption(Pool pool, Direction dir) {
60 return (static_cast<u32>(pool) << static_cast<u32>(Pool::Shift)) |
61 (static_cast<u32>(dir) << static_cast<u32>(Direction::Shift));
62 }
63
64 static constexpr Pool GetPool(u32 option) {
65 return static_cast<Pool>((static_cast<u32>(option) & static_cast<u32>(Pool::Mask)) >>
66 static_cast<u32>(Pool::Shift));
67 }
68
69 static constexpr Direction GetDirection(u32 option) {
70 return static_cast<Direction>(
71 (static_cast<u32>(option) & static_cast<u32>(Direction::Mask)) >>
72 static_cast<u32>(Direction::Shift));
73 }
74
75 static constexpr std::tuple<Pool, Direction> DecodeOption(u32 option) {
76 return std::make_tuple(GetPool(option), GetDirection(option));
77 }
78
56private: 79private:
57 class Impl final : NonCopyable { 80 class Impl final : NonCopyable {
58 private: 81 private:
59 using RefCount = u16; 82 using RefCount = u16;
60 83
61 private: 84 private:
62 PageHeap heap; 85 KPageHeap heap;
63 Pool pool{}; 86 Pool pool{};
64 87
65 public: 88 public:
@@ -67,8 +90,8 @@ private:
67 90
68 std::size_t Initialize(Pool new_pool, u64 start_address, u64 end_address); 91 std::size_t Initialize(Pool new_pool, u64 start_address, u64 end_address);
69 92
70 VAddr AllocateBlock(s32 index) { 93 VAddr AllocateBlock(s32 index, bool random) {
71 return heap.AllocateBlock(index); 94 return heap.AllocateBlock(index, random);
72 } 95 }
73 96
74 void Free(VAddr addr, std::size_t num_pages) { 97 void Free(VAddr addr, std::size_t num_pages) {
@@ -93,4 +116,4 @@ private:
93 std::array<Impl, MaxManagerCount> managers; 116 std::array<Impl, MaxManagerCount> managers;
94}; 117};
95 118
96} // namespace Kernel::Memory 119} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_bitmap.h b/src/core/hle/kernel/k_page_bitmap.h
new file mode 100644
index 000000000..c75d667c9
--- /dev/null
+++ b/src/core/hle/kernel/k_page_bitmap.h
@@ -0,0 +1,279 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <bit>
9
10#include "common/alignment.h"
11#include "common/assert.h"
12#include "common/bit_util.h"
13#include "common/common_types.h"
14#include "common/tiny_mt.h"
15#include "core/hle/kernel/k_system_control.h"
16
17namespace Kernel {
18
19class KPageBitmap {
20private:
21 class RandomBitGenerator {
22 private:
23 Common::TinyMT rng{};
24 u32 entropy{};
25 u32 bits_available{};
26
27 private:
28 void RefreshEntropy() {
29 entropy = rng.GenerateRandomU32();
30 bits_available = static_cast<u32>(Common::BitSize<decltype(entropy)>());
31 }
32
33 bool GenerateRandomBit() {
34 if (bits_available == 0) {
35 this->RefreshEntropy();
36 }
37
38 const bool rnd_bit = (entropy & 1) != 0;
39 entropy >>= 1;
40 --bits_available;
41 return rnd_bit;
42 }
43
44 public:
45 RandomBitGenerator() {
46 rng.Initialize(static_cast<u32>(KSystemControl::GenerateRandomU64()));
47 }
48
49 std::size_t SelectRandomBit(u64 bitmap) {
50 u64 selected = 0;
51
52 u64 cur_num_bits = Common::BitSize<decltype(bitmap)>() / 2;
53 u64 cur_mask = (1ULL << cur_num_bits) - 1;
54
55 while (cur_num_bits) {
56 const u64 low = (bitmap >> 0) & cur_mask;
57 const u64 high = (bitmap >> cur_num_bits) & cur_mask;
58
59 bool choose_low;
60 if (high == 0) {
61 // If only low val is set, choose low.
62 choose_low = true;
63 } else if (low == 0) {
64 // If only high val is set, choose high.
65 choose_low = false;
66 } else {
67 // If both are set, choose random.
68 choose_low = this->GenerateRandomBit();
69 }
70
71 // If we chose low, proceed with low.
72 if (choose_low) {
73 bitmap = low;
74 selected += 0;
75 } else {
76 bitmap = high;
77 selected += cur_num_bits;
78 }
79
80 // Proceed.
81 cur_num_bits /= 2;
82 cur_mask >>= cur_num_bits;
83 }
84
85 return selected;
86 }
87 };
88
89public:
90 static constexpr std::size_t MaxDepth = 4;
91
92private:
93 std::array<u64*, MaxDepth> bit_storages{};
94 RandomBitGenerator rng{};
95 std::size_t num_bits{};
96 std::size_t used_depths{};
97
98public:
99 KPageBitmap() = default;
100
101 constexpr std::size_t GetNumBits() const {
102 return num_bits;
103 }
104 constexpr s32 GetHighestDepthIndex() const {
105 return static_cast<s32>(used_depths) - 1;
106 }
107
108 u64* Initialize(u64* storage, std::size_t size) {
109 // Initially, everything is un-set.
110 num_bits = 0;
111
112 // Calculate the needed bitmap depth.
113 used_depths = static_cast<std::size_t>(GetRequiredDepth(size));
114 ASSERT(used_depths <= MaxDepth);
115
116 // Set the bitmap pointers.
117 for (s32 depth = this->GetHighestDepthIndex(); depth >= 0; depth--) {
118 bit_storages[depth] = storage;
119 size = Common::AlignUp(size, Common::BitSize<u64>()) / Common::BitSize<u64>();
120 storage += size;
121 }
122
123 return storage;
124 }
125
126 s64 FindFreeBlock(bool random) {
127 uintptr_t offset = 0;
128 s32 depth = 0;
129
130 if (random) {
131 do {
132 const u64 v = bit_storages[depth][offset];
133 if (v == 0) {
134 // If depth is bigger than zero, then a previous level indicated a block was
135 // free.
136 ASSERT(depth == 0);
137 return -1;
138 }
139 offset = offset * Common::BitSize<u64>() + rng.SelectRandomBit(v);
140 ++depth;
141 } while (depth < static_cast<s32>(used_depths));
142 } else {
143 do {
144 const u64 v = bit_storages[depth][offset];
145 if (v == 0) {
146 // If depth is bigger than zero, then a previous level indicated a block was
147 // free.
148 ASSERT(depth == 0);
149 return -1;
150 }
151 offset = offset * Common::BitSize<u64>() + std::countr_zero(v);
152 ++depth;
153 } while (depth < static_cast<s32>(used_depths));
154 }
155
156 return static_cast<s64>(offset);
157 }
158
159 void SetBit(std::size_t offset) {
160 this->SetBit(this->GetHighestDepthIndex(), offset);
161 num_bits++;
162 }
163
164 void ClearBit(std::size_t offset) {
165 this->ClearBit(this->GetHighestDepthIndex(), offset);
166 num_bits--;
167 }
168
169 bool ClearRange(std::size_t offset, std::size_t count) {
170 s32 depth = this->GetHighestDepthIndex();
171 u64* bits = bit_storages[depth];
172 std::size_t bit_ind = offset / Common::BitSize<u64>();
173 if (count < Common::BitSize<u64>()) {
174 const std::size_t shift = offset % Common::BitSize<u64>();
175 ASSERT(shift + count <= Common::BitSize<u64>());
176 // Check that all the bits are set.
177 const u64 mask = ((u64(1) << count) - 1) << shift;
178 u64 v = bits[bit_ind];
179 if ((v & mask) != mask) {
180 return false;
181 }
182
183 // Clear the bits.
184 v &= ~mask;
185 bits[bit_ind] = v;
186 if (v == 0) {
187 this->ClearBit(depth - 1, bit_ind);
188 }
189 } else {
190 ASSERT(offset % Common::BitSize<u64>() == 0);
191 ASSERT(count % Common::BitSize<u64>() == 0);
192 // Check that all the bits are set.
193 std::size_t remaining = count;
194 std::size_t i = 0;
195 do {
196 if (bits[bit_ind + i++] != ~u64(0)) {
197 return false;
198 }
199 remaining -= Common::BitSize<u64>();
200 } while (remaining > 0);
201
202 // Clear the bits.
203 remaining = count;
204 i = 0;
205 do {
206 bits[bit_ind + i] = 0;
207 this->ClearBit(depth - 1, bit_ind + i);
208 i++;
209 remaining -= Common::BitSize<u64>();
210 } while (remaining > 0);
211 }
212
213 num_bits -= count;
214 return true;
215 }
216
217private:
218 void SetBit(s32 depth, std::size_t offset) {
219 while (depth >= 0) {
220 std::size_t ind = offset / Common::BitSize<u64>();
221 std::size_t which = offset % Common::BitSize<u64>();
222 const u64 mask = u64(1) << which;
223
224 u64* bit = std::addressof(bit_storages[depth][ind]);
225 u64 v = *bit;
226 ASSERT((v & mask) == 0);
227 *bit = v | mask;
228 if (v) {
229 break;
230 }
231 offset = ind;
232 depth--;
233 }
234 }
235
236 void ClearBit(s32 depth, std::size_t offset) {
237 while (depth >= 0) {
238 std::size_t ind = offset / Common::BitSize<u64>();
239 std::size_t which = offset % Common::BitSize<u64>();
240 const u64 mask = u64(1) << which;
241
242 u64* bit = std::addressof(bit_storages[depth][ind]);
243 u64 v = *bit;
244 ASSERT((v & mask) != 0);
245 v &= ~mask;
246 *bit = v;
247 if (v) {
248 break;
249 }
250 offset = ind;
251 depth--;
252 }
253 }
254
255private:
256 static constexpr s32 GetRequiredDepth(std::size_t region_size) {
257 s32 depth = 0;
258 while (true) {
259 region_size /= Common::BitSize<u64>();
260 depth++;
261 if (region_size == 0) {
262 return depth;
263 }
264 }
265 }
266
267public:
268 static constexpr std::size_t CalculateManagementOverheadSize(std::size_t region_size) {
269 std::size_t overhead_bits = 0;
270 for (s32 depth = GetRequiredDepth(region_size) - 1; depth >= 0; depth--) {
271 region_size =
272 Common::AlignUp(region_size, Common::BitSize<u64>()) / Common::BitSize<u64>();
273 overhead_bits += region_size;
274 }
275 return overhead_bits * sizeof(u64);
276 }
277};
278
279} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/page_heap.cpp b/src/core/hle/kernel/k_page_heap.cpp
index 0ab1f7205..07e062922 100644
--- a/src/core/hle/kernel/memory/page_heap.cpp
+++ b/src/core/hle/kernel/k_page_heap.cpp
@@ -2,16 +2,13 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#include "core/core.h" 5#include "core/core.h"
9#include "core/hle/kernel/memory/page_heap.h" 6#include "core/hle/kernel/k_page_heap.h"
10#include "core/memory.h" 7#include "core/memory.h"
11 8
12namespace Kernel::Memory { 9namespace Kernel {
13 10
14void PageHeap::Initialize(VAddr address, std::size_t size, std::size_t metadata_size) { 11void KPageHeap::Initialize(VAddr address, std::size_t size, std::size_t metadata_size) {
15 // Check our assumptions 12 // Check our assumptions
16 ASSERT(Common::IsAligned((address), PageSize)); 13 ASSERT(Common::IsAligned((address), PageSize));
17 ASSERT(Common::IsAligned(size, PageSize)); 14 ASSERT(Common::IsAligned(size, PageSize));
@@ -32,11 +29,11 @@ void PageHeap::Initialize(VAddr address, std::size_t size, std::size_t metadata_
32 } 29 }
33} 30}
34 31
35VAddr PageHeap::AllocateBlock(s32 index) { 32VAddr KPageHeap::AllocateBlock(s32 index, bool random) {
36 const std::size_t needed_size{blocks[index].GetSize()}; 33 const std::size_t needed_size{blocks[index].GetSize()};
37 34
38 for (s32 i{index}; i < static_cast<s32>(MemoryBlockPageShifts.size()); i++) { 35 for (s32 i{index}; i < static_cast<s32>(MemoryBlockPageShifts.size()); i++) {
39 if (const VAddr addr{blocks[i].PopBlock()}; addr) { 36 if (const VAddr addr{blocks[i].PopBlock(random)}; addr) {
40 if (const std::size_t allocated_size{blocks[i].GetSize()}; 37 if (const std::size_t allocated_size{blocks[i].GetSize()};
41 allocated_size > needed_size) { 38 allocated_size > needed_size) {
42 Free(addr + needed_size, (allocated_size - needed_size) / PageSize); 39 Free(addr + needed_size, (allocated_size - needed_size) / PageSize);
@@ -48,13 +45,13 @@ VAddr PageHeap::AllocateBlock(s32 index) {
48 return 0; 45 return 0;
49} 46}
50 47
51void PageHeap::FreeBlock(VAddr block, s32 index) { 48void KPageHeap::FreeBlock(VAddr block, s32 index) {
52 do { 49 do {
53 block = blocks[index++].PushBlock(block); 50 block = blocks[index++].PushBlock(block);
54 } while (block != 0); 51 } while (block != 0);
55} 52}
56 53
57void PageHeap::Free(VAddr addr, std::size_t num_pages) { 54void KPageHeap::Free(VAddr addr, std::size_t num_pages) {
58 // Freeing no pages is a no-op 55 // Freeing no pages is a no-op
59 if (num_pages == 0) { 56 if (num_pages == 0) {
60 return; 57 return;
@@ -104,16 +101,16 @@ void PageHeap::Free(VAddr addr, std::size_t num_pages) {
104 } 101 }
105} 102}
106 103
107std::size_t PageHeap::CalculateMetadataOverheadSize(std::size_t region_size) { 104std::size_t KPageHeap::CalculateManagementOverheadSize(std::size_t region_size) {
108 std::size_t overhead_size = 0; 105 std::size_t overhead_size = 0;
109 for (std::size_t i = 0; i < MemoryBlockPageShifts.size(); i++) { 106 for (std::size_t i = 0; i < MemoryBlockPageShifts.size(); i++) {
110 const std::size_t cur_block_shift{MemoryBlockPageShifts[i]}; 107 const std::size_t cur_block_shift{MemoryBlockPageShifts[i]};
111 const std::size_t next_block_shift{ 108 const std::size_t next_block_shift{
112 (i != MemoryBlockPageShifts.size() - 1) ? MemoryBlockPageShifts[i + 1] : 0}; 109 (i != MemoryBlockPageShifts.size() - 1) ? MemoryBlockPageShifts[i + 1] : 0};
113 overhead_size += PageHeap::Block::CalculateMetadataOverheadSize( 110 overhead_size += KPageHeap::Block::CalculateManagementOverheadSize(
114 region_size, cur_block_shift, next_block_shift); 111 region_size, cur_block_shift, next_block_shift);
115 } 112 }
116 return Common::AlignUp(overhead_size, PageSize); 113 return Common::AlignUp(overhead_size, PageSize);
117} 114}
118 115
119} // namespace Kernel::Memory 116} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_heap.h b/src/core/hle/kernel/k_page_heap.h
new file mode 100644
index 000000000..de5d6a189
--- /dev/null
+++ b/src/core/hle/kernel/k_page_heap.h
@@ -0,0 +1,193 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <bit>
9#include <vector>
10
11#include "common/alignment.h"
12#include "common/assert.h"
13#include "common/common_funcs.h"
14#include "common/common_types.h"
15#include "core/hle/kernel/k_page_bitmap.h"
16#include "core/hle/kernel/memory_types.h"
17
18namespace Kernel {
19
20class KPageHeap final : NonCopyable {
21public:
22 static constexpr s32 GetAlignedBlockIndex(std::size_t num_pages, std::size_t align_pages) {
23 const auto target_pages{std::max(num_pages, align_pages)};
24 for (std::size_t i = 0; i < NumMemoryBlockPageShifts; i++) {
25 if (target_pages <=
26 (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) {
27 return static_cast<s32>(i);
28 }
29 }
30 return -1;
31 }
32
33 static constexpr s32 GetBlockIndex(std::size_t num_pages) {
34 for (s32 i{static_cast<s32>(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) {
35 if (num_pages >= (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) {
36 return i;
37 }
38 }
39 return -1;
40 }
41
42 static constexpr std::size_t GetBlockSize(std::size_t index) {
43 return static_cast<std::size_t>(1) << MemoryBlockPageShifts[index];
44 }
45
46 static constexpr std::size_t GetBlockNumPages(std::size_t index) {
47 return GetBlockSize(index) / PageSize;
48 }
49
50private:
51 static constexpr std::size_t NumMemoryBlockPageShifts{7};
52 static constexpr std::array<std::size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{
53 0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E,
54 };
55
56 class Block final : NonCopyable {
57 private:
58 KPageBitmap bitmap;
59 VAddr heap_address{};
60 uintptr_t end_offset{};
61 std::size_t block_shift{};
62 std::size_t next_block_shift{};
63
64 public:
65 Block() = default;
66
67 constexpr std::size_t GetShift() const {
68 return block_shift;
69 }
70 constexpr std::size_t GetNextShift() const {
71 return next_block_shift;
72 }
73 constexpr std::size_t GetSize() const {
74 return static_cast<std::size_t>(1) << GetShift();
75 }
76 constexpr std::size_t GetNumPages() const {
77 return GetSize() / PageSize;
78 }
79 constexpr std::size_t GetNumFreeBlocks() const {
80 return bitmap.GetNumBits();
81 }
82 constexpr std::size_t GetNumFreePages() const {
83 return GetNumFreeBlocks() * GetNumPages();
84 }
85
86 u64* Initialize(VAddr addr, std::size_t size, std::size_t bs, std::size_t nbs,
87 u64* bit_storage) {
88 // Set shifts
89 block_shift = bs;
90 next_block_shift = nbs;
91
92 // Align up the address
93 VAddr end{addr + size};
94 const auto align{(next_block_shift != 0) ? (1ULL << next_block_shift)
95 : (1ULL << block_shift)};
96 addr = Common::AlignDown((addr), align);
97 end = Common::AlignUp((end), align);
98
99 heap_address = addr;
100 end_offset = (end - addr) / (1ULL << block_shift);
101 return bitmap.Initialize(bit_storage, end_offset);
102 }
103
104 VAddr PushBlock(VAddr address) {
105 // Set the bit for the free block
106 std::size_t offset{(address - heap_address) >> GetShift()};
107 bitmap.SetBit(offset);
108
109 // If we have a next shift, try to clear the blocks below and return the address
110 if (GetNextShift()) {
111 const auto diff{1ULL << (GetNextShift() - GetShift())};
112 offset = Common::AlignDown(offset, diff);
113 if (bitmap.ClearRange(offset, diff)) {
114 return heap_address + (offset << GetShift());
115 }
116 }
117
118 // We couldn't coalesce, or we're already as big as possible
119 return 0;
120 }
121
122 VAddr PopBlock(bool random) {
123 // Find a free block
124 const s64 soffset{bitmap.FindFreeBlock(random)};
125 if (soffset < 0) {
126 return 0;
127 }
128 const auto offset{static_cast<std::size_t>(soffset)};
129
130 // Update our tracking and return it
131 bitmap.ClearBit(offset);
132 return heap_address + (offset << GetShift());
133 }
134
135 public:
136 static constexpr std::size_t CalculateManagementOverheadSize(std::size_t region_size,
137 std::size_t cur_block_shift,
138 std::size_t next_block_shift) {
139 const auto cur_block_size{(1ULL << cur_block_shift)};
140 const auto next_block_size{(1ULL << next_block_shift)};
141 const auto align{(next_block_shift != 0) ? next_block_size : cur_block_size};
142 return KPageBitmap::CalculateManagementOverheadSize(
143 (align * 2 + Common::AlignUp(region_size, align)) / cur_block_size);
144 }
145 };
146
147public:
148 KPageHeap() = default;
149
150 constexpr VAddr GetAddress() const {
151 return heap_address;
152 }
153 constexpr std::size_t GetSize() const {
154 return heap_size;
155 }
156 constexpr VAddr GetEndAddress() const {
157 return GetAddress() + GetSize();
158 }
159 constexpr std::size_t GetPageOffset(VAddr block) const {
160 return (block - GetAddress()) / PageSize;
161 }
162
163 void Initialize(VAddr heap_address, std::size_t heap_size, std::size_t metadata_size);
164 VAddr AllocateBlock(s32 index, bool random);
165 void Free(VAddr addr, std::size_t num_pages);
166
167 void UpdateUsedSize() {
168 used_size = heap_size - (GetNumFreePages() * PageSize);
169 }
170
171 static std::size_t CalculateManagementOverheadSize(std::size_t region_size);
172
173private:
174 constexpr std::size_t GetNumFreePages() const {
175 std::size_t num_free{};
176
177 for (const auto& block : blocks) {
178 num_free += block.GetNumFreePages();
179 }
180
181 return num_free;
182 }
183
184 void FreeBlock(VAddr block, s32 index);
185
186 VAddr heap_address{};
187 std::size_t heap_size{};
188 std::size_t used_size{};
189 std::array<Block, NumMemoryBlockPageShifts> blocks{};
190 std::vector<u64> metadata;
191};
192
193} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/page_linked_list.h b/src/core/hle/kernel/k_page_linked_list.h
index 45dc13eaf..64024d01f 100644
--- a/src/core/hle/kernel/memory/page_linked_list.h
+++ b/src/core/hle/kernel/k_page_linked_list.h
@@ -8,12 +8,12 @@
8 8
9#include "common/assert.h" 9#include "common/assert.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/kernel/memory/memory_types.h" 11#include "core/hle/kernel/memory_types.h"
12#include "core/hle/result.h" 12#include "core/hle/result.h"
13 13
14namespace Kernel::Memory { 14namespace Kernel {
15 15
16class PageLinkedList final { 16class KPageLinkedList final {
17public: 17public:
18 class Node final { 18 class Node final {
19 public: 19 public:
@@ -33,8 +33,8 @@ public:
33 }; 33 };
34 34
35public: 35public:
36 PageLinkedList() = default; 36 KPageLinkedList() = default;
37 PageLinkedList(u64 address, u64 num_pages) { 37 KPageLinkedList(u64 address, u64 num_pages) {
38 ASSERT(AddBlock(address, num_pages).IsSuccess()); 38 ASSERT(AddBlock(address, num_pages).IsSuccess());
39 } 39 }
40 40
@@ -54,7 +54,7 @@ public:
54 return num_pages; 54 return num_pages;
55 } 55 }
56 56
57 bool IsEqual(PageLinkedList& other) const { 57 bool IsEqual(KPageLinkedList& other) const {
58 auto this_node = nodes.begin(); 58 auto this_node = nodes.begin();
59 auto other_node = other.nodes.begin(); 59 auto other_node = other.nodes.begin();
60 while (this_node != nodes.end() && other_node != other.nodes.end()) { 60 while (this_node != nodes.end() && other_node != other.nodes.end()) {
@@ -89,4 +89,4 @@ private:
89 std::list<Node> nodes; 89 std::list<Node> nodes;
90}; 90};
91 91
92} // namespace Kernel::Memory 92} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 00ed9b881..d09d5ce48 100644
--- a/src/core/hle/kernel/memory/page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -6,19 +6,20 @@
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/scope_exit.h" 7#include "common/scope_exit.h"
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/k_address_space_info.h"
10#include "core/hle/kernel/k_memory_block.h"
11#include "core/hle/kernel/k_memory_block_manager.h"
12#include "core/hle/kernel/k_page_linked_list.h"
13#include "core/hle/kernel/k_page_table.h"
14#include "core/hle/kernel/k_resource_limit.h"
9#include "core/hle/kernel/k_scoped_resource_reservation.h" 15#include "core/hle/kernel/k_scoped_resource_reservation.h"
16#include "core/hle/kernel/k_system_control.h"
10#include "core/hle/kernel/kernel.h" 17#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/memory/address_space_info.h"
12#include "core/hle/kernel/memory/memory_block.h"
13#include "core/hle/kernel/memory/memory_block_manager.h"
14#include "core/hle/kernel/memory/page_linked_list.h"
15#include "core/hle/kernel/memory/page_table.h"
16#include "core/hle/kernel/memory/system_control.h"
17#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
18#include "core/hle/kernel/svc_results.h" 19#include "core/hle/kernel/svc_results.h"
19#include "core/memory.h" 20#include "core/memory.h"
20 21
21namespace Kernel::Memory { 22namespace Kernel {
22 23
23namespace { 24namespace {
24 25
@@ -37,14 +38,14 @@ constexpr std::size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceT
37 } 38 }
38} 39}
39 40
40constexpr u64 GetAddressInRange(const MemoryInfo& info, VAddr addr) { 41constexpr u64 GetAddressInRange(const KMemoryInfo& info, VAddr addr) {
41 if (info.GetAddress() < addr) { 42 if (info.GetAddress() < addr) {
42 return addr; 43 return addr;
43 } 44 }
44 return info.GetAddress(); 45 return info.GetAddress();
45} 46}
46 47
47constexpr std::size_t GetSizeInRange(const MemoryInfo& info, VAddr start, VAddr end) { 48constexpr std::size_t GetSizeInRange(const KMemoryInfo& info, VAddr start, VAddr end) {
48 std::size_t size{info.GetSize()}; 49 std::size_t size{info.GetSize()};
49 if (info.GetAddress() < start) { 50 if (info.GetAddress() < start) {
50 size -= start - info.GetAddress(); 51 size -= start - info.GetAddress();
@@ -57,25 +58,25 @@ constexpr std::size_t GetSizeInRange(const MemoryInfo& info, VAddr start, VAddr
57 58
58} // namespace 59} // namespace
59 60
60PageTable::PageTable(Core::System& system) : system{system} {} 61KPageTable::KPageTable(Core::System& system) : system{system} {}
61 62
62ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, 63ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type,
63 bool enable_aslr, VAddr code_addr, std::size_t code_size, 64 bool enable_aslr, VAddr code_addr,
64 Memory::MemoryManager::Pool pool) { 65 std::size_t code_size, KMemoryManager::Pool pool) {
65 66
66 const auto GetSpaceStart = [this](AddressSpaceInfo::Type type) { 67 const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
67 return AddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); 68 return KAddressSpaceInfo::GetAddressSpaceStart(address_space_width, type);
68 }; 69 };
69 const auto GetSpaceSize = [this](AddressSpaceInfo::Type type) { 70 const auto GetSpaceSize = [this](KAddressSpaceInfo::Type type) {
70 return AddressSpaceInfo::GetAddressSpaceSize(address_space_width, type); 71 return KAddressSpaceInfo::GetAddressSpaceSize(address_space_width, type);
71 }; 72 };
72 73
73 // Set our width and heap/alias sizes 74 // Set our width and heap/alias sizes
74 address_space_width = GetAddressSpaceWidthFromType(as_type); 75 address_space_width = GetAddressSpaceWidthFromType(as_type);
75 const VAddr start = 0; 76 const VAddr start = 0;
76 const VAddr end{1ULL << address_space_width}; 77 const VAddr end{1ULL << address_space_width};
77 std::size_t alias_region_size{GetSpaceSize(AddressSpaceInfo::Type::Alias)}; 78 std::size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)};
78 std::size_t heap_region_size{GetSpaceSize(AddressSpaceInfo::Type::Heap)}; 79 std::size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)};
79 80
80 ASSERT(start <= code_addr); 81 ASSERT(start <= code_addr);
81 ASSERT(code_addr < code_addr + code_size); 82 ASSERT(code_addr < code_addr + code_size);
@@ -95,12 +96,12 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t
95 std::size_t kernel_map_region_size{}; 96 std::size_t kernel_map_region_size{};
96 97
97 if (address_space_width == 39) { 98 if (address_space_width == 39) {
98 alias_region_size = GetSpaceSize(AddressSpaceInfo::Type::Alias); 99 alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Alias);
99 heap_region_size = GetSpaceSize(AddressSpaceInfo::Type::Heap); 100 heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Heap);
100 stack_region_size = GetSpaceSize(AddressSpaceInfo::Type::Stack); 101 stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Stack);
101 kernel_map_region_size = GetSpaceSize(AddressSpaceInfo::Type::Is32Bit); 102 kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
102 code_region_start = GetSpaceStart(AddressSpaceInfo::Type::Large64Bit); 103 code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::Map39Bit);
103 code_region_end = code_region_start + GetSpaceSize(AddressSpaceInfo::Type::Large64Bit); 104 code_region_end = code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit);
104 alias_code_region_start = code_region_start; 105 alias_code_region_start = code_region_start;
105 alias_code_region_end = code_region_end; 106 alias_code_region_end = code_region_end;
106 process_code_start = Common::AlignDown(code_addr, RegionAlignment); 107 process_code_start = Common::AlignDown(code_addr, RegionAlignment);
@@ -108,12 +109,12 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t
108 } else { 109 } else {
109 stack_region_size = 0; 110 stack_region_size = 0;
110 kernel_map_region_size = 0; 111 kernel_map_region_size = 0;
111 code_region_start = GetSpaceStart(AddressSpaceInfo::Type::Is32Bit); 112 code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::MapSmall);
112 code_region_end = code_region_start + GetSpaceSize(AddressSpaceInfo::Type::Is32Bit); 113 code_region_end = code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
113 stack_region_start = code_region_start; 114 stack_region_start = code_region_start;
114 alias_code_region_start = code_region_start; 115 alias_code_region_start = code_region_start;
115 alias_code_region_end = GetSpaceStart(AddressSpaceInfo::Type::Small64Bit) + 116 alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type::MapLarge) +
116 GetSpaceSize(AddressSpaceInfo::Type::Small64Bit); 117 GetSpaceSize(KAddressSpaceInfo::Type::MapLarge);
117 stack_region_end = code_region_end; 118 stack_region_end = code_region_end;
118 kernel_map_region_start = code_region_start; 119 kernel_map_region_start = code_region_start;
119 kernel_map_region_end = code_region_end; 120 kernel_map_region_end = code_region_end;
@@ -149,13 +150,13 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t
149 // Determine random placements for each region 150 // Determine random placements for each region
150 std::size_t alias_rnd{}, heap_rnd{}, stack_rnd{}, kmap_rnd{}; 151 std::size_t alias_rnd{}, heap_rnd{}, stack_rnd{}, kmap_rnd{};
151 if (enable_aslr) { 152 if (enable_aslr) {
152 alias_rnd = SystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * 153 alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
153 RegionAlignment; 154 RegionAlignment;
154 heap_rnd = SystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * 155 heap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
155 RegionAlignment; 156 RegionAlignment;
156 stack_rnd = SystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * 157 stack_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
157 RegionAlignment; 158 RegionAlignment;
158 kmap_rnd = SystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * 159 kmap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
159 RegionAlignment; 160 RegionAlignment;
160 } 161 }
161 162
@@ -270,8 +271,8 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t
270 return InitializeMemoryLayout(start, end); 271 return InitializeMemoryLayout(start, end);
271} 272}
272 273
273ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemoryState state, 274ResultCode KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemoryState state,
274 MemoryPermission perm) { 275 KMemoryPermission perm) {
275 std::lock_guard lock{page_table_lock}; 276 std::lock_guard lock{page_table_lock};
276 277
277 const u64 size{num_pages * PageSize}; 278 const u64 size{num_pages * PageSize};
@@ -284,7 +285,7 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemorySt
284 return ResultInvalidCurrentMemory; 285 return ResultInvalidCurrentMemory;
285 } 286 }
286 287
287 PageLinkedList page_linked_list; 288 KPageLinkedList page_linked_list;
288 CASCADE_CODE( 289 CASCADE_CODE(
289 system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); 290 system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool));
290 CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)); 291 CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup));
@@ -294,44 +295,44 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemorySt
294 return RESULT_SUCCESS; 295 return RESULT_SUCCESS;
295} 296}
296 297
297ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) { 298ResultCode KPageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) {
298 std::lock_guard lock{page_table_lock}; 299 std::lock_guard lock{page_table_lock};
299 300
300 const std::size_t num_pages{size / PageSize}; 301 const std::size_t num_pages{size / PageSize};
301 302
302 MemoryState state{}; 303 KMemoryState state{};
303 MemoryPermission perm{}; 304 KMemoryPermission perm{};
304 CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, MemoryState::All, 305 CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, KMemoryState::All,
305 MemoryState::Normal, MemoryPermission::Mask, 306 KMemoryState::Normal, KMemoryPermission::Mask,
306 MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, 307 KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask,
307 MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); 308 KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
308 309
309 if (IsRegionMapped(dst_addr, size)) { 310 if (IsRegionMapped(dst_addr, size)) {
310 return ResultInvalidCurrentMemory; 311 return ResultInvalidCurrentMemory;
311 } 312 }
312 313
313 PageLinkedList page_linked_list; 314 KPageLinkedList page_linked_list;
314 AddRegionToPages(src_addr, num_pages, page_linked_list); 315 AddRegionToPages(src_addr, num_pages, page_linked_list);
315 316
316 { 317 {
317 auto block_guard = detail::ScopeExit( 318 auto block_guard = detail::ScopeExit(
318 [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); }); 319 [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); });
319 320
320 CASCADE_CODE( 321 CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::None,
321 Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); 322 OperationType::ChangePermissions));
322 CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::None)); 323 CASCADE_CODE(MapPages(dst_addr, page_linked_list, KMemoryPermission::None));
323 324
324 block_guard.Cancel(); 325 block_guard.Cancel();
325 } 326 }
326 327
327 block_manager->Update(src_addr, num_pages, state, MemoryPermission::None, 328 block_manager->Update(src_addr, num_pages, state, KMemoryPermission::None,
328 MemoryAttribute::Locked); 329 KMemoryAttribute::Locked);
329 block_manager->Update(dst_addr, num_pages, MemoryState::AliasCode); 330 block_manager->Update(dst_addr, num_pages, KMemoryState::AliasCode);
330 331
331 return RESULT_SUCCESS; 332 return RESULT_SUCCESS;
332} 333}
333 334
334ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) { 335ResultCode KPageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) {
335 std::lock_guard lock{page_table_lock}; 336 std::lock_guard lock{page_table_lock};
336 337
337 if (!size) { 338 if (!size) {
@@ -340,34 +341,35 @@ ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std
340 341
341 const std::size_t num_pages{size / PageSize}; 342 const std::size_t num_pages{size / PageSize};
342 343
343 CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, 344 CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, KMemoryState::All,
344 MemoryState::Normal, MemoryPermission::None, 345 KMemoryState::Normal, KMemoryPermission::None,
345 MemoryPermission::None, MemoryAttribute::Mask, 346 KMemoryPermission::None, KMemoryAttribute::Mask,
346 MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); 347 KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped));
347 348
348 MemoryState state{}; 349 KMemoryState state{};
349 CASCADE_CODE(CheckMemoryState( 350 CASCADE_CODE(CheckMemoryState(
350 &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias, 351 &state, nullptr, nullptr, dst_addr, PageSize, KMemoryState::FlagCanCodeAlias,
351 MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None, 352 KMemoryState::FlagCanCodeAlias, KMemoryPermission::None, KMemoryPermission::None,
352 MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); 353 KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
353 CASCADE_CODE(CheckMemoryState(dst_addr, size, MemoryState::All, state, MemoryPermission::None, 354 CASCADE_CODE(CheckMemoryState(dst_addr, size, KMemoryState::All, state, KMemoryPermission::None,
354 MemoryPermission::None, MemoryAttribute::Mask, 355 KMemoryPermission::None, KMemoryAttribute::Mask,
355 MemoryAttribute::None)); 356 KMemoryAttribute::None));
356 CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); 357 CASCADE_CODE(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap));
357 358
358 block_manager->Update(dst_addr, num_pages, MemoryState::Free); 359 block_manager->Update(dst_addr, num_pages, KMemoryState::Free);
359 block_manager->Update(src_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite); 360 block_manager->Update(src_addr, num_pages, KMemoryState::Normal,
361 KMemoryPermission::ReadAndWrite);
360 362
361 return RESULT_SUCCESS; 363 return RESULT_SUCCESS;
362} 364}
363 365
364void PageTable::MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, VAddr end) { 366void KPageTable::MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end) {
365 auto node{page_linked_list.Nodes().begin()}; 367 auto node{page_linked_list.Nodes().begin()};
366 PAddr map_addr{node->GetAddress()}; 368 PAddr map_addr{node->GetAddress()};
367 std::size_t src_num_pages{node->GetNumPages()}; 369 std::size_t src_num_pages{node->GetNumPages()};
368 370
369 block_manager->IterateForRange(start, end, [&](const MemoryInfo& info) { 371 block_manager->IterateForRange(start, end, [&](const KMemoryInfo& info) {
370 if (info.state != MemoryState::Free) { 372 if (info.state != KMemoryState::Free) {
371 return; 373 return;
372 } 374 }
373 375
@@ -382,7 +384,7 @@ void PageTable::MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start,
382 } 384 }
383 385
384 const std::size_t num_pages{std::min(src_num_pages, dst_num_pages)}; 386 const std::size_t num_pages{std::min(src_num_pages, dst_num_pages)};
385 Operate(dst_addr, num_pages, MemoryPermission::ReadAndWrite, OperationType::Map, 387 Operate(dst_addr, num_pages, KMemoryPermission::ReadAndWrite, OperationType::Map,
386 map_addr); 388 map_addr);
387 389
388 dst_addr += num_pages * PageSize; 390 dst_addr += num_pages * PageSize;
@@ -393,14 +395,14 @@ void PageTable::MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start,
393 }); 395 });
394} 396}
395 397
396ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { 398ResultCode KPageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
397 std::lock_guard lock{page_table_lock}; 399 std::lock_guard lock{page_table_lock};
398 400
399 std::size_t mapped_size{}; 401 std::size_t mapped_size{};
400 const VAddr end_addr{addr + size}; 402 const VAddr end_addr{addr + size};
401 403
402 block_manager->IterateForRange(addr, end_addr, [&](const MemoryInfo& info) { 404 block_manager->IterateForRange(addr, end_addr, [&](const KMemoryInfo& info) {
403 if (info.state != MemoryState::Free) { 405 if (info.state != KMemoryState::Free) {
404 mapped_size += GetSizeInRange(info, addr, end_addr); 406 mapped_size += GetSizeInRange(info, addr, end_addr);
405 } 407 }
406 }); 408 });
@@ -421,7 +423,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
421 return ResultResourceLimitedExceeded; 423 return ResultResourceLimitedExceeded;
422 } 424 }
423 425
424 PageLinkedList page_linked_list; 426 KPageLinkedList page_linked_list;
425 427
426 CASCADE_CODE( 428 CASCADE_CODE(
427 system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, memory_pool)); 429 system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, memory_pool));
@@ -434,14 +436,14 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
434 physical_memory_usage += remaining_size; 436 physical_memory_usage += remaining_size;
435 437
436 const std::size_t num_pages{size / PageSize}; 438 const std::size_t num_pages{size / PageSize};
437 block_manager->Update(addr, num_pages, MemoryState::Free, MemoryPermission::None, 439 block_manager->Update(addr, num_pages, KMemoryState::Free, KMemoryPermission::None,
438 MemoryAttribute::None, MemoryState::Normal, 440 KMemoryAttribute::None, KMemoryState::Normal,
439 MemoryPermission::ReadAndWrite, MemoryAttribute::None); 441 KMemoryPermission::ReadAndWrite, KMemoryAttribute::None);
440 442
441 return RESULT_SUCCESS; 443 return RESULT_SUCCESS;
442} 444}
443 445
444ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { 446ResultCode KPageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
445 std::lock_guard lock{page_table_lock}; 447 std::lock_guard lock{page_table_lock};
446 448
447 const VAddr end_addr{addr + size}; 449 const VAddr end_addr{addr + size};
@@ -449,14 +451,14 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
449 std::size_t mapped_size{}; 451 std::size_t mapped_size{};
450 452
451 // Verify that the region can be unmapped 453 // Verify that the region can be unmapped
452 block_manager->IterateForRange(addr, end_addr, [&](const MemoryInfo& info) { 454 block_manager->IterateForRange(addr, end_addr, [&](const KMemoryInfo& info) {
453 if (info.state == MemoryState::Normal) { 455 if (info.state == KMemoryState::Normal) {
454 if (info.attribute != MemoryAttribute::None) { 456 if (info.attribute != KMemoryAttribute::None) {
455 result = ResultInvalidCurrentMemory; 457 result = ResultInvalidCurrentMemory;
456 return; 458 return;
457 } 459 }
458 mapped_size += GetSizeInRange(info, addr, end_addr); 460 mapped_size += GetSizeInRange(info, addr, end_addr);
459 } else if (info.state != MemoryState::Free) { 461 } else if (info.state != KMemoryState::Free) {
460 result = ResultInvalidCurrentMemory; 462 result = ResultInvalidCurrentMemory;
461 } 463 }
462 }); 464 });
@@ -478,23 +480,23 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
478 return RESULT_SUCCESS; 480 return RESULT_SUCCESS;
479} 481}
480 482
481ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) { 483ResultCode KPageTable::UnmapMemory(VAddr addr, std::size_t size) {
482 std::lock_guard lock{page_table_lock}; 484 std::lock_guard lock{page_table_lock};
483 485
484 const VAddr end_addr{addr + size}; 486 const VAddr end_addr{addr + size};
485 ResultCode result{RESULT_SUCCESS}; 487 ResultCode result{RESULT_SUCCESS};
486 PageLinkedList page_linked_list; 488 KPageLinkedList page_linked_list;
487 489
488 // Unmap each region within the range 490 // Unmap each region within the range
489 block_manager->IterateForRange(addr, end_addr, [&](const MemoryInfo& info) { 491 block_manager->IterateForRange(addr, end_addr, [&](const KMemoryInfo& info) {
490 if (info.state == MemoryState::Normal) { 492 if (info.state == KMemoryState::Normal) {
491 const std::size_t block_size{GetSizeInRange(info, addr, end_addr)}; 493 const std::size_t block_size{GetSizeInRange(info, addr, end_addr)};
492 const std::size_t block_num_pages{block_size / PageSize}; 494 const std::size_t block_num_pages{block_size / PageSize};
493 const VAddr block_addr{GetAddressInRange(info, addr)}; 495 const VAddr block_addr{GetAddressInRange(info, addr)};
494 496
495 AddRegionToPages(block_addr, block_size / PageSize, page_linked_list); 497 AddRegionToPages(block_addr, block_size / PageSize, page_linked_list);
496 498
497 if (result = Operate(block_addr, block_num_pages, MemoryPermission::None, 499 if (result = Operate(block_addr, block_num_pages, KMemoryPermission::None,
498 OperationType::Unmap); 500 OperationType::Unmap);
499 result.IsError()) { 501 result.IsError()) {
500 return; 502 return;
@@ -509,66 +511,67 @@ ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) {
509 const std::size_t num_pages{size / PageSize}; 511 const std::size_t num_pages{size / PageSize};
510 system.Kernel().MemoryManager().Free(page_linked_list, num_pages, memory_pool); 512 system.Kernel().MemoryManager().Free(page_linked_list, num_pages, memory_pool);
511 513
512 block_manager->Update(addr, num_pages, MemoryState::Free); 514 block_manager->Update(addr, num_pages, KMemoryState::Free);
513 515
514 return RESULT_SUCCESS; 516 return RESULT_SUCCESS;
515} 517}
516 518
517ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { 519ResultCode KPageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) {
518 std::lock_guard lock{page_table_lock}; 520 std::lock_guard lock{page_table_lock};
519 521
520 MemoryState src_state{}; 522 KMemoryState src_state{};
521 CASCADE_CODE(CheckMemoryState( 523 CASCADE_CODE(CheckMemoryState(
522 &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, 524 &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias,
523 MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite, 525 KMemoryState::FlagCanAlias, KMemoryPermission::Mask, KMemoryPermission::ReadAndWrite,
524 MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); 526 KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
525 527
526 if (IsRegionMapped(dst_addr, size)) { 528 if (IsRegionMapped(dst_addr, size)) {
527 return ResultInvalidCurrentMemory; 529 return ResultInvalidCurrentMemory;
528 } 530 }
529 531
530 PageLinkedList page_linked_list; 532 KPageLinkedList page_linked_list;
531 const std::size_t num_pages{size / PageSize}; 533 const std::size_t num_pages{size / PageSize};
532 534
533 AddRegionToPages(src_addr, num_pages, page_linked_list); 535 AddRegionToPages(src_addr, num_pages, page_linked_list);
534 536
535 { 537 {
536 auto block_guard = detail::ScopeExit([&] { 538 auto block_guard = detail::ScopeExit([&] {
537 Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, 539 Operate(src_addr, num_pages, KMemoryPermission::ReadAndWrite,
538 OperationType::ChangePermissions); 540 OperationType::ChangePermissions);
539 }); 541 });
540 542
541 CASCADE_CODE( 543 CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::None,
542 Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); 544 OperationType::ChangePermissions));
543 CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)); 545 CASCADE_CODE(MapPages(dst_addr, page_linked_list, KMemoryPermission::ReadAndWrite));
544 546
545 block_guard.Cancel(); 547 block_guard.Cancel();
546 } 548 }
547 549
548 block_manager->Update(src_addr, num_pages, src_state, MemoryPermission::None, 550 block_manager->Update(src_addr, num_pages, src_state, KMemoryPermission::None,
549 MemoryAttribute::Locked); 551 KMemoryAttribute::Locked);
550 block_manager->Update(dst_addr, num_pages, MemoryState::Stack, MemoryPermission::ReadAndWrite); 552 block_manager->Update(dst_addr, num_pages, KMemoryState::Stack,
553 KMemoryPermission::ReadAndWrite);
551 554
552 return RESULT_SUCCESS; 555 return RESULT_SUCCESS;
553} 556}
554 557
555ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { 558ResultCode KPageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) {
556 std::lock_guard lock{page_table_lock}; 559 std::lock_guard lock{page_table_lock};
557 560
558 MemoryState src_state{}; 561 KMemoryState src_state{};
559 CASCADE_CODE(CheckMemoryState( 562 CASCADE_CODE(CheckMemoryState(
560 &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, 563 &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias,
561 MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None, 564 KMemoryState::FlagCanAlias, KMemoryPermission::Mask, KMemoryPermission::None,
562 MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); 565 KMemoryAttribute::Mask, KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped));
563 566
564 MemoryPermission dst_perm{}; 567 KMemoryPermission dst_perm{};
565 CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, 568 CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, KMemoryState::All,
566 MemoryState::Stack, MemoryPermission::None, 569 KMemoryState::Stack, KMemoryPermission::None,
567 MemoryPermission::None, MemoryAttribute::Mask, 570 KMemoryPermission::None, KMemoryAttribute::Mask,
568 MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); 571 KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
569 572
570 PageLinkedList src_pages; 573 KPageLinkedList src_pages;
571 PageLinkedList dst_pages; 574 KPageLinkedList dst_pages;
572 const std::size_t num_pages{size / PageSize}; 575 const std::size_t num_pages{size / PageSize};
573 576
574 AddRegionToPages(src_addr, num_pages, src_pages); 577 AddRegionToPages(src_addr, num_pages, src_pages);
@@ -581,21 +584,21 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) {
581 { 584 {
582 auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); }); 585 auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); });
583 586
584 CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); 587 CASCADE_CODE(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap));
585 CASCADE_CODE(Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, 588 CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::ReadAndWrite,
586 OperationType::ChangePermissions)); 589 OperationType::ChangePermissions));
587 590
588 block_guard.Cancel(); 591 block_guard.Cancel();
589 } 592 }
590 593
591 block_manager->Update(src_addr, num_pages, src_state, MemoryPermission::ReadAndWrite); 594 block_manager->Update(src_addr, num_pages, src_state, KMemoryPermission::ReadAndWrite);
592 block_manager->Update(dst_addr, num_pages, MemoryState::Free); 595 block_manager->Update(dst_addr, num_pages, KMemoryState::Free);
593 596
594 return RESULT_SUCCESS; 597 return RESULT_SUCCESS;
595} 598}
596 599
597ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_list, 600ResultCode KPageTable::MapPages(VAddr addr, const KPageLinkedList& page_linked_list,
598 MemoryPermission perm) { 601 KMemoryPermission perm) {
599 VAddr cur_addr{addr}; 602 VAddr cur_addr{addr};
600 603
601 for (const auto& node : page_linked_list.Nodes()) { 604 for (const auto& node : page_linked_list.Nodes()) {
@@ -604,8 +607,8 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis
604 result.IsError()) { 607 result.IsError()) {
605 const std::size_t num_pages{(addr - cur_addr) / PageSize}; 608 const std::size_t num_pages{(addr - cur_addr) / PageSize};
606 609
607 ASSERT( 610 ASSERT(Operate(addr, num_pages, KMemoryPermission::None, OperationType::Unmap)
608 Operate(addr, num_pages, MemoryPermission::None, OperationType::Unmap).IsSuccess()); 611 .IsSuccess());
609 612
610 return result; 613 return result;
611 } 614 }
@@ -616,8 +619,8 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis
616 return RESULT_SUCCESS; 619 return RESULT_SUCCESS;
617} 620}
618 621
619ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, MemoryState state, 622ResultCode KPageTable::MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state,
620 MemoryPermission perm) { 623 KMemoryPermission perm) {
621 std::lock_guard lock{page_table_lock}; 624 std::lock_guard lock{page_table_lock};
622 625
623 const std::size_t num_pages{page_linked_list.GetNumPages()}; 626 const std::size_t num_pages{page_linked_list.GetNumPages()};
@@ -638,26 +641,27 @@ ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, Mem
638 return RESULT_SUCCESS; 641 return RESULT_SUCCESS;
639} 642}
640 643
641ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, MemoryPermission perm) { 644ResultCode KPageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size,
645 KMemoryPermission perm) {
642 646
643 std::lock_guard lock{page_table_lock}; 647 std::lock_guard lock{page_table_lock};
644 648
645 MemoryState prev_state{}; 649 KMemoryState prev_state{};
646 MemoryPermission prev_perm{}; 650 KMemoryPermission prev_perm{};
647 651
648 CASCADE_CODE(CheckMemoryState( 652 CASCADE_CODE(CheckMemoryState(
649 &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, MemoryState::FlagCode, 653 &prev_state, &prev_perm, nullptr, addr, size, KMemoryState::FlagCode,
650 MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, 654 KMemoryState::FlagCode, KMemoryPermission::None, KMemoryPermission::None,
651 MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); 655 KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
652 656
653 MemoryState state{prev_state}; 657 KMemoryState state{prev_state};
654 658
655 // Ensure state is mutable if permission allows write 659 // Ensure state is mutable if permission allows write
656 if ((perm & MemoryPermission::Write) != MemoryPermission::None) { 660 if ((perm & KMemoryPermission::Write) != KMemoryPermission::None) {
657 if (prev_state == MemoryState::Code) { 661 if (prev_state == KMemoryState::Code) {
658 state = MemoryState::CodeData; 662 state = KMemoryState::CodeData;
659 } else if (prev_state == MemoryState::AliasCode) { 663 } else if (prev_state == KMemoryState::AliasCode) {
660 state = MemoryState::AliasCodeData; 664 state = KMemoryState::AliasCodeData;
661 } else { 665 } else {
662 UNREACHABLE(); 666 UNREACHABLE();
663 } 667 }
@@ -668,13 +672,13 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo
668 return RESULT_SUCCESS; 672 return RESULT_SUCCESS;
669 } 673 }
670 674
671 if ((prev_perm & MemoryPermission::Execute) != (perm & MemoryPermission::Execute)) { 675 if ((prev_perm & KMemoryPermission::Execute) != (perm & KMemoryPermission::Execute)) {
672 // Memory execution state is changing, invalidate CPU cache range 676 // Memory execution state is changing, invalidate CPU cache range
673 system.InvalidateCpuInstructionCacheRange(addr, size); 677 system.InvalidateCpuInstructionCacheRange(addr, size);
674 } 678 }
675 679
676 const std::size_t num_pages{size / PageSize}; 680 const std::size_t num_pages{size / PageSize};
677 const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None 681 const OperationType operation{(perm & KMemoryPermission::Execute) != KMemoryPermission::None
678 ? OperationType::ChangePermissionsAndRefresh 682 ? OperationType::ChangePermissionsAndRefresh
679 : OperationType::ChangePermissions}; 683 : OperationType::ChangePermissions};
680 684
@@ -685,69 +689,69 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo
685 return RESULT_SUCCESS; 689 return RESULT_SUCCESS;
686} 690}
687 691
688MemoryInfo PageTable::QueryInfoImpl(VAddr addr) { 692KMemoryInfo KPageTable::QueryInfoImpl(VAddr addr) {
689 std::lock_guard lock{page_table_lock}; 693 std::lock_guard lock{page_table_lock};
690 694
691 return block_manager->FindBlock(addr).GetMemoryInfo(); 695 return block_manager->FindBlock(addr).GetMemoryInfo();
692} 696}
693 697
694MemoryInfo PageTable::QueryInfo(VAddr addr) { 698KMemoryInfo KPageTable::QueryInfo(VAddr addr) {
695 if (!Contains(addr, 1)) { 699 if (!Contains(addr, 1)) {
696 return {address_space_end, 0 - address_space_end, MemoryState::Inaccessible, 700 return {address_space_end, 0 - address_space_end, KMemoryState::Inaccessible,
697 MemoryPermission::None, MemoryAttribute::None, MemoryPermission::None}; 701 KMemoryPermission::None, KMemoryAttribute::None, KMemoryPermission::None};
698 } 702 }
699 703
700 return QueryInfoImpl(addr); 704 return QueryInfoImpl(addr);
701} 705}
702 706
703ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, MemoryPermission perm) { 707ResultCode KPageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm) {
704 std::lock_guard lock{page_table_lock}; 708 std::lock_guard lock{page_table_lock};
705 709
706 MemoryState state{}; 710 KMemoryState state{};
707 MemoryAttribute attribute{}; 711 KMemoryAttribute attribute{};
708 712
709 CASCADE_CODE(CheckMemoryState(&state, nullptr, &attribute, addr, size, 713 CASCADE_CODE(CheckMemoryState(
710 MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, 714 &state, nullptr, &attribute, addr, size,
711 MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, 715 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
712 MemoryPermission::Mask, MemoryPermission::ReadAndWrite, 716 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, KMemoryPermission::Mask,
713 MemoryAttribute::Mask, MemoryAttribute::None, 717 KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, KMemoryAttribute::None,
714 MemoryAttribute::IpcAndDeviceMapped)); 718 KMemoryAttribute::IpcAndDeviceMapped));
715 719
716 block_manager->Update(addr, size / PageSize, state, perm, attribute | MemoryAttribute::Locked); 720 block_manager->Update(addr, size / PageSize, state, perm, attribute | KMemoryAttribute::Locked);
717 721
718 return RESULT_SUCCESS; 722 return RESULT_SUCCESS;
719} 723}
720 724
721ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) { 725ResultCode KPageTable::ResetTransferMemory(VAddr addr, std::size_t size) {
722 std::lock_guard lock{page_table_lock}; 726 std::lock_guard lock{page_table_lock};
723 727
724 MemoryState state{}; 728 KMemoryState state{};
725 729
726 CASCADE_CODE(CheckMemoryState(&state, nullptr, nullptr, addr, size, 730 CASCADE_CODE(
727 MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, 731 CheckMemoryState(&state, nullptr, nullptr, addr, size,
728 MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, 732 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
729 MemoryPermission::None, MemoryPermission::None, 733 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
730 MemoryAttribute::Mask, MemoryAttribute::Locked, 734 KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::Mask,
731 MemoryAttribute::IpcAndDeviceMapped)); 735 KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped));
732 736
733 block_manager->Update(addr, size / PageSize, state, MemoryPermission::ReadAndWrite); 737 block_manager->Update(addr, size / PageSize, state, KMemoryPermission::ReadAndWrite);
734 738
735 return RESULT_SUCCESS; 739 return RESULT_SUCCESS;
736} 740}
737 741
738ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAttribute mask, 742ResultCode KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask,
739 MemoryAttribute value) { 743 KMemoryAttribute value) {
740 std::lock_guard lock{page_table_lock}; 744 std::lock_guard lock{page_table_lock};
741 745
742 MemoryState state{}; 746 KMemoryState state{};
743 MemoryPermission perm{}; 747 KMemoryPermission perm{};
744 MemoryAttribute attribute{}; 748 KMemoryAttribute attribute{};
745 749
746 CASCADE_CODE(CheckMemoryState(&state, &perm, &attribute, addr, size, 750 CASCADE_CODE(CheckMemoryState(
747 MemoryState::FlagCanChangeAttribute, 751 &state, &perm, &attribute, addr, size, KMemoryState::FlagCanChangeAttribute,
748 MemoryState::FlagCanChangeAttribute, MemoryPermission::None, 752 KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None,
749 MemoryPermission::None, MemoryAttribute::LockedAndIpcLocked, 753 KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None,
750 MemoryAttribute::None, MemoryAttribute::DeviceSharedAndUncached)); 754 KMemoryAttribute::DeviceSharedAndUncached));
751 755
752 attribute = attribute & ~mask; 756 attribute = attribute & ~mask;
753 attribute = attribute | (mask & value); 757 attribute = attribute | (mask & value);
@@ -757,13 +761,13 @@ ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAtt
757 return RESULT_SUCCESS; 761 return RESULT_SUCCESS;
758} 762}
759 763
760ResultCode PageTable::SetHeapCapacity(std::size_t new_heap_capacity) { 764ResultCode KPageTable::SetHeapCapacity(std::size_t new_heap_capacity) {
761 std::lock_guard lock{page_table_lock}; 765 std::lock_guard lock{page_table_lock};
762 heap_capacity = new_heap_capacity; 766 heap_capacity = new_heap_capacity;
763 return RESULT_SUCCESS; 767 return RESULT_SUCCESS;
764} 768}
765 769
766ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) { 770ResultVal<VAddr> KPageTable::SetHeapSize(std::size_t size) {
767 771
768 if (size > heap_region_end - heap_region_start) { 772 if (size > heap_region_end - heap_region_start) {
769 return ResultOutOfMemory; 773 return ResultOutOfMemory;
@@ -789,7 +793,7 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
789 return ResultResourceLimitedExceeded; 793 return ResultResourceLimitedExceeded;
790 } 794 }
791 795
792 PageLinkedList page_linked_list; 796 KPageLinkedList page_linked_list;
793 const std::size_t num_pages{delta / PageSize}; 797 const std::size_t num_pages{delta / PageSize};
794 798
795 CASCADE_CODE( 799 CASCADE_CODE(
@@ -805,8 +809,8 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
805 // Succeeded in allocation, commit the resource reservation 809 // Succeeded in allocation, commit the resource reservation
806 memory_reservation.Commit(); 810 memory_reservation.Commit();
807 811
808 block_manager->Update(current_heap_addr, num_pages, MemoryState::Normal, 812 block_manager->Update(current_heap_addr, num_pages, KMemoryState::Normal,
809 MemoryPermission::ReadAndWrite); 813 KMemoryPermission::ReadAndWrite);
810 814
811 current_heap_addr = heap_region_start + size; 815 current_heap_addr = heap_region_start + size;
812 } 816 }
@@ -814,10 +818,10 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
814 return MakeResult<VAddr>(heap_region_start); 818 return MakeResult<VAddr>(heap_region_start);
815} 819}
816 820
817ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, 821ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align,
818 bool is_map_only, VAddr region_start, 822 bool is_map_only, VAddr region_start,
819 std::size_t region_num_pages, MemoryState state, 823 std::size_t region_num_pages, KMemoryState state,
820 MemoryPermission perm, PAddr map_addr) { 824 KMemoryPermission perm, PAddr map_addr) {
821 std::lock_guard lock{page_table_lock}; 825 std::lock_guard lock{page_table_lock};
822 826
823 if (!CanContain(region_start, region_num_pages * PageSize, state)) { 827 if (!CanContain(region_start, region_num_pages * PageSize, state)) {
@@ -837,7 +841,7 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s
837 if (is_map_only) { 841 if (is_map_only) {
838 CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); 842 CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr));
839 } else { 843 } else {
840 PageLinkedList page_group; 844 KPageLinkedList page_group;
841 CASCADE_CODE( 845 CASCADE_CODE(
842 system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool)); 846 system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool));
843 CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)); 847 CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup));
@@ -848,22 +852,22 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s
848 return MakeResult<VAddr>(addr); 852 return MakeResult<VAddr>(addr);
849} 853}
850 854
851ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { 855ResultCode KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
852 std::lock_guard lock{page_table_lock}; 856 std::lock_guard lock{page_table_lock};
853 857
854 MemoryPermission perm{}; 858 KMemoryPermission perm{};
855 if (const ResultCode result{CheckMemoryState( 859 if (const ResultCode result{CheckMemoryState(
856 nullptr, &perm, nullptr, addr, size, MemoryState::FlagCanChangeAttribute, 860 nullptr, &perm, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute,
857 MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None, 861 KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None,
858 MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None, 862 KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None,
859 MemoryAttribute::DeviceSharedAndUncached)}; 863 KMemoryAttribute::DeviceSharedAndUncached)};
860 result.IsError()) { 864 result.IsError()) {
861 return result; 865 return result;
862 } 866 }
863 867
864 block_manager->UpdateLock( 868 block_manager->UpdateLock(
865 addr, size / PageSize, 869 addr, size / PageSize,
866 [](MemoryBlockManager::iterator block, MemoryPermission perm) { 870 [](KMemoryBlockManager::iterator block, KMemoryPermission perm) {
867 block->ShareToDevice(perm); 871 block->ShareToDevice(perm);
868 }, 872 },
869 perm); 873 perm);
@@ -871,22 +875,22 @@ ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
871 return RESULT_SUCCESS; 875 return RESULT_SUCCESS;
872} 876}
873 877
874ResultCode PageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) { 878ResultCode KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) {
875 std::lock_guard lock{page_table_lock}; 879 std::lock_guard lock{page_table_lock};
876 880
877 MemoryPermission perm{}; 881 KMemoryPermission perm{};
878 if (const ResultCode result{CheckMemoryState( 882 if (const ResultCode result{CheckMemoryState(
879 nullptr, &perm, nullptr, addr, size, MemoryState::FlagCanChangeAttribute, 883 nullptr, &perm, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute,
880 MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None, 884 KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None,
881 MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None, 885 KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None,
882 MemoryAttribute::DeviceSharedAndUncached)}; 886 KMemoryAttribute::DeviceSharedAndUncached)};
883 result.IsError()) { 887 result.IsError()) {
884 return result; 888 return result;
885 } 889 }
886 890
887 block_manager->UpdateLock( 891 block_manager->UpdateLock(
888 addr, size / PageSize, 892 addr, size / PageSize,
889 [](MemoryBlockManager::iterator block, MemoryPermission perm) { 893 [](KMemoryBlockManager::iterator block, KMemoryPermission perm) {
890 block->UnshareToDevice(perm); 894 block->UnshareToDevice(perm);
891 }, 895 },
892 perm); 896 perm);
@@ -894,20 +898,21 @@ ResultCode PageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size)
894 return RESULT_SUCCESS; 898 return RESULT_SUCCESS;
895} 899}
896 900
897ResultCode PageTable::InitializeMemoryLayout(VAddr start, VAddr end) { 901ResultCode KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) {
898 block_manager = std::make_unique<MemoryBlockManager>(start, end); 902 block_manager = std::make_unique<KMemoryBlockManager>(start, end);
899 903
900 return RESULT_SUCCESS; 904 return RESULT_SUCCESS;
901} 905}
902 906
903bool PageTable::IsRegionMapped(VAddr address, u64 size) { 907bool KPageTable::IsRegionMapped(VAddr address, u64 size) {
904 return CheckMemoryState(address, size, MemoryState::All, MemoryState::Free, 908 return CheckMemoryState(address, size, KMemoryState::All, KMemoryState::Free,
905 MemoryPermission::Mask, MemoryPermission::None, MemoryAttribute::Mask, 909 KMemoryPermission::Mask, KMemoryPermission::None,
906 MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped) 910 KMemoryAttribute::Mask, KMemoryAttribute::None,
911 KMemoryAttribute::IpcAndDeviceMapped)
907 .IsError(); 912 .IsError();
908} 913}
909 914
910bool PageTable::IsRegionContiguous(VAddr addr, u64 size) const { 915bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const {
911 auto start_ptr = system.Memory().GetPointer(addr); 916 auto start_ptr = system.Memory().GetPointer(addr);
912 for (u64 offset{}; offset < size; offset += PageSize) { 917 for (u64 offset{}; offset < size; offset += PageSize) {
913 if (start_ptr != system.Memory().GetPointer(addr + offset)) { 918 if (start_ptr != system.Memory().GetPointer(addr + offset)) {
@@ -918,8 +923,8 @@ bool PageTable::IsRegionContiguous(VAddr addr, u64 size) const {
918 return true; 923 return true;
919} 924}
920 925
921void PageTable::AddRegionToPages(VAddr start, std::size_t num_pages, 926void KPageTable::AddRegionToPages(VAddr start, std::size_t num_pages,
922 PageLinkedList& page_linked_list) { 927 KPageLinkedList& page_linked_list) {
923 VAddr addr{start}; 928 VAddr addr{start};
924 while (addr < start + (num_pages * PageSize)) { 929 while (addr < start + (num_pages * PageSize)) {
925 const PAddr paddr{GetPhysicalAddr(addr)}; 930 const PAddr paddr{GetPhysicalAddr(addr)};
@@ -931,8 +936,8 @@ void PageTable::AddRegionToPages(VAddr start, std::size_t num_pages,
931 } 936 }
932} 937}
933 938
934VAddr PageTable::AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, 939VAddr KPageTable::AllocateVirtualMemory(VAddr start, std::size_t region_num_pages,
935 u64 needed_num_pages, std::size_t align) { 940 u64 needed_num_pages, std::size_t align) {
936 if (is_aslr_enabled) { 941 if (is_aslr_enabled) {
937 UNIMPLEMENTED(); 942 UNIMPLEMENTED();
938 } 943 }
@@ -940,8 +945,8 @@ VAddr PageTable::AllocateVirtualMemory(VAddr start, std::size_t region_num_pages
940 IsKernel() ? 1 : 4); 945 IsKernel() ? 1 : 4);
941} 946}
942 947
943ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, const PageLinkedList& page_group, 948ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageLinkedList& page_group,
944 OperationType operation) { 949 OperationType operation) {
945 std::lock_guard lock{page_table_lock}; 950 std::lock_guard lock{page_table_lock};
946 951
947 ASSERT(Common::IsAligned(addr, PageSize)); 952 ASSERT(Common::IsAligned(addr, PageSize));
@@ -965,8 +970,8 @@ ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, const PageLinke
965 return RESULT_SUCCESS; 970 return RESULT_SUCCESS;
966} 971}
967 972
968ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, MemoryPermission perm, 973ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm,
969 OperationType operation, PAddr map_addr) { 974 OperationType operation, PAddr map_addr) {
970 std::lock_guard lock{page_table_lock}; 975 std::lock_guard lock{page_table_lock};
971 976
972 ASSERT(num_pages > 0); 977 ASSERT(num_pages > 0);
@@ -992,34 +997,34 @@ ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, MemoryPermissio
992 return RESULT_SUCCESS; 997 return RESULT_SUCCESS;
993} 998}
994 999
995constexpr VAddr PageTable::GetRegionAddress(MemoryState state) const { 1000constexpr VAddr KPageTable::GetRegionAddress(KMemoryState state) const {
996 switch (state) { 1001 switch (state) {
997 case MemoryState::Free: 1002 case KMemoryState::Free:
998 case MemoryState::Kernel: 1003 case KMemoryState::Kernel:
999 return address_space_start; 1004 return address_space_start;
1000 case MemoryState::Normal: 1005 case KMemoryState::Normal:
1001 return heap_region_start; 1006 return heap_region_start;
1002 case MemoryState::Ipc: 1007 case KMemoryState::Ipc:
1003 case MemoryState::NonSecureIpc: 1008 case KMemoryState::NonSecureIpc:
1004 case MemoryState::NonDeviceIpc: 1009 case KMemoryState::NonDeviceIpc:
1005 return alias_region_start; 1010 return alias_region_start;
1006 case MemoryState::Stack: 1011 case KMemoryState::Stack:
1007 return stack_region_start; 1012 return stack_region_start;
1008 case MemoryState::Io: 1013 case KMemoryState::Io:
1009 case MemoryState::Static: 1014 case KMemoryState::Static:
1010 case MemoryState::ThreadLocal: 1015 case KMemoryState::ThreadLocal:
1011 return kernel_map_region_start; 1016 return kernel_map_region_start;
1012 case MemoryState::Shared: 1017 case KMemoryState::Shared:
1013 case MemoryState::AliasCode: 1018 case KMemoryState::AliasCode:
1014 case MemoryState::AliasCodeData: 1019 case KMemoryState::AliasCodeData:
1015 case MemoryState::Transferred: 1020 case KMemoryState::Transferred:
1016 case MemoryState::SharedTransferred: 1021 case KMemoryState::SharedTransferred:
1017 case MemoryState::SharedCode: 1022 case KMemoryState::SharedCode:
1018 case MemoryState::GeneratedCode: 1023 case KMemoryState::GeneratedCode:
1019 case MemoryState::CodeOut: 1024 case KMemoryState::CodeOut:
1020 return alias_code_region_start; 1025 return alias_code_region_start;
1021 case MemoryState::Code: 1026 case KMemoryState::Code:
1022 case MemoryState::CodeData: 1027 case KMemoryState::CodeData:
1023 return code_region_start; 1028 return code_region_start;
1024 default: 1029 default:
1025 UNREACHABLE(); 1030 UNREACHABLE();
@@ -1027,34 +1032,34 @@ constexpr VAddr PageTable::GetRegionAddress(MemoryState state) const {
1027 } 1032 }
1028} 1033}
1029 1034
1030constexpr std::size_t PageTable::GetRegionSize(MemoryState state) const { 1035constexpr std::size_t KPageTable::GetRegionSize(KMemoryState state) const {
1031 switch (state) { 1036 switch (state) {
1032 case MemoryState::Free: 1037 case KMemoryState::Free:
1033 case MemoryState::Kernel: 1038 case KMemoryState::Kernel:
1034 return address_space_end - address_space_start; 1039 return address_space_end - address_space_start;
1035 case MemoryState::Normal: 1040 case KMemoryState::Normal:
1036 return heap_region_end - heap_region_start; 1041 return heap_region_end - heap_region_start;
1037 case MemoryState::Ipc: 1042 case KMemoryState::Ipc:
1038 case MemoryState::NonSecureIpc: 1043 case KMemoryState::NonSecureIpc:
1039 case MemoryState::NonDeviceIpc: 1044 case KMemoryState::NonDeviceIpc:
1040 return alias_region_end - alias_region_start; 1045 return alias_region_end - alias_region_start;
1041 case MemoryState::Stack: 1046 case KMemoryState::Stack:
1042 return stack_region_end - stack_region_start; 1047 return stack_region_end - stack_region_start;
1043 case MemoryState::Io: 1048 case KMemoryState::Io:
1044 case MemoryState::Static: 1049 case KMemoryState::Static:
1045 case MemoryState::ThreadLocal: 1050 case KMemoryState::ThreadLocal:
1046 return kernel_map_region_end - kernel_map_region_start; 1051 return kernel_map_region_end - kernel_map_region_start;
1047 case MemoryState::Shared: 1052 case KMemoryState::Shared:
1048 case MemoryState::AliasCode: 1053 case KMemoryState::AliasCode:
1049 case MemoryState::AliasCodeData: 1054 case KMemoryState::AliasCodeData:
1050 case MemoryState::Transferred: 1055 case KMemoryState::Transferred:
1051 case MemoryState::SharedTransferred: 1056 case KMemoryState::SharedTransferred:
1052 case MemoryState::SharedCode: 1057 case KMemoryState::SharedCode:
1053 case MemoryState::GeneratedCode: 1058 case KMemoryState::GeneratedCode:
1054 case MemoryState::CodeOut: 1059 case KMemoryState::CodeOut:
1055 return alias_code_region_end - alias_code_region_start; 1060 return alias_code_region_end - alias_code_region_start;
1056 case MemoryState::Code: 1061 case KMemoryState::Code:
1057 case MemoryState::CodeData: 1062 case KMemoryState::CodeData:
1058 return code_region_end - code_region_start; 1063 return code_region_end - code_region_start;
1059 default: 1064 default:
1060 UNREACHABLE(); 1065 UNREACHABLE();
@@ -1062,7 +1067,7 @@ constexpr std::size_t PageTable::GetRegionSize(MemoryState state) const {
1062 } 1067 }
1063} 1068}
1064 1069
1065constexpr bool PageTable::CanContain(VAddr addr, std::size_t size, MemoryState state) const { 1070constexpr bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) const {
1066 const VAddr end{addr + size}; 1071 const VAddr end{addr + size};
1067 const VAddr last{end - 1}; 1072 const VAddr last{end - 1};
1068 const VAddr region_start{GetRegionAddress(state)}; 1073 const VAddr region_start{GetRegionAddress(state)};
@@ -1073,30 +1078,30 @@ constexpr bool PageTable::CanContain(VAddr addr, std::size_t size, MemoryState s
1073 const bool is_in_alias{!(end <= alias_region_start || alias_region_end <= addr)}; 1078 const bool is_in_alias{!(end <= alias_region_start || alias_region_end <= addr)};
1074 1079
1075 switch (state) { 1080 switch (state) {
1076 case MemoryState::Free: 1081 case KMemoryState::Free:
1077 case MemoryState::Kernel: 1082 case KMemoryState::Kernel:
1078 return is_in_region; 1083 return is_in_region;
1079 case MemoryState::Io: 1084 case KMemoryState::Io:
1080 case MemoryState::Static: 1085 case KMemoryState::Static:
1081 case MemoryState::Code: 1086 case KMemoryState::Code:
1082 case MemoryState::CodeData: 1087 case KMemoryState::CodeData:
1083 case MemoryState::Shared: 1088 case KMemoryState::Shared:
1084 case MemoryState::AliasCode: 1089 case KMemoryState::AliasCode:
1085 case MemoryState::AliasCodeData: 1090 case KMemoryState::AliasCodeData:
1086 case MemoryState::Stack: 1091 case KMemoryState::Stack:
1087 case MemoryState::ThreadLocal: 1092 case KMemoryState::ThreadLocal:
1088 case MemoryState::Transferred: 1093 case KMemoryState::Transferred:
1089 case MemoryState::SharedTransferred: 1094 case KMemoryState::SharedTransferred:
1090 case MemoryState::SharedCode: 1095 case KMemoryState::SharedCode:
1091 case MemoryState::GeneratedCode: 1096 case KMemoryState::GeneratedCode:
1092 case MemoryState::CodeOut: 1097 case KMemoryState::CodeOut:
1093 return is_in_region && !is_in_heap && !is_in_alias; 1098 return is_in_region && !is_in_heap && !is_in_alias;
1094 case MemoryState::Normal: 1099 case KMemoryState::Normal:
1095 ASSERT(is_in_heap); 1100 ASSERT(is_in_heap);
1096 return is_in_region && !is_in_alias; 1101 return is_in_region && !is_in_alias;
1097 case MemoryState::Ipc: 1102 case KMemoryState::Ipc:
1098 case MemoryState::NonSecureIpc: 1103 case KMemoryState::NonSecureIpc:
1099 case MemoryState::NonDeviceIpc: 1104 case KMemoryState::NonDeviceIpc:
1100 ASSERT(is_in_alias); 1105 ASSERT(is_in_alias);
1101 return is_in_region && !is_in_heap; 1106 return is_in_region && !is_in_heap;
1102 default: 1107 default:
@@ -1104,10 +1109,11 @@ constexpr bool PageTable::CanContain(VAddr addr, std::size_t size, MemoryState s
1104 } 1109 }
1105} 1110}
1106 1111
1107constexpr ResultCode PageTable::CheckMemoryState(const MemoryInfo& info, MemoryState state_mask, 1112constexpr ResultCode KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask,
1108 MemoryState state, MemoryPermission perm_mask, 1113 KMemoryState state, KMemoryPermission perm_mask,
1109 MemoryPermission perm, MemoryAttribute attr_mask, 1114 KMemoryPermission perm,
1110 MemoryAttribute attr) const { 1115 KMemoryAttribute attr_mask,
1116 KMemoryAttribute attr) const {
1111 // Validate the states match expectation 1117 // Validate the states match expectation
1112 if ((info.state & state_mask) != state) { 1118 if ((info.state & state_mask) != state) {
1113 return ResultInvalidCurrentMemory; 1119 return ResultInvalidCurrentMemory;
@@ -1122,23 +1128,23 @@ constexpr ResultCode PageTable::CheckMemoryState(const MemoryInfo& info, MemoryS
1122 return RESULT_SUCCESS; 1128 return RESULT_SUCCESS;
1123} 1129}
1124 1130
1125ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission* out_perm, 1131ResultCode KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
1126 MemoryAttribute* out_attr, VAddr addr, std::size_t size, 1132 KMemoryAttribute* out_attr, VAddr addr, std::size_t size,
1127 MemoryState state_mask, MemoryState state, 1133 KMemoryState state_mask, KMemoryState state,
1128 MemoryPermission perm_mask, MemoryPermission perm, 1134 KMemoryPermission perm_mask, KMemoryPermission perm,
1129 MemoryAttribute attr_mask, MemoryAttribute attr, 1135 KMemoryAttribute attr_mask, KMemoryAttribute attr,
1130 MemoryAttribute ignore_attr) { 1136 KMemoryAttribute ignore_attr) {
1131 std::lock_guard lock{page_table_lock}; 1137 std::lock_guard lock{page_table_lock};
1132 1138
1133 // Get information about the first block 1139 // Get information about the first block
1134 const VAddr last_addr{addr + size - 1}; 1140 const VAddr last_addr{addr + size - 1};
1135 MemoryBlockManager::const_iterator it{block_manager->FindIterator(addr)}; 1141 KMemoryBlockManager::const_iterator it{block_manager->FindIterator(addr)};
1136 MemoryInfo info{it->GetMemoryInfo()}; 1142 KMemoryInfo info{it->GetMemoryInfo()};
1137 1143
1138 // Validate all blocks in the range have correct state 1144 // Validate all blocks in the range have correct state
1139 const MemoryState first_state{info.state}; 1145 const KMemoryState first_state{info.state};
1140 const MemoryPermission first_perm{info.perm}; 1146 const KMemoryPermission first_perm{info.perm};
1141 const MemoryAttribute first_attr{info.attribute}; 1147 const KMemoryAttribute first_attr{info.attribute};
1142 1148
1143 while (true) { 1149 while (true) {
1144 // Validate the current block 1150 // Validate the current block
@@ -1148,8 +1154,8 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission*
1148 if (!(info.perm == first_perm)) { 1154 if (!(info.perm == first_perm)) {
1149 return ResultInvalidCurrentMemory; 1155 return ResultInvalidCurrentMemory;
1150 } 1156 }
1151 if (!((info.attribute | static_cast<MemoryAttribute>(ignore_attr)) == 1157 if (!((info.attribute | static_cast<KMemoryAttribute>(ignore_attr)) ==
1152 (first_attr | static_cast<MemoryAttribute>(ignore_attr)))) { 1158 (first_attr | static_cast<KMemoryAttribute>(ignore_attr)))) {
1153 return ResultInvalidCurrentMemory; 1159 return ResultInvalidCurrentMemory;
1154 } 1160 }
1155 1161
@@ -1175,10 +1181,10 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission*
1175 *out_perm = first_perm; 1181 *out_perm = first_perm;
1176 } 1182 }
1177 if (out_attr) { 1183 if (out_attr) {
1178 *out_attr = first_attr & static_cast<MemoryAttribute>(~ignore_attr); 1184 *out_attr = first_attr & static_cast<KMemoryAttribute>(~ignore_attr);
1179 } 1185 }
1180 1186
1181 return RESULT_SUCCESS; 1187 return RESULT_SUCCESS;
1182} 1188}
1183 1189
1184} // namespace Kernel::Memory 1190} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/page_table.h b/src/core/hle/kernel/k_page_table.h
index ce0d38849..49b824379 100644
--- a/src/core/hle/kernel/memory/page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -10,27 +10,27 @@
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/page_table.h" 11#include "common/page_table.h"
12#include "core/file_sys/program_metadata.h" 12#include "core/file_sys/program_metadata.h"
13#include "core/hle/kernel/memory/memory_block.h" 13#include "core/hle/kernel/k_memory_block.h"
14#include "core/hle/kernel/memory/memory_manager.h" 14#include "core/hle/kernel/k_memory_manager.h"
15#include "core/hle/result.h" 15#include "core/hle/result.h"
16 16
17namespace Core { 17namespace Core {
18class System; 18class System;
19} 19}
20 20
21namespace Kernel::Memory { 21namespace Kernel {
22 22
23class MemoryBlockManager; 23class KMemoryBlockManager;
24 24
25class PageTable final : NonCopyable { 25class KPageTable final : NonCopyable {
26public: 26public:
27 explicit PageTable(Core::System& system); 27 explicit KPageTable(Core::System& system);
28 28
29 ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, 29 ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
30 VAddr code_addr, std::size_t code_size, 30 VAddr code_addr, std::size_t code_size,
31 Memory::MemoryManager::Pool pool); 31 KMemoryManager::Pool pool);
32 ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, MemoryState state, 32 ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state,
33 MemoryPermission perm); 33 KMemoryPermission perm);
34 ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); 34 ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size);
35 ResultCode UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); 35 ResultCode UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size);
36 ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); 36 ResultCode MapPhysicalMemory(VAddr addr, std::size_t size);
@@ -38,20 +38,20 @@ public:
38 ResultCode UnmapMemory(VAddr addr, std::size_t size); 38 ResultCode UnmapMemory(VAddr addr, std::size_t size);
39 ResultCode Map(VAddr dst_addr, VAddr src_addr, std::size_t size); 39 ResultCode Map(VAddr dst_addr, VAddr src_addr, std::size_t size);
40 ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size); 40 ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size);
41 ResultCode MapPages(VAddr addr, PageLinkedList& page_linked_list, MemoryState state, 41 ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state,
42 MemoryPermission perm); 42 KMemoryPermission perm);
43 ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, MemoryPermission perm); 43 ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm);
44 MemoryInfo QueryInfo(VAddr addr); 44 KMemoryInfo QueryInfo(VAddr addr);
45 ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, MemoryPermission perm); 45 ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm);
46 ResultCode ResetTransferMemory(VAddr addr, std::size_t size); 46 ResultCode ResetTransferMemory(VAddr addr, std::size_t size);
47 ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAttribute mask, 47 ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask,
48 MemoryAttribute value); 48 KMemoryAttribute value);
49 ResultCode SetHeapCapacity(std::size_t new_heap_capacity); 49 ResultCode SetHeapCapacity(std::size_t new_heap_capacity);
50 ResultVal<VAddr> SetHeapSize(std::size_t size); 50 ResultVal<VAddr> SetHeapSize(std::size_t size);
51 ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, 51 ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align,
52 bool is_map_only, VAddr region_start, 52 bool is_map_only, VAddr region_start,
53 std::size_t region_num_pages, MemoryState state, 53 std::size_t region_num_pages, KMemoryState state,
54 MemoryPermission perm, PAddr map_addr = 0); 54 KMemoryPermission perm, PAddr map_addr = 0);
55 ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size); 55 ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size);
56 ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); 56 ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size);
57 57
@@ -72,47 +72,49 @@ private:
72 ChangePermissionsAndRefresh, 72 ChangePermissionsAndRefresh,
73 }; 73 };
74 74
75 static constexpr MemoryAttribute DefaultMemoryIgnoreAttr = 75 static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr = KMemoryAttribute::DontCareMask |
76 MemoryAttribute::DontCareMask | MemoryAttribute::IpcLocked | MemoryAttribute::DeviceShared; 76 KMemoryAttribute::IpcLocked |
77 KMemoryAttribute::DeviceShared;
77 78
78 ResultCode InitializeMemoryLayout(VAddr start, VAddr end); 79 ResultCode InitializeMemoryLayout(VAddr start, VAddr end);
79 ResultCode MapPages(VAddr addr, const PageLinkedList& page_linked_list, MemoryPermission perm); 80 ResultCode MapPages(VAddr addr, const KPageLinkedList& page_linked_list,
80 void MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, VAddr end); 81 KMemoryPermission perm);
82 void MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end);
81 bool IsRegionMapped(VAddr address, u64 size); 83 bool IsRegionMapped(VAddr address, u64 size);
82 bool IsRegionContiguous(VAddr addr, u64 size) const; 84 bool IsRegionContiguous(VAddr addr, u64 size) const;
83 void AddRegionToPages(VAddr start, std::size_t num_pages, PageLinkedList& page_linked_list); 85 void AddRegionToPages(VAddr start, std::size_t num_pages, KPageLinkedList& page_linked_list);
84 MemoryInfo QueryInfoImpl(VAddr addr); 86 KMemoryInfo QueryInfoImpl(VAddr addr);
85 VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages, 87 VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages,
86 std::size_t align); 88 std::size_t align);
87 ResultCode Operate(VAddr addr, std::size_t num_pages, const PageLinkedList& page_group, 89 ResultCode Operate(VAddr addr, std::size_t num_pages, const KPageLinkedList& page_group,
88 OperationType operation); 90 OperationType operation);
89 ResultCode Operate(VAddr addr, std::size_t num_pages, MemoryPermission perm, 91 ResultCode Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm,
90 OperationType operation, PAddr map_addr = 0); 92 OperationType operation, PAddr map_addr = 0);
91 constexpr VAddr GetRegionAddress(MemoryState state) const; 93 constexpr VAddr GetRegionAddress(KMemoryState state) const;
92 constexpr std::size_t GetRegionSize(MemoryState state) const; 94 constexpr std::size_t GetRegionSize(KMemoryState state) const;
93 constexpr bool CanContain(VAddr addr, std::size_t size, MemoryState state) const; 95 constexpr bool CanContain(VAddr addr, std::size_t size, KMemoryState state) const;
94 96
95 constexpr ResultCode CheckMemoryState(const MemoryInfo& info, MemoryState state_mask, 97 constexpr ResultCode CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask,
96 MemoryState state, MemoryPermission perm_mask, 98 KMemoryState state, KMemoryPermission perm_mask,
97 MemoryPermission perm, MemoryAttribute attr_mask, 99 KMemoryPermission perm, KMemoryAttribute attr_mask,
98 MemoryAttribute attr) const; 100 KMemoryAttribute attr) const;
99 ResultCode CheckMemoryState(MemoryState* out_state, MemoryPermission* out_perm, 101 ResultCode CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
100 MemoryAttribute* out_attr, VAddr addr, std::size_t size, 102 KMemoryAttribute* out_attr, VAddr addr, std::size_t size,
101 MemoryState state_mask, MemoryState state, 103 KMemoryState state_mask, KMemoryState state,
102 MemoryPermission perm_mask, MemoryPermission perm, 104 KMemoryPermission perm_mask, KMemoryPermission perm,
103 MemoryAttribute attr_mask, MemoryAttribute attr, 105 KMemoryAttribute attr_mask, KMemoryAttribute attr,
104 MemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr); 106 KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr);
105 ResultCode CheckMemoryState(VAddr addr, std::size_t size, MemoryState state_mask, 107 ResultCode CheckMemoryState(VAddr addr, std::size_t size, KMemoryState state_mask,
106 MemoryState state, MemoryPermission perm_mask, 108 KMemoryState state, KMemoryPermission perm_mask,
107 MemoryPermission perm, MemoryAttribute attr_mask, 109 KMemoryPermission perm, KMemoryAttribute attr_mask,
108 MemoryAttribute attr, 110 KMemoryAttribute attr,
109 MemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) { 111 KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) {
110 return CheckMemoryState(nullptr, nullptr, nullptr, addr, size, state_mask, state, perm_mask, 112 return CheckMemoryState(nullptr, nullptr, nullptr, addr, size, state_mask, state, perm_mask,
111 perm, attr_mask, attr, ignore_attr); 113 perm, attr_mask, attr, ignore_attr);
112 } 114 }
113 115
114 std::recursive_mutex page_table_lock; 116 std::recursive_mutex page_table_lock;
115 std::unique_ptr<MemoryBlockManager> block_manager; 117 std::unique_ptr<KMemoryBlockManager> block_manager;
116 118
117public: 119public:
118 constexpr VAddr GetAddressSpaceStart() const { 120 constexpr VAddr GetAddressSpaceStart() const {
@@ -212,7 +214,7 @@ public:
212 return !IsOutsideASLRRegion(address, size); 214 return !IsOutsideASLRRegion(address, size);
213 } 215 }
214 constexpr PAddr GetPhysicalAddr(VAddr addr) { 216 constexpr PAddr GetPhysicalAddr(VAddr addr) {
215 return page_table_impl.backing_addr[addr >> Memory::PageBits] + addr; 217 return page_table_impl.backing_addr[addr >> PageBits] + addr;
216 } 218 }
217 219
218private: 220private:
@@ -267,11 +269,11 @@ private:
267 bool is_kernel{}; 269 bool is_kernel{};
268 bool is_aslr_enabled{}; 270 bool is_aslr_enabled{};
269 271
270 MemoryManager::Pool memory_pool{MemoryManager::Pool::Application}; 272 KMemoryManager::Pool memory_pool{KMemoryManager::Pool::Application};
271 273
272 Common::PageTable page_table_impl; 274 Common::PageTable page_table_impl;
273 275
274 Core::System& system; 276 Core::System& system;
275}; 277};
276 278
277} // namespace Kernel::Memory 279} // namespace Kernel
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index 2eadd51d7..9b14f42b5 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -4,33 +4,32 @@
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hle/kernel/k_page_table.h"
7#include "core/hle/kernel/k_scoped_resource_reservation.h" 8#include "core/hle/kernel/k_scoped_resource_reservation.h"
9#include "core/hle/kernel/k_shared_memory.h"
8#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
9#include "core/hle/kernel/memory/page_table.h"
10#include "core/hle/kernel/shared_memory.h"
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14SharedMemory::SharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory) 14KSharedMemory::KSharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory)
15 : Object{kernel}, device_memory{device_memory} {} 15 : Object{kernel}, device_memory{device_memory} {}
16 16
17SharedMemory::~SharedMemory() { 17KSharedMemory::~KSharedMemory() {
18 kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size); 18 kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size);
19} 19}
20 20
21std::shared_ptr<SharedMemory> SharedMemory::Create( 21std::shared_ptr<KSharedMemory> KSharedMemory::Create(
22 KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, 22 KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process,
23 Memory::PageLinkedList&& page_list, Memory::MemoryPermission owner_permission, 23 KPageLinkedList&& page_list, KMemoryPermission owner_permission,
24 Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, 24 KMemoryPermission user_permission, PAddr physical_address, std::size_t size, std::string name) {
25 std::string name) {
26 25
27 const auto resource_limit = kernel.GetSystemResourceLimit(); 26 const auto resource_limit = kernel.GetSystemResourceLimit();
28 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, 27 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
29 size); 28 size);
30 ASSERT(memory_reservation.Succeeded()); 29 ASSERT(memory_reservation.Succeeded());
31 30
32 std::shared_ptr<SharedMemory> shared_memory{ 31 std::shared_ptr<KSharedMemory> shared_memory{
33 std::make_shared<SharedMemory>(kernel, device_memory)}; 32 std::make_shared<KSharedMemory>(kernel, device_memory)};
34 33
35 shared_memory->owner_process = owner_process; 34 shared_memory->owner_process = owner_process;
36 shared_memory->page_list = std::move(page_list); 35 shared_memory->page_list = std::move(page_list);
@@ -44,22 +43,22 @@ std::shared_ptr<SharedMemory> SharedMemory::Create(
44 return shared_memory; 43 return shared_memory;
45} 44}
46 45
47ResultCode SharedMemory::Map(Process& target_process, VAddr address, std::size_t size, 46ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_t size,
48 Memory::MemoryPermission permissions) { 47 KMemoryPermission permissions) {
49 const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize}; 48 const u64 page_count{(size + PageSize - 1) / PageSize};
50 49
51 if (page_list.GetNumPages() != page_count) { 50 if (page_list.GetNumPages() != page_count) {
52 UNIMPLEMENTED_MSG("Page count does not match"); 51 UNIMPLEMENTED_MSG("Page count does not match");
53 } 52 }
54 53
55 const Memory::MemoryPermission expected = 54 const KMemoryPermission expected =
56 &target_process == owner_process ? owner_permission : user_permission; 55 &target_process == owner_process ? owner_permission : user_permission;
57 56
58 if (permissions != expected) { 57 if (permissions != expected) {
59 UNIMPLEMENTED_MSG("Permission does not match"); 58 UNIMPLEMENTED_MSG("Permission does not match");
60 } 59 }
61 60
62 return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared, 61 return target_process.PageTable().MapPages(address, page_list, KMemoryState::Shared,
63 permissions); 62 permissions);
64} 63}
65 64
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/k_shared_memory.h
index 623bd8b11..016e34be5 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/k_shared_memory.h
@@ -9,8 +9,8 @@
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/device_memory.h" 11#include "core/device_memory.h"
12#include "core/hle/kernel/memory/memory_block.h" 12#include "core/hle/kernel/k_memory_block.h"
13#include "core/hle/kernel/memory/page_linked_list.h" 13#include "core/hle/kernel/k_page_linked_list.h"
14#include "core/hle/kernel/object.h" 14#include "core/hle/kernel/object.h"
15#include "core/hle/kernel/process.h" 15#include "core/hle/kernel/process.h"
16#include "core/hle/result.h" 16#include "core/hle/result.h"
@@ -19,15 +19,15 @@ namespace Kernel {
19 19
20class KernelCore; 20class KernelCore;
21 21
22class SharedMemory final : public Object { 22class KSharedMemory final : public Object {
23public: 23public:
24 explicit SharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory); 24 explicit KSharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory);
25 ~SharedMemory() override; 25 ~KSharedMemory() override;
26 26
27 static std::shared_ptr<SharedMemory> Create( 27 static std::shared_ptr<KSharedMemory> Create(
28 KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, 28 KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process,
29 Memory::PageLinkedList&& page_list, Memory::MemoryPermission owner_permission, 29 KPageLinkedList&& page_list, KMemoryPermission owner_permission,
30 Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, 30 KMemoryPermission user_permission, PAddr physical_address, std::size_t size,
31 std::string name); 31 std::string name);
32 32
33 std::string GetTypeName() const override { 33 std::string GetTypeName() const override {
@@ -51,7 +51,7 @@ public:
51 * @param permissions Memory block map permissions (specified by SVC field) 51 * @param permissions Memory block map permissions (specified by SVC field)
52 */ 52 */
53 ResultCode Map(Process& target_process, VAddr address, std::size_t size, 53 ResultCode Map(Process& target_process, VAddr address, std::size_t size,
54 Memory::MemoryPermission permissions); 54 KMemoryPermission permissions);
55 55
56 /** 56 /**
57 * Gets a pointer to the shared memory block 57 * Gets a pointer to the shared memory block
@@ -76,9 +76,9 @@ public:
76private: 76private:
77 Core::DeviceMemory& device_memory; 77 Core::DeviceMemory& device_memory;
78 Process* owner_process{}; 78 Process* owner_process{};
79 Memory::PageLinkedList page_list; 79 KPageLinkedList page_list;
80 Memory::MemoryPermission owner_permission{}; 80 KMemoryPermission owner_permission{};
81 Memory::MemoryPermission user_permission{}; 81 KMemoryPermission user_permission{};
82 PAddr physical_address{}; 82 PAddr physical_address{};
83 std::size_t size{}; 83 std::size_t size{};
84 std::string name; 84 std::string name;
diff --git a/src/core/hle/kernel/memory/slab_heap.h b/src/core/hle/kernel/k_slab_heap.h
index 465eaddb3..aa4471d2f 100644
--- a/src/core/hle/kernel/memory/slab_heap.h
+++ b/src/core/hle/kernel/k_slab_heap.h
@@ -2,9 +2,6 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once 5#pragma once
9 6
10#include <atomic> 7#include <atomic>
@@ -12,17 +9,17 @@
12#include "common/assert.h" 9#include "common/assert.h"
13#include "common/common_types.h" 10#include "common/common_types.h"
14 11
15namespace Kernel::Memory { 12namespace Kernel {
16 13
17namespace impl { 14namespace impl {
18 15
19class SlabHeapImpl final : NonCopyable { 16class KSlabHeapImpl final : NonCopyable {
20public: 17public:
21 struct Node { 18 struct Node {
22 Node* next{}; 19 Node* next{};
23 }; 20 };
24 21
25 constexpr SlabHeapImpl() = default; 22 constexpr KSlabHeapImpl() = default;
26 23
27 void Initialize(std::size_t size) { 24 void Initialize(std::size_t size) {
28 ASSERT(head == nullptr); 25 ASSERT(head == nullptr);
@@ -65,9 +62,9 @@ private:
65 62
66} // namespace impl 63} // namespace impl
67 64
68class SlabHeapBase : NonCopyable { 65class KSlabHeapBase : NonCopyable {
69public: 66public:
70 constexpr SlabHeapBase() = default; 67 constexpr KSlabHeapBase() = default;
71 68
72 constexpr bool Contains(uintptr_t addr) const { 69 constexpr bool Contains(uintptr_t addr) const {
73 return start <= addr && addr < end; 70 return start <= addr && addr < end;
@@ -126,7 +123,7 @@ public:
126 } 123 }
127 124
128private: 125private:
129 using Impl = impl::SlabHeapImpl; 126 using Impl = impl::KSlabHeapImpl;
130 127
131 Impl impl; 128 Impl impl;
132 uintptr_t peak{}; 129 uintptr_t peak{};
@@ -135,9 +132,9 @@ private:
135}; 132};
136 133
137template <typename T> 134template <typename T>
138class SlabHeap final : public SlabHeapBase { 135class KSlabHeap final : public KSlabHeapBase {
139public: 136public:
140 constexpr SlabHeap() : SlabHeapBase() {} 137 constexpr KSlabHeap() : KSlabHeapBase() {}
141 138
142 void Initialize(void* memory, std::size_t memory_size) { 139 void Initialize(void* memory, std::size_t memory_size) {
143 InitializeImpl(sizeof(T), memory, memory_size); 140 InitializeImpl(sizeof(T), memory, memory_size);
@@ -160,4 +157,4 @@ public:
160 } 157 }
161}; 158};
162 159
163} // namespace Kernel::Memory 160} // namespace Kernel
diff --git a/src/core/hle/kernel/k_spin_lock.cpp b/src/core/hle/kernel/k_spin_lock.cpp
new file mode 100644
index 000000000..4412aa4bb
--- /dev/null
+++ b/src/core/hle/kernel/k_spin_lock.cpp
@@ -0,0 +1,54 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/kernel/k_spin_lock.h"
6
7#if _MSC_VER
8#include <intrin.h>
9#if _M_AMD64
10#define __x86_64__ 1
11#endif
12#if _M_ARM64
13#define __aarch64__ 1
14#endif
15#else
16#if __x86_64__
17#include <xmmintrin.h>
18#endif
19#endif
20
21namespace {
22
23void ThreadPause() {
24#if __x86_64__
25 _mm_pause();
26#elif __aarch64__ && _MSC_VER
27 __yield();
28#elif __aarch64__
29 asm("yield");
30#endif
31}
32
33} // namespace
34
35namespace Kernel {
36
37void KSpinLock::Lock() {
38 while (lck.test_and_set(std::memory_order_acquire)) {
39 ThreadPause();
40 }
41}
42
43void KSpinLock::Unlock() {
44 lck.clear(std::memory_order_release);
45}
46
47bool KSpinLock::TryLock() {
48 if (lck.test_and_set(std::memory_order_acquire)) {
49 return false;
50 }
51 return true;
52}
53
54} // namespace Kernel
diff --git a/src/core/hle/kernel/k_spin_lock.h b/src/core/hle/kernel/k_spin_lock.h
new file mode 100644
index 000000000..12c4b2e88
--- /dev/null
+++ b/src/core/hle/kernel/k_spin_lock.h
@@ -0,0 +1,33 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <atomic>
8
9#include "core/hle/kernel/k_scoped_lock.h"
10
11namespace Kernel {
12
13class KSpinLock {
14public:
15 KSpinLock() = default;
16
17 KSpinLock(const KSpinLock&) = delete;
18 KSpinLock& operator=(const KSpinLock&) = delete;
19
20 KSpinLock(KSpinLock&&) = delete;
21 KSpinLock& operator=(KSpinLock&&) = delete;
22
23 void Lock();
24 void Unlock();
25 [[nodiscard]] bool TryLock();
26
27private:
28 std::atomic_flag lck = ATOMIC_FLAG_INIT;
29};
30
31using KScopedSpinLock = KScopedLock<KSpinLock>;
32
33} // namespace Kernel
diff --git a/src/core/hle/kernel/memory/system_control.cpp b/src/core/hle/kernel/k_system_control.cpp
index 11d204bc2..aa1682f69 100644
--- a/src/core/hle/kernel/memory/system_control.cpp
+++ b/src/core/hle/kernel/k_system_control.cpp
@@ -1,12 +1,13 @@
1// Copyright 2020 yuzu Emulator Project 1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <random> 5#include <random>
6 6
7#include "core/hle/kernel/memory/system_control.h" 7#include "core/hle/kernel/k_system_control.h"
8
9namespace Kernel {
8 10
9namespace Kernel::Memory::SystemControl {
10namespace { 11namespace {
11template <typename F> 12template <typename F>
12u64 GenerateUniformRange(u64 min, u64 max, F f) { 13u64 GenerateUniformRange(u64 min, u64 max, F f) {
@@ -25,16 +26,17 @@ u64 GenerateUniformRange(u64 min, u64 max, F f) {
25 } 26 }
26} 27}
27 28
28u64 GenerateRandomU64ForInit() { 29} // Anonymous namespace
30
31u64 KSystemControl::GenerateRandomU64() {
29 static std::random_device device; 32 static std::random_device device;
30 static std::mt19937 gen(device()); 33 static std::mt19937 gen(device());
31 static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); 34 static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
32 return distribution(gen); 35 return distribution(gen);
33} 36}
34} // Anonymous namespace
35 37
36u64 GenerateRandomRange(u64 min, u64 max) { 38u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) {
37 return GenerateUniformRange(min, max, GenerateRandomU64ForInit); 39 return GenerateUniformRange(min, max, GenerateRandomU64);
38} 40}
39 41
40} // namespace Kernel::Memory::SystemControl 42} // namespace Kernel
diff --git a/src/core/hle/kernel/k_system_control.h b/src/core/hle/kernel/k_system_control.h
new file mode 100644
index 000000000..1d5b64ffa
--- /dev/null
+++ b/src/core/hle/kernel/k_system_control.h
@@ -0,0 +1,19 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9namespace Kernel {
10
11class KSystemControl {
12public:
13 KSystemControl() = default;
14
15 static u64 GenerateRandomRange(u64 min, u64 max);
16 static u64 GenerateRandomU64();
17};
18
19} // namespace Kernel
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index e5620da5a..1661afbd9 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -20,13 +20,13 @@
20#include "core/hardware_properties.h" 20#include "core/hardware_properties.h"
21#include "core/hle/kernel/handle_table.h" 21#include "core/hle/kernel/handle_table.h"
22#include "core/hle/kernel/k_condition_variable.h" 22#include "core/hle/kernel/k_condition_variable.h"
23#include "core/hle/kernel/k_memory_layout.h"
23#include "core/hle/kernel/k_resource_limit.h" 24#include "core/hle/kernel/k_resource_limit.h"
24#include "core/hle/kernel/k_scheduler.h" 25#include "core/hle/kernel/k_scheduler.h"
25#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 26#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
26#include "core/hle/kernel/k_thread.h" 27#include "core/hle/kernel/k_thread.h"
27#include "core/hle/kernel/k_thread_queue.h" 28#include "core/hle/kernel/k_thread_queue.h"
28#include "core/hle/kernel/kernel.h" 29#include "core/hle/kernel/kernel.h"
29#include "core/hle/kernel/memory/memory_layout.h"
30#include "core/hle/kernel/object.h" 30#include "core/hle/kernel/object.h"
31#include "core/hle/kernel/process.h" 31#include "core/hle/kernel/process.h"
32#include "core/hle/kernel/svc_results.h" 32#include "core/hle/kernel/svc_results.h"
@@ -782,7 +782,7 @@ void KThread::AddWaiterImpl(KThread* thread) {
782 } 782 }
783 783
784 // Keep track of how many kernel waiters we have. 784 // Keep track of how many kernel waiters we have.
785 if (Memory::IsKernelAddressKey(thread->GetAddressKey())) { 785 if (IsKernelAddressKey(thread->GetAddressKey())) {
786 ASSERT((num_kernel_waiters++) >= 0); 786 ASSERT((num_kernel_waiters++) >= 0);
787 } 787 }
788 788
@@ -795,7 +795,7 @@ void KThread::RemoveWaiterImpl(KThread* thread) {
795 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 795 ASSERT(kernel.GlobalSchedulerContext().IsLocked());
796 796
797 // Keep track of how many kernel waiters we have. 797 // Keep track of how many kernel waiters we have.
798 if (Memory::IsKernelAddressKey(thread->GetAddressKey())) { 798 if (IsKernelAddressKey(thread->GetAddressKey())) {
799 ASSERT((num_kernel_waiters--) > 0); 799 ASSERT((num_kernel_waiters--) > 0);
800 } 800 }
801 801
@@ -870,7 +870,7 @@ KThread* KThread::RemoveWaiterByKey(s32* out_num_waiters, VAddr key) {
870 KThread* thread = std::addressof(*it); 870 KThread* thread = std::addressof(*it);
871 871
872 // Keep track of how many kernel waiters we have. 872 // Keep track of how many kernel waiters we have.
873 if (Memory::IsKernelAddressKey(thread->GetAddressKey())) { 873 if (IsKernelAddressKey(thread->GetAddressKey())) {
874 ASSERT((num_kernel_waiters--) > 0); 874 ASSERT((num_kernel_waiters--) > 0);
875 } 875 }
876 it = waiter_list.erase(it); 876 it = waiter_list.erase(it);
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 39c5182c5..331cf3a60 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -27,17 +27,17 @@
27#include "core/hardware_properties.h" 27#include "core/hardware_properties.h"
28#include "core/hle/kernel/client_port.h" 28#include "core/hle/kernel/client_port.h"
29#include "core/hle/kernel/handle_table.h" 29#include "core/hle/kernel/handle_table.h"
30#include "core/hle/kernel/k_memory_layout.h"
31#include "core/hle/kernel/k_memory_manager.h"
30#include "core/hle/kernel/k_resource_limit.h" 32#include "core/hle/kernel/k_resource_limit.h"
31#include "core/hle/kernel/k_scheduler.h" 33#include "core/hle/kernel/k_scheduler.h"
34#include "core/hle/kernel/k_shared_memory.h"
35#include "core/hle/kernel/k_slab_heap.h"
32#include "core/hle/kernel/k_thread.h" 36#include "core/hle/kernel/k_thread.h"
33#include "core/hle/kernel/kernel.h" 37#include "core/hle/kernel/kernel.h"
34#include "core/hle/kernel/memory/memory_layout.h"
35#include "core/hle/kernel/memory/memory_manager.h"
36#include "core/hle/kernel/memory/slab_heap.h"
37#include "core/hle/kernel/physical_core.h" 38#include "core/hle/kernel/physical_core.h"
38#include "core/hle/kernel/process.h" 39#include "core/hle/kernel/process.h"
39#include "core/hle/kernel/service_thread.h" 40#include "core/hle/kernel/service_thread.h"
40#include "core/hle/kernel/shared_memory.h"
41#include "core/hle/kernel/svc_results.h" 41#include "core/hle/kernel/svc_results.h"
42#include "core/hle/kernel/time_manager.h" 42#include "core/hle/kernel/time_manager.h"
43#include "core/hle/lock.h" 43#include "core/hle/lock.h"
@@ -271,7 +271,7 @@ struct KernelCore::Impl {
271 271
272 void InitializeMemoryLayout() { 272 void InitializeMemoryLayout() {
273 // Initialize memory layout 273 // Initialize memory layout
274 constexpr Memory::MemoryLayout layout{Memory::MemoryLayout::GetDefaultLayout()}; 274 constexpr KMemoryLayout layout{KMemoryLayout::GetDefaultLayout()};
275 constexpr std::size_t hid_size{0x40000}; 275 constexpr std::size_t hid_size{0x40000};
276 constexpr std::size_t font_size{0x1100000}; 276 constexpr std::size_t font_size{0x1100000};
277 constexpr std::size_t irs_size{0x8000}; 277 constexpr std::size_t irs_size{0x8000};
@@ -282,36 +282,36 @@ struct KernelCore::Impl {
282 constexpr PAddr time_addr{layout.System().StartAddress() + hid_size + font_size + irs_size}; 282 constexpr PAddr time_addr{layout.System().StartAddress() + hid_size + font_size + irs_size};
283 283
284 // Initialize memory manager 284 // Initialize memory manager
285 memory_manager = std::make_unique<Memory::MemoryManager>(); 285 memory_manager = std::make_unique<KMemoryManager>();
286 memory_manager->InitializeManager(Memory::MemoryManager::Pool::Application, 286 memory_manager->InitializeManager(KMemoryManager::Pool::Application,
287 layout.Application().StartAddress(), 287 layout.Application().StartAddress(),
288 layout.Application().EndAddress()); 288 layout.Application().EndAddress());
289 memory_manager->InitializeManager(Memory::MemoryManager::Pool::Applet, 289 memory_manager->InitializeManager(KMemoryManager::Pool::Applet,
290 layout.Applet().StartAddress(), 290 layout.Applet().StartAddress(),
291 layout.Applet().EndAddress()); 291 layout.Applet().EndAddress());
292 memory_manager->InitializeManager(Memory::MemoryManager::Pool::System, 292 memory_manager->InitializeManager(KMemoryManager::Pool::System,
293 layout.System().StartAddress(), 293 layout.System().StartAddress(),
294 layout.System().EndAddress()); 294 layout.System().EndAddress());
295 295
296 hid_shared_mem = Kernel::SharedMemory::Create( 296 hid_shared_mem = Kernel::KSharedMemory::Create(
297 system.Kernel(), system.DeviceMemory(), nullptr, 297 system.Kernel(), system.DeviceMemory(), nullptr, {hid_addr, hid_size / PageSize},
298 {hid_addr, hid_size / Memory::PageSize}, Memory::MemoryPermission::None, 298 KMemoryPermission::None, KMemoryPermission::Read, hid_addr, hid_size,
299 Memory::MemoryPermission::Read, hid_addr, hid_size, "HID:SharedMemory"); 299 "HID:SharedMemory");
300 font_shared_mem = Kernel::SharedMemory::Create( 300 font_shared_mem = Kernel::KSharedMemory::Create(
301 system.Kernel(), system.DeviceMemory(), nullptr, 301 system.Kernel(), system.DeviceMemory(), nullptr, {font_pa, font_size / PageSize},
302 {font_pa, font_size / Memory::PageSize}, Memory::MemoryPermission::None, 302 KMemoryPermission::None, KMemoryPermission::Read, font_pa, font_size,
303 Memory::MemoryPermission::Read, font_pa, font_size, "Font:SharedMemory"); 303 "Font:SharedMemory");
304 irs_shared_mem = Kernel::SharedMemory::Create( 304 irs_shared_mem = Kernel::KSharedMemory::Create(
305 system.Kernel(), system.DeviceMemory(), nullptr, 305 system.Kernel(), system.DeviceMemory(), nullptr, {irs_addr, irs_size / PageSize},
306 {irs_addr, irs_size / Memory::PageSize}, Memory::MemoryPermission::None, 306 KMemoryPermission::None, KMemoryPermission::Read, irs_addr, irs_size,
307 Memory::MemoryPermission::Read, irs_addr, irs_size, "IRS:SharedMemory"); 307 "IRS:SharedMemory");
308 time_shared_mem = Kernel::SharedMemory::Create( 308 time_shared_mem = Kernel::KSharedMemory::Create(
309 system.Kernel(), system.DeviceMemory(), nullptr, 309 system.Kernel(), system.DeviceMemory(), nullptr, {time_addr, time_size / PageSize},
310 {time_addr, time_size / Memory::PageSize}, Memory::MemoryPermission::None, 310 KMemoryPermission::None, KMemoryPermission::Read, time_addr, time_size,
311 Memory::MemoryPermission::Read, time_addr, time_size, "Time:SharedMemory"); 311 "Time:SharedMemory");
312 312
313 // Allocate slab heaps 313 // Allocate slab heaps
314 user_slab_heap_pages = std::make_unique<Memory::SlabHeap<Memory::Page>>(); 314 user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>();
315 315
316 constexpr u64 user_slab_heap_size{0x1ef000}; 316 constexpr u64 user_slab_heap_size{0x1ef000};
317 // Reserve slab heaps 317 // Reserve slab heaps
@@ -353,14 +353,14 @@ struct KernelCore::Impl {
353 std::atomic<u32> next_host_thread_id{Core::Hardware::NUM_CPU_CORES}; 353 std::atomic<u32> next_host_thread_id{Core::Hardware::NUM_CPU_CORES};
354 354
355 // Kernel memory management 355 // Kernel memory management
356 std::unique_ptr<Memory::MemoryManager> memory_manager; 356 std::unique_ptr<KMemoryManager> memory_manager;
357 std::unique_ptr<Memory::SlabHeap<Memory::Page>> user_slab_heap_pages; 357 std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages;
358 358
359 // Shared memory for services 359 // Shared memory for services
360 std::shared_ptr<Kernel::SharedMemory> hid_shared_mem; 360 std::shared_ptr<Kernel::KSharedMemory> hid_shared_mem;
361 std::shared_ptr<Kernel::SharedMemory> font_shared_mem; 361 std::shared_ptr<Kernel::KSharedMemory> font_shared_mem;
362 std::shared_ptr<Kernel::SharedMemory> irs_shared_mem; 362 std::shared_ptr<Kernel::KSharedMemory> irs_shared_mem;
363 std::shared_ptr<Kernel::SharedMemory> time_shared_mem; 363 std::shared_ptr<Kernel::KSharedMemory> time_shared_mem;
364 364
365 // Threads used for services 365 // Threads used for services
366 std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; 366 std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads;
@@ -578,51 +578,51 @@ KThread* KernelCore::GetCurrentEmuThread() const {
578 return impl->GetCurrentEmuThread(); 578 return impl->GetCurrentEmuThread();
579} 579}
580 580
581Memory::MemoryManager& KernelCore::MemoryManager() { 581KMemoryManager& KernelCore::MemoryManager() {
582 return *impl->memory_manager; 582 return *impl->memory_manager;
583} 583}
584 584
585const Memory::MemoryManager& KernelCore::MemoryManager() const { 585const KMemoryManager& KernelCore::MemoryManager() const {
586 return *impl->memory_manager; 586 return *impl->memory_manager;
587} 587}
588 588
589Memory::SlabHeap<Memory::Page>& KernelCore::GetUserSlabHeapPages() { 589KSlabHeap<Page>& KernelCore::GetUserSlabHeapPages() {
590 return *impl->user_slab_heap_pages; 590 return *impl->user_slab_heap_pages;
591} 591}
592 592
593const Memory::SlabHeap<Memory::Page>& KernelCore::GetUserSlabHeapPages() const { 593const KSlabHeap<Page>& KernelCore::GetUserSlabHeapPages() const {
594 return *impl->user_slab_heap_pages; 594 return *impl->user_slab_heap_pages;
595} 595}
596 596
597Kernel::SharedMemory& KernelCore::GetHidSharedMem() { 597Kernel::KSharedMemory& KernelCore::GetHidSharedMem() {
598 return *impl->hid_shared_mem; 598 return *impl->hid_shared_mem;
599} 599}
600 600
601const Kernel::SharedMemory& KernelCore::GetHidSharedMem() const { 601const Kernel::KSharedMemory& KernelCore::GetHidSharedMem() const {
602 return *impl->hid_shared_mem; 602 return *impl->hid_shared_mem;
603} 603}
604 604
605Kernel::SharedMemory& KernelCore::GetFontSharedMem() { 605Kernel::KSharedMemory& KernelCore::GetFontSharedMem() {
606 return *impl->font_shared_mem; 606 return *impl->font_shared_mem;
607} 607}
608 608
609const Kernel::SharedMemory& KernelCore::GetFontSharedMem() const { 609const Kernel::KSharedMemory& KernelCore::GetFontSharedMem() const {
610 return *impl->font_shared_mem; 610 return *impl->font_shared_mem;
611} 611}
612 612
613Kernel::SharedMemory& KernelCore::GetIrsSharedMem() { 613Kernel::KSharedMemory& KernelCore::GetIrsSharedMem() {
614 return *impl->irs_shared_mem; 614 return *impl->irs_shared_mem;
615} 615}
616 616
617const Kernel::SharedMemory& KernelCore::GetIrsSharedMem() const { 617const Kernel::KSharedMemory& KernelCore::GetIrsSharedMem() const {
618 return *impl->irs_shared_mem; 618 return *impl->irs_shared_mem;
619} 619}
620 620
621Kernel::SharedMemory& KernelCore::GetTimeSharedMem() { 621Kernel::KSharedMemory& KernelCore::GetTimeSharedMem() {
622 return *impl->time_shared_mem; 622 return *impl->time_shared_mem;
623} 623}
624 624
625const Kernel::SharedMemory& KernelCore::GetTimeSharedMem() const { 625const Kernel::KSharedMemory& KernelCore::GetTimeSharedMem() const {
626 return *impl->time_shared_mem; 626 return *impl->time_shared_mem;
627} 627}
628 628
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 806a0d986..56906f2da 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -11,7 +11,7 @@
11#include <vector> 11#include <vector>
12#include "core/arm/cpu_interrupt_handler.h" 12#include "core/arm/cpu_interrupt_handler.h"
13#include "core/hardware_properties.h" 13#include "core/hardware_properties.h"
14#include "core/hle/kernel/memory/memory_types.h" 14#include "core/hle/kernel/memory_types.h"
15#include "core/hle/kernel/object.h" 15#include "core/hle/kernel/object.h"
16 16
17namespace Core { 17namespace Core {
@@ -27,25 +27,23 @@ struct EventType;
27 27
28namespace Kernel { 28namespace Kernel {
29 29
30namespace Memory {
31class MemoryManager;
32template <typename T>
33class SlabHeap;
34} // namespace Memory
35
36class ClientPort; 30class ClientPort;
37class GlobalSchedulerContext; 31class GlobalSchedulerContext;
38class HandleTable; 32class HandleTable;
39class PhysicalCore; 33class KMemoryManager;
40class Process;
41class KResourceLimit; 34class KResourceLimit;
42class KScheduler; 35class KScheduler;
43class SharedMemory; 36class KSharedMemory;
37class KThread;
38class PhysicalCore;
39class Process;
44class ServiceThread; 40class ServiceThread;
45class Synchronization; 41class Synchronization;
46class KThread;
47class TimeManager; 42class TimeManager;
48 43
44template <typename T>
45class KSlabHeap;
46
49using EmuThreadHandle = uintptr_t; 47using EmuThreadHandle = uintptr_t;
50constexpr EmuThreadHandle EmuThreadHandleInvalid{}; 48constexpr EmuThreadHandle EmuThreadHandleInvalid{};
51constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63}; 49constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63};
@@ -178,40 +176,40 @@ public:
178 void RegisterHostThread(); 176 void RegisterHostThread();
179 177
180 /// Gets the virtual memory manager for the kernel. 178 /// Gets the virtual memory manager for the kernel.
181 Memory::MemoryManager& MemoryManager(); 179 KMemoryManager& MemoryManager();
182 180
183 /// Gets the virtual memory manager for the kernel. 181 /// Gets the virtual memory manager for the kernel.
184 const Memory::MemoryManager& MemoryManager() const; 182 const KMemoryManager& MemoryManager() const;
185 183
186 /// Gets the slab heap allocated for user space pages. 184 /// Gets the slab heap allocated for user space pages.
187 Memory::SlabHeap<Memory::Page>& GetUserSlabHeapPages(); 185 KSlabHeap<Page>& GetUserSlabHeapPages();
188 186
189 /// Gets the slab heap allocated for user space pages. 187 /// Gets the slab heap allocated for user space pages.
190 const Memory::SlabHeap<Memory::Page>& GetUserSlabHeapPages() const; 188 const KSlabHeap<Page>& GetUserSlabHeapPages() const;
191 189
192 /// Gets the shared memory object for HID services. 190 /// Gets the shared memory object for HID services.
193 Kernel::SharedMemory& GetHidSharedMem(); 191 Kernel::KSharedMemory& GetHidSharedMem();
194 192
195 /// Gets the shared memory object for HID services. 193 /// Gets the shared memory object for HID services.
196 const Kernel::SharedMemory& GetHidSharedMem() const; 194 const Kernel::KSharedMemory& GetHidSharedMem() const;
197 195
198 /// Gets the shared memory object for font services. 196 /// Gets the shared memory object for font services.
199 Kernel::SharedMemory& GetFontSharedMem(); 197 Kernel::KSharedMemory& GetFontSharedMem();
200 198
201 /// Gets the shared memory object for font services. 199 /// Gets the shared memory object for font services.
202 const Kernel::SharedMemory& GetFontSharedMem() const; 200 const Kernel::KSharedMemory& GetFontSharedMem() const;
203 201
204 /// Gets the shared memory object for IRS services. 202 /// Gets the shared memory object for IRS services.
205 Kernel::SharedMemory& GetIrsSharedMem(); 203 Kernel::KSharedMemory& GetIrsSharedMem();
206 204
207 /// Gets the shared memory object for IRS services. 205 /// Gets the shared memory object for IRS services.
208 const Kernel::SharedMemory& GetIrsSharedMem() const; 206 const Kernel::KSharedMemory& GetIrsSharedMem() const;
209 207
210 /// Gets the shared memory object for Time services. 208 /// Gets the shared memory object for Time services.
211 Kernel::SharedMemory& GetTimeSharedMem(); 209 Kernel::KSharedMemory& GetTimeSharedMem();
212 210
213 /// Gets the shared memory object for Time services. 211 /// Gets the shared memory object for Time services.
214 const Kernel::SharedMemory& GetTimeSharedMem() const; 212 const Kernel::KSharedMemory& GetTimeSharedMem() const;
215 213
216 /// Suspend/unsuspend the OS. 214 /// Suspend/unsuspend the OS.
217 void Suspend(bool in_suspention); 215 void Suspend(bool in_suspention);
diff --git a/src/core/hle/kernel/memory/page_heap.h b/src/core/hle/kernel/memory/page_heap.h
deleted file mode 100644
index 131093284..000000000
--- a/src/core/hle/kernel/memory/page_heap.h
+++ /dev/null
@@ -1,370 +0,0 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once
9
10#include <array>
11#include <bit>
12#include <vector>
13
14#include "common/alignment.h"
15#include "common/assert.h"
16#include "common/common_funcs.h"
17#include "common/common_types.h"
18#include "core/hle/kernel/memory/memory_types.h"
19
20namespace Kernel::Memory {
21
22class PageHeap final : NonCopyable {
23public:
24 static constexpr s32 GetAlignedBlockIndex(std::size_t num_pages, std::size_t align_pages) {
25 const auto target_pages{std::max(num_pages, align_pages)};
26 for (std::size_t i = 0; i < NumMemoryBlockPageShifts; i++) {
27 if (target_pages <=
28 (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) {
29 return static_cast<s32>(i);
30 }
31 }
32 return -1;
33 }
34
35 static constexpr s32 GetBlockIndex(std::size_t num_pages) {
36 for (s32 i{static_cast<s32>(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) {
37 if (num_pages >= (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) {
38 return i;
39 }
40 }
41 return -1;
42 }
43
44 static constexpr std::size_t GetBlockSize(std::size_t index) {
45 return static_cast<std::size_t>(1) << MemoryBlockPageShifts[index];
46 }
47
48 static constexpr std::size_t GetBlockNumPages(std::size_t index) {
49 return GetBlockSize(index) / PageSize;
50 }
51
52private:
53 static constexpr std::size_t NumMemoryBlockPageShifts{7};
54 static constexpr std::array<std::size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{
55 0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E,
56 };
57
58 class Block final : NonCopyable {
59 private:
60 class Bitmap final : NonCopyable {
61 public:
62 static constexpr std::size_t MaxDepth{4};
63
64 private:
65 std::array<u64*, MaxDepth> bit_storages{};
66 std::size_t num_bits{};
67 std::size_t used_depths{};
68
69 public:
70 constexpr Bitmap() = default;
71
72 constexpr std::size_t GetNumBits() const {
73 return num_bits;
74 }
75 constexpr s32 GetHighestDepthIndex() const {
76 return static_cast<s32>(used_depths) - 1;
77 }
78
79 constexpr u64* Initialize(u64* storage, std::size_t size) {
80 //* Initially, everything is un-set
81 num_bits = 0;
82
83 // Calculate the needed bitmap depth
84 used_depths = static_cast<std::size_t>(GetRequiredDepth(size));
85 ASSERT(used_depths <= MaxDepth);
86
87 // Set the bitmap pointers
88 for (s32 depth{GetHighestDepthIndex()}; depth >= 0; depth--) {
89 bit_storages[depth] = storage;
90 size = Common::AlignUp(size, 64) / 64;
91 storage += size;
92 }
93
94 return storage;
95 }
96
97 s64 FindFreeBlock() const {
98 uintptr_t offset{};
99 s32 depth{};
100
101 do {
102 const u64 v{bit_storages[depth][offset]};
103 if (v == 0) {
104 // Non-zero depth indicates that a previous level had a free block
105 ASSERT(depth == 0);
106 return -1;
107 }
108 offset = offset * 64 + static_cast<u32>(std::countr_zero(v));
109 ++depth;
110 } while (depth < static_cast<s32>(used_depths));
111
112 return static_cast<s64>(offset);
113 }
114
115 constexpr void SetBit(std::size_t offset) {
116 SetBit(GetHighestDepthIndex(), offset);
117 num_bits++;
118 }
119
120 constexpr void ClearBit(std::size_t offset) {
121 ClearBit(GetHighestDepthIndex(), offset);
122 num_bits--;
123 }
124
125 constexpr bool ClearRange(std::size_t offset, std::size_t count) {
126 const s32 depth{GetHighestDepthIndex()};
127 const auto bit_ind{offset / 64};
128 u64* bits{bit_storages[depth]};
129 if (count < 64) {
130 const auto shift{offset % 64};
131 ASSERT(shift + count <= 64);
132 // Check that all the bits are set
133 const u64 mask{((1ULL << count) - 1) << shift};
134 u64 v{bits[bit_ind]};
135 if ((v & mask) != mask) {
136 return false;
137 }
138
139 // Clear the bits
140 v &= ~mask;
141 bits[bit_ind] = v;
142 if (v == 0) {
143 ClearBit(depth - 1, bit_ind);
144 }
145 } else {
146 ASSERT(offset % 64 == 0);
147 ASSERT(count % 64 == 0);
148 // Check that all the bits are set
149 std::size_t remaining{count};
150 std::size_t i = 0;
151 do {
152 if (bits[bit_ind + i++] != ~u64(0)) {
153 return false;
154 }
155 remaining -= 64;
156 } while (remaining > 0);
157
158 // Clear the bits
159 remaining = count;
160 i = 0;
161 do {
162 bits[bit_ind + i] = 0;
163 ClearBit(depth - 1, bit_ind + i);
164 i++;
165 remaining -= 64;
166 } while (remaining > 0);
167 }
168
169 num_bits -= count;
170 return true;
171 }
172
173 private:
174 constexpr void SetBit(s32 depth, std::size_t offset) {
175 while (depth >= 0) {
176 const auto ind{offset / 64};
177 const auto which{offset % 64};
178 const u64 mask{1ULL << which};
179
180 u64* bit{std::addressof(bit_storages[depth][ind])};
181 const u64 v{*bit};
182 ASSERT((v & mask) == 0);
183 *bit = v | mask;
184 if (v) {
185 break;
186 }
187 offset = ind;
188 depth--;
189 }
190 }
191
192 constexpr void ClearBit(s32 depth, std::size_t offset) {
193 while (depth >= 0) {
194 const auto ind{offset / 64};
195 const auto which{offset % 64};
196 const u64 mask{1ULL << which};
197
198 u64* bit{std::addressof(bit_storages[depth][ind])};
199 u64 v{*bit};
200 ASSERT((v & mask) != 0);
201 v &= ~mask;
202 *bit = v;
203 if (v) {
204 break;
205 }
206 offset = ind;
207 depth--;
208 }
209 }
210
211 private:
212 static constexpr s32 GetRequiredDepth(std::size_t region_size) {
213 s32 depth = 0;
214 while (true) {
215 region_size /= 64;
216 depth++;
217 if (region_size == 0) {
218 return depth;
219 }
220 }
221 }
222
223 public:
224 static constexpr std::size_t CalculateMetadataOverheadSize(std::size_t region_size) {
225 std::size_t overhead_bits = 0;
226 for (s32 depth{GetRequiredDepth(region_size) - 1}; depth >= 0; depth--) {
227 region_size = Common::AlignUp(region_size, 64) / 64;
228 overhead_bits += region_size;
229 }
230 return overhead_bits * sizeof(u64);
231 }
232 };
233
234 private:
235 Bitmap bitmap;
236 VAddr heap_address{};
237 uintptr_t end_offset{};
238 std::size_t block_shift{};
239 std::size_t next_block_shift{};
240
241 public:
242 constexpr Block() = default;
243
244 constexpr std::size_t GetShift() const {
245 return block_shift;
246 }
247 constexpr std::size_t GetNextShift() const {
248 return next_block_shift;
249 }
250 constexpr std::size_t GetSize() const {
251 return static_cast<std::size_t>(1) << GetShift();
252 }
253 constexpr std::size_t GetNumPages() const {
254 return GetSize() / PageSize;
255 }
256 constexpr std::size_t GetNumFreeBlocks() const {
257 return bitmap.GetNumBits();
258 }
259 constexpr std::size_t GetNumFreePages() const {
260 return GetNumFreeBlocks() * GetNumPages();
261 }
262
263 constexpr u64* Initialize(VAddr addr, std::size_t size, std::size_t bs, std::size_t nbs,
264 u64* bit_storage) {
265 // Set shifts
266 block_shift = bs;
267 next_block_shift = nbs;
268
269 // Align up the address
270 VAddr end{addr + size};
271 const auto align{(next_block_shift != 0) ? (1ULL << next_block_shift)
272 : (1ULL << block_shift)};
273 addr = Common::AlignDown((addr), align);
274 end = Common::AlignUp((end), align);
275
276 heap_address = addr;
277 end_offset = (end - addr) / (1ULL << block_shift);
278 return bitmap.Initialize(bit_storage, end_offset);
279 }
280
281 constexpr VAddr PushBlock(VAddr address) {
282 // Set the bit for the free block
283 std::size_t offset{(address - heap_address) >> GetShift()};
284 bitmap.SetBit(offset);
285
286 // If we have a next shift, try to clear the blocks below and return the address
287 if (GetNextShift()) {
288 const auto diff{1ULL << (GetNextShift() - GetShift())};
289 offset = Common::AlignDown(offset, diff);
290 if (bitmap.ClearRange(offset, diff)) {
291 return heap_address + (offset << GetShift());
292 }
293 }
294
295 // We couldn't coalesce, or we're already as big as possible
296 return 0;
297 }
298
299 VAddr PopBlock() {
300 // Find a free block
301 const s64 soffset{bitmap.FindFreeBlock()};
302 if (soffset < 0) {
303 return 0;
304 }
305 const auto offset{static_cast<std::size_t>(soffset)};
306
307 // Update our tracking and return it
308 bitmap.ClearBit(offset);
309 return heap_address + (offset << GetShift());
310 }
311
312 public:
313 static constexpr std::size_t CalculateMetadataOverheadSize(std::size_t region_size,
314 std::size_t cur_block_shift,
315 std::size_t next_block_shift) {
316 const auto cur_block_size{(1ULL << cur_block_shift)};
317 const auto next_block_size{(1ULL << next_block_shift)};
318 const auto align{(next_block_shift != 0) ? next_block_size : cur_block_size};
319 return Bitmap::CalculateMetadataOverheadSize(
320 (align * 2 + Common::AlignUp(region_size, align)) / cur_block_size);
321 }
322 };
323
324public:
325 PageHeap() = default;
326
327 constexpr VAddr GetAddress() const {
328 return heap_address;
329 }
330 constexpr std::size_t GetSize() const {
331 return heap_size;
332 }
333 constexpr VAddr GetEndAddress() const {
334 return GetAddress() + GetSize();
335 }
336 constexpr std::size_t GetPageOffset(VAddr block) const {
337 return (block - GetAddress()) / PageSize;
338 }
339
340 void Initialize(VAddr heap_address, std::size_t heap_size, std::size_t metadata_size);
341 VAddr AllocateBlock(s32 index);
342 void Free(VAddr addr, std::size_t num_pages);
343
344 void UpdateUsedSize() {
345 used_size = heap_size - (GetNumFreePages() * PageSize);
346 }
347
348 static std::size_t CalculateMetadataOverheadSize(std::size_t region_size);
349
350private:
351 constexpr std::size_t GetNumFreePages() const {
352 std::size_t num_free{};
353
354 for (const auto& block : blocks) {
355 num_free += block.GetNumFreePages();
356 }
357
358 return num_free;
359 }
360
361 void FreeBlock(VAddr block, s32 index);
362
363 VAddr heap_address{};
364 std::size_t heap_size{};
365 std::size_t used_size{};
366 std::array<Block, NumMemoryBlockPageShifts> blocks{};
367 std::vector<u64> metadata;
368};
369
370} // namespace Kernel::Memory
diff --git a/src/core/hle/kernel/memory/system_control.h b/src/core/hle/kernel/memory/system_control.h
deleted file mode 100644
index 19cab8cbc..000000000
--- a/src/core/hle/kernel/memory/system_control.h
+++ /dev/null
@@ -1,13 +0,0 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9namespace Kernel::Memory::SystemControl {
10
11u64 GenerateRandomRange(u64 min, u64 max);
12
13} // namespace Kernel::Memory::SystemControl
diff --git a/src/core/hle/kernel/memory/memory_types.h b/src/core/hle/kernel/memory_types.h
index a75bf77c0..d458f0eca 100644
--- a/src/core/hle/kernel/memory/memory_types.h
+++ b/src/core/hle/kernel/memory_types.h
@@ -8,11 +8,11 @@
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11namespace Kernel::Memory { 11namespace Kernel {
12 12
13constexpr std::size_t PageBits{12}; 13constexpr std::size_t PageBits{12};
14constexpr std::size_t PageSize{1 << PageBits}; 14constexpr std::size_t PageSize{1 << PageBits};
15 15
16using Page = std::array<u8, PageSize>; 16using Page = std::array<u8, PageSize>;
17 17
18} // namespace Kernel::Memory 18} // namespace Kernel
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 47b3ac57b..73b85d6f9 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -14,14 +14,14 @@
14#include "core/device_memory.h" 14#include "core/device_memory.h"
15#include "core/file_sys/program_metadata.h" 15#include "core/file_sys/program_metadata.h"
16#include "core/hle/kernel/code_set.h" 16#include "core/hle/kernel/code_set.h"
17#include "core/hle/kernel/k_memory_block_manager.h"
18#include "core/hle/kernel/k_page_table.h"
17#include "core/hle/kernel/k_resource_limit.h" 19#include "core/hle/kernel/k_resource_limit.h"
18#include "core/hle/kernel/k_scheduler.h" 20#include "core/hle/kernel/k_scheduler.h"
19#include "core/hle/kernel/k_scoped_resource_reservation.h" 21#include "core/hle/kernel/k_scoped_resource_reservation.h"
22#include "core/hle/kernel/k_slab_heap.h"
20#include "core/hle/kernel/k_thread.h" 23#include "core/hle/kernel/k_thread.h"
21#include "core/hle/kernel/kernel.h" 24#include "core/hle/kernel/kernel.h"
22#include "core/hle/kernel/memory/memory_block_manager.h"
23#include "core/hle/kernel/memory/page_table.h"
24#include "core/hle/kernel/memory/slab_heap.h"
25#include "core/hle/kernel/process.h" 25#include "core/hle/kernel/process.h"
26#include "core/hle/kernel/svc_results.h" 26#include "core/hle/kernel/svc_results.h"
27#include "core/hle/lock.h" 27#include "core/hle/lock.h"
@@ -274,7 +274,7 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
274 // Set initial resource limits 274 // Set initial resource limits
275 resource_limit->SetLimitValue( 275 resource_limit->SetLimitValue(
276 LimitableResource::PhysicalMemory, 276 LimitableResource::PhysicalMemory,
277 kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); 277 kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
278 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, 278 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
279 code_size + system_resource_size); 279 code_size + system_resource_size);
280 if (!memory_reservation.Succeeded()) { 280 if (!memory_reservation.Succeeded()) {
@@ -285,15 +285,15 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
285 // Initialize proces address space 285 // Initialize proces address space
286 if (const ResultCode result{ 286 if (const ResultCode result{
287 page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, 287 page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000,
288 code_size, Memory::MemoryManager::Pool::Application)}; 288 code_size, KMemoryManager::Pool::Application)};
289 result.IsError()) { 289 result.IsError()) {
290 return result; 290 return result;
291 } 291 }
292 292
293 // Map process code region 293 // Map process code region
294 if (const ResultCode result{page_table->MapProcessCode( 294 if (const ResultCode result{page_table->MapProcessCode(page_table->GetCodeRegionStart(),
295 page_table->GetCodeRegionStart(), code_size / Memory::PageSize, 295 code_size / PageSize, KMemoryState::Code,
296 Memory::MemoryState::Code, Memory::MemoryPermission::None)}; 296 KMemoryPermission::None)};
297 result.IsError()) { 297 result.IsError()) {
298 return result; 298 return result;
299 } 299 }
@@ -323,6 +323,11 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
323 UNREACHABLE(); 323 UNREACHABLE();
324 } 324 }
325 325
326 // Set initial resource limits
327 resource_limit->SetLimitValue(
328 LimitableResource::PhysicalMemory,
329 kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
330
326 resource_limit->SetLimitValue(LimitableResource::Threads, 608); 331 resource_limit->SetLimitValue(LimitableResource::Threads, 608);
327 resource_limit->SetLimitValue(LimitableResource::Events, 700); 332 resource_limit->SetLimitValue(LimitableResource::Events, 700);
328 resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); 333 resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);
@@ -400,22 +405,22 @@ VAddr Process::CreateTLSRegion() {
400 return *tls_page_iter->ReserveSlot(); 405 return *tls_page_iter->ReserveSlot();
401 } 406 }
402 407
403 Memory::Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()}; 408 Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()};
404 ASSERT(tls_page_ptr); 409 ASSERT(tls_page_ptr);
405 410
406 const VAddr start{page_table->GetKernelMapRegionStart()}; 411 const VAddr start{page_table->GetKernelMapRegionStart()};
407 const VAddr size{page_table->GetKernelMapRegionEnd() - start}; 412 const VAddr size{page_table->GetKernelMapRegionEnd() - start};
408 const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; 413 const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)};
409 const VAddr tls_page_addr{ 414 const VAddr tls_page_addr{page_table
410 page_table 415 ->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize,
411 ->AllocateAndMapMemory(1, Memory::PageSize, true, start, size / Memory::PageSize, 416 KMemoryState::ThreadLocal,
412 Memory::MemoryState::ThreadLocal, 417 KMemoryPermission::ReadAndWrite,
413 Memory::MemoryPermission::ReadAndWrite, tls_map_addr) 418 tls_map_addr)
414 .ValueOr(0)}; 419 .ValueOr(0)};
415 420
416 ASSERT(tls_page_addr); 421 ASSERT(tls_page_addr);
417 422
418 std::memset(tls_page_ptr, 0, Memory::PageSize); 423 std::memset(tls_page_ptr, 0, PageSize);
419 tls_pages.emplace_back(tls_page_addr); 424 tls_pages.emplace_back(tls_page_addr);
420 425
421 const auto reserve_result{tls_pages.back().ReserveSlot()}; 426 const auto reserve_result{tls_pages.back().ReserveSlot()};
@@ -442,15 +447,15 @@ void Process::FreeTLSRegion(VAddr tls_address) {
442void Process::LoadModule(CodeSet code_set, VAddr base_addr) { 447void Process::LoadModule(CodeSet code_set, VAddr base_addr) {
443 std::lock_guard lock{HLE::g_hle_lock}; 448 std::lock_guard lock{HLE::g_hle_lock};
444 const auto ReprotectSegment = [&](const CodeSet::Segment& segment, 449 const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
445 Memory::MemoryPermission permission) { 450 KMemoryPermission permission) {
446 page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); 451 page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission);
447 }; 452 };
448 453
449 system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size()); 454 system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size());
450 455
451 ReprotectSegment(code_set.CodeSegment(), Memory::MemoryPermission::ReadAndExecute); 456 ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute);
452 ReprotectSegment(code_set.RODataSegment(), Memory::MemoryPermission::Read); 457 ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read);
453 ReprotectSegment(code_set.DataSegment(), Memory::MemoryPermission::ReadAndWrite); 458 ReprotectSegment(code_set.DataSegment(), KMemoryPermission::ReadAndWrite);
454} 459}
455 460
456bool Process::IsSignaled() const { 461bool Process::IsSignaled() const {
@@ -459,9 +464,9 @@ bool Process::IsSignaled() const {
459} 464}
460 465
461Process::Process(Core::System& system) 466Process::Process(Core::System& system)
462 : KSynchronizationObject{system.Kernel()}, 467 : KSynchronizationObject{system.Kernel()}, page_table{std::make_unique<KPageTable>(system)},
463 page_table{std::make_unique<Memory::PageTable>(system)}, handle_table{system.Kernel()}, 468 handle_table{system.Kernel()}, address_arbiter{system}, condition_var{system},
464 address_arbiter{system}, condition_var{system}, state_lock{system.Kernel()}, system{system} {} 469 state_lock{system.Kernel()}, system{system} {}
465 470
466Process::~Process() = default; 471Process::~Process() = default;
467 472
@@ -479,16 +484,15 @@ ResultCode Process::AllocateMainThreadStack(std::size_t stack_size) {
479 ASSERT(stack_size); 484 ASSERT(stack_size);
480 485
481 // The kernel always ensures that the given stack size is page aligned. 486 // The kernel always ensures that the given stack size is page aligned.
482 main_thread_stack_size = Common::AlignUp(stack_size, Memory::PageSize); 487 main_thread_stack_size = Common::AlignUp(stack_size, PageSize);
483 488
484 const VAddr start{page_table->GetStackRegionStart()}; 489 const VAddr start{page_table->GetStackRegionStart()};
485 const std::size_t size{page_table->GetStackRegionEnd() - start}; 490 const std::size_t size{page_table->GetStackRegionEnd() - start};
486 491
487 CASCADE_RESULT(main_thread_stack_top, 492 CASCADE_RESULT(main_thread_stack_top,
488 page_table->AllocateAndMapMemory( 493 page_table->AllocateAndMapMemory(
489 main_thread_stack_size / Memory::PageSize, Memory::PageSize, false, start, 494 main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize,
490 size / Memory::PageSize, Memory::MemoryState::Stack, 495 KMemoryState::Stack, KMemoryPermission::ReadAndWrite));
491 Memory::MemoryPermission::ReadAndWrite));
492 496
493 main_thread_stack_top += main_thread_stack_size; 497 main_thread_stack_top += main_thread_stack_size;
494 498
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 320b0f347..45eefb90e 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -29,16 +29,13 @@ class ProgramMetadata;
29namespace Kernel { 29namespace Kernel {
30 30
31class KernelCore; 31class KernelCore;
32class KPageTable;
32class KResourceLimit; 33class KResourceLimit;
33class KThread; 34class KThread;
34class TLSPage; 35class TLSPage;
35 36
36struct CodeSet; 37struct CodeSet;
37 38
38namespace Memory {
39class PageTable;
40}
41
42enum class MemoryRegion : u16 { 39enum class MemoryRegion : u16 {
43 APPLICATION = 1, 40 APPLICATION = 1,
44 SYSTEM = 2, 41 SYSTEM = 2,
@@ -104,12 +101,12 @@ public:
104 } 101 }
105 102
106 /// Gets a reference to the process' page table. 103 /// Gets a reference to the process' page table.
107 Memory::PageTable& PageTable() { 104 KPageTable& PageTable() {
108 return *page_table; 105 return *page_table;
109 } 106 }
110 107
111 /// Gets const a reference to the process' page table. 108 /// Gets const a reference to the process' page table.
112 const Memory::PageTable& PageTable() const { 109 const KPageTable& PageTable() const {
113 return *page_table; 110 return *page_table;
114 } 111 }
115 112
@@ -385,7 +382,7 @@ private:
385 ResultCode AllocateMainThreadStack(std::size_t stack_size); 382 ResultCode AllocateMainThreadStack(std::size_t stack_size);
386 383
387 /// Memory manager for this process 384 /// Memory manager for this process
388 std::unique_ptr<Memory::PageTable> page_table; 385 std::unique_ptr<KPageTable> page_table;
389 386
390 /// Current status of the process 387 /// Current status of the process
391 ProcessStatus status{}; 388 ProcessStatus status{};
diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp
index 7c567049e..3fc326eab 100644
--- a/src/core/hle/kernel/process_capability.cpp
+++ b/src/core/hle/kernel/process_capability.cpp
@@ -7,7 +7,7 @@
7#include "common/bit_util.h" 7#include "common/bit_util.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/hle/kernel/handle_table.h" 9#include "core/hle/kernel/handle_table.h"
10#include "core/hle/kernel/memory/page_table.h" 10#include "core/hle/kernel/k_page_table.h"
11#include "core/hle/kernel/process_capability.h" 11#include "core/hle/kernel/process_capability.h"
12#include "core/hle/kernel/svc_results.h" 12#include "core/hle/kernel/svc_results.h"
13 13
@@ -69,7 +69,7 @@ u32 GetFlagBitOffset(CapabilityType type) {
69 69
70ResultCode ProcessCapabilities::InitializeForKernelProcess(const u32* capabilities, 70ResultCode ProcessCapabilities::InitializeForKernelProcess(const u32* capabilities,
71 std::size_t num_capabilities, 71 std::size_t num_capabilities,
72 Memory::PageTable& page_table) { 72 KPageTable& page_table) {
73 Clear(); 73 Clear();
74 74
75 // Allow all cores and priorities. 75 // Allow all cores and priorities.
@@ -82,7 +82,7 @@ ResultCode ProcessCapabilities::InitializeForKernelProcess(const u32* capabiliti
82 82
83ResultCode ProcessCapabilities::InitializeForUserProcess(const u32* capabilities, 83ResultCode ProcessCapabilities::InitializeForUserProcess(const u32* capabilities,
84 std::size_t num_capabilities, 84 std::size_t num_capabilities,
85 Memory::PageTable& page_table) { 85 KPageTable& page_table) {
86 Clear(); 86 Clear();
87 87
88 return ParseCapabilities(capabilities, num_capabilities, page_table); 88 return ParseCapabilities(capabilities, num_capabilities, page_table);
@@ -108,7 +108,7 @@ void ProcessCapabilities::InitializeForMetadatalessProcess() {
108 108
109ResultCode ProcessCapabilities::ParseCapabilities(const u32* capabilities, 109ResultCode ProcessCapabilities::ParseCapabilities(const u32* capabilities,
110 std::size_t num_capabilities, 110 std::size_t num_capabilities,
111 Memory::PageTable& page_table) { 111 KPageTable& page_table) {
112 u32 set_flags = 0; 112 u32 set_flags = 0;
113 u32 set_svc_bits = 0; 113 u32 set_svc_bits = 0;
114 114
@@ -155,7 +155,7 @@ ResultCode ProcessCapabilities::ParseCapabilities(const u32* capabilities,
155} 155}
156 156
157ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, 157ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits,
158 u32 flag, Memory::PageTable& page_table) { 158 u32 flag, KPageTable& page_table) {
159 const auto type = GetCapabilityType(flag); 159 const auto type = GetCapabilityType(flag);
160 160
161 if (type == CapabilityType::Unset) { 161 if (type == CapabilityType::Unset) {
@@ -293,12 +293,12 @@ ResultCode ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags)
293} 293}
294 294
295ResultCode ProcessCapabilities::HandleMapPhysicalFlags(u32 flags, u32 size_flags, 295ResultCode ProcessCapabilities::HandleMapPhysicalFlags(u32 flags, u32 size_flags,
296 Memory::PageTable& page_table) { 296 KPageTable& page_table) {
297 // TODO(Lioncache): Implement once the memory manager can handle this. 297 // TODO(Lioncache): Implement once the memory manager can handle this.
298 return RESULT_SUCCESS; 298 return RESULT_SUCCESS;
299} 299}
300 300
301ResultCode ProcessCapabilities::HandleMapIOFlags(u32 flags, Memory::PageTable& page_table) { 301ResultCode ProcessCapabilities::HandleMapIOFlags(u32 flags, KPageTable& page_table) {
302 // TODO(Lioncache): Implement once the memory manager can handle this. 302 // TODO(Lioncache): Implement once the memory manager can handle this.
303 return RESULT_SUCCESS; 303 return RESULT_SUCCESS;
304} 304}
diff --git a/src/core/hle/kernel/process_capability.h b/src/core/hle/kernel/process_capability.h
index ea9d12c16..73ad197fa 100644
--- a/src/core/hle/kernel/process_capability.h
+++ b/src/core/hle/kernel/process_capability.h
@@ -12,9 +12,7 @@ union ResultCode;
12 12
13namespace Kernel { 13namespace Kernel {
14 14
15namespace Memory { 15class KPageTable;
16class PageTable;
17}
18 16
19/// The possible types of programs that may be indicated 17/// The possible types of programs that may be indicated
20/// by the program type capability descriptor. 18/// by the program type capability descriptor.
@@ -90,7 +88,7 @@ public:
90 /// otherwise, an error code upon failure. 88 /// otherwise, an error code upon failure.
91 /// 89 ///
92 ResultCode InitializeForKernelProcess(const u32* capabilities, std::size_t num_capabilities, 90 ResultCode InitializeForKernelProcess(const u32* capabilities, std::size_t num_capabilities,
93 Memory::PageTable& page_table); 91 KPageTable& page_table);
94 92
95 /// Initializes this process capabilities instance for a userland process. 93 /// Initializes this process capabilities instance for a userland process.
96 /// 94 ///
@@ -103,7 +101,7 @@ public:
103 /// otherwise, an error code upon failure. 101 /// otherwise, an error code upon failure.
104 /// 102 ///
105 ResultCode InitializeForUserProcess(const u32* capabilities, std::size_t num_capabilities, 103 ResultCode InitializeForUserProcess(const u32* capabilities, std::size_t num_capabilities,
106 Memory::PageTable& page_table); 104 KPageTable& page_table);
107 105
108 /// Initializes this process capabilities instance for a process that does not 106 /// Initializes this process capabilities instance for a process that does not
109 /// have any metadata to parse. 107 /// have any metadata to parse.
@@ -189,7 +187,7 @@ private:
189 /// @return RESULT_SUCCESS if no errors occur, otherwise an error code. 187 /// @return RESULT_SUCCESS if no errors occur, otherwise an error code.
190 /// 188 ///
191 ResultCode ParseCapabilities(const u32* capabilities, std::size_t num_capabilities, 189 ResultCode ParseCapabilities(const u32* capabilities, std::size_t num_capabilities,
192 Memory::PageTable& page_table); 190 KPageTable& page_table);
193 191
194 /// Attempts to parse a capability descriptor that is only represented by a 192 /// Attempts to parse a capability descriptor that is only represented by a
195 /// single flag set. 193 /// single flag set.
@@ -204,7 +202,7 @@ private:
204 /// @return RESULT_SUCCESS if no errors occurred, otherwise an error code. 202 /// @return RESULT_SUCCESS if no errors occurred, otherwise an error code.
205 /// 203 ///
206 ResultCode ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag, 204 ResultCode ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag,
207 Memory::PageTable& page_table); 205 KPageTable& page_table);
208 206
209 /// Clears the internal state of this process capability instance. Necessary, 207 /// Clears the internal state of this process capability instance. Necessary,
210 /// to have a sane starting point due to us allowing running executables without 208 /// to have a sane starting point due to us allowing running executables without
@@ -228,10 +226,10 @@ private:
228 ResultCode HandleSyscallFlags(u32& set_svc_bits, u32 flags); 226 ResultCode HandleSyscallFlags(u32& set_svc_bits, u32 flags);
229 227
230 /// Handles flags related to mapping physical memory pages. 228 /// Handles flags related to mapping physical memory pages.
231 ResultCode HandleMapPhysicalFlags(u32 flags, u32 size_flags, Memory::PageTable& page_table); 229 ResultCode HandleMapPhysicalFlags(u32 flags, u32 size_flags, KPageTable& page_table);
232 230
233 /// Handles flags related to mapping IO pages. 231 /// Handles flags related to mapping IO pages.
234 ResultCode HandleMapIOFlags(u32 flags, Memory::PageTable& page_table); 232 ResultCode HandleMapIOFlags(u32 flags, KPageTable& page_table);
235 233
236 /// Handles flags related to the interrupt capability flags. 234 /// Handles flags related to the interrupt capability flags.
237 ResultCode HandleInterruptFlags(u32 flags); 235 ResultCode HandleInterruptFlags(u32 flags);
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 31d899e06..cc8fa6576 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -27,21 +27,21 @@
27#include "core/hle/kernel/k_address_arbiter.h" 27#include "core/hle/kernel/k_address_arbiter.h"
28#include "core/hle/kernel/k_condition_variable.h" 28#include "core/hle/kernel/k_condition_variable.h"
29#include "core/hle/kernel/k_event.h" 29#include "core/hle/kernel/k_event.h"
30#include "core/hle/kernel/k_memory_block.h"
31#include "core/hle/kernel/k_memory_layout.h"
32#include "core/hle/kernel/k_page_table.h"
30#include "core/hle/kernel/k_readable_event.h" 33#include "core/hle/kernel/k_readable_event.h"
31#include "core/hle/kernel/k_resource_limit.h" 34#include "core/hle/kernel/k_resource_limit.h"
32#include "core/hle/kernel/k_scheduler.h" 35#include "core/hle/kernel/k_scheduler.h"
33#include "core/hle/kernel/k_scoped_resource_reservation.h" 36#include "core/hle/kernel/k_scoped_resource_reservation.h"
34#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 37#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
38#include "core/hle/kernel/k_shared_memory.h"
35#include "core/hle/kernel/k_synchronization_object.h" 39#include "core/hle/kernel/k_synchronization_object.h"
36#include "core/hle/kernel/k_thread.h" 40#include "core/hle/kernel/k_thread.h"
37#include "core/hle/kernel/k_writable_event.h" 41#include "core/hle/kernel/k_writable_event.h"
38#include "core/hle/kernel/kernel.h" 42#include "core/hle/kernel/kernel.h"
39#include "core/hle/kernel/memory/memory_block.h"
40#include "core/hle/kernel/memory/memory_layout.h"
41#include "core/hle/kernel/memory/page_table.h"
42#include "core/hle/kernel/physical_core.h" 43#include "core/hle/kernel/physical_core.h"
43#include "core/hle/kernel/process.h" 44#include "core/hle/kernel/process.h"
44#include "core/hle/kernel/shared_memory.h"
45#include "core/hle/kernel/svc.h" 45#include "core/hle/kernel/svc.h"
46#include "core/hle/kernel/svc_results.h" 46#include "core/hle/kernel/svc_results.h"
47#include "core/hle/kernel/svc_types.h" 47#include "core/hle/kernel/svc_types.h"
@@ -67,8 +67,8 @@ constexpr bool IsValidAddressRange(VAddr address, u64 size) {
67// Helper function that performs the common sanity checks for svcMapMemory 67// Helper function that performs the common sanity checks for svcMapMemory
68// and svcUnmapMemory. This is doable, as both functions perform their sanitizing 68// and svcUnmapMemory. This is doable, as both functions perform their sanitizing
69// in the same order. 69// in the same order.
70ResultCode MapUnmapMemorySanityChecks(const Memory::PageTable& manager, VAddr dst_addr, 70ResultCode MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr,
71 VAddr src_addr, u64 size) { 71 u64 size) {
72 if (!Common::Is4KBAligned(dst_addr)) { 72 if (!Common::Is4KBAligned(dst_addr)) {
73 LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); 73 LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr);
74 return ResultInvalidAddress; 74 return ResultInvalidAddress;
@@ -230,9 +230,9 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si
230 return ResultInvalidCurrentMemory; 230 return ResultInvalidCurrentMemory;
231 } 231 }
232 232
233 const auto attributes{static_cast<Memory::MemoryAttribute>(mask | attribute)}; 233 const auto attributes{static_cast<MemoryAttribute>(mask | attribute)};
234 if (attributes != static_cast<Memory::MemoryAttribute>(mask) || 234 if (attributes != static_cast<MemoryAttribute>(mask) ||
235 (attributes | Memory::MemoryAttribute::Uncached) != Memory::MemoryAttribute::Uncached) { 235 (attributes | MemoryAttribute::Uncached) != MemoryAttribute::Uncached) {
236 LOG_ERROR(Kernel_SVC, 236 LOG_ERROR(Kernel_SVC,
237 "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}", 237 "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}",
238 attribute, mask); 238 attribute, mask);
@@ -241,8 +241,8 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si
241 241
242 auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; 242 auto& page_table{system.Kernel().CurrentProcess()->PageTable()};
243 243
244 return page_table.SetMemoryAttribute(address, size, static_cast<Memory::MemoryAttribute>(mask), 244 return page_table.SetMemoryAttribute(address, size, static_cast<KMemoryAttribute>(mask),
245 static_cast<Memory::MemoryAttribute>(attribute)); 245 static_cast<KMemoryAttribute>(attribute));
246} 246}
247 247
248static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, 248static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask,
@@ -508,7 +508,7 @@ static ResultCode ArbitrateLock(Core::System& system, Handle thread_handle, VAdd
508 thread_handle, address, tag); 508 thread_handle, address, tag);
509 509
510 // Validate the input address. 510 // Validate the input address.
511 if (Memory::IsKernelAddress(address)) { 511 if (IsKernelAddress(address)) {
512 LOG_ERROR(Kernel_SVC, "Attempting to arbitrate a lock on a kernel address (address={:08X})", 512 LOG_ERROR(Kernel_SVC, "Attempting to arbitrate a lock on a kernel address (address={:08X})",
513 address); 513 address);
514 return ResultInvalidCurrentMemory; 514 return ResultInvalidCurrentMemory;
@@ -531,8 +531,7 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr address) {
531 LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); 531 LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address);
532 532
533 // Validate the input address. 533 // Validate the input address.
534 534 if (IsKernelAddress(address)) {
535 if (Memory::IsKernelAddress(address)) {
536 LOG_ERROR(Kernel_SVC, 535 LOG_ERROR(Kernel_SVC,
537 "Attempting to arbitrate an unlock on a kernel address (address={:08X})", 536 "Attempting to arbitrate an unlock on a kernel address (address={:08X})",
538 address); 537 address);
@@ -1232,9 +1231,8 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han
1232 return ResultInvalidCurrentMemory; 1231 return ResultInvalidCurrentMemory;
1233 } 1232 }
1234 1233
1235 const auto permission_type = static_cast<Memory::MemoryPermission>(permissions); 1234 const auto permission_type = static_cast<MemoryPermission>(permissions);
1236 if ((permission_type | Memory::MemoryPermission::Write) != 1235 if ((permission_type | MemoryPermission::Write) != MemoryPermission::ReadWrite) {
1237 Memory::MemoryPermission::ReadAndWrite) {
1238 LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", 1236 LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}",
1239 permissions); 1237 permissions);
1240 return ResultInvalidMemoryPermissions; 1238 return ResultInvalidMemoryPermissions;
@@ -1267,14 +1265,15 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han
1267 return ResultInvalidMemoryRange; 1265 return ResultInvalidMemoryRange;
1268 } 1266 }
1269 1267
1270 auto shared_memory{current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle)}; 1268 auto shared_memory{current_process->GetHandleTable().Get<KSharedMemory>(shared_memory_handle)};
1271 if (!shared_memory) { 1269 if (!shared_memory) {
1272 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", 1270 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}",
1273 shared_memory_handle); 1271 shared_memory_handle);
1274 return ResultInvalidHandle; 1272 return ResultInvalidHandle;
1275 } 1273 }
1276 1274
1277 return shared_memory->Map(*current_process, addr, size, permission_type); 1275 return shared_memory->Map(*current_process, addr, size,
1276 static_cast<KMemoryPermission>(permission_type));
1278} 1277}
1279 1278
1280static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, 1279static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr,
@@ -1638,7 +1637,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr address,
1638 cv_key, tag, timeout_ns); 1637 cv_key, tag, timeout_ns);
1639 1638
1640 // Validate input. 1639 // Validate input.
1641 if (Memory::IsKernelAddress(address)) { 1640 if (IsKernelAddress(address)) {
1642 LOG_ERROR(Kernel_SVC, "Attempted to wait on kernel address (address={:08X})", address); 1641 LOG_ERROR(Kernel_SVC, "Attempted to wait on kernel address (address={:08X})", address);
1643 return ResultInvalidCurrentMemory; 1642 return ResultInvalidCurrentMemory;
1644 } 1643 }
@@ -1720,7 +1719,7 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, Svc::Arbit
1720 address, arb_type, value, timeout_ns); 1719 address, arb_type, value, timeout_ns);
1721 1720
1722 // Validate input. 1721 // Validate input.
1723 if (Memory::IsKernelAddress(address)) { 1722 if (IsKernelAddress(address)) {
1724 LOG_ERROR(Kernel_SVC, "Attempting to wait on kernel address (address={:08X})", address); 1723 LOG_ERROR(Kernel_SVC, "Attempting to wait on kernel address (address={:08X})", address);
1725 return ResultInvalidCurrentMemory; 1724 return ResultInvalidCurrentMemory;
1726 } 1725 }
@@ -1765,7 +1764,7 @@ static ResultCode SignalToAddress(Core::System& system, VAddr address, Svc::Sign
1765 address, signal_type, value, count); 1764 address, signal_type, value, count);
1766 1765
1767 // Validate input. 1766 // Validate input.
1768 if (Memory::IsKernelAddress(address)) { 1767 if (IsKernelAddress(address)) {
1769 LOG_ERROR(Kernel_SVC, "Attempting to signal to a kernel address (address={:08X})", address); 1768 LOG_ERROR(Kernel_SVC, "Attempting to signal to a kernel address (address={:08X})", address);
1770 return ResultInvalidCurrentMemory; 1769 return ResultInvalidCurrentMemory;
1771 } 1770 }
@@ -1887,9 +1886,8 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd
1887 return ResultInvalidCurrentMemory; 1886 return ResultInvalidCurrentMemory;
1888 } 1887 }
1889 1888
1890 const auto perms{static_cast<Memory::MemoryPermission>(permissions)}; 1889 const auto perms{static_cast<MemoryPermission>(permissions)};
1891 if (perms > Memory::MemoryPermission::ReadAndWrite || 1890 if (perms > MemoryPermission::ReadWrite || perms == MemoryPermission::Write) {
1892 perms == Memory::MemoryPermission::Write) {
1893 LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", 1891 LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})",
1894 permissions); 1892 permissions);
1895 return ResultInvalidMemoryPermissions; 1893 return ResultInvalidMemoryPermissions;
@@ -1903,7 +1901,8 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd
1903 LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); 1901 LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory");
1904 return ResultResourceLimitedExceeded; 1902 return ResultResourceLimitedExceeded;
1905 } 1903 }
1906 auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms); 1904 auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size,
1905 static_cast<KMemoryPermission>(perms));
1907 1906
1908 if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { 1907 if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) {
1909 return reserve_result; 1908 return reserve_result;
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp
index 6b0fc1591..cad063e4d 100644
--- a/src/core/hle/kernel/transfer_memory.cpp
+++ b/src/core/hle/kernel/transfer_memory.cpp
@@ -2,9 +2,9 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/kernel/k_page_table.h"
5#include "core/hle/kernel/k_resource_limit.h" 6#include "core/hle/kernel/k_resource_limit.h"
6#include "core/hle/kernel/kernel.h" 7#include "core/hle/kernel/kernel.h"
7#include "core/hle/kernel/memory/page_table.h"
8#include "core/hle/kernel/process.h" 8#include "core/hle/kernel/process.h"
9#include "core/hle/kernel/transfer_memory.h" 9#include "core/hle/kernel/transfer_memory.h"
10#include "core/hle/result.h" 10#include "core/hle/result.h"
@@ -24,7 +24,7 @@ TransferMemory::~TransferMemory() {
24std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, 24std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel,
25 Core::Memory::Memory& memory, 25 Core::Memory::Memory& memory,
26 VAddr base_address, std::size_t size, 26 VAddr base_address, std::size_t size,
27 Memory::MemoryPermission permissions) { 27 KMemoryPermission permissions) {
28 std::shared_ptr<TransferMemory> transfer_memory{ 28 std::shared_ptr<TransferMemory> transfer_memory{
29 std::make_shared<TransferMemory>(kernel, memory)}; 29 std::make_shared<TransferMemory>(kernel, memory)};
30 30
diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h
index 777799d12..521951424 100644
--- a/src/core/hle/kernel/transfer_memory.h
+++ b/src/core/hle/kernel/transfer_memory.h
@@ -6,7 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8 8
9#include "core/hle/kernel/memory/memory_block.h" 9#include "core/hle/kernel/k_memory_block.h"
10#include "core/hle/kernel/object.h" 10#include "core/hle/kernel/object.h"
11#include "core/hle/kernel/physical_memory.h" 11#include "core/hle/kernel/physical_memory.h"
12 12
@@ -36,7 +36,7 @@ public:
36 36
37 static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory, 37 static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory,
38 VAddr base_address, std::size_t size, 38 VAddr base_address, std::size_t size,
39 Memory::MemoryPermission permissions); 39 KMemoryPermission permissions);
40 40
41 TransferMemory(const TransferMemory&) = delete; 41 TransferMemory(const TransferMemory&) = delete;
42 TransferMemory& operator=(const TransferMemory&) = delete; 42 TransferMemory& operator=(const TransferMemory&) = delete;
@@ -82,7 +82,7 @@ private:
82 std::size_t size{}; 82 std::size_t size{};
83 83
84 /// The memory permissions that are applied to this instance. 84 /// The memory permissions that are applied to this instance.
85 Memory::MemoryPermission owner_permissions{}; 85 KMemoryPermission owner_permissions{};
86 86
87 /// The process that this transfer memory instance was created under. 87 /// The process that this transfer memory instance was created under.
88 Process* owner_process{}; 88 Process* owner_process{};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 3d0fe42f6..ba27bbb05 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -15,9 +15,9 @@
15#include "core/hle/kernel/client_port.h" 15#include "core/hle/kernel/client_port.h"
16#include "core/hle/kernel/client_session.h" 16#include "core/hle/kernel/client_session.h"
17#include "core/hle/kernel/k_readable_event.h" 17#include "core/hle/kernel/k_readable_event.h"
18#include "core/hle/kernel/k_shared_memory.h"
18#include "core/hle/kernel/k_writable_event.h" 19#include "core/hle/kernel/k_writable_event.h"
19#include "core/hle/kernel/kernel.h" 20#include "core/hle/kernel/kernel.h"
20#include "core/hle/kernel/shared_memory.h"
21#include "core/hle/service/hid/errors.h" 21#include "core/hle/service/hid/errors.h"
22#include "core/hle/service/hid/hid.h" 22#include "core/hle/service/hid/hid.h"
23#include "core/hle/service/hid/irs.h" 23#include "core/hle/service/hid/irs.h"
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 99d155586..36ed228c8 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -14,7 +14,7 @@ struct EventType;
14} 14}
15 15
16namespace Kernel { 16namespace Kernel {
17class SharedMemory; 17class KSharedMemory;
18} 18}
19 19
20namespace Service::SM { 20namespace Service::SM {
@@ -69,7 +69,7 @@ private:
69 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 69 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
70 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 70 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
71 71
72 std::shared_ptr<Kernel::SharedMemory> shared_mem; 72 std::shared_ptr<Kernel::KSharedMemory> shared_mem;
73 73
74 std::shared_ptr<Core::Timing::EventType> pad_update_event; 74 std::shared_ptr<Core::Timing::EventType> pad_update_event;
75 std::shared_ptr<Core::Timing::EventType> motion_update_event; 75 std::shared_ptr<Core::Timing::EventType> motion_update_event;
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index c8413099f..2dfa936fb 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -6,8 +6,8 @@
6#include "core/core.h" 6#include "core/core.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/k_shared_memory.h"
9#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
10#include "core/hle/kernel/shared_memory.h"
11#include "core/hle/service/hid/irs.h" 11#include "core/hle/service/hid/irs.h"
12 12
13namespace Service::HID { 13namespace Service::HID {
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index be0c486ba..b0c8c7168 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -12,7 +12,7 @@ class System;
12} 12}
13 13
14namespace Kernel { 14namespace Kernel {
15class SharedMemory; 15class KSharedMemory;
16} 16}
17 17
18namespace Service::HID { 18namespace Service::HID {
@@ -42,7 +42,7 @@ private:
42 void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); 42 void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
43 void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); 43 void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
44 44
45 std::shared_ptr<Kernel::SharedMemory> shared_mem; 45 std::shared_ptr<Kernel::KSharedMemory> shared_mem;
46 const u32 device_handle{0xABCD}; 46 const u32 device_handle{0xABCD};
47}; 47};
48 48
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index c724d2554..d111c1357 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -11,8 +11,8 @@
11#include "common/scope_exit.h" 11#include "common/scope_exit.h"
12#include "core/core.h" 12#include "core/core.h"
13#include "core/hle/ipc_helpers.h" 13#include "core/hle/ipc_helpers.h"
14#include "core/hle/kernel/memory/page_table.h" 14#include "core/hle/kernel/k_page_table.h"
15#include "core/hle/kernel/memory/system_control.h" 15#include "core/hle/kernel/k_system_control.h"
16#include "core/hle/kernel/process.h" 16#include "core/hle/kernel/process.h"
17#include "core/hle/kernel/svc_results.h" 17#include "core/hle/kernel/svc_results.h"
18#include "core/hle/service/ldr/ldr.h" 18#include "core/hle/service/ldr/ldr.h"
@@ -287,12 +287,11 @@ public:
287 rb.Push(RESULT_SUCCESS); 287 rb.Push(RESULT_SUCCESS);
288 } 288 }
289 289
290 bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start, 290 bool ValidateRegionForMap(Kernel::KPageTable& page_table, VAddr start, std::size_t size) const {
291 std::size_t size) const { 291 constexpr std::size_t padding_size{4 * Kernel::PageSize};
292 constexpr std::size_t padding_size{4 * Kernel::Memory::PageSize};
293 const auto start_info{page_table.QueryInfo(start - 1)}; 292 const auto start_info{page_table.QueryInfo(start - 1)};
294 293
295 if (start_info.state != Kernel::Memory::MemoryState::Free) { 294 if (start_info.state != Kernel::KMemoryState::Free) {
296 return {}; 295 return {};
297 } 296 }
298 297
@@ -302,21 +301,20 @@ public:
302 301
303 const auto end_info{page_table.QueryInfo(start + size)}; 302 const auto end_info{page_table.QueryInfo(start + size)};
304 303
305 if (end_info.state != Kernel::Memory::MemoryState::Free) { 304 if (end_info.state != Kernel::KMemoryState::Free) {
306 return {}; 305 return {};
307 } 306 }
308 307
309 return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize()); 308 return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize());
310 } 309 }
311 310
312 VAddr GetRandomMapRegion(const Kernel::Memory::PageTable& page_table, std::size_t size) const { 311 VAddr GetRandomMapRegion(const Kernel::KPageTable& page_table, std::size_t size) const {
313 VAddr addr{}; 312 VAddr addr{};
314 const std::size_t end_pages{(page_table.GetAliasCodeRegionSize() - size) >> 313 const std::size_t end_pages{(page_table.GetAliasCodeRegionSize() - size) >>
315 Kernel::Memory::PageBits}; 314 Kernel::PageBits};
316 do { 315 do {
317 addr = page_table.GetAliasCodeRegionStart() + 316 addr = page_table.GetAliasCodeRegionStart() +
318 (Kernel::Memory::SystemControl::GenerateRandomRange(0, end_pages) 317 (Kernel::KSystemControl::GenerateRandomRange(0, end_pages) << Kernel::PageBits);
319 << Kernel::Memory::PageBits);
320 } while (!page_table.IsInsideAddressSpace(addr, size) || 318 } while (!page_table.IsInsideAddressSpace(addr, size) ||
321 page_table.IsInsideHeapRegion(addr, size) || 319 page_table.IsInsideHeapRegion(addr, size) ||
322 page_table.IsInsideAliasRegion(addr, size)); 320 page_table.IsInsideAliasRegion(addr, size));
@@ -387,7 +385,7 @@ public:
387 const VAddr data_start{start + nro_header.segment_headers[DATA_INDEX].memory_offset}; 385 const VAddr data_start{start + nro_header.segment_headers[DATA_INDEX].memory_offset};
388 const VAddr bss_start{data_start + nro_header.segment_headers[DATA_INDEX].memory_size}; 386 const VAddr bss_start{data_start + nro_header.segment_headers[DATA_INDEX].memory_size};
389 const VAddr bss_end_addr{ 387 const VAddr bss_end_addr{
390 Common::AlignUp(bss_start + nro_header.bss_size, Kernel::Memory::PageSize)}; 388 Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)};
391 389
392 auto CopyCode{[&](VAddr src_addr, VAddr dst_addr, u64 size) { 390 auto CopyCode{[&](VAddr src_addr, VAddr dst_addr, u64 size) {
393 std::vector<u8> source_data(size); 391 std::vector<u8> source_data(size);
@@ -402,12 +400,12 @@ public:
402 nro_header.segment_headers[DATA_INDEX].memory_size); 400 nro_header.segment_headers[DATA_INDEX].memory_size);
403 401
404 CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( 402 CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(
405 text_start, ro_start - text_start, Kernel::Memory::MemoryPermission::ReadAndExecute)); 403 text_start, ro_start - text_start, Kernel::KMemoryPermission::ReadAndExecute));
406 CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( 404 CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(ro_start, data_start - ro_start,
407 ro_start, data_start - ro_start, Kernel::Memory::MemoryPermission::Read)); 405 Kernel::KMemoryPermission::Read));
408 406
409 return process->PageTable().SetCodeMemoryPermission( 407 return process->PageTable().SetCodeMemoryPermission(
410 data_start, bss_end_addr - data_start, Kernel::Memory::MemoryPermission::ReadAndWrite); 408 data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite);
411 } 409 }
412 410
413 void LoadNro(Kernel::HLERequestContext& ctx) { 411 void LoadNro(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index b6ac0a81a..fcd15d81f 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -19,9 +19,9 @@
19#include "core/file_sys/romfs.h" 19#include "core/file_sys/romfs.h"
20#include "core/file_sys/system_archive/system_archive.h" 20#include "core/file_sys/system_archive/system_archive.h"
21#include "core/hle/ipc_helpers.h" 21#include "core/hle/ipc_helpers.h"
22#include "core/hle/kernel/k_shared_memory.h"
22#include "core/hle/kernel/kernel.h" 23#include "core/hle/kernel/kernel.h"
23#include "core/hle/kernel/physical_memory.h" 24#include "core/hle/kernel/physical_memory.h"
24#include "core/hle/kernel/shared_memory.h"
25#include "core/hle/service/filesystem/filesystem.h" 25#include "core/hle/service/filesystem/filesystem.h"
26#include "core/hle/service/ns/pl_u.h" 26#include "core/hle/service/ns/pl_u.h"
27 27
@@ -131,7 +131,7 @@ struct PL_U::Impl {
131 } 131 }
132 132
133 /// Handle to shared memory region designated for a shared font 133 /// Handle to shared memory region designated for a shared font
134 std::shared_ptr<Kernel::SharedMemory> shared_font_mem; 134 std::shared_ptr<Kernel::KSharedMemory> shared_font_mem;
135 135
136 /// Backing memory for the shared font data 136 /// Backing memory for the shared font data
137 std::shared_ptr<Kernel::PhysicalMemory> shared_font; 137 std::shared_ptr<Kernel::PhysicalMemory> shared_font;
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp
index e0ae9f874..4d8de81be 100644
--- a/src/core/hle/service/time/time_sharedmemory.cpp
+++ b/src/core/hle/service/time/time_sharedmemory.cpp
@@ -22,7 +22,7 @@ SharedMemory::SharedMemory(Core::System& system) : system(system) {
22 22
23SharedMemory::~SharedMemory() = default; 23SharedMemory::~SharedMemory() = default;
24 24
25std::shared_ptr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() const { 25std::shared_ptr<Kernel::KSharedMemory> SharedMemory::GetSharedMemoryHolder() const {
26 return shared_memory_holder; 26 return shared_memory_holder;
27} 27}
28 28
diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h
index e0c3e63da..299680517 100644
--- a/src/core/hle/service/time/time_sharedmemory.h
+++ b/src/core/hle/service/time/time_sharedmemory.h
@@ -6,8 +6,8 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/uuid.h" 8#include "common/uuid.h"
9#include "core/hle/kernel/k_shared_memory.h"
9#include "core/hle/kernel/k_thread.h" 10#include "core/hle/kernel/k_thread.h"
10#include "core/hle/kernel/shared_memory.h"
11#include "core/hle/service/time/clock_types.h" 11#include "core/hle/service/time/clock_types.h"
12 12
13namespace Service::Time { 13namespace Service::Time {
@@ -18,7 +18,7 @@ public:
18 ~SharedMemory(); 18 ~SharedMemory();
19 19
20 // Return the shared memory handle 20 // Return the shared memory handle
21 std::shared_ptr<Kernel::SharedMemory> GetSharedMemoryHolder() const; 21 std::shared_ptr<Kernel::KSharedMemory> GetSharedMemoryHolder() const;
22 22
23 // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this? 23 // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this?
24 template <typename T, std::size_t Offset> 24 template <typename T, std::size_t Offset>
@@ -63,7 +63,7 @@ public:
63 void SetAutomaticCorrectionEnabled(bool is_enabled); 63 void SetAutomaticCorrectionEnabled(bool is_enabled);
64 64
65private: 65private:
66 std::shared_ptr<Kernel::SharedMemory> shared_memory_holder; 66 std::shared_ptr<Kernel::KSharedMemory> shared_memory_holder;
67 Core::System& system; 67 Core::System& system;
68 Format shared_memory_format{}; 68 Format shared_memory_format{};
69}; 69};
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 79ebf11de..4a10211f6 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -12,8 +12,8 @@
12#include "core/file_sys/control_metadata.h" 12#include "core/file_sys/control_metadata.h"
13#include "core/file_sys/patch_manager.h" 13#include "core/file_sys/patch_manager.h"
14#include "core/file_sys/romfs_factory.h" 14#include "core/file_sys/romfs_factory.h"
15#include "core/hle/kernel/k_page_table.h"
15#include "core/hle/kernel/kernel.h" 16#include "core/hle/kernel/kernel.h"
16#include "core/hle/kernel/memory/page_table.h"
17#include "core/hle/kernel/process.h" 17#include "core/hle/kernel/process.h"
18#include "core/hle/service/filesystem/filesystem.h" 18#include "core/hle/service/filesystem/filesystem.h"
19#include "core/loader/deconstructed_rom_directory.h" 19#include "core/loader/deconstructed_rom_directory.h"
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index dca1fcb18..f4a339390 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -10,7 +10,7 @@
10#include "common/file_util.h" 10#include "common/file_util.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "core/hle/kernel/code_set.h" 12#include "core/hle/kernel/code_set.h"
13#include "core/hle/kernel/memory/page_table.h" 13#include "core/hle/kernel/k_page_table.h"
14#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
15#include "core/loader/elf.h" 15#include "core/loader/elf.h"
16#include "core/memory.h" 16#include "core/memory.h"
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index e162c4ff0..3f4ba233d 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -6,7 +6,7 @@
6#include "core/file_sys/kernel_executable.h" 6#include "core/file_sys/kernel_executable.h"
7#include "core/file_sys/program_metadata.h" 7#include "core/file_sys/program_metadata.h"
8#include "core/hle/kernel/code_set.h" 8#include "core/hle/kernel/code_set.h"
9#include "core/hle/kernel/memory/page_table.h" 9#include "core/hle/kernel/k_page_table.h"
10#include "core/hle/kernel/process.h" 10#include "core/hle/kernel/process.h"
11#include "core/loader/kip.h" 11#include "core/loader/kip.h"
12#include "core/memory.h" 12#include "core/memory.h"
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index f976d0a9c..14618cb40 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -15,8 +15,8 @@
15#include "core/file_sys/romfs_factory.h" 15#include "core/file_sys/romfs_factory.h"
16#include "core/file_sys/vfs_offset.h" 16#include "core/file_sys/vfs_offset.h"
17#include "core/hle/kernel/code_set.h" 17#include "core/hle/kernel/code_set.h"
18#include "core/hle/kernel/k_page_table.h"
18#include "core/hle/kernel/k_thread.h" 19#include "core/hle/kernel/k_thread.h"
19#include "core/hle/kernel/memory/page_table.h"
20#include "core/hle/kernel/process.h" 20#include "core/hle/kernel/process.h"
21#include "core/hle/service/filesystem/filesystem.h" 21#include "core/hle/service/filesystem/filesystem.h"
22#include "core/loader/nro.h" 22#include "core/loader/nro.h"
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index ea347ea83..cbd048695 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -15,8 +15,8 @@
15#include "core/core.h" 15#include "core/core.h"
16#include "core/file_sys/patch_manager.h" 16#include "core/file_sys/patch_manager.h"
17#include "core/hle/kernel/code_set.h" 17#include "core/hle/kernel/code_set.h"
18#include "core/hle/kernel/k_page_table.h"
18#include "core/hle/kernel/k_thread.h" 19#include "core/hle/kernel/k_thread.h"
19#include "core/hle/kernel/memory/page_table.h"
20#include "core/hle/kernel/process.h" 20#include "core/hle/kernel/process.h"
21#include "core/loader/nso.h" 21#include "core/loader/nso.h"
22#include "core/memory.h" 22#include "core/memory.h"
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 11609682a..b9dd3e275 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -16,7 +16,7 @@
16#include "core/arm/arm_interface.h" 16#include "core/arm/arm_interface.h"
17#include "core/core.h" 17#include "core/core.h"
18#include "core/device_memory.h" 18#include "core/device_memory.h"
19#include "core/hle/kernel/memory/page_table.h" 19#include "core/hle/kernel/k_page_table.h"
20#include "core/hle/kernel/physical_memory.h" 20#include "core/hle/kernel/physical_memory.h"
21#include "core/hle/kernel/process.h" 21#include "core/hle/kernel/process.h"
22#include "core/memory.h" 22#include "core/memory.h"
diff --git a/src/core/memory.h b/src/core/memory.h
index 705ebb23d..6d34fcfe2 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -116,6 +116,11 @@ public:
116 */ 116 */
117 u8* GetPointer(VAddr vaddr); 117 u8* GetPointer(VAddr vaddr);
118 118
119 template <typename T>
120 T* GetPointer(VAddr vaddr) {
121 return reinterpret_cast<T*>(GetPointer(vaddr));
122 }
123
119 /** 124 /**
120 * Gets a pointer to the given address. 125 * Gets a pointer to the given address.
121 * 126 *
@@ -126,6 +131,11 @@ public:
126 */ 131 */
127 const u8* GetPointer(VAddr vaddr) const; 132 const u8* GetPointer(VAddr vaddr) const;
128 133
134 template <typename T>
135 const T* GetPointer(VAddr vaddr) const {
136 return reinterpret_cast<T*>(GetPointer(vaddr));
137 }
138
129 /** 139 /**
130 * Reads an 8-bit unsigned value from the current process' address space 140 * Reads an 8-bit unsigned value from the current process' address space
131 * at the given virtual address. 141 * at the given virtual address.
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 2dd0eb0f8..8eec567ab 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -10,7 +10,7 @@
10#include "core/core_timing.h" 10#include "core/core_timing.h"
11#include "core/core_timing_util.h" 11#include "core/core_timing_util.h"
12#include "core/hardware_properties.h" 12#include "core/hardware_properties.h"
13#include "core/hle/kernel/memory/page_table.h" 13#include "core/hle/kernel/k_page_table.h"
14#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
15#include "core/hle/service/hid/controllers/npad.h" 15#include "core/hle/service/hid/controllers/npad.h"
16#include "core/hle/service/hid/hid.h" 16#include "core/hle/service/hid/hid.h"
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index f199c3362..74fb32814 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -17,7 +17,7 @@
17#include "core/arm/arm_interface.h" 17#include "core/arm/arm_interface.h"
18#include "core/core.h" 18#include "core/core.h"
19#include "core/hle/kernel/hle_ipc.h" 19#include "core/hle/kernel/hle_ipc.h"
20#include "core/hle/kernel/memory/page_table.h" 20#include "core/hle/kernel/k_page_table.h"
21#include "core/hle/kernel/process.h" 21#include "core/hle/kernel/process.h"
22#include "core/hle/result.h" 22#include "core/hle/result.h"
23#include "core/memory.h" 23#include "core/memory.h"
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 44240a9c4..4eb71efbd 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -6,7 +6,7 @@
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/memory/page_table.h" 9#include "core/hle/kernel/k_page_table.h"
10#include "core/hle/kernel/process.h" 10#include "core/hle/kernel/process.h"
11#include "core/memory.h" 11#include "core/memory.h"
12#include "video_core/gpu.h" 12#include "video_core/gpu.h"