summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp62
1 files changed, 45 insertions, 17 deletions
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