|
|
|
@ -51,7 +51,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { |
|
|
|
} |
|
|
|
|
|
|
|
auto& process = *Core::CurrentProcess(); |
|
|
|
const VAddr heap_base = process.vm_manager.GetHeapRegionBaseAddress(); |
|
|
|
const VAddr heap_base = process.VMManager().GetHeapRegionBaseAddress(); |
|
|
|
CASCADE_RESULT(*heap_addr, |
|
|
|
process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite)); |
|
|
|
return RESULT_SUCCESS; |
|
|
|
@ -327,14 +327,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) |
|
|
|
info_sub_id, handle); |
|
|
|
|
|
|
|
const auto& current_process = Core::CurrentProcess(); |
|
|
|
const auto& vm_manager = current_process->vm_manager; |
|
|
|
const auto& vm_manager = current_process->VMManager(); |
|
|
|
|
|
|
|
switch (static_cast<GetInfoType>(info_id)) { |
|
|
|
case GetInfoType::AllowedCpuIdBitmask: |
|
|
|
*result = current_process->allowed_processor_mask; |
|
|
|
*result = current_process->GetAllowedProcessorMask(); |
|
|
|
break; |
|
|
|
case GetInfoType::AllowedThreadPrioBitmask: |
|
|
|
*result = current_process->allowed_thread_priority_mask; |
|
|
|
*result = current_process->GetAllowedThreadPriorityMask(); |
|
|
|
break; |
|
|
|
case GetInfoType::MapRegionBaseAddr: |
|
|
|
*result = vm_manager.GetMapRegionBaseAddress(); |
|
|
|
@ -386,10 +386,10 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) |
|
|
|
*result = vm_manager.GetNewMapRegionSize(); |
|
|
|
break; |
|
|
|
case GetInfoType::IsVirtualAddressMemoryEnabled: |
|
|
|
*result = current_process->is_virtual_address_memory_enabled; |
|
|
|
*result = current_process->IsVirtualMemoryEnabled(); |
|
|
|
break; |
|
|
|
case GetInfoType::TitleId: |
|
|
|
*result = current_process->program_id; |
|
|
|
*result = current_process->GetTitleID(); |
|
|
|
break; |
|
|
|
case GetInfoType::PrivilegedProcessId: |
|
|
|
LOG_WARNING(Kernel_SVC, |
|
|
|
@ -415,8 +415,36 @@ static ResultCode SetThreadActivity(Handle handle, u32 unknown) { |
|
|
|
} |
|
|
|
|
|
|
|
/// Gets the thread context
|
|
|
|
static ResultCode GetThreadContext(Handle handle, VAddr addr) { |
|
|
|
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr); |
|
|
|
static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { |
|
|
|
LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); |
|
|
|
|
|
|
|
auto& kernel = Core::System::GetInstance().Kernel(); |
|
|
|
const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle); |
|
|
|
if (!thread) { |
|
|
|
return ERR_INVALID_HANDLE; |
|
|
|
} |
|
|
|
|
|
|
|
const auto current_process = Core::CurrentProcess(); |
|
|
|
if (thread->owner_process != current_process) { |
|
|
|
return ERR_INVALID_HANDLE; |
|
|
|
} |
|
|
|
|
|
|
|
if (thread == GetCurrentThread()) { |
|
|
|
return ERR_ALREADY_REGISTERED; |
|
|
|
} |
|
|
|
|
|
|
|
Core::ARM_Interface::ThreadContext ctx = thread->context; |
|
|
|
// Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
|
|
|
|
ctx.pstate &= 0xFF0FFE20; |
|
|
|
|
|
|
|
// If 64-bit, we can just write the context registers directly and we're good.
|
|
|
|
// However, if 32-bit, we have to ensure some registers are zeroed out.
|
|
|
|
if (!current_process->Is64BitProcess()) { |
|
|
|
std::fill(ctx.cpu_registers.begin() + 15, ctx.cpu_registers.end(), 0); |
|
|
|
std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{}); |
|
|
|
} |
|
|
|
|
|
|
|
Memory::WriteBlock(thread_context, &ctx, sizeof(ctx)); |
|
|
|
return RESULT_SUCCESS; |
|
|
|
} |
|
|
|
|
|
|
|
@ -444,8 +472,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { |
|
|
|
|
|
|
|
// Note: The kernel uses the current process's resource limit instead of
|
|
|
|
// the one from the thread owner's resource limit.
|
|
|
|
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit; |
|
|
|
if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { |
|
|
|
const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit(); |
|
|
|
if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { |
|
|
|
return ERR_NOT_AUTHORIZED; |
|
|
|
} |
|
|
|
|
|
|
|
@ -519,9 +547,9 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i |
|
|
|
if (!process) { |
|
|
|
return ERR_INVALID_HANDLE; |
|
|
|
} |
|
|
|
auto vma = process->vm_manager.FindVMA(addr); |
|
|
|
auto vma = process->VMManager().FindVMA(addr); |
|
|
|
memory_info->attributes = 0; |
|
|
|
if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) { |
|
|
|
if (vma == Core::CurrentProcess()->VMManager().vma_map.end()) { |
|
|
|
memory_info->base_address = 0; |
|
|
|
memory_info->permission = static_cast<u32>(VMAPermission::None); |
|
|
|
memory_info->size = 0; |
|
|
|
@ -568,14 +596,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V |
|
|
|
return ERR_INVALID_THREAD_PRIORITY; |
|
|
|
} |
|
|
|
|
|
|
|
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit; |
|
|
|
if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { |
|
|
|
const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit(); |
|
|
|
if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { |
|
|
|
return ERR_NOT_AUTHORIZED; |
|
|
|
} |
|
|
|
|
|
|
|
if (processor_id == THREADPROCESSORID_DEFAULT) { |
|
|
|
// Set the target CPU to the one specified in the process' exheader.
|
|
|
|
processor_id = Core::CurrentProcess()->ideal_processor; |
|
|
|
processor_id = Core::CurrentProcess()->GetDefaultProcessorID(); |
|
|
|
ASSERT(processor_id != THREADPROCESSORID_DEFAULT); |
|
|
|
} |
|
|
|
|
|
|
|
@ -902,10 +930,10 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { |
|
|
|
} |
|
|
|
|
|
|
|
if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) { |
|
|
|
ASSERT(thread->owner_process->ideal_processor != |
|
|
|
ASSERT(thread->owner_process->GetDefaultProcessorID() != |
|
|
|
static_cast<u8>(THREADPROCESSORID_DEFAULT)); |
|
|
|
// Set the target CPU to the one specified in the process' exheader.
|
|
|
|
core = thread->owner_process->ideal_processor; |
|
|
|
core = thread->owner_process->GetDefaultProcessorID(); |
|
|
|
mask = 1ull << core; |
|
|
|
} |
|
|
|
|
|
|
|
|