diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 62 |
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 |
| 418 | static ResultCode GetThreadContext(Handle handle, VAddr addr) { | 418 | static 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 | ||