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.h97
-rw-r--r--src/core/hle/kernel/scheduler.cpp2
-rw-r--r--src/core/hle/kernel/shared_memory.cpp14
-rw-r--r--src/core/hle/kernel/svc.cpp30
-rw-r--r--src/core/hle/kernel/thread.cpp4
5 files changed, 96 insertions, 51 deletions
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index adb03c228..2dfb88fa9 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -135,6 +135,16 @@ public:
135 return HANDLE_TYPE; 135 return HANDLE_TYPE;
136 } 136 }
137 137
138 /// Gets a reference to the process' memory manager.
139 Kernel::VMManager& VMManager() {
140 return vm_manager;
141 }
142
143 /// Gets a const reference to the process' memory manager.
144 const Kernel::VMManager& VMManager() const {
145 return vm_manager;
146 }
147
138 /// Gets the current status of the process 148 /// Gets the current status of the process
139 ProcessStatus GetStatus() const { 149 ProcessStatus GetStatus() const {
140 return status; 150 return status;
@@ -145,6 +155,40 @@ public:
145 return process_id; 155 return process_id;
146 } 156 }
147 157
158 /// Gets the title ID corresponding to this process.
159 u64 GetTitleID() const {
160 return program_id;
161 }
162
163 /// Gets the resource limit descriptor for this process
164 ResourceLimit& GetResourceLimit() {
165 return *resource_limit;
166 }
167
168 /// Gets the resource limit descriptor for this process
169 const ResourceLimit& GetResourceLimit() const {
170 return *resource_limit;
171 }
172
173 /// Gets the default CPU ID for this process
174 u8 GetDefaultProcessorID() const {
175 return ideal_processor;
176 }
177
178 /// Gets the bitmask of allowed CPUs that this process' threads can run on.
179 u32 GetAllowedProcessorMask() const {
180 return allowed_processor_mask;
181 }
182
183 /// Gets the bitmask of allowed thread priorities.
184 u32 GetAllowedThreadPriorityMask() const {
185 return allowed_thread_priority_mask;
186 }
187
188 u32 IsVirtualMemoryEnabled() const {
189 return is_virtual_address_memory_enabled;
190 }
191
148 /** 192 /**
149 * Loads process-specifics configuration info with metadata provided 193 * Loads process-specifics configuration info with metadata provided
150 * by an executable. 194 * by an executable.
@@ -153,30 +197,6 @@ public:
153 */ 197 */
154 void LoadFromMetadata(const FileSys::ProgramMetadata& metadata); 198 void LoadFromMetadata(const FileSys::ProgramMetadata& metadata);
155 199
156 /// Title ID corresponding to the process
157 u64 program_id;
158
159 /// Resource limit descriptor for this process
160 SharedPtr<ResourceLimit> resource_limit;
161
162 /// The process may only call SVCs which have the corresponding bit set.
163 std::bitset<0x80> svc_access_mask;
164 /// Maximum size of the handle table for the process.
165 unsigned int handle_table_size = 0x200;
166 /// Special memory ranges mapped into this processes address space. This is used to give
167 /// processes access to specific I/O regions and device memory.
168 boost::container::static_vector<AddressMapping, 8> address_mappings;
169 ProcessFlags flags;
170 /// Kernel compatibility version for this process
171 u16 kernel_version = 0;
172 /// The default CPU for this process, threads are scheduled on this cpu by default.
173 u8 ideal_processor = 0;
174 /// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
175 /// this value from the process header.
176 u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
177 u32 allowed_thread_priority_mask = 0xFFFFFFFF;
178 u32 is_virtual_address_memory_enabled = 0;
179
180 /** 200 /**
181 * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them 201 * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
182 * to this process. 202 * to this process.
@@ -212,18 +232,43 @@ public:
212 232
213 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); 233 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
214 234
215 VMManager vm_manager;
216
217private: 235private:
218 explicit Process(KernelCore& kernel); 236 explicit Process(KernelCore& kernel);
219 ~Process() override; 237 ~Process() override;
220 238
239 /// Memory manager for this process.
240 Kernel::VMManager vm_manager;
241
221 /// Current status of the process 242 /// Current status of the process
222 ProcessStatus status; 243 ProcessStatus status;
223 244
224 /// The ID of this process 245 /// The ID of this process
225 u32 process_id = 0; 246 u32 process_id = 0;
226 247
248 /// Title ID corresponding to the process
249 u64 program_id;
250
251 /// Resource limit descriptor for this process
252 SharedPtr<ResourceLimit> resource_limit;
253
254 /// The process may only call SVCs which have the corresponding bit set.
255 std::bitset<0x80> svc_access_mask;
256 /// Maximum size of the handle table for the process.
257 u32 handle_table_size = 0x200;
258 /// Special memory ranges mapped into this processes address space. This is used to give
259 /// processes access to specific I/O regions and device memory.
260 boost::container::static_vector<AddressMapping, 8> address_mappings;
261 ProcessFlags flags;
262 /// Kernel compatibility version for this process
263 u16 kernel_version = 0;
264 /// The default CPU for this process, threads are scheduled on this cpu by default.
265 u8 ideal_processor = 0;
266 /// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
267 /// this value from the process header.
268 u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
269 u32 allowed_thread_priority_mask = 0xFFFFFFFF;
270 u32 is_virtual_address_memory_enabled = 0;
271
227 // Memory used to back the allocations in the regular heap. A single vector is used to cover 272 // Memory used to back the allocations in the regular heap. A single vector is used to cover
228 // the entire virtual address space extents that bound the allocations, including any holes. 273 // the entire virtual address space extents that bound the allocations, including any holes.
229 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous 274 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 9faf903cf..1e82cfffb 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -88,7 +88,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
88 88
89 if (previous_process != current_thread->owner_process) { 89 if (previous_process != current_thread->owner_process) {
90 Core::CurrentProcess() = current_thread->owner_process; 90 Core::CurrentProcess() = current_thread->owner_process;
91 SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table); 91 SetCurrentPageTable(&Core::CurrentProcess()->VMManager().page_table);
92 } 92 }
93 93
94 cpu_core.LoadContext(new_thread->context); 94 cpu_core.LoadContext(new_thread->context);
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 9b78c8cb5..d061e6155 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -35,11 +35,11 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, SharedPtr<Proce
35 35
36 // Refresh the address mappings for the current process. 36 // Refresh the address mappings for the current process.
37 if (Core::CurrentProcess() != nullptr) { 37 if (Core::CurrentProcess() != nullptr) {
38 Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings( 38 Core::CurrentProcess()->VMManager().RefreshMemoryBlockMappings(
39 shared_memory->backing_block.get()); 39 shared_memory->backing_block.get());
40 } 40 }
41 } else { 41 } else {
42 auto& vm_manager = shared_memory->owner_process->vm_manager; 42 auto& vm_manager = shared_memory->owner_process->VMManager();
43 43
44 // The memory is already available and mapped in the owner process. 44 // The memory is already available and mapped in the owner process.
45 auto vma = vm_manager.FindVMA(address); 45 auto vma = vm_manager.FindVMA(address);
@@ -73,7 +73,7 @@ SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
73 shared_memory->backing_block = std::move(heap_block); 73 shared_memory->backing_block = std::move(heap_block);
74 shared_memory->backing_block_offset = offset; 74 shared_memory->backing_block_offset = offset;
75 shared_memory->base_address = 75 shared_memory->base_address =
76 kernel.CurrentProcess()->vm_manager.GetHeapRegionBaseAddress() + offset; 76 kernel.CurrentProcess()->VMManager().GetHeapRegionBaseAddress() + offset;
77 77
78 return shared_memory; 78 return shared_memory;
79} 79}
@@ -107,7 +107,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
107 VAddr target_address = address; 107 VAddr target_address = address;
108 108
109 // Map the memory block into the target process 109 // Map the memory block into the target process
110 auto result = target_process->vm_manager.MapMemoryBlock( 110 auto result = target_process->VMManager().MapMemoryBlock(
111 target_address, backing_block, backing_block_offset, size, MemoryState::Shared); 111 target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
112 if (result.Failed()) { 112 if (result.Failed()) {
113 LOG_ERROR( 113 LOG_ERROR(
@@ -117,14 +117,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
117 return result.Code(); 117 return result.Code();
118 } 118 }
119 119
120 return target_process->vm_manager.ReprotectRange(target_address, size, 120 return target_process->VMManager().ReprotectRange(target_address, size,
121 ConvertPermissions(permissions)); 121 ConvertPermissions(permissions));
122} 122}
123 123
124ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) { 124ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) {
125 // TODO(Subv): Verify what happens if the application tries to unmap an address that is not 125 // TODO(Subv): Verify what happens if the application tries to unmap an address that is not
126 // mapped to a SharedMemory. 126 // mapped to a SharedMemory.
127 return target_process->vm_manager.UnmapRange(address, size); 127 return target_process->VMManager().UnmapRange(address, size);
128} 128}
129 129
130VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { 130VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 44bbaf0c8..b76280456 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -51,7 +51,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
51 } 51 }
52 52
53 auto& process = *Core::CurrentProcess(); 53 auto& process = *Core::CurrentProcess();
54 const VAddr heap_base = process.vm_manager.GetHeapRegionBaseAddress(); 54 const VAddr heap_base = process.VMManager().GetHeapRegionBaseAddress();
55 CASCADE_RESULT(*heap_addr, 55 CASCADE_RESULT(*heap_addr,
56 process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite)); 56 process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite));
57 return RESULT_SUCCESS; 57 return RESULT_SUCCESS;
@@ -327,14 +327,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
327 info_sub_id, handle); 327 info_sub_id, handle);
328 328
329 const auto& current_process = Core::CurrentProcess(); 329 const auto& current_process = Core::CurrentProcess();
330 const auto& vm_manager = current_process->vm_manager; 330 const auto& vm_manager = current_process->VMManager();
331 331
332 switch (static_cast<GetInfoType>(info_id)) { 332 switch (static_cast<GetInfoType>(info_id)) {
333 case GetInfoType::AllowedCpuIdBitmask: 333 case GetInfoType::AllowedCpuIdBitmask:
334 *result = current_process->allowed_processor_mask; 334 *result = current_process->GetAllowedProcessorMask();
335 break; 335 break;
336 case GetInfoType::AllowedThreadPrioBitmask: 336 case GetInfoType::AllowedThreadPrioBitmask:
337 *result = current_process->allowed_thread_priority_mask; 337 *result = current_process->GetAllowedThreadPriorityMask();
338 break; 338 break;
339 case GetInfoType::MapRegionBaseAddr: 339 case GetInfoType::MapRegionBaseAddr:
340 *result = vm_manager.GetMapRegionBaseAddress(); 340 *result = vm_manager.GetMapRegionBaseAddress();
@@ -386,10 +386,10 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
386 *result = vm_manager.GetNewMapRegionSize(); 386 *result = vm_manager.GetNewMapRegionSize();
387 break; 387 break;
388 case GetInfoType::IsVirtualAddressMemoryEnabled: 388 case GetInfoType::IsVirtualAddressMemoryEnabled:
389 *result = current_process->is_virtual_address_memory_enabled; 389 *result = current_process->IsVirtualMemoryEnabled();
390 break; 390 break;
391 case GetInfoType::TitleId: 391 case GetInfoType::TitleId:
392 *result = current_process->program_id; 392 *result = current_process->GetTitleID();
393 break; 393 break;
394 case GetInfoType::PrivilegedProcessId: 394 case GetInfoType::PrivilegedProcessId:
395 LOG_WARNING(Kernel_SVC, 395 LOG_WARNING(Kernel_SVC,
@@ -444,8 +444,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
444 444
445 // Note: The kernel uses the current process's resource limit instead of 445 // Note: The kernel uses the current process's resource limit instead of
446 // the one from the thread owner's resource limit. 446 // the one from the thread owner's resource limit.
447 SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit; 447 const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
448 if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { 448 if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
449 return ERR_NOT_AUTHORIZED; 449 return ERR_NOT_AUTHORIZED;
450 } 450 }
451 451
@@ -519,9 +519,9 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
519 if (!process) { 519 if (!process) {
520 return ERR_INVALID_HANDLE; 520 return ERR_INVALID_HANDLE;
521 } 521 }
522 auto vma = process->vm_manager.FindVMA(addr); 522 auto vma = process->VMManager().FindVMA(addr);
523 memory_info->attributes = 0; 523 memory_info->attributes = 0;
524 if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) { 524 if (vma == Core::CurrentProcess()->VMManager().vma_map.end()) {
525 memory_info->base_address = 0; 525 memory_info->base_address = 0;
526 memory_info->permission = static_cast<u32>(VMAPermission::None); 526 memory_info->permission = static_cast<u32>(VMAPermission::None);
527 memory_info->size = 0; 527 memory_info->size = 0;
@@ -568,14 +568,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
568 return ERR_INVALID_THREAD_PRIORITY; 568 return ERR_INVALID_THREAD_PRIORITY;
569 } 569 }
570 570
571 SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit; 571 const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
572 if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { 572 if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
573 return ERR_NOT_AUTHORIZED; 573 return ERR_NOT_AUTHORIZED;
574 } 574 }
575 575
576 if (processor_id == THREADPROCESSORID_DEFAULT) { 576 if (processor_id == THREADPROCESSORID_DEFAULT) {
577 // Set the target CPU to the one specified in the process' exheader. 577 // Set the target CPU to the one specified in the process' exheader.
578 processor_id = Core::CurrentProcess()->ideal_processor; 578 processor_id = Core::CurrentProcess()->GetDefaultProcessorID();
579 ASSERT(processor_id != THREADPROCESSORID_DEFAULT); 579 ASSERT(processor_id != THREADPROCESSORID_DEFAULT);
580 } 580 }
581 581
@@ -902,10 +902,10 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
902 } 902 }
903 903
904 if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) { 904 if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) {
905 ASSERT(thread->owner_process->ideal_processor != 905 ASSERT(thread->owner_process->GetDefaultProcessorID() !=
906 static_cast<u8>(THREADPROCESSORID_DEFAULT)); 906 static_cast<u8>(THREADPROCESSORID_DEFAULT));
907 // Set the target CPU to the one specified in the process' exheader. 907 // Set the target CPU to the one specified in the process' exheader.
908 core = thread->owner_process->ideal_processor; 908 core = thread->owner_process->GetDefaultProcessorID();
909 mask = 1ull << core; 909 mask = 1ull << core;
910 } 910 }
911 911
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 064ed908d..b5c16cfbb 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -259,10 +259,10 @@ void Thread::BoostPriority(u32 priority) {
259SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, 259SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority,
260 Process& owner_process) { 260 Process& owner_process) {
261 // Setup page table so we can write to memory 261 // Setup page table so we can write to memory
262 SetCurrentPageTable(&owner_process.vm_manager.page_table); 262 SetCurrentPageTable(&owner_process.VMManager().page_table);
263 263
264 // Initialize new "main" thread 264 // Initialize new "main" thread
265 const VAddr stack_top = owner_process.vm_manager.GetTLSIORegionEndAddress(); 265 const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress();
266 auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0, 266 auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0,
267 stack_top, &owner_process); 267 stack_top, &owner_process);
268 268