mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	svc: Implement svcExitProcess.
This commit is contained in:
		
							parent
							
								
									9b8afed5f7
								
							
						
					
					
						commit
						aa7c824ea4
					
				@ -2,6 +2,7 @@
 | 
				
			|||||||
// Licensed under GPLv2 or any later version
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
#include "common/assert.h"
 | 
					#include "common/assert.h"
 | 
				
			||||||
#include "common/common_funcs.h"
 | 
					#include "common/common_funcs.h"
 | 
				
			||||||
@ -16,6 +17,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Kernel {
 | 
					namespace Kernel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Lists all processes that exist in the current session.
 | 
				
			||||||
 | 
					static std::vector<SharedPtr<Process>> process_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
 | 
					SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
 | 
				
			||||||
    SharedPtr<CodeSet> codeset(new CodeSet);
 | 
					    SharedPtr<CodeSet> codeset(new CodeSet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,7 +40,9 @@ SharedPtr<Process> Process::Create(std::string&& name) {
 | 
				
			|||||||
    process->name = std::move(name);
 | 
					    process->name = std::move(name);
 | 
				
			||||||
    process->flags.raw = 0;
 | 
					    process->flags.raw = 0;
 | 
				
			||||||
    process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
 | 
					    process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
 | 
				
			||||||
 | 
					    process->status = ProcessStatus::Created;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process_list.push_back(process);
 | 
				
			||||||
    return process;
 | 
					    return process;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -129,6 +135,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vm_manager.LogLayout(Log::Level::Debug);
 | 
					    vm_manager.LogLayout(Log::Level::Debug);
 | 
				
			||||||
 | 
					    status = ProcessStatus::Running;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Kernel::SetupMainThread(entry_point, main_thread_priority, this);
 | 
					    Kernel::SetupMainThread(entry_point, main_thread_priority, this);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -137,11 +144,11 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
 | 
				
			|||||||
    memory_region = GetMemoryRegion(flags.memory_region);
 | 
					    memory_region = GetMemoryRegion(flags.memory_region);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
 | 
					    auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
 | 
				
			||||||
        MemoryState memory_state) {
 | 
					                          MemoryState memory_state) {
 | 
				
			||||||
        auto vma = vm_manager
 | 
					        auto vma = vm_manager
 | 
				
			||||||
            .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, segment.size,
 | 
					                       .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset,
 | 
				
			||||||
                memory_state)
 | 
					                                       segment.size, memory_state)
 | 
				
			||||||
            .Unwrap();
 | 
					                       .Unwrap();
 | 
				
			||||||
        vm_manager.Reprotect(vma, permissions);
 | 
					        vm_manager.Reprotect(vma, permissions);
 | 
				
			||||||
        misc_memory_used += segment.size;
 | 
					        misc_memory_used += segment.size;
 | 
				
			||||||
        memory_region->used += segment.size;
 | 
					        memory_region->used += segment.size;
 | 
				
			||||||
@ -299,5 +306,20 @@ ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) {
 | 
				
			|||||||
Kernel::Process::Process() {}
 | 
					Kernel::Process::Process() {}
 | 
				
			||||||
Kernel::Process::~Process() {}
 | 
					Kernel::Process::~Process() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SharedPtr<Process> g_current_process;
 | 
					void ClearProcessList() {
 | 
				
			||||||
 | 
					    process_list.clear();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SharedPtr<Process> GetProcessById(u32 process_id) {
 | 
				
			||||||
 | 
					    auto itr = std::find_if(
 | 
				
			||||||
 | 
					        process_list.begin(), process_list.end(),
 | 
				
			||||||
 | 
					        [&](const SharedPtr<Process>& process) { return process->process_id == process_id; });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (itr == process_list.end())
 | 
				
			||||||
 | 
					        return nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return *itr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SharedPtr<Process> g_current_process;
 | 
				
			||||||
 | 
					} // namespace Kernel
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@
 | 
				
			|||||||
#include <cstddef>
 | 
					#include <cstddef>
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
#include <boost/container/static_vector.hpp>
 | 
					#include <boost/container/static_vector.hpp>
 | 
				
			||||||
#include "common/bit_field.h"
 | 
					#include "common/bit_field.h"
 | 
				
			||||||
#include "common/common_types.h"
 | 
					#include "common/common_types.h"
 | 
				
			||||||
@ -48,6 +49,8 @@ union ProcessFlags {
 | 
				
			|||||||
    BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
 | 
					    BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum class ProcessStatus { Created, Running, Exited };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ResourceLimit;
 | 
					class ResourceLimit;
 | 
				
			||||||
struct MemoryRegionInfo;
 | 
					struct MemoryRegionInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -124,6 +127,8 @@ public:
 | 
				
			|||||||
    u16 kernel_version = 0;
 | 
					    u16 kernel_version = 0;
 | 
				
			||||||
    /// The default CPU for this process, threads are scheduled on this cpu by default.
 | 
					    /// The default CPU for this process, threads are scheduled on this cpu by default.
 | 
				
			||||||
    u8 ideal_processor = 0;
 | 
					    u8 ideal_processor = 0;
 | 
				
			||||||
 | 
					    /// Current status of the process
 | 
				
			||||||
 | 
					    ProcessStatus status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The id of this process
 | 
					    /// The id of this process
 | 
				
			||||||
    u32 process_id = next_process_id++;
 | 
					    u32 process_id = next_process_id++;
 | 
				
			||||||
@ -181,11 +186,15 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
 | 
					    ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    Process();
 | 
					    Process();
 | 
				
			||||||
    ~Process() override;
 | 
					    ~Process() override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ClearProcessList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Retrieves a process from the current list of processes.
 | 
				
			||||||
 | 
					SharedPtr<Process> GetProcessById(u32 process_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern SharedPtr<Process> g_current_process;
 | 
					extern SharedPtr<Process> g_current_process;
 | 
				
			||||||
}
 | 
					} // namespace Kernel
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,8 @@
 | 
				
			|||||||
#include "core/hle/kernel/client_port.h"
 | 
					#include "core/hle/kernel/client_port.h"
 | 
				
			||||||
#include "core/hle/kernel/client_session.h"
 | 
					#include "core/hle/kernel/client_session.h"
 | 
				
			||||||
#include "core/hle/kernel/handle_table.h"
 | 
					#include "core/hle/kernel/handle_table.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/mutex.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/object_address_table.h"
 | 
				
			||||||
#include "core/hle/kernel/process.h"
 | 
					#include "core/hle/kernel/process.h"
 | 
				
			||||||
#include "core/hle/kernel/resource_limit.h"
 | 
					#include "core/hle/kernel/resource_limit.h"
 | 
				
			||||||
#include "core/hle/kernel/sync_object.h"
 | 
					#include "core/hle/kernel/sync_object.h"
 | 
				
			||||||
@ -45,7 +47,7 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
 | 
				
			|||||||
/// Unmaps a region that was previously mapped with svcMapMemory
 | 
					/// Unmaps a region that was previously mapped with svcMapMemory
 | 
				
			||||||
static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
 | 
					static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
 | 
				
			||||||
    LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
 | 
					    LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
 | 
				
			||||||
        src_addr, size);
 | 
					              src_addr, size);
 | 
				
			||||||
    return Kernel::g_current_process->UnmapMemory(dst_addr, src_addr, size);
 | 
					    return Kernel::g_current_process->UnmapMemory(dst_addr, src_addr, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -99,7 +101,8 @@ static ResultCode SendSyncRequest(Kernel::Handle handle) {
 | 
				
			|||||||
static ResultCode GetThreadId(u32* thread_id, Kernel::Handle thread_handle) {
 | 
					static ResultCode GetThreadId(u32* thread_id, Kernel::Handle thread_handle) {
 | 
				
			||||||
    LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
 | 
					    LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle);
 | 
					    const SharedPtr<Kernel::Thread> thread =
 | 
				
			||||||
 | 
					        Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle);
 | 
				
			||||||
    if (!thread) {
 | 
					    if (!thread) {
 | 
				
			||||||
        return ERR_INVALID_HANDLE;
 | 
					        return ERR_INVALID_HANDLE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -177,7 +180,7 @@ static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
 | 
					/// Used to output a message on a debug hardware unit - does nothing on a retail unit
 | 
				
			||||||
static void OutputDebugString(VAddr address, int len) {
 | 
					static void OutputDebugString(VAddr address, s32 len) {
 | 
				
			||||||
    std::vector<char> string(len);
 | 
					    std::vector<char> string(len);
 | 
				
			||||||
    Memory::ReadBlock(address, string.data(), len);
 | 
					    Memory::ReadBlock(address, string.data(), len);
 | 
				
			||||||
    LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data());
 | 
					    LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data());
 | 
				
			||||||
@ -272,6 +275,38 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
 | 
				
			|||||||
    return QueryProcessMemory(memory_info, page_info, Kernel::CurrentProcess, addr);
 | 
					    return QueryProcessMemory(memory_info, page_info, Kernel::CurrentProcess, addr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Exits the current process
 | 
				
			||||||
 | 
					static void ExitProcess() {
 | 
				
			||||||
 | 
					    LOG_INFO(Kernel_SVC, "Process %u exiting", Kernel::g_current_process->process_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ASSERT_MSG(Kernel::g_current_process->status == Kernel::ProcessStatus::Running,
 | 
				
			||||||
 | 
					               "Process has already exited");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Kernel::g_current_process->status = Kernel::ProcessStatus::Exited;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Stop all the process threads that are currently waiting for objects.
 | 
				
			||||||
 | 
					    auto& thread_list = Kernel::GetThreadList();
 | 
				
			||||||
 | 
					    for (auto& thread : thread_list) {
 | 
				
			||||||
 | 
					        if (thread->owner_process != Kernel::g_current_process)
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (thread == Kernel::GetCurrentThread())
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO(Subv): When are the other running/ready threads terminated?
 | 
				
			||||||
 | 
					        ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
 | 
				
			||||||
 | 
					                       thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
 | 
				
			||||||
 | 
					                   "Exiting processes with non-waiting threads is currently unimplemented");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        thread->Stop();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Kill the current thread
 | 
				
			||||||
 | 
					    Kernel::GetCurrentThread()->Stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Core::System::GetInstance().PrepareReschedule();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Creates a new thread
 | 
					/// Creates a new thread
 | 
				
			||||||
static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top,
 | 
					static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top,
 | 
				
			||||||
                               u32 priority, s32 processor_id) {
 | 
					                               u32 priority, s32 processor_id) {
 | 
				
			||||||
@ -400,7 +435,7 @@ static const FunctionDef SVC_Table[] = {
 | 
				
			|||||||
    {0x04, HLE::Wrap<MapMemory>, "svcMapMemory"},
 | 
					    {0x04, HLE::Wrap<MapMemory>, "svcMapMemory"},
 | 
				
			||||||
    {0x05, HLE::Wrap<UnmapMemory>, "svcUnmapMemory"},
 | 
					    {0x05, HLE::Wrap<UnmapMemory>, "svcUnmapMemory"},
 | 
				
			||||||
    {0x06, HLE::Wrap<QueryMemory>, "svcQueryMemory"},
 | 
					    {0x06, HLE::Wrap<QueryMemory>, "svcQueryMemory"},
 | 
				
			||||||
    {0x07, nullptr, "svcExitProcess"},
 | 
					    {0x07, HLE::Wrap<ExitProcess>, "svcExitProcess"},
 | 
				
			||||||
    {0x08, HLE::Wrap<CreateThread>, "svcCreateThread"},
 | 
					    {0x08, HLE::Wrap<CreateThread>, "svcCreateThread"},
 | 
				
			||||||
    {0x09, HLE::Wrap<StartThread>, "svcStartThread"},
 | 
					    {0x09, HLE::Wrap<StartThread>, "svcStartThread"},
 | 
				
			||||||
    {0x0A, HLE::Wrap<ExitThread>, "svcExitThread"},
 | 
					    {0x0A, HLE::Wrap<ExitThread>, "svcExitThread"},
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user