summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_memory_region_type.h327
1 files changed, 327 insertions, 0 deletions
diff --git a/src/core/hle/kernel/k_memory_region_type.h b/src/core/hle/kernel/k_memory_region_type.h
index 6fb5abde9..243e2fd3d 100644
--- a/src/core/hle/kernel/k_memory_region_type.h
+++ b/src/core/hle/kernel/k_memory_region_type.h
@@ -4,6 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/bit_util.h"
8#include "common/common_funcs.h"
7#include "common/common_types.h" 9#include "common/common_types.h"
8 10
9namespace Kernel { 11namespace Kernel {
@@ -18,5 +20,330 @@ enum class KMemoryRegionAttr : typename std::underlying_type<KMemoryRegionType>:
18 NoUserMap = 0x40000000, 20 NoUserMap = 0x40000000,
19 LinearMapped = 0x80000000, 21 LinearMapped = 0x80000000,
20}; 22};
23DECLARE_ENUM_FLAG_OPERATORS(KMemoryRegionAttr);
24
25namespace impl {
26
27constexpr size_t BitsForDeriveSparse(size_t n) {
28 return n + 1;
29}
30
31constexpr size_t BitsForDeriveDense(size_t n) {
32 size_t low = 0, high = 1;
33 for (size_t i = 0; i < n - 1; ++i) {
34 if ((++low) == high) {
35 ++high;
36 low = 0;
37 }
38 }
39 return high + 1;
40}
41
42class KMemoryRegionTypeValue {
43private:
44 using ValueType = typename std::underlying_type<KMemoryRegionType>::type;
45
46private:
47 ValueType m_value{};
48 size_t m_next_bit{};
49 bool m_finalized{};
50 bool m_sparse_only{};
51 bool m_dense_only{};
52
53private:
54 constexpr KMemoryRegionTypeValue(ValueType v) : m_value(v) {}
55
56public:
57 constexpr KMemoryRegionTypeValue() = default;
58
59 constexpr operator KMemoryRegionType() const {
60 return static_cast<KMemoryRegionType>(m_value);
61 }
62
63 constexpr ValueType GetValue() const {
64 return m_value;
65 }
66
67 constexpr const KMemoryRegionTypeValue& Finalize() {
68 m_finalized = true;
69 return *this;
70 }
71
72 constexpr const KMemoryRegionTypeValue& SetSparseOnly() {
73 m_sparse_only = true;
74 return *this;
75 }
76
77 constexpr const KMemoryRegionTypeValue& SetDenseOnly() {
78 m_dense_only = true;
79 return *this;
80 }
81
82 constexpr KMemoryRegionTypeValue& SetAttribute(KMemoryRegionAttr attr) {
83 m_value |= static_cast<u32>(attr);
84 return *this;
85 }
86
87 constexpr KMemoryRegionTypeValue DeriveInitial(
88 size_t i, size_t next = Common::BitSize<ValueType>()) const {
89 KMemoryRegionTypeValue new_type = *this;
90 new_type.m_value = (ValueType{1} << i);
91 new_type.m_next_bit = next;
92 return new_type;
93 }
94
95 constexpr KMemoryRegionTypeValue DeriveAttribute(KMemoryRegionAttr attr) const {
96 KMemoryRegionTypeValue new_type = *this;
97 new_type.m_value |= static_cast<u32>(attr);
98 return new_type;
99 }
100
101 constexpr KMemoryRegionTypeValue DeriveTransition(size_t ofs = 0, size_t adv = 1) const {
102 KMemoryRegionTypeValue new_type = *this;
103 new_type.m_value |= (ValueType{1} << (m_next_bit + ofs));
104 new_type.m_next_bit += adv;
105 return new_type;
106 }
107
108 constexpr KMemoryRegionTypeValue DeriveSparse(size_t ofs, size_t n, size_t i) const {
109 KMemoryRegionTypeValue new_type = *this;
110 new_type.m_value |= (ValueType{1} << (m_next_bit + ofs));
111 new_type.m_value |= (ValueType{1} << (m_next_bit + ofs + 1 + i));
112 new_type.m_next_bit += ofs + n + 1;
113 return new_type;
114 }
115
116 constexpr KMemoryRegionTypeValue Derive(size_t n, size_t i) const {
117 size_t low = 0, high = 1;
118 for (size_t j = 0; j < i; ++j) {
119 if ((++low) == high) {
120 ++high;
121 low = 0;
122 }
123 }
124
125 KMemoryRegionTypeValue new_type = *this;
126 new_type.m_value |= (ValueType{1} << (m_next_bit + low));
127 new_type.m_value |= (ValueType{1} << (m_next_bit + high));
128 new_type.m_next_bit += BitsForDeriveDense(n);
129 return new_type;
130 }
131
132 constexpr KMemoryRegionTypeValue Advance(size_t n) const {
133 KMemoryRegionTypeValue new_type = *this;
134 new_type.m_next_bit += n;
135 return new_type;
136 }
137
138 constexpr bool IsAncestorOf(ValueType v) const {
139 return (m_value | v) == v;
140 }
141};
142
143} // namespace impl
144
145constexpr auto KMemoryRegionType_None = impl::KMemoryRegionTypeValue();
146constexpr auto KMemoryRegionType_Kernel = KMemoryRegionType_None.DeriveInitial(0, 2);
147constexpr auto KMemoryRegionType_Dram = KMemoryRegionType_None.DeriveInitial(1, 2);
148static_assert(KMemoryRegionType_Kernel.GetValue() == 0x1);
149static_assert(KMemoryRegionType_Dram.GetValue() == 0x2);
150
151constexpr auto KMemoryRegionType_DramKernelBase =
152 KMemoryRegionType_Dram.DeriveSparse(0, 3, 0)
153 .SetAttribute(KMemoryRegionAttr::NoUserMap)
154 .SetAttribute(KMemoryRegionAttr::CarveoutProtected);
155constexpr auto KMemoryRegionType_DramReservedBase = KMemoryRegionType_Dram.DeriveSparse(0, 3, 1);
156constexpr auto KMemoryRegionType_DramHeapBase =
157 KMemoryRegionType_Dram.DeriveSparse(0, 3, 2).SetAttribute(KMemoryRegionAttr::LinearMapped);
158static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramKernelBase.GetValue()) ==
159 (static_cast<KMemoryRegionAttr>(0xE) | KMemoryRegionAttr::CarveoutProtected |
160 KMemoryRegionAttr::NoUserMap));
161static_assert(KMemoryRegionType_DramReservedBase.GetValue() == (0x16));
162static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramHeapBase.GetValue()) ==
163 (static_cast<KMemoryRegionAttr>(0x26) | KMemoryRegionAttr::LinearMapped));
164
165constexpr auto KMemoryRegionType_DramKernelCode =
166 KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 0);
167constexpr auto KMemoryRegionType_DramKernelSlab =
168 KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 1);
169constexpr auto KMemoryRegionType_DramKernelPtHeap =
170 KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 2).SetAttribute(
171 KMemoryRegionAttr::LinearMapped);
172constexpr auto KMemoryRegionType_DramKernelInitPt =
173 KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 3).SetAttribute(
174 KMemoryRegionAttr::LinearMapped);
175static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramKernelCode.GetValue()) ==
176 (static_cast<KMemoryRegionAttr>(0xCE) | KMemoryRegionAttr::CarveoutProtected |
177 KMemoryRegionAttr::NoUserMap));
178static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramKernelSlab.GetValue()) ==
179 (static_cast<KMemoryRegionAttr>(0x14E) | KMemoryRegionAttr::CarveoutProtected |
180 KMemoryRegionAttr::NoUserMap));
181static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramKernelPtHeap.GetValue()) ==
182 (static_cast<KMemoryRegionAttr>(0x24E) | KMemoryRegionAttr::CarveoutProtected |
183 KMemoryRegionAttr::NoUserMap | KMemoryRegionAttr::LinearMapped));
184static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramKernelInitPt.GetValue()) ==
185 (static_cast<KMemoryRegionAttr>(0x44E) | KMemoryRegionAttr::CarveoutProtected |
186 KMemoryRegionAttr::NoUserMap | KMemoryRegionAttr::LinearMapped));
187
188constexpr auto KMemoryRegionType_DramReservedEarly =
189 KMemoryRegionType_DramReservedBase.DeriveAttribute(KMemoryRegionAttr::NoUserMap);
190static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramReservedEarly.GetValue()) ==
191 (static_cast<KMemoryRegionAttr>(0x16) | KMemoryRegionAttr::NoUserMap));
192
193constexpr auto KMemoryRegionType_KernelTraceBuffer =
194 KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 0)
195 .SetAttribute(KMemoryRegionAttr::LinearMapped)
196 .SetAttribute(KMemoryRegionAttr::UserReadOnly);
197constexpr auto KMemoryRegionType_OnMemoryBootImage =
198 KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 1);
199constexpr auto KMemoryRegionType_DTB = KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 2);
200static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_KernelTraceBuffer.GetValue()) ==
201 (static_cast<KMemoryRegionAttr>(0xD6) | KMemoryRegionAttr::LinearMapped |
202 KMemoryRegionAttr::UserReadOnly));
203static_assert(KMemoryRegionType_OnMemoryBootImage.GetValue() == 0x156);
204static_assert(KMemoryRegionType_DTB.GetValue() == 0x256);
205
206constexpr auto KMemoryRegionType_DramPoolPartition =
207 KMemoryRegionType_DramHeapBase.DeriveAttribute(KMemoryRegionAttr::NoUserMap);
208static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramPoolPartition.GetValue()) ==
209 (static_cast<KMemoryRegionAttr>(0x26) | KMemoryRegionAttr::LinearMapped |
210 KMemoryRegionAttr::NoUserMap));
211
212constexpr auto KMemoryRegionType_DramPoolManagement =
213 KMemoryRegionType_DramPoolPartition.DeriveTransition(0, 2).DeriveTransition().SetAttribute(
214 KMemoryRegionAttr::CarveoutProtected);
215constexpr auto KMemoryRegionType_DramUserPool =
216 KMemoryRegionType_DramPoolPartition.DeriveTransition(1, 2).DeriveTransition();
217static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramPoolManagement.GetValue()) ==
218 (static_cast<KMemoryRegionAttr>(0x166) | KMemoryRegionAttr::LinearMapped |
219 KMemoryRegionAttr::NoUserMap | KMemoryRegionAttr::CarveoutProtected));
220static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramUserPool.GetValue()) ==
221 (static_cast<KMemoryRegionAttr>(0x1A6) | KMemoryRegionAttr::LinearMapped |
222 KMemoryRegionAttr::NoUserMap));
223
224constexpr auto KMemoryRegionType_DramApplicationPool = KMemoryRegionType_DramUserPool.Derive(4, 0);
225constexpr auto KMemoryRegionType_DramAppletPool = KMemoryRegionType_DramUserPool.Derive(4, 1);
226constexpr auto KMemoryRegionType_DramSystemNonSecurePool =
227 KMemoryRegionType_DramUserPool.Derive(4, 2);
228constexpr auto KMemoryRegionType_DramSystemPool =
229 KMemoryRegionType_DramUserPool.Derive(4, 3).SetAttribute(KMemoryRegionAttr::CarveoutProtected);
230static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramApplicationPool.GetValue()) ==
231 (static_cast<KMemoryRegionAttr>(0x7A6) | KMemoryRegionAttr::LinearMapped |
232 KMemoryRegionAttr::NoUserMap));
233static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramAppletPool.GetValue()) ==
234 (static_cast<KMemoryRegionAttr>(0xBA6) | KMemoryRegionAttr::LinearMapped |
235 KMemoryRegionAttr::NoUserMap));
236static_assert(
237 static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramSystemNonSecurePool.GetValue()) ==
238 (static_cast<KMemoryRegionAttr>(0xDA6) | KMemoryRegionAttr::LinearMapped |
239 KMemoryRegionAttr::NoUserMap));
240static_assert(static_cast<KMemoryRegionAttr>(KMemoryRegionType_DramSystemPool.GetValue()) ==
241 (static_cast<KMemoryRegionAttr>(0x13A6) | KMemoryRegionAttr::LinearMapped |
242 KMemoryRegionAttr::NoUserMap | KMemoryRegionAttr::CarveoutProtected));
243
244constexpr auto KMemoryRegionType_VirtualDramHeapBase = KMemoryRegionType_Dram.DeriveSparse(1, 3, 0);
245constexpr auto KMemoryRegionType_VirtualDramKernelPtHeap =
246 KMemoryRegionType_Dram.DeriveSparse(1, 3, 1);
247constexpr auto KMemoryRegionType_VirtualDramKernelTraceBuffer =
248 KMemoryRegionType_Dram.DeriveSparse(1, 3, 2);
249static_assert(KMemoryRegionType_VirtualDramHeapBase.GetValue() == 0x1A);
250static_assert(KMemoryRegionType_VirtualDramKernelPtHeap.GetValue() == 0x2A);
251static_assert(KMemoryRegionType_VirtualDramKernelTraceBuffer.GetValue() == 0x4A);
252
253constexpr auto KMemoryRegionType_VirtualDramKernelInitPt =
254 KMemoryRegionType_VirtualDramHeapBase.Derive(3, 0);
255constexpr auto KMemoryRegionType_VirtualDramPoolManagement =
256 KMemoryRegionType_VirtualDramHeapBase.Derive(3, 1);
257constexpr auto KMemoryRegionType_VirtualDramUserPool =
258 KMemoryRegionType_VirtualDramHeapBase.Derive(3, 2);
259static_assert(KMemoryRegionType_VirtualDramKernelInitPt.GetValue() == 0x19A);
260static_assert(KMemoryRegionType_VirtualDramPoolManagement.GetValue() == 0x29A);
261static_assert(KMemoryRegionType_VirtualDramUserPool.GetValue() == 0x31A);
262
263// NOTE: For unknown reason, the pools are derived out-of-order here. It's worth eventually trying
264// to understand why Nintendo made this choice.
265// UNUSED: .Derive(6, 0);
266// UNUSED: .Derive(6, 1);
267constexpr auto KMemoryRegionType_VirtualDramAppletPool =
268 KMemoryRegionType_VirtualDramUserPool.Derive(6, 2);
269constexpr auto KMemoryRegionType_VirtualDramApplicationPool =
270 KMemoryRegionType_VirtualDramUserPool.Derive(6, 3);
271constexpr auto KMemoryRegionType_VirtualDramSystemNonSecurePool =
272 KMemoryRegionType_VirtualDramUserPool.Derive(6, 4);
273constexpr auto KMemoryRegionType_VirtualDramSystemPool =
274 KMemoryRegionType_VirtualDramUserPool.Derive(6, 5);
275static_assert(KMemoryRegionType_VirtualDramAppletPool.GetValue() == 0x1B1A);
276static_assert(KMemoryRegionType_VirtualDramApplicationPool.GetValue() == 0x271A);
277static_assert(KMemoryRegionType_VirtualDramSystemNonSecurePool.GetValue() == 0x2B1A);
278static_assert(KMemoryRegionType_VirtualDramSystemPool.GetValue() == 0x331A);
279
280constexpr auto KMemoryRegionType_ArchDeviceBase =
281 KMemoryRegionType_Kernel.DeriveTransition(0, 1).SetSparseOnly();
282constexpr auto KMemoryRegionType_BoardDeviceBase =
283 KMemoryRegionType_Kernel.DeriveTransition(0, 2).SetDenseOnly();
284static_assert(KMemoryRegionType_ArchDeviceBase.GetValue() == 0x5);
285static_assert(KMemoryRegionType_BoardDeviceBase.GetValue() == 0x5);
286
287#if defined(ATMOSPHERE_ARCH_ARM64)
288#include <mesosphere/arch/arm64/kern_k_memory_region_device_types.inc>
289#elif defined(ATMOSPHERE_ARCH_ARM)
290#include <mesosphere/arch/arm/kern_k_memory_region_device_types.inc>
291#else
292// Default to no architecture devices.
293constexpr auto NumArchitectureDeviceRegions = 0;
294#endif
295static_assert(NumArchitectureDeviceRegions >= 0);
296
297#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
298#include <mesosphere/board/nintendo/nx/kern_k_memory_region_device_types.inc>
299#else
300// Default to no board devices.
301constexpr auto NumBoardDeviceRegions = 0;
302#endif
303static_assert(NumBoardDeviceRegions >= 0);
304
305constexpr auto KMemoryRegionType_KernelCode = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 0);
306constexpr auto KMemoryRegionType_KernelStack = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 1);
307constexpr auto KMemoryRegionType_KernelMisc = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 2);
308constexpr auto KMemoryRegionType_KernelSlab = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 3);
309static_assert(KMemoryRegionType_KernelCode.GetValue() == 0x19);
310static_assert(KMemoryRegionType_KernelStack.GetValue() == 0x29);
311static_assert(KMemoryRegionType_KernelMisc.GetValue() == 0x49);
312static_assert(KMemoryRegionType_KernelSlab.GetValue() == 0x89);
313
314constexpr auto KMemoryRegionType_KernelMiscDerivedBase =
315 KMemoryRegionType_KernelMisc.DeriveTransition();
316static_assert(KMemoryRegionType_KernelMiscDerivedBase.GetValue() == 0x149);
317
318// UNUSED: .Derive(7, 0);
319constexpr auto KMemoryRegionType_KernelMiscMainStack =
320 KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 1);
321constexpr auto KMemoryRegionType_KernelMiscMappedDevice =
322 KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 2);
323constexpr auto KMemoryRegionType_KernelMiscExceptionStack =
324 KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 3);
325constexpr auto KMemoryRegionType_KernelMiscUnknownDebug =
326 KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 4);
327// UNUSED: .Derive(7, 5);
328constexpr auto KMemoryRegionType_KernelMiscIdleStack =
329 KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 6);
330static_assert(KMemoryRegionType_KernelMiscMainStack.GetValue() == 0xB49);
331static_assert(KMemoryRegionType_KernelMiscMappedDevice.GetValue() == 0xD49);
332static_assert(KMemoryRegionType_KernelMiscExceptionStack.GetValue() == 0x1349);
333static_assert(KMemoryRegionType_KernelMiscUnknownDebug.GetValue() == 0x1549);
334static_assert(KMemoryRegionType_KernelMiscIdleStack.GetValue() == 0x2349);
335
336constexpr auto KMemoryRegionType_KernelTemp = KMemoryRegionType_Kernel.Advance(2).Derive(2, 0);
337static_assert(KMemoryRegionType_KernelTemp.GetValue() == 0x31);
338
339constexpr KMemoryRegionType GetTypeForVirtualLinearMapping(u32 type_id) {
340 if (KMemoryRegionType_KernelTraceBuffer.IsAncestorOf(type_id)) {
341 return KMemoryRegionType_VirtualDramKernelTraceBuffer;
342 } else if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) {
343 return KMemoryRegionType_VirtualDramKernelPtHeap;
344 } else {
345 return KMemoryRegionType_Dram;
346 }
347}
21 348
22} // namespace Kernel 349} // namespace Kernel