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/process.cpp8
-rw-r--r--src/core/hle/kernel/process.h12
-rw-r--r--src/core/hle/kernel/vm_manager.cpp154
-rw-r--r--src/core/hle/kernel/vm_manager.h84
4 files changed, 248 insertions, 10 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 121f741fd..f337f626f 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -8,6 +8,7 @@
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/core.h" 10#include "core/core.h"
11#include "core/file_sys/program_metadata.h"
11#include "core/hle/kernel/errors.h" 12#include "core/hle/kernel/errors.h"
12#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
@@ -34,14 +35,21 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
34 process->name = std::move(name); 35 process->name = std::move(name);
35 process->flags.raw = 0; 36 process->flags.raw = 0;
36 process->flags.memory_region.Assign(MemoryRegion::APPLICATION); 37 process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
38 process->resource_limit = kernel.ResourceLimitForCategory(ResourceLimitCategory::APPLICATION);
37 process->status = ProcessStatus::Created; 39 process->status = ProcessStatus::Created;
38 process->program_id = 0; 40 process->program_id = 0;
39 process->process_id = kernel.CreateNewProcessID(); 41 process->process_id = kernel.CreateNewProcessID();
42 process->svc_access_mask.set();
40 43
41 kernel.AppendNewProcess(process); 44 kernel.AppendNewProcess(process);
42 return process; 45 return process;
43} 46}
44 47
48void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
49 program_id = metadata.GetTitleID();
50 vm_manager.Reset(metadata.GetAddressSpaceType());
51}
52
45void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) { 53void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) {
46 for (std::size_t i = 0; i < len; ++i) { 54 for (std::size_t i = 0; i < len; ++i) {
47 u32 descriptor = kernel_caps[i]; 55 u32 descriptor = kernel_caps[i];
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 04d74e572..adb03c228 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -17,6 +17,10 @@
17#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
18#include "core/hle/kernel/vm_manager.h" 18#include "core/hle/kernel/vm_manager.h"
19 19
20namespace FileSys {
21class ProgramMetadata;
22}
23
20namespace Kernel { 24namespace Kernel {
21 25
22class KernelCore; 26class KernelCore;
@@ -141,6 +145,14 @@ public:
141 return process_id; 145 return process_id;
142 } 146 }
143 147
148 /**
149 * Loads process-specifics configuration info with metadata provided
150 * by an executable.
151 *
152 * @param metadata The provided metadata to load process specific info.
153 */
154 void LoadFromMetadata(const FileSys::ProgramMetadata& metadata);
155
144 /// Title ID corresponding to the process 156 /// Title ID corresponding to the process
145 u64 program_id; 157 u64 program_id;
146 158
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 608cbd57b..337f17b7b 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -9,6 +9,7 @@
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/arm/arm_interface.h" 10#include "core/arm/arm_interface.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/file_sys/program_metadata.h"
12#include "core/hle/kernel/errors.h" 13#include "core/hle/kernel/errors.h"
13#include "core/hle/kernel/vm_manager.h" 14#include "core/hle/kernel/vm_manager.h"
14#include "core/memory.h" 15#include "core/memory.h"
@@ -54,25 +55,24 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
54} 55}
55 56
56VMManager::VMManager() { 57VMManager::VMManager() {
57 Reset(); 58 // Default to assuming a 39-bit address space. This way we have a sane
59 // starting point with executables that don't provide metadata.
60 Reset(FileSys::ProgramAddressSpaceType::Is39Bit);
58} 61}
59 62
60VMManager::~VMManager() { 63VMManager::~VMManager() {
61 Reset(); 64 Reset(FileSys::ProgramAddressSpaceType::Is39Bit);
62} 65}
63 66
64void VMManager::Reset() { 67void VMManager::Reset(FileSys::ProgramAddressSpaceType type) {
65 vma_map.clear(); 68 Clear();
69 InitializeMemoryRegionRanges(type);
66 70
67 // Initialize the map with a single free region covering the entire managed space. 71 // Initialize the map with a single free region covering the entire managed space.
68 VirtualMemoryArea initial_vma; 72 VirtualMemoryArea initial_vma;
69 initial_vma.size = MAX_ADDRESS; 73 initial_vma.size = MAX_ADDRESS;
70 vma_map.emplace(initial_vma.base, initial_vma); 74 vma_map.emplace(initial_vma.base, initial_vma);
71 75
72 page_table.pointers.fill(nullptr);
73 page_table.special_regions.clear();
74 page_table.attributes.fill(Memory::PageType::Unmapped);
75
76 UpdatePageTableForVMA(initial_vma); 76 UpdatePageTableForVMA(initial_vma);
77} 77}
78 78
@@ -382,6 +382,84 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
382 } 382 }
383} 383}
384 384
385void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType type) {
386 u64 map_region_size = 0;
387 u64 heap_region_size = 0;
388 u64 new_map_region_size = 0;
389 u64 tls_io_region_size = 0;
390
391 switch (type) {
392 case FileSys::ProgramAddressSpaceType::Is32Bit:
393 address_space_width = 32;
394 code_region_base = 0x200000;
395 code_region_end = code_region_base + 0x3FE00000;
396 map_region_size = 0x40000000;
397 heap_region_size = 0x40000000;
398 break;
399 case FileSys::ProgramAddressSpaceType::Is36Bit:
400 address_space_width = 36;
401 code_region_base = 0x8000000;
402 code_region_end = code_region_base + 0x78000000;
403 map_region_size = 0x180000000;
404 heap_region_size = 0x180000000;
405 break;
406 case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
407 address_space_width = 32;
408 code_region_base = 0x200000;
409 code_region_end = code_region_base + 0x3FE00000;
410 map_region_size = 0;
411 heap_region_size = 0x80000000;
412 break;
413 case FileSys::ProgramAddressSpaceType::Is39Bit:
414 address_space_width = 39;
415 code_region_base = 0x8000000;
416 code_region_end = code_region_base + 0x80000000;
417 map_region_size = 0x1000000000;
418 heap_region_size = 0x180000000;
419 new_map_region_size = 0x80000000;
420 tls_io_region_size = 0x1000000000;
421 break;
422 default:
423 UNREACHABLE_MSG("Invalid address space type specified: {}", static_cast<u32>(type));
424 return;
425 }
426
427 address_space_base = 0;
428 address_space_end = 1ULL << address_space_width;
429
430 map_region_base = code_region_end;
431 map_region_end = map_region_base + map_region_size;
432
433 heap_region_base = map_region_end;
434 heap_region_end = heap_region_base + heap_region_size;
435
436 new_map_region_base = heap_region_end;
437 new_map_region_end = new_map_region_base + new_map_region_size;
438
439 tls_io_region_base = new_map_region_end;
440 tls_io_region_end = tls_io_region_base + tls_io_region_size;
441
442 if (new_map_region_size == 0) {
443 new_map_region_base = address_space_base;
444 new_map_region_end = address_space_end;
445 }
446}
447
448void VMManager::Clear() {
449 ClearVMAMap();
450 ClearPageTable();
451}
452
453void VMManager::ClearVMAMap() {
454 vma_map.clear();
455}
456
457void VMManager::ClearPageTable() {
458 page_table.pointers.fill(nullptr);
459 page_table.special_regions.clear();
460 page_table.attributes.fill(Memory::PageType::Unmapped);
461}
462
385u64 VMManager::GetTotalMemoryUsage() const { 463u64 VMManager::GetTotalMemoryUsage() const {
386 LOG_WARNING(Kernel, "(STUBBED) called"); 464 LOG_WARNING(Kernel, "(STUBBED) called");
387 return 0xF8000000; 465 return 0xF8000000;
@@ -402,4 +480,64 @@ u64 VMManager::GetAddressSpaceSize() const {
402 return MAX_ADDRESS; 480 return MAX_ADDRESS;
403} 481}
404 482
483VAddr VMManager::GetCodeRegionBaseAddress() const {
484 return code_region_base;
485}
486
487VAddr VMManager::GetCodeRegionEndAddress() const {
488 return code_region_end;
489}
490
491u64 VMManager::GetCodeRegionSize() const {
492 return code_region_end - code_region_base;
493}
494
495VAddr VMManager::GetHeapRegionBaseAddress() const {
496 return heap_region_base;
497}
498
499VAddr VMManager::GetHeapRegionEndAddress() const {
500 return heap_region_end;
501}
502
503u64 VMManager::GetHeapRegionSize() const {
504 return heap_region_end - heap_region_base;
505}
506
507VAddr VMManager::GetMapRegionBaseAddress() const {
508 return map_region_base;
509}
510
511VAddr VMManager::GetMapRegionEndAddress() const {
512 return map_region_end;
513}
514
515u64 VMManager::GetMapRegionSize() const {
516 return map_region_end - map_region_base;
517}
518
519VAddr VMManager::GetNewMapRegionBaseAddress() const {
520 return new_map_region_base;
521}
522
523VAddr VMManager::GetNewMapRegionEndAddress() const {
524 return new_map_region_end;
525}
526
527u64 VMManager::GetNewMapRegionSize() const {
528 return new_map_region_end - new_map_region_base;
529}
530
531VAddr VMManager::GetTLSIORegionBaseAddress() const {
532 return tls_io_region_base;
533}
534
535VAddr VMManager::GetTLSIORegionEndAddress() const {
536 return tls_io_region_end;
537}
538
539u64 VMManager::GetTLSIORegionSize() const {
540 return tls_io_region_end - tls_io_region_base;
541}
542
405} // namespace Kernel 543} // namespace Kernel
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index de75036c0..0ce240126 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -12,6 +12,10 @@
12#include "core/memory.h" 12#include "core/memory.h"
13#include "core/memory_hook.h" 13#include "core/memory_hook.h"
14 14
15namespace FileSys {
16enum class ProgramAddressSpaceType : u8;
17}
18
15namespace Kernel { 19namespace Kernel {
16 20
17enum class VMAType : u8 { 21enum class VMAType : u8 {
@@ -130,7 +134,7 @@ public:
130 ~VMManager(); 134 ~VMManager();
131 135
132 /// Clears the address space map, re-initializing with a single free area. 136 /// Clears the address space map, re-initializing with a single free area.
133 void Reset(); 137 void Reset(FileSys::ProgramAddressSpaceType type);
134 138
135 /// Finds the VMA in which the given address is included in, or `vma_map.end()`. 139 /// Finds the VMA in which the given address is included in, or `vma_map.end()`.
136 VMAHandle FindVMA(VAddr target) const; 140 VMAHandle FindVMA(VAddr target) const;
@@ -195,12 +199,57 @@ public:
195 /// Gets the total heap usage, used by svcGetInfo 199 /// Gets the total heap usage, used by svcGetInfo
196 u64 GetTotalHeapUsage() const; 200 u64 GetTotalHeapUsage() const;
197 201
198 /// Gets the total address space base address, used by svcGetInfo 202 /// Gets the address space base address, used by svcGetInfo
199 VAddr GetAddressSpaceBaseAddr() const; 203 VAddr GetAddressSpaceBaseAddr() const;
200 204
201 /// Gets the total address space address size, used by svcGetInfo 205 /// Gets the total address space address size, used by svcGetInfo
202 u64 GetAddressSpaceSize() const; 206 u64 GetAddressSpaceSize() const;
203 207
208 /// Gets the base address of the code region.
209 VAddr GetCodeRegionBaseAddress() const;
210
211 /// Gets the end address of the code region.
212 VAddr GetCodeRegionEndAddress() const;
213
214 /// Gets the total size of the code region in bytes.
215 u64 GetCodeRegionSize() const;
216
217 /// Gets the base address of the heap region.
218 VAddr GetHeapRegionBaseAddress() const;
219
220 /// Gets the end address of the heap region;
221 VAddr GetHeapRegionEndAddress() const;
222
223 /// Gets the total size of the heap region in bytes.
224 u64 GetHeapRegionSize() const;
225
226 /// Gets the base address of the map region.
227 VAddr GetMapRegionBaseAddress() const;
228
229 /// Gets the end address of the map region.
230 VAddr GetMapRegionEndAddress() const;
231
232 /// Gets the total size of the map region in bytes.
233 u64 GetMapRegionSize() const;
234
235 /// Gets the base address of the new map region.
236 VAddr GetNewMapRegionBaseAddress() const;
237
238 /// Gets the end address of the new map region.
239 VAddr GetNewMapRegionEndAddress() const;
240
241 /// Gets the total size of the new map region in bytes.
242 u64 GetNewMapRegionSize() const;
243
244 /// Gets the base address of the TLS IO region.
245 VAddr GetTLSIORegionBaseAddress() const;
246
247 /// Gets the end address of the TLS IO region.
248 VAddr GetTLSIORegionEndAddress() const;
249
250 /// Gets the total size of the TLS IO region in bytes.
251 u64 GetTLSIORegionSize() const;
252
204 /// Each VMManager has its own page table, which is set as the main one when the owning process 253 /// Each VMManager has its own page table, which is set as the main one when the owning process
205 /// is scheduled. 254 /// is scheduled.
206 Memory::PageTable page_table; 255 Memory::PageTable page_table;
@@ -240,5 +289,36 @@ private:
240 289
241 /// Updates the pages corresponding to this VMA so they match the VMA's attributes. 290 /// Updates the pages corresponding to this VMA so they match the VMA's attributes.
242 void UpdatePageTableForVMA(const VirtualMemoryArea& vma); 291 void UpdatePageTableForVMA(const VirtualMemoryArea& vma);
292
293 /// Initializes memory region ranges to adhere to a given address space type.
294 void InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType type);
295
296 /// Clears the underlying map and page table.
297 void Clear();
298
299 /// Clears out the VMA map, unmapping any previously mapped ranges.
300 void ClearVMAMap();
301
302 /// Clears out the page table
303 void ClearPageTable();
304
305 u32 address_space_width = 0;
306 VAddr address_space_base = 0;
307 VAddr address_space_end = 0;
308
309 VAddr code_region_base = 0;
310 VAddr code_region_end = 0;
311
312 VAddr heap_region_base = 0;
313 VAddr heap_region_end = 0;
314
315 VAddr map_region_base = 0;
316 VAddr map_region_end = 0;
317
318 VAddr new_map_region_base = 0;
319 VAddr new_map_region_end = 0;
320
321 VAddr tls_io_region_base = 0;
322 VAddr tls_io_region_end = 0;
243}; 323};
244} // namespace Kernel 324} // namespace Kernel