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/core.cpp6
-rw-r--r--src/core/core.h3
-rw-r--r--src/core/hle/kernel/kernel.cpp6
-rw-r--r--src/core/hle/kernel/kernel.h2
-rw-r--r--src/core/hle/kernel/memory.cpp90
-rw-r--r--src/core/hle/kernel/memory.h34
-rw-r--r--src/core/hle/kernel/process.cpp78
-rw-r--r--src/core/hle/kernel/process.h17
-rw-r--r--src/core/hle/kernel/shared_memory.cpp63
-rw-r--r--src/core/hle/kernel/shared_memory.h3
-rw-r--r--src/core/hle/kernel/thread.cpp33
-rw-r--r--src/core/memory.cpp106
-rw-r--r--src/core/memory.h88
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/core/memory/memory.cpp56
16 files changed, 29 insertions, 559 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 780a3affe..884c28e20 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -63,8 +63,6 @@ add_library(core STATIC
63 hle/kernel/hle_ipc.h 63 hle/kernel/hle_ipc.h
64 hle/kernel/kernel.cpp 64 hle/kernel/kernel.cpp
65 hle/kernel/kernel.h 65 hle/kernel/kernel.h
66 hle/kernel/memory.cpp
67 hle/kernel/memory.h
68 hle/kernel/mutex.cpp 66 hle/kernel/mutex.cpp
69 hle/kernel/mutex.h 67 hle/kernel/mutex.h
70 hle/kernel/object.cpp 68 hle/kernel/object.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 54fc4170f..9824769cf 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -110,7 +110,7 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file
110 } 110 }
111 } 111 }
112 112
113 ResultStatus init_result{Init(emu_window, system_mode.first.get())}; 113 ResultStatus init_result{Init(emu_window)};
114 if (init_result != ResultStatus::Success) { 114 if (init_result != ResultStatus::Success) {
115 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", 115 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
116 static_cast<int>(init_result)); 116 static_cast<int>(init_result));
@@ -161,7 +161,7 @@ Cpu& System::CpuCore(size_t core_index) {
161 return *cpu_cores[core_index]; 161 return *cpu_cores[core_index];
162} 162}
163 163
164System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) { 164System::ResultStatus System::Init(EmuWindow& emu_window) {
165 LOG_DEBUG(HW_Memory, "initialized OK"); 165 LOG_DEBUG(HW_Memory, "initialized OK");
166 166
167 CoreTiming::Init(); 167 CoreTiming::Init();
@@ -178,7 +178,7 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
178 telemetry_session = std::make_unique<Core::TelemetrySession>(); 178 telemetry_session = std::make_unique<Core::TelemetrySession>();
179 service_manager = std::make_shared<Service::SM::ServiceManager>(); 179 service_manager = std::make_shared<Service::SM::ServiceManager>();
180 180
181 Kernel::Init(system_mode); 181 Kernel::Init();
182 Service::Init(service_manager); 182 Service::Init(service_manager);
183 GDBStub::Init(); 183 GDBStub::Init();
184 184
diff --git a/src/core/core.h b/src/core/core.h
index f8b6644bb..ed475ac4e 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -189,10 +189,9 @@ private:
189 * Initialize the emulated system. 189 * Initialize the emulated system.
190 * @param emu_window Reference to the host-system window used for video output and keyboard 190 * @param emu_window Reference to the host-system window used for video output and keyboard
191 * input. 191 * input.
192 * @param system_mode The system mode.
193 * @return ResultStatus code, indicating if the operation succeeded. 192 * @return ResultStatus code, indicating if the operation succeeded.
194 */ 193 */
195 ResultStatus Init(EmuWindow& emu_window, u32 system_mode); 194 ResultStatus Init(EmuWindow& emu_window);
196 195
197 /// AppLoader used to load the current executing application 196 /// AppLoader used to load the current executing application
198 std::unique_ptr<Loader::AppLoader> app_loader; 197 std::unique_ptr<Loader::AppLoader> app_loader;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 3eb4f465c..1b0cd0abf 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -4,7 +4,6 @@
4 4
5#include "core/hle/kernel/handle_table.h" 5#include "core/hle/kernel/handle_table.h"
6#include "core/hle/kernel/kernel.h" 6#include "core/hle/kernel/kernel.h"
7#include "core/hle/kernel/memory.h"
8#include "core/hle/kernel/process.h" 7#include "core/hle/kernel/process.h"
9#include "core/hle/kernel/resource_limit.h" 8#include "core/hle/kernel/resource_limit.h"
10#include "core/hle/kernel/thread.h" 9#include "core/hle/kernel/thread.h"
@@ -15,9 +14,7 @@ namespace Kernel {
15unsigned int Object::next_object_id; 14unsigned int Object::next_object_id;
16 15
17/// Initialize the kernel 16/// Initialize the kernel
18void Init(u32 system_mode) { 17void Init() {
19 Kernel::MemoryInit(system_mode);
20
21 Kernel::ResourceLimitsInit(); 18 Kernel::ResourceLimitsInit();
22 Kernel::ThreadingInit(); 19 Kernel::ThreadingInit();
23 Kernel::TimersInit(); 20 Kernel::TimersInit();
@@ -37,7 +34,6 @@ void Shutdown() {
37 34
38 Kernel::TimersShutdown(); 35 Kernel::TimersShutdown();
39 Kernel::ResourceLimitsShutdown(); 36 Kernel::ResourceLimitsShutdown();
40 Kernel::MemoryShutdown();
41} 37}
42 38
43} // namespace Kernel 39} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 2bc45d7db..131311472 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -9,7 +9,7 @@
9namespace Kernel { 9namespace Kernel {
10 10
11/// Initialize the kernel with the specified system mode. 11/// Initialize the kernel with the specified system mode.
12void Init(u32 system_mode); 12void Init();
13 13
14/// Shutdown the kernel 14/// Shutdown the kernel
15void Shutdown(); 15void Shutdown();
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
deleted file mode 100644
index a7f3c3c5a..000000000
--- a/src/core/hle/kernel/memory.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cinttypes>
7#include <memory>
8#include <utility>
9#include <vector>
10#include "common/assert.h"
11#include "common/common_types.h"
12#include "common/logging/log.h"
13#include "core/hle/kernel/memory.h"
14#include "core/hle/kernel/process.h"
15#include "core/hle/kernel/vm_manager.h"
16#include "core/memory.h"
17
18////////////////////////////////////////////////////////////////////////////////////////////////////
19
20namespace Kernel {
21
22MemoryRegionInfo memory_regions[3];
23
24/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system
25/// memory configuration type.
26static const u32 memory_region_sizes[8][3] = {
27 // Old 3DS layouts
28 {0x04000000, 0x02C00000, 0x01400000}, // 0
29 {/* This appears to be unused. */}, // 1
30 {0x06000000, 0x00C00000, 0x01400000}, // 2
31 {0x05000000, 0x01C00000, 0x01400000}, // 3
32 {0x04800000, 0x02400000, 0x01400000}, // 4
33 {0x02000000, 0x04C00000, 0x01400000}, // 5
34
35 // New 3DS layouts
36 {0x07C00000, 0x06400000, 0x02000000}, // 6
37 {0x0B200000, 0x02E00000, 0x02000000}, // 7
38};
39
40void MemoryInit(u32 mem_type) {
41 // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead.
42 ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!");
43 ASSERT(mem_type != 1);
44
45 // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with
46 // the sizes specified in the memory_region_sizes table.
47 VAddr base = 0;
48 for (int i = 0; i < 3; ++i) {
49 memory_regions[i].base = base;
50 memory_regions[i].size = memory_region_sizes[mem_type][i];
51 memory_regions[i].used = 0;
52 memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>();
53 // Reserve enough space for this region of FCRAM.
54 // We do not want this block of memory to be relocated when allocating from it.
55 memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size);
56
57 base += memory_regions[i].size;
58 }
59
60 // We must've allocated the entire FCRAM by the end
61 ASSERT(base == Memory::FCRAM_SIZE);
62}
63
64void MemoryShutdown() {
65 for (auto& region : memory_regions) {
66 region.base = 0;
67 region.size = 0;
68 region.used = 0;
69 region.linear_heap_memory = nullptr;
70 }
71}
72
73MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
74 switch (region) {
75 case MemoryRegion::APPLICATION:
76 return &memory_regions[0];
77 case MemoryRegion::SYSTEM:
78 return &memory_regions[1];
79 case MemoryRegion::BASE:
80 return &memory_regions[2];
81 default:
82 UNREACHABLE();
83 }
84}
85
86void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {}
87
88void MapSharedPages(VMManager& address_space) {}
89
90} // namespace Kernel
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h
deleted file mode 100644
index 1d05b8871..000000000
--- a/src/core/hle/kernel/memory.h
+++ /dev/null
@@ -1,34 +0,0 @@
1// Copyright 2014 Citra 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 <memory>
8#include <vector>
9
10#include "common/common_types.h"
11
12namespace Kernel {
13
14class VMManager;
15enum class MemoryRegion : u16;
16struct AddressMapping;
17
18struct MemoryRegionInfo {
19 u64 base; // Not an address, but offset from start of FCRAM
20 u64 size;
21 u64 used;
22
23 std::shared_ptr<std::vector<u8>> linear_heap_memory;
24};
25
26void MemoryInit(u32 mem_type);
27void MemoryShutdown();
28MemoryRegionInfo* GetMemoryRegion(MemoryRegion region);
29
30void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping);
31void MapSharedPages(VMManager& address_space);
32
33extern MemoryRegionInfo memory_regions[3];
34} // namespace Kernel
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 0c0506085..5403ceef5 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -8,7 +8,6 @@
8#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/hle/kernel/errors.h" 10#include "core/hle/kernel/errors.h"
11#include "core/hle/kernel/memory.h"
12#include "core/hle/kernel/process.h" 11#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/resource_limit.h" 12#include "core/hle/kernel/resource_limit.h"
14#include "core/hle/kernel/thread.h" 13#include "core/hle/kernel/thread.h"
@@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
125 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, 124 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
126 MemoryState::Mapped) 125 MemoryState::Mapped)
127 .Unwrap(); 126 .Unwrap();
128 misc_memory_used += stack_size;
129 memory_region->used += stack_size;
130
131 // Map special address mappings
132 MapSharedPages(vm_manager);
133 for (const auto& mapping : address_mappings) {
134 HandleSpecialMapping(vm_manager, mapping);
135 }
136 127
137 vm_manager.LogLayout(); 128 vm_manager.LogLayout();
138 status = ProcessStatus::Running; 129 status = ProcessStatus::Running;
@@ -141,17 +132,13 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
141} 132}
142 133
143void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { 134void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
144 memory_region = GetMemoryRegion(flags.memory_region); 135 const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
145 136 MemoryState memory_state) {
146 auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
147 MemoryState memory_state) {
148 auto vma = vm_manager 137 auto vma = vm_manager
149 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, 138 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset,
150 segment.size, memory_state) 139 segment.size, memory_state)
151 .Unwrap(); 140 .Unwrap();
152 vm_manager.Reprotect(vma, permissions); 141 vm_manager.Reprotect(vma, permissions);
153 misc_memory_used += segment.size;
154 memory_region->used += segment.size;
155 }; 142 };
156 143
157 // Map CodeSet segments 144 // Map CodeSet segments
@@ -160,20 +147,6 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
160 MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable); 147 MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
161} 148}
162 149
163VAddr Process::GetLinearHeapAreaAddress() const {
164 // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of
165 // the extra RAM in the n3DS.
166 return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR;
167}
168
169VAddr Process::GetLinearHeapBase() const {
170 return GetLinearHeapAreaAddress() + memory_region->base;
171}
172
173VAddr Process::GetLinearHeapLimit() const {
174 return GetLinearHeapBase() + memory_region->size;
175}
176
177ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { 150ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
178 if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || 151 if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||
179 target + size < target) { 152 target + size < target) {
@@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
206 vm_manager.Reprotect(vma, perms); 179 vm_manager.Reprotect(vma, perms);
207 180
208 heap_used = size; 181 heap_used = size;
209 memory_region->used += size;
210 182
211 return MakeResult<VAddr>(heap_end - size); 183 return MakeResult<VAddr>(heap_end - size);
212} 184}
@@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
226 return result; 198 return result;
227 199
228 heap_used -= size; 200 heap_used -= size;
229 memory_region->used -= size;
230
231 return RESULT_SUCCESS;
232}
233
234ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) {
235 UNIMPLEMENTED();
236 return {};
237}
238
239ResultCode Process::LinearFree(VAddr target, u32 size) {
240 auto& linheap_memory = memory_region->linear_heap_memory;
241
242 if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() ||
243 target + size < target) {
244
245 return ERR_INVALID_ADDRESS;
246 }
247
248 if (size == 0) {
249 return RESULT_SUCCESS;
250 }
251
252 VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size();
253 if (target + size > heap_end) {
254 return ERR_INVALID_ADDRESS_STATE;
255 }
256
257 ResultCode result = vm_manager.UnmapRange(target, size);
258 if (result.IsError())
259 return result;
260
261 linear_heap_used -= size;
262 memory_region->used -= size;
263
264 if (target + size == heap_end) {
265 // End of linear heap has been freed, so check what's the last allocated block in it and
266 // reduce the size.
267 auto vma = vm_manager.FindVMA(target);
268 ASSERT(vma != vm_manager.vma_map.end());
269 ASSERT(vma->second.type == VMAType::Free);
270 VAddr new_end = vma->second.base;
271 if (new_end >= GetLinearHeapBase()) {
272 linheap_memory->resize(new_end - GetLinearHeapBase());
273 }
274 }
275 201
276 return RESULT_SUCCESS; 202 return RESULT_SUCCESS;
277} 203}
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 1204026be..98d8da35e 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -53,7 +53,6 @@ union ProcessFlags {
53enum class ProcessStatus { Created, Running, Exited }; 53enum class ProcessStatus { Created, Running, Exited };
54 54
55class ResourceLimit; 55class ResourceLimit;
56struct MemoryRegionInfo;
57 56
58struct CodeSet final : public Object { 57struct CodeSet final : public Object {
59 static SharedPtr<CodeSet> Create(std::string name); 58 static SharedPtr<CodeSet> Create(std::string name);
@@ -163,12 +162,11 @@ public:
163 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous 162 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
164 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. 163 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe.
165 std::shared_ptr<std::vector<u8>> heap_memory; 164 std::shared_ptr<std::vector<u8>> heap_memory;
166 // The left/right bounds of the address space covered by heap_memory.
167 VAddr heap_start = 0, heap_end = 0;
168
169 u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0;
170 165
171 MemoryRegionInfo* memory_region = nullptr; 166 // The left/right bounds of the address space covered by heap_memory.
167 VAddr heap_start = 0;
168 VAddr heap_end = 0;
169 u64 heap_used = 0;
172 170
173 /// The Thread Local Storage area is allocated as processes create threads, 171 /// The Thread Local Storage area is allocated as processes create threads,
174 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part 172 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
@@ -179,16 +177,9 @@ public:
179 177
180 std::string name; 178 std::string name;
181 179
182 VAddr GetLinearHeapAreaAddress() const;
183 VAddr GetLinearHeapBase() const;
184 VAddr GetLinearHeapLimit() const;
185
186 ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); 180 ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
187 ResultCode HeapFree(VAddr target, u32 size); 181 ResultCode HeapFree(VAddr target, u32 size);
188 182
189 ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms);
190 ResultCode LinearFree(VAddr target, u32 size);
191
192 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); 183 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size);
193 184
194 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); 185 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index a5b11bd87..b3ddebb3d 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -8,7 +8,6 @@
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/hle/kernel/errors.h" 10#include "core/hle/kernel/errors.h"
11#include "core/hle/kernel/memory.h"
12#include "core/hle/kernel/shared_memory.h" 11#include "core/hle/kernel/shared_memory.h"
13#include "core/memory.h" 12#include "core/memory.h"
14 13
@@ -29,51 +28,22 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
29 shared_memory->permissions = permissions; 28 shared_memory->permissions = permissions;
30 shared_memory->other_permissions = other_permissions; 29 shared_memory->other_permissions = other_permissions;
31 30
32 if (address == 0) { 31 auto& vm_manager = shared_memory->owner_process->vm_manager;
33 // We need to allocate a block from the Linear Heap ourselves. 32
34 // We'll manually allocate some memory from the linear heap in the specified region. 33 // The memory is already available and mapped in the owner process.
35 MemoryRegionInfo* memory_region = GetMemoryRegion(region); 34 auto vma = vm_manager.FindVMA(address);
36 auto& linheap_memory = memory_region->linear_heap_memory; 35 ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
37 36 ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address");
38 ASSERT_MSG(linheap_memory->size() + size <= memory_region->size, 37
39 "Not enough space in region to allocate shared memory!"); 38 // The returned VMA might be a bigger one encompassing the desired address.
40 39 auto vma_offset = address - vma->first;
41 shared_memory->backing_block = linheap_memory; 40 ASSERT_MSG(vma_offset + size <= vma->second.size,
42 shared_memory->backing_block_offset = linheap_memory->size(); 41 "Shared memory exceeds bounds of mapped block");
43 // Allocate some memory from the end of the linear heap for this region.
44 linheap_memory->insert(linheap_memory->end(), size, 0);
45 memory_region->used += size;
46
47 shared_memory->linear_heap_phys_address =
48 Memory::FCRAM_PADDR + memory_region->base +
49 static_cast<PAddr>(shared_memory->backing_block_offset);
50
51 // Increase the amount of used linear heap memory for the owner process.
52 if (shared_memory->owner_process != nullptr) {
53 shared_memory->owner_process->linear_heap_used += size;
54 }
55
56 // Refresh the address mappings for the current process.
57 if (Core::CurrentProcess() != nullptr) {
58 Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
59 }
60 } else {
61 auto& vm_manager = shared_memory->owner_process->vm_manager;
62 // The memory is already available and mapped in the owner process.
63 auto vma = vm_manager.FindVMA(address);
64 ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
65 ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address");
66
67 // The returned VMA might be a bigger one encompassing the desired address.
68 auto vma_offset = address - vma->first;
69 ASSERT_MSG(vma_offset + size <= vma->second.size,
70 "Shared memory exceeds bounds of mapped block");
71
72 shared_memory->backing_block = vma->second.backing_block;
73 shared_memory->backing_block_offset = vma->second.offset + vma_offset;
74 }
75 42
43 shared_memory->backing_block = vma->second.backing_block;
44 shared_memory->backing_block_offset = vma->second.offset + vma_offset;
76 shared_memory->base_address = address; 45 shared_memory->base_address = address;
46
77 return shared_memory; 47 return shared_memory;
78} 48}
79 49
@@ -124,11 +94,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
124 94
125 VAddr target_address = address; 95 VAddr target_address = address;
126 96
127 if (base_address == 0 && target_address == 0) {
128 // Calculate the address at which to map the memory block.
129 target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value();
130 }
131
132 // Map the memory block into the target process 97 // Map the memory block into the target process
133 auto result = target_process->vm_manager.MapMemoryBlock( 98 auto result = target_process->vm_manager.MapMemoryBlock(
134 target_address, backing_block, backing_block_offset, size, MemoryState::Shared); 99 target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 8a6f68529..c50fee615 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -111,9 +111,6 @@ public:
111 SharedPtr<Process> owner_process; 111 SharedPtr<Process> owner_process;
112 /// Address of shared memory block in the owner process if specified. 112 /// Address of shared memory block in the owner process if specified.
113 VAddr base_address; 113 VAddr base_address;
114 /// Physical address of the shared memory block in the linear heap if no address was specified
115 /// during creation.
116 PAddr linear_heap_phys_address;
117 /// Backing memory for this shared memory block. 114 /// Backing memory for this shared memory block.
118 std::shared_ptr<std::vector<u8>> backing_block; 115 std::shared_ptr<std::vector<u8>> backing_block;
119 /// Offset into the backing block for this shared memory. 116 /// Offset into the backing block for this shared memory.
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index cdb8120f2..ea9554cbb 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -20,7 +20,6 @@
20#include "core/core_timing_util.h" 20#include "core/core_timing_util.h"
21#include "core/hle/kernel/errors.h" 21#include "core/hle/kernel/errors.h"
22#include "core/hle/kernel/handle_table.h" 22#include "core/hle/kernel/handle_table.h"
23#include "core/hle/kernel/memory.h"
24#include "core/hle/kernel/object.h" 23#include "core/hle/kernel/object.h"
25#include "core/hle/kernel/process.h" 24#include "core/hle/kernel/process.h"
26#include "core/hle/kernel/thread.h" 25#include "core/hle/kernel/thread.h"
@@ -81,8 +80,8 @@ void Thread::Stop() {
81 wait_objects.clear(); 80 wait_objects.clear();
82 81
83 // Mark the TLS slot in the thread's page as free. 82 // Mark the TLS slot in the thread's page as free.
84 u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; 83 const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
85 u64 tls_slot = 84 const u64 tls_slot =
86 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; 85 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
87 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); 86 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
88} 87}
@@ -336,38 +335,10 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
336 auto& tls_slots = owner_process->tls_slots; 335 auto& tls_slots = owner_process->tls_slots;
337 336
338 auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); 337 auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots);
339
340 if (needs_allocation) { 338 if (needs_allocation) {
341 // There are no already-allocated pages with free slots, lets allocate a new one.
342 // TLS pages are allocated from the BASE region in the linear heap.
343 MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE);
344 auto& linheap_memory = memory_region->linear_heap_memory;
345
346 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
347 LOG_ERROR(Kernel_SVC,
348 "Not enough space in region to allocate a new TLS page for thread");
349 return ERR_OUT_OF_MEMORY;
350 }
351
352 size_t offset = linheap_memory->size();
353
354 // Allocate some memory from the end of the linear heap for this region.
355 linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
356 memory_region->used += Memory::PAGE_SIZE;
357 owner_process->linear_heap_used += Memory::PAGE_SIZE;
358
359 tls_slots.emplace_back(0); // The page is completely available at the start 339 tls_slots.emplace_back(0); // The page is completely available at the start
360 available_page = tls_slots.size() - 1; 340 available_page = tls_slots.size() - 1;
361 available_slot = 0; // Use the first slot in the new page 341 available_slot = 0; // Use the first slot in the new page
362
363 auto& vm_manager = owner_process->vm_manager;
364 vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
365
366 // Map the page to the current process' address space.
367 // TODO(Subv): Find the correct MemoryState for this region.
368 vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
369 linheap_memory, offset, Memory::PAGE_SIZE,
370 MemoryState::ThreadLocal);
371 } 342 }
372 343
373 // Mark the slot as used 344 // Mark the slot as used
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index e753e3436..0d41b2527 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -14,7 +14,6 @@
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/core.h" 16#include "core/core.h"
17#include "core/hle/kernel/memory.h"
18#include "core/hle/kernel/process.h" 17#include "core/hle/kernel/process.h"
19#include "core/hle/lock.h" 18#include "core/hle/lock.h"
20#include "core/memory.h" 19#include "core/memory.h"
@@ -24,8 +23,6 @@
24 23
25namespace Memory { 24namespace Memory {
26 25
27static std::array<u8, Memory::VRAM_SIZE> vram;
28
29static PageTable* current_page_table = nullptr; 26static PageTable* current_page_table = nullptr;
30 27
31void SetCurrentPageTable(PageTable* page_table) { 28void SetCurrentPageTable(PageTable* page_table) {
@@ -242,10 +239,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) {
242 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; 239 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
243} 240}
244 241
245bool IsValidPhysicalAddress(const PAddr paddr) {
246 return GetPhysicalPointer(paddr) != nullptr;
247}
248
249u8* GetPointer(const VAddr vaddr) { 242u8* GetPointer(const VAddr vaddr) {
250 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 243 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
251 if (page_pointer) { 244 if (page_pointer) {
@@ -274,61 +267,6 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) {
274 return string; 267 return string;
275} 268}
276 269
277u8* GetPhysicalPointer(PAddr address) {
278 struct MemoryArea {
279 PAddr paddr_base;
280 u32 size;
281 };
282
283 static constexpr MemoryArea memory_areas[] = {
284 {VRAM_PADDR, VRAM_SIZE},
285 {IO_AREA_PADDR, IO_AREA_SIZE},
286 {DSP_RAM_PADDR, DSP_RAM_SIZE},
287 {FCRAM_PADDR, FCRAM_N3DS_SIZE},
288 };
289
290 const auto area =
291 std::find_if(std::begin(memory_areas), std::end(memory_areas), [&](const auto& area) {
292 return address >= area.paddr_base && address < area.paddr_base + area.size;
293 });
294
295 if (area == std::end(memory_areas)) {
296 LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address);
297 return nullptr;
298 }
299
300 if (area->paddr_base == IO_AREA_PADDR) {
301 LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address);
302 return nullptr;
303 }
304
305 u64 offset_into_region = address - area->paddr_base;
306
307 u8* target_pointer = nullptr;
308 switch (area->paddr_base) {
309 case VRAM_PADDR:
310 target_pointer = vram.data() + offset_into_region;
311 break;
312 case DSP_RAM_PADDR:
313 break;
314 case FCRAM_PADDR:
315 for (const auto& region : Kernel::memory_regions) {
316 if (offset_into_region >= region.base &&
317 offset_into_region < region.base + region.size) {
318 target_pointer =
319 region.linear_heap_memory->data() + offset_into_region - region.base;
320 break;
321 }
322 }
323 ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address");
324 break;
325 default:
326 UNREACHABLE();
327 }
328
329 return target_pointer;
330}
331
332void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { 270void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) {
333 if (gpu_addr == 0) { 271 if (gpu_addr == 0) {
334 return; 272 return;
@@ -666,48 +604,4 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) {
666 CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); 604 CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size);
667} 605}
668 606
669boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
670 if (addr == 0) {
671 return 0;
672 } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) {
673 return addr - VRAM_VADDR + VRAM_PADDR;
674 } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) {
675 return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR;
676 } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) {
677 return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR;
678 } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) {
679 return addr - DSP_RAM_VADDR + DSP_RAM_PADDR;
680 } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) {
681 return addr - IO_AREA_VADDR + IO_AREA_PADDR;
682 }
683
684 return boost::none;
685}
686
687PAddr VirtualToPhysicalAddress(const VAddr addr) {
688 auto paddr = TryVirtualToPhysicalAddress(addr);
689 if (!paddr) {
690 LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr);
691 // To help with debugging, set bit on address so that it's obviously invalid.
692 return addr | 0x80000000;
693 }
694 return *paddr;
695}
696
697boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
698 if (addr == 0) {
699 return 0;
700 } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
701 return addr - VRAM_PADDR + VRAM_VADDR;
702 } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
703 return addr - FCRAM_PADDR + Core::CurrentProcess()->GetLinearHeapAreaAddress();
704 } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
705 return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
706 } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
707 return addr - IO_AREA_PADDR + IO_AREA_VADDR;
708 }
709
710 return boost::none;
711}
712
713} // namespace Memory 607} // namespace Memory
diff --git a/src/core/memory.h b/src/core/memory.h
index 8d5d017a4..b5d885b8a 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -6,12 +6,9 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <map>
10#include <string> 9#include <string>
11#include <tuple> 10#include <tuple>
12#include <vector>
13#include <boost/icl/interval_map.hpp> 11#include <boost/icl/interval_map.hpp>
14#include <boost/optional.hpp>
15#include "common/common_types.h" 12#include "common/common_types.h"
16#include "core/memory_hook.h" 13#include "core/memory_hook.h"
17#include "video_core/memory_manager.h" 14#include "video_core/memory_manager.h"
@@ -85,40 +82,6 @@ struct PageTable {
85 std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; 82 std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes;
86}; 83};
87 84
88/// Physical memory regions as seen from the ARM11
89enum : PAddr {
90 /// IO register area
91 IO_AREA_PADDR = 0x10100000,
92 IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB)
93 IO_AREA_PADDR_END = IO_AREA_PADDR + IO_AREA_SIZE,
94
95 /// MPCore internal memory region
96 MPCORE_RAM_PADDR = 0x17E00000,
97 MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB)
98 MPCORE_RAM_PADDR_END = MPCORE_RAM_PADDR + MPCORE_RAM_SIZE,
99
100 /// Video memory
101 VRAM_PADDR = 0x18000000,
102 VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
103 VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
104
105 /// DSP memory
106 DSP_RAM_PADDR = 0x1FF00000,
107 DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
108 DSP_RAM_PADDR_END = DSP_RAM_PADDR + DSP_RAM_SIZE,
109
110 /// AXI WRAM
111 AXI_WRAM_PADDR = 0x1FF80000,
112 AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB)
113 AXI_WRAM_PADDR_END = AXI_WRAM_PADDR + AXI_WRAM_SIZE,
114
115 /// Main FCRAM
116 FCRAM_PADDR = 0x20000000,
117 FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
118 FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
119 FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
120};
121
122/// Virtual user-space memory regions 85/// Virtual user-space memory regions
123enum : VAddr { 86enum : VAddr {
124 /// Where the application text, data and bss reside. 87 /// Where the application text, data and bss reside.
@@ -126,24 +89,6 @@ enum : VAddr {
126 PROCESS_IMAGE_MAX_SIZE = 0x08000000, 89 PROCESS_IMAGE_MAX_SIZE = 0x08000000,
127 PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE, 90 PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
128 91
129 /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
130 /// memory.
131 LINEAR_HEAP_VADDR = 0x14000000,
132 LINEAR_HEAP_SIZE = 0x08000000,
133 LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
134
135 /// Maps 1:1 to the IO register area.
136 IO_AREA_VADDR = 0x1EC00000,
137 IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,
138
139 /// Maps 1:1 to VRAM.
140 VRAM_VADDR = 0x1F000000,
141 VRAM_VADDR_END = VRAM_VADDR + VRAM_SIZE,
142
143 /// Maps 1:1 to DSP memory.
144 DSP_RAM_VADDR = 0x1FF00000,
145 DSP_RAM_VADDR_END = DSP_RAM_VADDR + DSP_RAM_SIZE,
146
147 /// Read-only page containing kernel and system configuration values. 92 /// Read-only page containing kernel and system configuration values.
148 CONFIG_MEMORY_VADDR = 0x1FF80000, 93 CONFIG_MEMORY_VADDR = 0x1FF80000,
149 CONFIG_MEMORY_SIZE = 0x00001000, 94 CONFIG_MEMORY_SIZE = 0x00001000,
@@ -154,13 +99,8 @@ enum : VAddr {
154 SHARED_PAGE_SIZE = 0x00001000, 99 SHARED_PAGE_SIZE = 0x00001000,
155 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, 100 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
156 101
157 /// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
158 NEW_LINEAR_HEAP_VADDR = 0x30000000,
159 NEW_LINEAR_HEAP_SIZE = 0x10000000,
160 NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
161
162 /// Area where TLS (Thread-Local Storage) buffers are allocated. 102 /// Area where TLS (Thread-Local Storage) buffers are allocated.
163 TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END, 103 TLS_AREA_VADDR = 0x40000000,
164 TLS_ENTRY_SIZE = 0x200, 104 TLS_ENTRY_SIZE = 0x200,
165 TLS_AREA_SIZE = 0x10000000, 105 TLS_AREA_SIZE = 0x10000000,
166 TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE, 106 TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
@@ -205,8 +145,6 @@ bool IsValidVirtualAddress(const VAddr addr);
205/// Determines if the given VAddr is a kernel address 145/// Determines if the given VAddr is a kernel address
206bool IsKernelVirtualAddress(const VAddr addr); 146bool IsKernelVirtualAddress(const VAddr addr);
207 147
208bool IsValidPhysicalAddress(const PAddr addr);
209
210u8 Read8(VAddr addr); 148u8 Read8(VAddr addr);
211u16 Read16(VAddr addr); 149u16 Read16(VAddr addr);
212u32 Read32(VAddr addr); 150u32 Read32(VAddr addr);
@@ -230,30 +168,6 @@ u8* GetPointer(VAddr virtual_address);
230 168
231std::string ReadCString(VAddr virtual_address, std::size_t max_length); 169std::string ReadCString(VAddr virtual_address, std::size_t max_length);
232 170
233/**
234 * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
235 * address. This should be used by services to translate addresses for use by the hardware.
236 */
237boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr);
238
239/**
240 * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
241 * address. This should be used by services to translate addresses for use by the hardware.
242 *
243 * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure.
244 */
245PAddr VirtualToPhysicalAddress(VAddr addr);
246
247/**
248 * Undoes a mapping performed by VirtualToPhysicalAddress().
249 */
250boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr);
251
252/**
253 * Gets a pointer to the memory region beginning at the specified physical address.
254 */
255u8* GetPhysicalPointer(PAddr address);
256
257enum class FlushMode { 171enum class FlushMode {
258 /// Write back modified surfaces to RAM 172 /// Write back modified surfaces to RAM
259 Flush, 173 Flush,
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 6a0a62ecc..4d74bb395 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -3,7 +3,6 @@ add_executable(tests
3 core/arm/arm_test_common.cpp 3 core/arm/arm_test_common.cpp
4 core/arm/arm_test_common.h 4 core/arm/arm_test_common.h
5 core/core_timing.cpp 5 core/core_timing.cpp
6 core/memory/memory.cpp
7 glad.cpp 6 glad.cpp
8 tests.cpp 7 tests.cpp
9) 8)
diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp
deleted file mode 100644
index 165496a54..000000000
--- a/src/tests/core/memory/memory.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <catch.hpp>
6#include "core/hle/kernel/memory.h"
7#include "core/hle/kernel/process.h"
8#include "core/memory.h"
9
10TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
11 SECTION("these regions should not be mapped on an empty process") {
12 auto process = Kernel::Process::Create("");
13 CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
14 CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
15 CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
16 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
17 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
18 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
19 CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
20 }
21
22 SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
23 auto process = Kernel::Process::Create("");
24 Kernel::MapSharedPages(process->vm_manager);
25 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
26 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
27 }
28
29 SECTION("special regions should be valid after mapping them") {
30 auto process = Kernel::Process::Create("");
31 SECTION("VRAM") {
32 Kernel::HandleSpecialMapping(process->vm_manager,
33 {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
34 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
35 }
36
37 SECTION("IO (Not yet implemented)") {
38 Kernel::HandleSpecialMapping(
39 process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
40 CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
41 }
42
43 SECTION("DSP") {
44 Kernel::HandleSpecialMapping(
45 process->vm_manager, {Memory::DSP_RAM_VADDR, Memory::DSP_RAM_SIZE, false, false});
46 CHECK(Memory::IsValidVirtualAddress(*process, Memory::DSP_RAM_VADDR) == true);
47 }
48 }
49
50 SECTION("Unmapping a VAddr should make it invalid") {
51 auto process = Kernel::Process::Create("");
52 Kernel::MapSharedPages(process->vm_manager);
53 process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
54 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
55 }
56}