kernel/process: move current process to kernel instance
Two functional change: QueryProcessMemory uses the process passed from handle instead current_process Thread::Stop() uses TLS from owner_process instead of current_process
This commit is contained in:
parent
d9342622b0
commit
8fb3d8ff38
19 changed files with 96 additions and 55 deletions
|
@ -126,7 +126,9 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file
|
||||||
return init_result;
|
return init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Loader::ResultStatus load_result{app_loader->Load(Kernel::g_current_process)};
|
Kernel::SharedPtr<Kernel::Process> process;
|
||||||
|
const Loader::ResultStatus load_result{app_loader->Load(process)};
|
||||||
|
kernel->SetCurrentProcess(process);
|
||||||
if (Loader::ResultStatus::Success != load_result) {
|
if (Loader::ResultStatus::Success != load_result) {
|
||||||
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<u32>(load_result));
|
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<u32>(load_result));
|
||||||
System::Shutdown();
|
System::Shutdown();
|
||||||
|
@ -140,7 +142,7 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file
|
||||||
return ResultStatus::ErrorLoader;
|
return ResultStatus::ErrorLoader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
|
Memory::SetCurrentPageTable(&kernel->GetCurrentProcess()->vm_manager.page_table);
|
||||||
status = ResultStatus::Success;
|
status = ResultStatus::Success;
|
||||||
m_emu_window = &emu_window;
|
m_emu_window = &emu_window;
|
||||||
m_filepath = filepath;
|
m_filepath = filepath;
|
||||||
|
|
|
@ -251,8 +251,11 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
||||||
|
|
||||||
|
public: // HACK: this is temporary exposed for tests,
|
||||||
|
// due to WIP kernel refactor causing desync state in memory
|
||||||
std::unique_ptr<Kernel::KernelSystem> kernel;
|
std::unique_ptr<Kernel::KernelSystem> kernel;
|
||||||
|
|
||||||
|
private:
|
||||||
static System s_instance;
|
static System s_instance;
|
||||||
|
|
||||||
ResultStatus status = ResultStatus::Success;
|
ResultStatus status = ResultStatus::Success;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/file_sys/archive_savedata.h"
|
#include "core/file_sys/archive_savedata.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
|
||||||
|
@ -16,16 +17,19 @@ ArchiveFactory_SaveData::ArchiveFactory_SaveData(
|
||||||
: sd_savedata_source(std::move(sd_savedata)) {}
|
: sd_savedata_source(std::move(sd_savedata)) {}
|
||||||
|
|
||||||
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) {
|
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) {
|
||||||
return sd_savedata_source->Open(Kernel::g_current_process->codeset->program_id);
|
return sd_savedata_source->Open(
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ArchiveFactory_SaveData::Format(const Path& path,
|
ResultCode ArchiveFactory_SaveData::Format(const Path& path,
|
||||||
const FileSys::ArchiveFormatInfo& format_info) {
|
const FileSys::ArchiveFormatInfo& format_info) {
|
||||||
return sd_savedata_source->Format(Kernel::g_current_process->codeset->program_id, format_info);
|
return sd_savedata_source->Format(
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id, format_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const {
|
ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const {
|
||||||
return sd_savedata_source->GetFormatInfo(Kernel::g_current_process->codeset->program_id);
|
return sd_savedata_source->GetFormatInfo(
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/file_sys/archive_selfncch.h"
|
#include "core/file_sys/archive_selfncch.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
#include "core/file_sys/ivfc_archive.h"
|
#include "core/file_sys/ivfc_archive.h"
|
||||||
|
@ -279,7 +280,7 @@ void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) {
|
||||||
|
|
||||||
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SelfNCCH::Open(const Path& path) {
|
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SelfNCCH::Open(const Path& path) {
|
||||||
auto archive = std::make_unique<SelfNCCHArchive>(
|
auto archive = std::make_unique<SelfNCCHArchive>(
|
||||||
ncch_data[Kernel::g_current_process->codeset->program_id]);
|
ncch_data[Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id]);
|
||||||
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/core.h" // TODO: for current_process. Remove this later
|
||||||
#include "core/hle/kernel/errors.h"
|
#include "core/hle/kernel/errors.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
@ -76,7 +77,9 @@ SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
|
||||||
if (handle == CurrentThread) {
|
if (handle == CurrentThread) {
|
||||||
return GetCurrentThread();
|
return GetCurrentThread();
|
||||||
} else if (handle == CurrentProcess) {
|
} else if (handle == CurrentProcess) {
|
||||||
return g_current_process;
|
// TODO: should this return HandleTable's parent process, or kernel's current process?
|
||||||
|
// Should change this either way
|
||||||
|
return Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValid(handle)) {
|
if (!IsValid(handle)) {
|
||||||
|
|
|
@ -30,7 +30,6 @@ KernelSystem::~KernelSystem() {
|
||||||
g_handle_table.Clear(); // Free all kernel objects
|
g_handle_table.Clear(); // Free all kernel objects
|
||||||
|
|
||||||
Kernel::ThreadingShutdown();
|
Kernel::ThreadingShutdown();
|
||||||
g_current_process = nullptr;
|
|
||||||
|
|
||||||
Kernel::TimersShutdown();
|
Kernel::TimersShutdown();
|
||||||
Kernel::MemoryShutdown();
|
Kernel::MemoryShutdown();
|
||||||
|
@ -48,4 +47,12 @@ u32 KernelSystem::GenerateObjectID() {
|
||||||
return next_object_id++;
|
return next_object_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedPtr<Process> KernelSystem::GetCurrentProcess() const {
|
||||||
|
return current_process;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernelSystem::SetCurrentProcess(SharedPtr<Process> process) {
|
||||||
|
current_process = std::move(process);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -184,6 +184,9 @@ public:
|
||||||
/// Retrieves a process from the current list of processes.
|
/// Retrieves a process from the current list of processes.
|
||||||
SharedPtr<Process> GetProcessById(u32 process_id) const;
|
SharedPtr<Process> GetProcessById(u32 process_id) const;
|
||||||
|
|
||||||
|
SharedPtr<Process> GetCurrentProcess() const;
|
||||||
|
void SetCurrentProcess(SharedPtr<Process> process);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ResourceLimitList> resource_limits;
|
std::unique_ptr<ResourceLimitList> resource_limits;
|
||||||
std::atomic<u32> next_object_id{0};
|
std::atomic<u32> next_object_id{0};
|
||||||
|
@ -194,6 +197,8 @@ private:
|
||||||
|
|
||||||
// Lists all processes that exist in the current session.
|
// Lists all processes that exist in the current session.
|
||||||
std::vector<SharedPtr<Process>> process_list;
|
std::vector<SharedPtr<Process>> process_list;
|
||||||
|
|
||||||
|
SharedPtr<Process> current_process;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -313,6 +313,4 @@ SharedPtr<Process> KernelSystem::GetProcessById(u32 process_id) const {
|
||||||
|
|
||||||
return *itr;
|
return *itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Process> g_current_process;
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -197,6 +197,4 @@ private:
|
||||||
friend class KernelSystem;
|
friend class KernelSystem;
|
||||||
KernelSystem& kernel;
|
KernelSystem& kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SharedPtr<Process> g_current_process;
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -52,8 +52,8 @@ SharedPtr<SharedMemory> KernelSystem::CreateSharedMemory(SharedPtr<Process> owne
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh the address mappings for the current process.
|
// Refresh the address mappings for the current process.
|
||||||
if (Kernel::g_current_process != nullptr) {
|
if (current_process != nullptr) {
|
||||||
Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
|
current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto& vm_manager = shared_memory->owner_process->vm_manager;
|
auto& vm_manager = shared_memory->owner_process->vm_manager;
|
||||||
|
|
|
@ -83,7 +83,7 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
|
||||||
}
|
}
|
||||||
VMAPermission vma_permissions = (VMAPermission)permissions;
|
VMAPermission vma_permissions = (VMAPermission)permissions;
|
||||||
|
|
||||||
auto& process = *g_current_process;
|
auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
|
||||||
switch (operation & MEMOP_OPERATION_MASK) {
|
switch (operation & MEMOP_OPERATION_MASK) {
|
||||||
case MEMOP_FREE: {
|
case MEMOP_FREE: {
|
||||||
|
@ -145,16 +145,17 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExitProcess() {
|
static void ExitProcess() {
|
||||||
LOG_INFO(Kernel_SVC, "Process {} exiting", g_current_process->process_id);
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->process_id);
|
||||||
|
|
||||||
ASSERT_MSG(g_current_process->status == ProcessStatus::Running, "Process has already exited");
|
ASSERT_MSG(current_process->status == ProcessStatus::Running, "Process has already exited");
|
||||||
|
|
||||||
g_current_process->status = ProcessStatus::Exited;
|
current_process->status = ProcessStatus::Exited;
|
||||||
|
|
||||||
// Stop all the process threads that are currently waiting for objects.
|
// Stop all the process threads that are currently waiting for objects.
|
||||||
auto& thread_list = GetThreadList();
|
auto& thread_list = GetThreadList();
|
||||||
for (auto& thread : thread_list) {
|
for (auto& thread : thread_list) {
|
||||||
if (thread->owner_process != g_current_process)
|
if (thread->owner_process != current_process)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (thread == GetCurrentThread())
|
if (thread == GetCurrentThread())
|
||||||
|
@ -195,7 +196,8 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
|
||||||
case MemoryPermission::WriteExecute:
|
case MemoryPermission::WriteExecute:
|
||||||
case MemoryPermission::ReadWriteExecute:
|
case MemoryPermission::ReadWriteExecute:
|
||||||
case MemoryPermission::DontCare:
|
case MemoryPermission::DontCare:
|
||||||
return shared_memory->Map(g_current_process.get(), addr, permissions_type,
|
return shared_memory->Map(Core::System::GetInstance().Kernel().GetCurrentProcess().get(),
|
||||||
|
addr, permissions_type,
|
||||||
static_cast<MemoryPermission>(other_permissions));
|
static_cast<MemoryPermission>(other_permissions));
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
|
LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
|
||||||
|
@ -213,7 +215,8 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
|
||||||
if (shared_memory == nullptr)
|
if (shared_memory == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
return shared_memory->Unmap(g_current_process.get(), addr);
|
return shared_memory->Unmap(Core::System::GetInstance().Kernel().GetCurrentProcess().get(),
|
||||||
|
addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||||
|
@ -733,14 +736,16 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point
|
||||||
return ERR_OUT_OF_RANGE;
|
return ERR_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
|
||||||
|
SharedPtr<ResourceLimit>& resource_limit = current_process->resource_limit;
|
||||||
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
|
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
|
||||||
return ERR_NOT_AUTHORIZED;
|
return ERR_NOT_AUTHORIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processor_id == ThreadProcessorIdDefault) {
|
if (processor_id == ThreadProcessorIdDefault) {
|
||||||
// Set the target CPU to the one specified in the process' exheader.
|
// Set the target CPU to the one specified in the process' exheader.
|
||||||
processor_id = g_current_process->ideal_processor;
|
processor_id = current_process->ideal_processor;
|
||||||
ASSERT(processor_id != ThreadProcessorIdDefault);
|
ASSERT(processor_id != ThreadProcessorIdDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -761,9 +766,9 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CASCADE_RESULT(SharedPtr<Thread> thread, Core::System::GetInstance().Kernel().CreateThread(
|
CASCADE_RESULT(SharedPtr<Thread> thread,
|
||||||
name, entry_point, priority, arg, processor_id,
|
Core::System::GetInstance().Kernel().CreateThread(
|
||||||
stack_top, g_current_process));
|
name, entry_point, priority, arg, processor_id, stack_top, current_process));
|
||||||
|
|
||||||
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
||||||
FPSCR_ROUND_TOZERO); // 0x03C00000
|
FPSCR_ROUND_TOZERO); // 0x03C00000
|
||||||
|
@ -810,7 +815,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
|
||||||
|
|
||||||
// Note: The kernel uses the current process's resource limit instead of
|
// Note: The kernel uses the current process's resource limit instead of
|
||||||
// the one from the thread owner's resource limit.
|
// the one from the thread owner's resource limit.
|
||||||
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
|
SharedPtr<ResourceLimit>& resource_limit =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->resource_limit;
|
||||||
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
|
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
|
||||||
return ERR_NOT_AUTHORIZED;
|
return ERR_NOT_AUTHORIZED;
|
||||||
}
|
}
|
||||||
|
@ -1097,16 +1103,18 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
|
||||||
return ERR_INVALID_ADDRESS;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
|
||||||
// When trying to create a memory block with address = 0,
|
// When trying to create a memory block with address = 0,
|
||||||
// if the process has the Shared Device Memory flag in the exheader,
|
// if the process has the Shared Device Memory flag in the exheader,
|
||||||
// then we have to allocate from the same region as the caller process instead of the BASE
|
// then we have to allocate from the same region as the caller process instead of the BASE
|
||||||
// region.
|
// region.
|
||||||
MemoryRegion region = MemoryRegion::BASE;
|
MemoryRegion region = MemoryRegion::BASE;
|
||||||
if (addr == 0 && g_current_process->flags.shared_device_mem)
|
if (addr == 0 && current_process->flags.shared_device_mem)
|
||||||
region = g_current_process->flags.memory_region;
|
region = current_process->flags.memory_region;
|
||||||
|
|
||||||
shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory(
|
shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory(
|
||||||
g_current_process, size, static_cast<MemoryPermission>(my_permission),
|
current_process, size, static_cast<MemoryPermission>(my_permission),
|
||||||
static_cast<MemoryPermission>(other_permission), addr, region);
|
static_cast<MemoryPermission>(other_permission), addr, region);
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory)));
|
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory)));
|
||||||
|
|
||||||
|
@ -1407,7 +1415,8 @@ void CallSVC(u32 immediate) {
|
||||||
// Lock the global kernel mutex when we enter the kernel HLE.
|
// Lock the global kernel mutex when we enter the kernel HLE.
|
||||||
std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
|
std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
|
||||||
|
|
||||||
ASSERT_MSG(g_current_process->status == ProcessStatus::Running,
|
DEBUG_ASSERT_MSG(Core::System::GetInstance().Kernel().GetCurrentProcess()->status ==
|
||||||
|
ProcessStatus::Running,
|
||||||
"Running threads from exiting processes is unimplemented");
|
"Running threads from exiting processes is unimplemented");
|
||||||
|
|
||||||
const FunctionDef* info = GetSVCInfo(immediate);
|
const FunctionDef* info = GetSVCInfo(immediate);
|
||||||
|
|
|
@ -96,7 +96,7 @@ void Thread::Stop() {
|
||||||
u32 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
|
u32 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
|
||||||
u32 tls_slot =
|
u32 tls_slot =
|
||||||
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
|
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
|
||||||
Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot);
|
owner_process->tls_slots[tls_page].reset(tls_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,7 +127,7 @@ static void SwitchContext(Thread* new_thread) {
|
||||||
// Cancel any outstanding wakeup events for this thread
|
// Cancel any outstanding wakeup events for this thread
|
||||||
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle);
|
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle);
|
||||||
|
|
||||||
auto previous_process = Kernel::g_current_process;
|
auto previous_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
|
||||||
current_thread = new_thread;
|
current_thread = new_thread;
|
||||||
|
|
||||||
|
@ -135,8 +135,8 @@ static void SwitchContext(Thread* new_thread) {
|
||||||
new_thread->status = ThreadStatus::Running;
|
new_thread->status = ThreadStatus::Running;
|
||||||
|
|
||||||
if (previous_process != current_thread->owner_process) {
|
if (previous_process != current_thread->owner_process) {
|
||||||
Kernel::g_current_process = current_thread->owner_process;
|
Core::System::GetInstance().Kernel().SetCurrentProcess(current_thread->owner_process);
|
||||||
SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
|
SetCurrentPageTable(¤t_thread->owner_process->vm_manager.page_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::CPU().LoadContext(new_thread->context);
|
Core::CPU().LoadContext(new_thread->context);
|
||||||
|
|
|
@ -258,7 +258,7 @@ ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId ap
|
||||||
slot_data->applet_id = static_cast<AppletId>(app_id);
|
slot_data->applet_id = static_cast<AppletId>(app_id);
|
||||||
// Note: In the real console the title id of a given applet slot is set by the APT module when
|
// Note: In the real console the title id of a given applet slot is set by the APT module when
|
||||||
// calling StartApplication.
|
// calling StartApplication.
|
||||||
slot_data->title_id = Kernel::g_current_process->codeset->program_id;
|
slot_data->title_id = system.Kernel().GetCurrentProcess()->codeset->program_id;
|
||||||
slot_data->attributes.raw = attributes.raw;
|
slot_data->attributes.raw = attributes.raw;
|
||||||
|
|
||||||
if (slot_data->applet_id == AppletId::Application ||
|
if (slot_data->applet_id == AppletId::Application ||
|
||||||
|
|
|
@ -97,7 +97,7 @@ void Module::Interface::Open(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
if (path_type == CecDataPathType::MboxProgramId) {
|
if (path_type == CecDataPathType::MboxProgramId) {
|
||||||
std::vector<u8> program_id(8);
|
std::vector<u8> program_id(8);
|
||||||
u64_le le_program_id = Kernel::g_current_process->codeset->program_id;
|
u64_le le_program_id = cecd->system.Kernel().GetCurrentProcess()->codeset->program_id;
|
||||||
std::memcpy(program_id.data(), &le_program_id, sizeof(u64));
|
std::memcpy(program_id.data(), &le_program_id, sizeof(u64));
|
||||||
session_data->file->Write(0, sizeof(u64), true, program_id.data());
|
session_data->file->Write(0, sizeof(u64), true, program_id.data());
|
||||||
session_data->file->Close();
|
session_data->file->Close();
|
||||||
|
@ -1351,7 +1351,7 @@ Module::SessionData::~SessionData() {
|
||||||
Module::Interface::Interface(std::shared_ptr<Module> cecd, const char* name, u32 max_session)
|
Module::Interface::Interface(std::shared_ptr<Module> cecd, const char* name, u32 max_session)
|
||||||
: ServiceFramework(name, max_session), cecd(std::move(cecd)) {}
|
: ServiceFramework(name, max_session), cecd(std::move(cecd)) {}
|
||||||
|
|
||||||
Module::Module(Core::System& system) {
|
Module::Module(Core::System& system) : system(system) {
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
cecinfo_event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "CECD::cecinfo_event");
|
cecinfo_event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "CECD::cecinfo_event");
|
||||||
change_state_event =
|
change_state_event =
|
||||||
|
|
|
@ -610,6 +610,8 @@ private:
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::Event> cecinfo_event;
|
Kernel::SharedPtr<Kernel::Event> cecinfo_event;
|
||||||
Kernel::SharedPtr<Kernel::Event> change_state_event;
|
Kernel::SharedPtr<Kernel::Event> change_state_event;
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initialize CECD service(s)
|
/// Initialize CECD service(s)
|
||||||
|
|
|
@ -188,11 +188,13 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses
|
||||||
return ReportUnimplementedFunction(cmd_buf, info);
|
return ReportUnimplementedFunction(cmd_buf, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Kernel::SharedPtr<Kernel::Process> current_process =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
|
||||||
// TODO(yuriks): The kernel should be the one handling this as part of translation after
|
// TODO(yuriks): The kernel should be the one handling this as part of translation after
|
||||||
// everything else is migrated
|
// everything else is migrated
|
||||||
Kernel::HLERequestContext context(std::move(server_session));
|
Kernel::HLERequestContext context(std::move(server_session));
|
||||||
context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process,
|
context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table);
|
||||||
Kernel::g_handle_table);
|
|
||||||
|
|
||||||
LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf));
|
LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf));
|
||||||
handler_invoker(this, info->handler_callback, context);
|
handler_invoker(this, info->handler_callback, context);
|
||||||
|
@ -204,8 +206,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses
|
||||||
// the thread to sleep then the writing of the command buffer will be deferred to the wakeup
|
// the thread to sleep then the writing of the command buffer will be deferred to the wakeup
|
||||||
// callback.
|
// callback.
|
||||||
if (thread->status == Kernel::ThreadStatus::Running) {
|
if (thread->status == Kernel::ThreadStatus::Running) {
|
||||||
context.WriteToOutgoingCommandBuffer(cmd_buf, *Kernel::g_current_process,
|
context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table);
|
||||||
Kernel::g_handle_table);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ static u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) {
|
||||||
* using a VMA from the current process.
|
* using a VMA from the current process.
|
||||||
*/
|
*/
|
||||||
static u8* GetPointerFromVMA(VAddr vaddr) {
|
static u8* GetPointerFromVMA(VAddr vaddr) {
|
||||||
return GetPointerFromVMA(*Kernel::g_current_process, vaddr);
|
return GetPointerFromVMA(*Core::System::GetInstance().Kernel().GetCurrentProcess(), vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,7 +128,8 @@ static MMIORegionPointer GetMMIOHandler(const PageTable& page_table, VAddr vaddr
|
||||||
}
|
}
|
||||||
|
|
||||||
static MMIORegionPointer GetMMIOHandler(VAddr vaddr) {
|
static MMIORegionPointer GetMMIOHandler(VAddr vaddr) {
|
||||||
const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
|
const PageTable& page_table =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->vm_manager.page_table;
|
||||||
return GetMMIOHandler(page_table, vaddr);
|
return GetMMIOHandler(page_table, vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +230,7 @@ bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidVirtualAddress(const VAddr vaddr) {
|
bool IsValidVirtualAddress(const VAddr vaddr) {
|
||||||
return IsValidVirtualAddress(*Kernel::g_current_process, vaddr);
|
return IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(), vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidPhysicalAddress(const PAddr paddr) {
|
bool IsValidPhysicalAddress(const PAddr paddr) {
|
||||||
|
@ -524,7 +525,8 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
|
void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
|
||||||
ReadBlock(*Kernel::g_current_process, src_addr, dest_buffer, size);
|
ReadBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), src_addr, dest_buffer,
|
||||||
|
size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write8(const VAddr addr, const u8 data) {
|
void Write8(const VAddr addr, const u8 data) {
|
||||||
|
@ -592,7 +594,8 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
|
void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
|
||||||
WriteBlock(*Kernel::g_current_process, dest_addr, src_buffer, size);
|
WriteBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), dest_addr, src_buffer,
|
||||||
|
size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
|
void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
|
||||||
|
@ -644,7 +647,7 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std:
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroBlock(const VAddr dest_addr, const std::size_t size) {
|
void ZeroBlock(const VAddr dest_addr, const std::size_t size) {
|
||||||
ZeroBlock(*Kernel::g_current_process, dest_addr, size);
|
ZeroBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), dest_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
||||||
|
@ -699,7 +702,7 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyBlock(VAddr dest_addr, VAddr src_addr, const std::size_t size) {
|
void CopyBlock(VAddr dest_addr, VAddr src_addr, const std::size_t size) {
|
||||||
CopyBlock(*Kernel::g_current_process, dest_addr, src_addr, size);
|
CopyBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), dest_addr, src_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -778,7 +781,8 @@ std::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
|
||||||
} else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
|
} else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
|
||||||
return addr - VRAM_PADDR + VRAM_VADDR;
|
return addr - VRAM_PADDR + VRAM_VADDR;
|
||||||
} else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
|
} else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
|
||||||
return addr - FCRAM_PADDR + Kernel::g_current_process->GetLinearHeapAreaAddress();
|
return addr - FCRAM_PADDR +
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->GetLinearHeapAreaAddress();
|
||||||
} else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
|
} else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
|
||||||
return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
|
return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
|
||||||
} else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
|
} else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
|
||||||
|
|
|
@ -17,10 +17,14 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
||||||
|
|
||||||
CoreTiming::Init();
|
CoreTiming::Init();
|
||||||
kernel = std::make_unique<Kernel::KernelSystem>(0);
|
// HACK: some memory functions are currently referring kernel from the global instance,
|
||||||
|
// so we need to create the kernel object there.
|
||||||
|
// Change this when all global states are eliminated.
|
||||||
|
Core::System::GetInstance().kernel = std::make_unique<Kernel::KernelSystem>(0);
|
||||||
|
kernel = Core::System::GetInstance().kernel.get();
|
||||||
|
|
||||||
Kernel::g_current_process = kernel->CreateProcess(kernel->CreateCodeSet("", 0));
|
kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0)));
|
||||||
page_table = &Kernel::g_current_process->vm_manager.page_table;
|
page_table = &kernel->GetCurrentProcess()->vm_manager.page_table;
|
||||||
|
|
||||||
page_table->pointers.fill(nullptr);
|
page_table->pointers.fill(nullptr);
|
||||||
page_table->attributes.fill(Memory::PageType::Unmapped);
|
page_table->attributes.fill(Memory::PageType::Unmapped);
|
||||||
|
|
|
@ -80,7 +80,7 @@ private:
|
||||||
std::shared_ptr<TestMemory> test_memory;
|
std::shared_ptr<TestMemory> test_memory;
|
||||||
std::vector<WriteRecord> write_records;
|
std::vector<WriteRecord> write_records;
|
||||||
|
|
||||||
std::unique_ptr<Kernel::KernelSystem> kernel;
|
Kernel::KernelSystem* kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ArmTests
|
} // namespace ArmTests
|
||||||
|
|
Loading…
Reference in a new issue