summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar bunnei2018-09-30 15:32:27 -0400
committerGravatar GitHub2018-09-30 15:32:27 -0400
commit5e2f23e2b185475c3ce7ae1750ec14daefcd3e08 (patch)
treeac2c341c94976552acd507359e8853105193d288 /src/core/hle/kernel
parentMerge pull request #1418 from FearlessTobi/port-4269 (diff)
parentkernel/svc: Implement svcGetThreadContext() (diff)
downloadyuzu-5e2f23e2b185475c3ce7ae1750ec14daefcd3e08.tar.gz
yuzu-5e2f23e2b185475c3ce7ae1750ec14daefcd3e08.tar.xz
yuzu-5e2f23e2b185475c3ce7ae1750ec14daefcd3e08.zip
Merge pull request #1417 from lioncash/context
svc: Implement svcGetThreadContext
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/errors.h2
-rw-r--r--src/core/hle/kernel/process.cpp1
-rw-r--r--src/core/hle/kernel/process.h107
-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.cpp62
-rw-r--r--src/core/hle/kernel/svc_wrap.h5
-rw-r--r--src/core/hle/kernel/thread.cpp4
8 files changed, 144 insertions, 53 deletions
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h
index 8c2be2681..e5fa67ae8 100644
--- a/src/core/hle/kernel/errors.h
+++ b/src/core/hle/kernel/errors.h
@@ -31,6 +31,7 @@ enum {
31 TooLarge = 119, 31 TooLarge = 119,
32 InvalidEnumValue = 120, 32 InvalidEnumValue = 120,
33 NoSuchEntry = 121, 33 NoSuchEntry = 121,
34 AlreadyRegistered = 122,
34 InvalidState = 125, 35 InvalidState = 125,
35 ResourceLimitExceeded = 132, 36 ResourceLimitExceeded = 132,
36}; 37};
@@ -58,6 +59,7 @@ constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS(ErrorModule::Kernel,
58constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle); 59constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle);
59constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); 60constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId);
60constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize); 61constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize);
62constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::Kernel, ErrCodes::AlreadyRegistered);
61constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState); 63constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState);
62constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel, 64constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel,
63 ErrCodes::InvalidThreadPriority); 65 ErrCodes::InvalidThreadPriority);
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index a8e3098ca..dc9fc8470 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -47,6 +47,7 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
47 47
48void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { 48void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
49 program_id = metadata.GetTitleID(); 49 program_id = metadata.GetTitleID();
50 is_64bit_process = metadata.Is64BitProgram();
50 vm_manager.Reset(metadata.GetAddressSpaceType()); 51 vm_manager.Reset(metadata.GetAddressSpaceType());
51} 52}
52 53
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index adb03c228..590e0c73d 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,45 @@ 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
192 /// Whether this process is an AArch64 or AArch32 process.
193 bool Is64BitProcess() const {
194 return is_64bit_process;
195 }
196
148 /** 197 /**
149 * Loads process-specifics configuration info with metadata provided 198 * Loads process-specifics configuration info with metadata provided
150 * by an executable. 199 * by an executable.
@@ -153,30 +202,6 @@ public:
153 */ 202 */
154 void LoadFromMetadata(const FileSys::ProgramMetadata& metadata); 203 void LoadFromMetadata(const FileSys::ProgramMetadata& metadata);
155 204
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 /** 205 /**
181 * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them 206 * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
182 * to this process. 207 * to this process.
@@ -212,18 +237,43 @@ public:
212 237
213 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); 238 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
214 239
215 VMManager vm_manager;
216
217private: 240private:
218 explicit Process(KernelCore& kernel); 241 explicit Process(KernelCore& kernel);
219 ~Process() override; 242 ~Process() override;
220 243
244 /// Memory manager for this process.
245 Kernel::VMManager vm_manager;
246
221 /// Current status of the process 247 /// Current status of the process
222 ProcessStatus status; 248 ProcessStatus status;
223 249
224 /// The ID of this process 250 /// The ID of this process
225 u32 process_id = 0; 251 u32 process_id = 0;
226 252
253 /// Title ID corresponding to the process
254 u64 program_id;
255
256 /// Resource limit descriptor for this process
257 SharedPtr<ResourceLimit> resource_limit;
258
259 /// The process may only call SVCs which have the corresponding bit set.
260 std::bitset<0x80> svc_access_mask;
261 /// Maximum size of the handle table for the process.
262 u32 handle_table_size = 0x200;
263 /// Special memory ranges mapped into this processes address space. This is used to give
264 /// processes access to specific I/O regions and device memory.
265 boost::container::static_vector<AddressMapping, 8> address_mappings;
266 ProcessFlags flags;
267 /// Kernel compatibility version for this process
268 u16 kernel_version = 0;
269 /// The default CPU for this process, threads are scheduled on this cpu by default.
270 u8 ideal_processor = 0;
271 /// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
272 /// this value from the process header.
273 u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
274 u32 allowed_thread_priority_mask = 0xFFFFFFFF;
275 u32 is_virtual_address_memory_enabled = 0;
276
227 // Memory used to back the allocations in the regular heap. A single vector is used to cover 277 // 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. 278 // 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 279 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
@@ -242,6 +292,11 @@ private:
242 /// This vector will grow as more pages are allocated for new threads. 292 /// This vector will grow as more pages are allocated for new threads.
243 std::vector<std::bitset<8>> tls_slots; 293 std::vector<std::bitset<8>> tls_slots;
244 294
295 /// Whether or not this process is AArch64, or AArch32.
296 /// By default, we currently assume this is true, unless otherwise
297 /// specified by metadata provided to the process during loading.
298 bool is_64bit_process = true;
299
245 std::string name; 300 std::string name;
246}; 301};
247 302
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..1cdaa740a 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,
@@ -415,8 +415,36 @@ static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
415} 415}
416 416
417/// Gets the thread context 417/// Gets the thread context
418static ResultCode GetThreadContext(Handle handle, VAddr addr) { 418static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
419 LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr); 419 LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
420
421 auto& kernel = Core::System::GetInstance().Kernel();
422 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle);
423 if (!thread) {
424 return ERR_INVALID_HANDLE;
425 }
426
427 const auto current_process = Core::CurrentProcess();
428 if (thread->owner_process != current_process) {
429 return ERR_INVALID_HANDLE;
430 }
431
432 if (thread == GetCurrentThread()) {
433 return ERR_ALREADY_REGISTERED;
434 }
435
436 Core::ARM_Interface::ThreadContext ctx = thread->context;
437 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
438 ctx.pstate &= 0xFF0FFE20;
439
440 // If 64-bit, we can just write the context registers directly and we're good.
441 // However, if 32-bit, we have to ensure some registers are zeroed out.
442 if (!current_process->Is64BitProcess()) {
443 std::fill(ctx.cpu_registers.begin() + 15, ctx.cpu_registers.end(), 0);
444 std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{});
445 }
446
447 Memory::WriteBlock(thread_context, &ctx, sizeof(ctx));
420 return RESULT_SUCCESS; 448 return RESULT_SUCCESS;
421} 449}
422 450
@@ -444,8 +472,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
444 472
445 // Note: The kernel uses the current process's resource limit instead of 473 // Note: The kernel uses the current process's resource limit instead of
446 // the one from the thread owner's resource limit. 474 // the one from the thread owner's resource limit.
447 SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit; 475 const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
448 if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { 476 if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
449 return ERR_NOT_AUTHORIZED; 477 return ERR_NOT_AUTHORIZED;
450 } 478 }
451 479
@@ -519,9 +547,9 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
519 if (!process) { 547 if (!process) {
520 return ERR_INVALID_HANDLE; 548 return ERR_INVALID_HANDLE;
521 } 549 }
522 auto vma = process->vm_manager.FindVMA(addr); 550 auto vma = process->VMManager().FindVMA(addr);
523 memory_info->attributes = 0; 551 memory_info->attributes = 0;
524 if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) { 552 if (vma == Core::CurrentProcess()->VMManager().vma_map.end()) {
525 memory_info->base_address = 0; 553 memory_info->base_address = 0;
526 memory_info->permission = static_cast<u32>(VMAPermission::None); 554 memory_info->permission = static_cast<u32>(VMAPermission::None);
527 memory_info->size = 0; 555 memory_info->size = 0;
@@ -568,14 +596,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
568 return ERR_INVALID_THREAD_PRIORITY; 596 return ERR_INVALID_THREAD_PRIORITY;
569 } 597 }
570 598
571 SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit; 599 const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
572 if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { 600 if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
573 return ERR_NOT_AUTHORIZED; 601 return ERR_NOT_AUTHORIZED;
574 } 602 }
575 603
576 if (processor_id == THREADPROCESSORID_DEFAULT) { 604 if (processor_id == THREADPROCESSORID_DEFAULT) {
577 // Set the target CPU to the one specified in the process' exheader. 605 // Set the target CPU to the one specified in the process' exheader.
578 processor_id = Core::CurrentProcess()->ideal_processor; 606 processor_id = Core::CurrentProcess()->GetDefaultProcessorID();
579 ASSERT(processor_id != THREADPROCESSORID_DEFAULT); 607 ASSERT(processor_id != THREADPROCESSORID_DEFAULT);
580 } 608 }
581 609
@@ -902,10 +930,10 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
902 } 930 }
903 931
904 if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) { 932 if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) {
905 ASSERT(thread->owner_process->ideal_processor != 933 ASSERT(thread->owner_process->GetDefaultProcessorID() !=
906 static_cast<u8>(THREADPROCESSORID_DEFAULT)); 934 static_cast<u8>(THREADPROCESSORID_DEFAULT));
907 // Set the target CPU to the one specified in the process' exheader. 935 // Set the target CPU to the one specified in the process' exheader.
908 core = thread->owner_process->ideal_processor; 936 core = thread->owner_process->GetDefaultProcessorID();
909 mask = 1ull << core; 937 mask = 1ull << core;
910 } 938 }
911 939
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index fea9ba5ea..22712e64f 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -64,6 +64,11 @@ void SvcWrap() {
64 FuncReturn(func(Param(0), (s32)Param(1)).raw); 64 FuncReturn(func(Param(0), (s32)Param(1)).raw);
65} 65}
66 66
67template <ResultCode func(u64, u32)>
68void SvcWrap() {
69 FuncReturn(func(Param(0), static_cast<u32>(Param(1))).raw);
70}
71
67template <ResultCode func(u64*, u64)> 72template <ResultCode func(u64*, u64)>
68void SvcWrap() { 73void SvcWrap() {
69 u64 param_1 = 0; 74 u64 param_1 = 0;
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