summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/kernel/memory/address_space_info.cpp113
-rw-r--r--src/core/hle/kernel/memory/address_space_info.h51
3 files changed, 166 insertions, 0 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 26e1636ee..e98091cba 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -154,6 +154,8 @@ add_library(core STATIC
154 hle/kernel/hle_ipc.h 154 hle/kernel/hle_ipc.h
155 hle/kernel/kernel.cpp 155 hle/kernel/kernel.cpp
156 hle/kernel/kernel.h 156 hle/kernel/kernel.h
157 hle/kernel/memory/address_space_info.cpp
158 hle/kernel/memory/address_space_info.h
157 hle/kernel/mutex.cpp 159 hle/kernel/mutex.cpp
158 hle/kernel/mutex.h 160 hle/kernel/mutex.h
159 hle/kernel/object.cpp 161 hle/kernel/object.cpp
diff --git a/src/core/hle/kernel/memory/address_space_info.cpp b/src/core/hle/kernel/memory/address_space_info.cpp
new file mode 100644
index 000000000..67e397a0d
--- /dev/null
+++ b/src/core/hle/kernel/memory/address_space_info.cpp
@@ -0,0 +1,113 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <array>
6
7#include "common/assert.h"
8#include "core/hle/kernel/memory/address_space_info.h"
9
10namespace Kernel::Memory {
11
12namespace {
13
14constexpr std::size_t Size_1_MB{0x100000};
15constexpr std::size_t Size_2_MB{2 * Size_1_MB};
16constexpr std::size_t Size_128_MB{128 * Size_1_MB};
17constexpr std::size_t Size_1_GB{0x40000000};
18constexpr std::size_t Size_2_GB{2 * Size_1_GB};
19constexpr std::size_t Size_4_GB{4 * Size_1_GB};
20constexpr std::size_t Size_6_GB{6 * Size_1_GB};
21constexpr std::size_t Size_64_GB{64 * Size_1_GB};
22constexpr std::size_t Size_512_GB{512 * Size_1_GB};
23constexpr u64 Invalid{std::numeric_limits<u64>::max()};
24
25// clang-format off
26constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{
27 { 32 /*bit_width*/, Size_2_MB /*addr*/, Size_1_GB - Size_2_MB /*size*/, AddressSpaceInfo::Type::Is32Bit, },
28 { 32 /*bit_width*/, Size_1_GB /*addr*/, Size_4_GB - Size_1_GB /*size*/, AddressSpaceInfo::Type::Small64Bit, },
29 { 32 /*bit_width*/, Invalid /*addr*/, Size_1_GB /*size*/, AddressSpaceInfo::Type::Heap, },
30 { 32 /*bit_width*/, Invalid /*addr*/, Size_1_GB /*size*/, AddressSpaceInfo::Type::Alias, },
31 { 36 /*bit_width*/, Size_128_MB /*addr*/, Size_2_GB - Size_128_MB /*size*/, AddressSpaceInfo::Type::Is32Bit, },
32 { 36 /*bit_width*/, Size_2_GB /*addr*/, Size_64_GB - Size_2_GB /*size*/, AddressSpaceInfo::Type::Small64Bit, },
33 { 36 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Heap, },
34 { 36 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Alias, },
35 { 39 /*bit_width*/, Size_128_MB /*addr*/, Size_512_GB - Size_128_MB /*size*/, AddressSpaceInfo::Type::Large64Bit, },
36 { 39 /*bit_width*/, Invalid /*addr*/, Size_64_GB /*size*/, AddressSpaceInfo::Type::Is32Bit },
37 { 39 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Heap, },
38 { 39 /*bit_width*/, Invalid /*addr*/, Size_64_GB /*size*/, AddressSpaceInfo::Type::Alias, },
39 { 39 /*bit_width*/, Invalid /*addr*/, Size_2_GB /*size*/, AddressSpaceInfo::Type::Stack, },
40}};
41// clang-format on
42
43constexpr bool IsAllowedIndexForAddress(std::size_t index) {
44 return index < std::size(AddressSpaceInfos) && AddressSpaceInfos[index].GetAddress() != Invalid;
45}
46
47constexpr std::size_t
48 AddressSpaceIndices32Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
49 0, 1, 0, 2, 0, 3,
50 };
51
52constexpr std::size_t
53 AddressSpaceIndices36Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
54 4, 5, 4, 6, 4, 7,
55 };
56
57constexpr std::size_t
58 AddressSpaceIndices39Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
59 9, 8, 8, 10, 12, 11,
60 };
61
62constexpr bool IsAllowed32BitType(AddressSpaceInfo::Type type) {
63 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit &&
64 type != AddressSpaceInfo::Type::Stack;
65}
66
67constexpr bool IsAllowed36BitType(AddressSpaceInfo::Type type) {
68 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit &&
69 type != AddressSpaceInfo::Type::Stack;
70}
71
72constexpr bool IsAllowed39BitType(AddressSpaceInfo::Type type) {
73 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Small64Bit;
74}
75
76} // namespace
77
78u64 AddressSpaceInfo::GetAddressSpaceStart(std::size_t width, AddressSpaceInfo::Type type) {
79 const std::size_t index{static_cast<std::size_t>(type)};
80 switch (width) {
81 case 32:
82 ASSERT(IsAllowed32BitType(type));
83 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices32Bit[index]));
84 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].GetAddress();
85 case 36:
86 ASSERT(IsAllowed36BitType(type));
87 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices36Bit[index]));
88 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].GetAddress();
89 case 39:
90 ASSERT(IsAllowed39BitType(type));
91 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index]));
92 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].GetAddress();
93 }
94 UNREACHABLE();
95}
96
97std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, AddressSpaceInfo::Type type) {
98 const std::size_t index{static_cast<std::size_t>(type)};
99 switch (width) {
100 case 32:
101 ASSERT(IsAllowed32BitType(type));
102 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].GetSize();
103 case 36:
104 ASSERT(IsAllowed36BitType(type));
105 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].GetSize();
106 case 39:
107 ASSERT(IsAllowed39BitType(type));
108 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].GetSize();
109 }
110 UNREACHABLE();
111}
112
113} // namespace Kernel::Memory
diff --git a/src/core/hle/kernel/memory/address_space_info.h b/src/core/hle/kernel/memory/address_space_info.h
new file mode 100644
index 000000000..421986626
--- /dev/null
+++ b/src/core/hle/kernel/memory/address_space_info.h
@@ -0,0 +1,51 @@
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_funcs.h"
8#include "common/common_types.h"
9
10namespace Kernel::Memory {
11
12class AddressSpaceInfo final : NonCopyable {
13public:
14 enum class Type : u32 {
15 Is32Bit = 0,
16 Small64Bit = 1,
17 Large64Bit = 2,
18 Heap = 3,
19 Stack = 4,
20 Alias = 5,
21 Count,
22 };
23
24private:
25 std::size_t bit_width{};
26 std::size_t addr{};
27 std::size_t size{};
28 Type type{};
29
30public:
31 static u64 GetAddressSpaceStart(std::size_t width, Type type);
32 static std::size_t GetAddressSpaceSize(std::size_t width, Type type);
33
34 constexpr AddressSpaceInfo(std::size_t bit_width, std::size_t addr, std::size_t size, Type type)
35 : bit_width{bit_width}, addr{addr}, size{size}, type{type} {}
36
37 constexpr std::size_t GetWidth() const {
38 return bit_width;
39 }
40 constexpr std::size_t GetAddress() const {
41 return addr;
42 }
43 constexpr std::size_t GetSize() const {
44 return size;
45 }
46 constexpr Type GetType() const {
47 return type;
48 }
49};
50
51} // namespace Kernel::Memory