Merge pull request #1417 from lioncash/context

svc: Implement svcGetThreadContext
This commit is contained in:
bunnei 2018-09-30 15:32:27 -04:00 committed by GitHub
commit 5e2f23e2b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 183 additions and 82 deletions

View File

@ -22,10 +22,16 @@ public:
std::array<u64, 31> cpu_registers; std::array<u64, 31> cpu_registers;
u64 sp; u64 sp;
u64 pc; u64 pc;
u64 pstate; u32 pstate;
std::array<u8, 4> padding;
std::array<u128, 32> vector_registers; std::array<u128, 32> vector_registers;
u64 fpcr; u32 fpcr;
u32 fpsr;
u64 tpidr;
}; };
// Internally within the kernel, it expects the AArch64 version of the
// thread context to be 800 bytes in size.
static_assert(sizeof(ThreadContext) == 0x320);
/// Runs the CPU until an event happens /// Runs the CPU until an event happens
virtual void Run() = 0; virtual void Run() = 0;

View File

@ -130,7 +130,7 @@ public:
std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
auto& current_process = Core::CurrentProcess(); auto& current_process = Core::CurrentProcess();
auto** const page_table = current_process->vm_manager.page_table.pointers.data(); auto** const page_table = current_process->VMManager().page_table.pointers.data();
Dynarmic::A64::UserConfig config; Dynarmic::A64::UserConfig config;
@ -139,7 +139,7 @@ std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
// Memory // Memory
config.page_table = reinterpret_cast<void**>(page_table); config.page_table = reinterpret_cast<void**>(page_table);
config.page_table_address_space_bits = current_process->vm_manager.GetAddressSpaceWidth(); config.page_table_address_space_bits = current_process->VMManager().GetAddressSpaceWidth();
config.silently_mirror_page_table = false; config.silently_mirror_page_table = false;
// Multi-process state // Multi-process state
@ -247,15 +247,19 @@ void ARM_Dynarmic::SaveContext(ThreadContext& ctx) {
ctx.pstate = jit->GetPstate(); ctx.pstate = jit->GetPstate();
ctx.vector_registers = jit->GetVectors(); ctx.vector_registers = jit->GetVectors();
ctx.fpcr = jit->GetFpcr(); ctx.fpcr = jit->GetFpcr();
ctx.fpsr = jit->GetFpsr();
ctx.tpidr = cb->tpidr_el0;
} }
void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) { void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) {
jit->SetRegisters(ctx.cpu_registers); jit->SetRegisters(ctx.cpu_registers);
jit->SetSP(ctx.sp); jit->SetSP(ctx.sp);
jit->SetPC(ctx.pc); jit->SetPC(ctx.pc);
jit->SetPstate(static_cast<u32>(ctx.pstate)); jit->SetPstate(ctx.pstate);
jit->SetVectors(ctx.vector_registers); jit->SetVectors(ctx.vector_registers);
jit->SetFpcr(static_cast<u32>(ctx.fpcr)); jit->SetFpcr(ctx.fpcr);
jit->SetFpsr(ctx.fpsr);
SetTPIDR_EL0(ctx.tpidr);
} }
void ARM_Dynarmic::PrepareReschedule() { void ARM_Dynarmic::PrepareReschedule() {

View File

@ -34,7 +34,7 @@ ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() {
if (!updatable) if (!updatable)
return MakeResult<VirtualFile>(file); return MakeResult<VirtualFile>(file);
const PatchManager patch_manager(Core::CurrentProcess()->program_id); const PatchManager patch_manager(Core::CurrentProcess()->GetTitleID());
return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file, ivfc_offset)); return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file, ivfc_offset));
} }

View File

@ -81,7 +81,7 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
// be interpreted as the title id of the current process. // be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData && title_id == 0) if (type == SaveDataType::SaveData && title_id == 0)
title_id = Core::CurrentProcess()->program_id; title_id = Core::CurrentProcess()->GetTitleID();
std::string out; std::string out;

View File

@ -250,7 +250,7 @@ static void RegWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr)
} else if (id == PC_REGISTER) { } else if (id == PC_REGISTER) {
thread->context.pc = val; thread->context.pc = val;
} else if (id == PSTATE_REGISTER) { } else if (id == PSTATE_REGISTER) {
thread->context.pstate = val; thread->context.pstate = static_cast<u32>(val);
} else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) { } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) {
thread->context.vector_registers[id - (PSTATE_REGISTER + 1)][0] = val; thread->context.vector_registers[id - (PSTATE_REGISTER + 1)][0] = val;
} }
@ -587,7 +587,7 @@ static void HandleQuery() {
strlen("Xfer:features:read:target.xml:")) == 0) { strlen("Xfer:features:read:target.xml:")) == 0) {
SendReply(target_xml); SendReply(target_xml);
} else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) { } else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
const VAddr base_address = Core::CurrentProcess()->vm_manager.GetCodeRegionBaseAddress(); const VAddr base_address = Core::CurrentProcess()->VMManager().GetCodeRegionBaseAddress();
std::string buffer = fmt::format("TextSeg={:0x}", base_address); std::string buffer = fmt::format("TextSeg={:0x}", base_address);
SendReply(buffer.c_str()); SendReply(buffer.c_str());
} else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) { } else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
@ -909,7 +909,7 @@ static void ReadMemory() {
SendReply("E01"); SendReply("E01");
} }
const auto& vm_manager = Core::CurrentProcess()->vm_manager; const auto& vm_manager = Core::CurrentProcess()->VMManager();
if (addr < vm_manager.GetCodeRegionBaseAddress() || if (addr < vm_manager.GetCodeRegionBaseAddress() ||
addr >= vm_manager.GetMapRegionEndAddress()) { addr >= vm_manager.GetMapRegionEndAddress()) {
return SendReply("E00"); return SendReply("E00");

View File

@ -31,6 +31,7 @@ enum {
TooLarge = 119, TooLarge = 119,
InvalidEnumValue = 120, InvalidEnumValue = 120,
NoSuchEntry = 121, NoSuchEntry = 121,
AlreadyRegistered = 122,
InvalidState = 125, InvalidState = 125,
ResourceLimitExceeded = 132, ResourceLimitExceeded = 132,
}; };
@ -58,6 +59,7 @@ constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS(ErrorModule::Kernel,
constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle); constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle);
constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId);
constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize); constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize);
constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::Kernel, ErrCodes::AlreadyRegistered);
constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState); constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState);
constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel, constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel,
ErrCodes::InvalidThreadPriority); ErrCodes::InvalidThreadPriority);

View File

@ -47,6 +47,7 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
program_id = metadata.GetTitleID(); program_id = metadata.GetTitleID();
is_64bit_process = metadata.Is64BitProgram();
vm_manager.Reset(metadata.GetAddressSpaceType()); vm_manager.Reset(metadata.GetAddressSpaceType());
} }

View File

@ -135,6 +135,16 @@ public:
return HANDLE_TYPE; return HANDLE_TYPE;
} }
/// Gets a reference to the process' memory manager.
Kernel::VMManager& VMManager() {
return vm_manager;
}
/// Gets a const reference to the process' memory manager.
const Kernel::VMManager& VMManager() const {
return vm_manager;
}
/// Gets the current status of the process /// Gets the current status of the process
ProcessStatus GetStatus() const { ProcessStatus GetStatus() const {
return status; return status;
@ -145,6 +155,45 @@ public:
return process_id; return process_id;
} }
/// Gets the title ID corresponding to this process.
u64 GetTitleID() const {
return program_id;
}
/// Gets the resource limit descriptor for this process
ResourceLimit& GetResourceLimit() {
return *resource_limit;
}
/// Gets the resource limit descriptor for this process
const ResourceLimit& GetResourceLimit() const {
return *resource_limit;
}
/// Gets the default CPU ID for this process
u8 GetDefaultProcessorID() const {
return ideal_processor;
}
/// Gets the bitmask of allowed CPUs that this process' threads can run on.
u32 GetAllowedProcessorMask() const {
return allowed_processor_mask;
}
/// Gets the bitmask of allowed thread priorities.
u32 GetAllowedThreadPriorityMask() const {
return allowed_thread_priority_mask;
}
u32 IsVirtualMemoryEnabled() const {
return is_virtual_address_memory_enabled;
}
/// Whether this process is an AArch64 or AArch32 process.
bool Is64BitProcess() const {
return is_64bit_process;
}
/** /**
* Loads process-specifics configuration info with metadata provided * Loads process-specifics configuration info with metadata provided
* by an executable. * by an executable.
@ -153,30 +202,6 @@ public:
*/ */
void LoadFromMetadata(const FileSys::ProgramMetadata& metadata); void LoadFromMetadata(const FileSys::ProgramMetadata& metadata);
/// Title ID corresponding to the process
u64 program_id;
/// Resource limit descriptor for this process
SharedPtr<ResourceLimit> resource_limit;
/// The process may only call SVCs which have the corresponding bit set.
std::bitset<0x80> svc_access_mask;
/// Maximum size of the handle table for the process.
unsigned int handle_table_size = 0x200;
/// Special memory ranges mapped into this processes address space. This is used to give
/// processes access to specific I/O regions and device memory.
boost::container::static_vector<AddressMapping, 8> address_mappings;
ProcessFlags flags;
/// Kernel compatibility version for this process
u16 kernel_version = 0;
/// The default CPU for this process, threads are scheduled on this cpu by default.
u8 ideal_processor = 0;
/// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
/// this value from the process header.
u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
u32 allowed_thread_priority_mask = 0xFFFFFFFF;
u32 is_virtual_address_memory_enabled = 0;
/** /**
* Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
* to this process. * to this process.
@ -212,18 +237,43 @@ public:
ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
VMManager vm_manager;
private: private:
explicit Process(KernelCore& kernel); explicit Process(KernelCore& kernel);
~Process() override; ~Process() override;
/// Memory manager for this process.
Kernel::VMManager vm_manager;
/// Current status of the process /// Current status of the process
ProcessStatus status; ProcessStatus status;
/// The ID of this process /// The ID of this process
u32 process_id = 0; u32 process_id = 0;
/// Title ID corresponding to the process
u64 program_id;
/// Resource limit descriptor for this process
SharedPtr<ResourceLimit> resource_limit;
/// The process may only call SVCs which have the corresponding bit set.
std::bitset<0x80> svc_access_mask;
/// Maximum size of the handle table for the process.
u32 handle_table_size = 0x200;
/// Special memory ranges mapped into this processes address space. This is used to give
/// processes access to specific I/O regions and device memory.
boost::container::static_vector<AddressMapping, 8> address_mappings;
ProcessFlags flags;
/// Kernel compatibility version for this process
u16 kernel_version = 0;
/// The default CPU for this process, threads are scheduled on this cpu by default.
u8 ideal_processor = 0;
/// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
/// this value from the process header.
u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
u32 allowed_thread_priority_mask = 0xFFFFFFFF;
u32 is_virtual_address_memory_enabled = 0;
// Memory used to back the allocations in the regular heap. A single vector is used to cover // Memory used to back the allocations in the regular heap. A single vector is used to cover
// the entire virtual address space extents that bound the allocations, including any holes. // the entire virtual address space extents that bound the allocations, including any holes.
// This makes deallocation and reallocation of holes fast and keeps process memory contiguous // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
@ -242,6 +292,11 @@ private:
/// This vector will grow as more pages are allocated for new threads. /// This vector will grow as more pages are allocated for new threads.
std::vector<std::bitset<8>> tls_slots; std::vector<std::bitset<8>> tls_slots;
/// Whether or not this process is AArch64, or AArch32.
/// By default, we currently assume this is true, unless otherwise
/// specified by metadata provided to the process during loading.
bool is_64bit_process = true;
std::string name; std::string name;
}; };

View File

@ -88,7 +88,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
if (previous_process != current_thread->owner_process) { if (previous_process != current_thread->owner_process) {
Core::CurrentProcess() = current_thread->owner_process; Core::CurrentProcess() = current_thread->owner_process;
SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table); SetCurrentPageTable(&Core::CurrentProcess()->VMManager().page_table);
} }
cpu_core.LoadContext(new_thread->context); cpu_core.LoadContext(new_thread->context);

View File

@ -35,11 +35,11 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, SharedPtr<Proce
// Refresh the address mappings for the current process. // Refresh the address mappings for the current process.
if (Core::CurrentProcess() != nullptr) { if (Core::CurrentProcess() != nullptr) {
Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings( Core::CurrentProcess()->VMManager().RefreshMemoryBlockMappings(
shared_memory->backing_block.get()); shared_memory->backing_block.get());
} }
} else { } else {
auto& vm_manager = shared_memory->owner_process->vm_manager; auto& vm_manager = shared_memory->owner_process->VMManager();
// The memory is already available and mapped in the owner process. // The memory is already available and mapped in the owner process.
auto vma = vm_manager.FindVMA(address); auto vma = vm_manager.FindVMA(address);
@ -73,7 +73,7 @@ SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
shared_memory->backing_block = std::move(heap_block); shared_memory->backing_block = std::move(heap_block);
shared_memory->backing_block_offset = offset; shared_memory->backing_block_offset = offset;
shared_memory->base_address = shared_memory->base_address =
kernel.CurrentProcess()->vm_manager.GetHeapRegionBaseAddress() + offset; kernel.CurrentProcess()->VMManager().GetHeapRegionBaseAddress() + offset;
return shared_memory; return shared_memory;
} }
@ -107,7 +107,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
VAddr target_address = address; VAddr target_address = address;
// Map the memory block into the target process // Map the memory block into the target process
auto result = target_process->vm_manager.MapMemoryBlock( auto result = target_process->VMManager().MapMemoryBlock(
target_address, backing_block, backing_block_offset, size, MemoryState::Shared); target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
if (result.Failed()) { if (result.Failed()) {
LOG_ERROR( LOG_ERROR(
@ -117,14 +117,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
return result.Code(); return result.Code();
} }
return target_process->vm_manager.ReprotectRange(target_address, size, return target_process->VMManager().ReprotectRange(target_address, size,
ConvertPermissions(permissions)); ConvertPermissions(permissions));
} }
ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) { ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) {
// TODO(Subv): Verify what happens if the application tries to unmap an address that is not // TODO(Subv): Verify what happens if the application tries to unmap an address that is not
// mapped to a SharedMemory. // mapped to a SharedMemory.
return target_process->vm_manager.UnmapRange(address, size); return target_process->VMManager().UnmapRange(address, size);
} }
VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) {

View File

@ -51,7 +51,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
} }
auto& process = *Core::CurrentProcess(); auto& process = *Core::CurrentProcess();
const VAddr heap_base = process.vm_manager.GetHeapRegionBaseAddress(); const VAddr heap_base = process.VMManager().GetHeapRegionBaseAddress();
CASCADE_RESULT(*heap_addr, CASCADE_RESULT(*heap_addr,
process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite)); process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite));
return RESULT_SUCCESS; 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); info_sub_id, handle);
const auto& current_process = Core::CurrentProcess(); 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)) { switch (static_cast<GetInfoType>(info_id)) {
case GetInfoType::AllowedCpuIdBitmask: case GetInfoType::AllowedCpuIdBitmask:
*result = current_process->allowed_processor_mask; *result = current_process->GetAllowedProcessorMask();
break; break;
case GetInfoType::AllowedThreadPrioBitmask: case GetInfoType::AllowedThreadPrioBitmask:
*result = current_process->allowed_thread_priority_mask; *result = current_process->GetAllowedThreadPriorityMask();
break; break;
case GetInfoType::MapRegionBaseAddr: case GetInfoType::MapRegionBaseAddr:
*result = vm_manager.GetMapRegionBaseAddress(); *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(); *result = vm_manager.GetNewMapRegionSize();
break; break;
case GetInfoType::IsVirtualAddressMemoryEnabled: case GetInfoType::IsVirtualAddressMemoryEnabled:
*result = current_process->is_virtual_address_memory_enabled; *result = current_process->IsVirtualMemoryEnabled();
break; break;
case GetInfoType::TitleId: case GetInfoType::TitleId:
*result = current_process->program_id; *result = current_process->GetTitleID();
break; break;
case GetInfoType::PrivilegedProcessId: case GetInfoType::PrivilegedProcessId:
LOG_WARNING(Kernel_SVC, LOG_WARNING(Kernel_SVC,
@ -415,8 +415,36 @@ static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
} }
/// Gets the thread context /// Gets the thread context
static ResultCode GetThreadContext(Handle handle, VAddr addr) { static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr); 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; 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 // 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 = Core::CurrentProcess()->resource_limit; const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
return ERR_NOT_AUTHORIZED; return ERR_NOT_AUTHORIZED;
} }
@ -519,9 +547,9 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
if (!process) { if (!process) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
auto vma = process->vm_manager.FindVMA(addr); auto vma = process->VMManager().FindVMA(addr);
memory_info->attributes = 0; 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->base_address = 0;
memory_info->permission = static_cast<u32>(VMAPermission::None); memory_info->permission = static_cast<u32>(VMAPermission::None);
memory_info->size = 0; 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; return ERR_INVALID_THREAD_PRIORITY;
} }
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit; const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) { if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
return ERR_NOT_AUTHORIZED; return ERR_NOT_AUTHORIZED;
} }
if (processor_id == THREADPROCESSORID_DEFAULT) { if (processor_id == THREADPROCESSORID_DEFAULT) {
// 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 = Core::CurrentProcess()->ideal_processor; processor_id = Core::CurrentProcess()->GetDefaultProcessorID();
ASSERT(processor_id != THREADPROCESSORID_DEFAULT); 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)) { if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) {
ASSERT(thread->owner_process->ideal_processor != ASSERT(thread->owner_process->GetDefaultProcessorID() !=
static_cast<u8>(THREADPROCESSORID_DEFAULT)); static_cast<u8>(THREADPROCESSORID_DEFAULT));
// Set the target CPU to the one specified in the process' exheader. // 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; mask = 1ull << core;
} }

View File

@ -64,6 +64,11 @@ void SvcWrap() {
FuncReturn(func(Param(0), (s32)Param(1)).raw); FuncReturn(func(Param(0), (s32)Param(1)).raw);
} }
template <ResultCode func(u64, u32)>
void SvcWrap() {
FuncReturn(func(Param(0), static_cast<u32>(Param(1))).raw);
}
template <ResultCode func(u64*, u64)> template <ResultCode func(u64*, u64)>
void SvcWrap() { void SvcWrap() {
u64 param_1 = 0; u64 param_1 = 0;

View File

@ -259,10 +259,10 @@ void Thread::BoostPriority(u32 priority) {
SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority,
Process& owner_process) { Process& owner_process) {
// Setup page table so we can write to memory // Setup page table so we can write to memory
SetCurrentPageTable(&owner_process.vm_manager.page_table); SetCurrentPageTable(&owner_process.VMManager().page_table);
// Initialize new "main" thread // Initialize new "main" thread
const VAddr stack_top = owner_process.vm_manager.GetTLSIORegionEndAddress(); const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress();
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0, auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0,
stack_top, &owner_process); stack_top, &owner_process);

View File

@ -51,7 +51,7 @@ enum class FatalType : u32 {
}; };
static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) { static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) {
const auto title_id = Core::CurrentProcess()->program_id; const auto title_id = Core::CurrentProcess()->GetTitleID();
std::string crash_report = std::string crash_report =
fmt::format("Yuzu {}-{} crash report\n" fmt::format("Yuzu {}-{} crash report\n"
"Title ID: {:016x}\n" "Title ID: {:016x}\n"

View File

@ -317,7 +317,7 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) {
void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
// Map backing memory for the font data // Map backing memory for the font data
Core::CurrentProcess()->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0, Core::CurrentProcess()->VMManager().MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0,
SHARED_FONT_MEM_SIZE, SHARED_FONT_MEM_SIZE,
Kernel::MemoryState::Shared); Kernel::MemoryState::Shared);

View File

@ -132,7 +132,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process)
process.LoadFromMetadata(metadata); process.LoadFromMetadata(metadata);
// Load NSO modules // Load NSO modules
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
VAddr next_load_addr = base_address; VAddr next_load_addr = base_address;
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
"subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {

View File

@ -395,7 +395,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::Process& process) {
if (buffer.size() != file->GetSize()) if (buffer.size() != file->GetSize())
return ResultStatus::ErrorIncorrectELFFileSize; return ResultStatus::ErrorIncorrectELFFileSize;
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
ElfReader elf_reader(&buffer[0]); ElfReader elf_reader(&buffer[0]);
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(base_address); SharedPtr<CodeSet> codeset = elf_reader.LoadInto(base_address);
codeset->name = file->GetName(); codeset->name = file->GetName();

View File

@ -181,7 +181,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::Process& process) {
} }
// Load NRO // Load NRO
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
if (!LoadNro(file, base_address)) { if (!LoadNro(file, base_address)) {
return ResultStatus::ErrorLoadingNRO; return ResultStatus::ErrorLoadingNRO;

View File

@ -159,7 +159,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::Process& process) {
} }
// Load module // Load module
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
LoadModule(file, base_address); LoadModule(file, base_address);
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address); LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);

View File

@ -119,7 +119,7 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin
static u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) { static u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) {
u8* direct_pointer = nullptr; u8* direct_pointer = nullptr;
auto& vm_manager = process.vm_manager; auto& vm_manager = process.VMManager();
auto it = vm_manager.FindVMA(vaddr); auto it = vm_manager.FindVMA(vaddr);
ASSERT(it != vm_manager.vma_map.end()); ASSERT(it != vm_manager.vma_map.end());
@ -214,7 +214,7 @@ void Write(const VAddr vaddr, const T data) {
} }
bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
auto& page_table = process.vm_manager.page_table; const auto& page_table = process.VMManager().page_table;
const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
if (page_pointer) if (page_pointer)
@ -363,7 +363,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
} }
}; };
const auto& vm_manager = Core::CurrentProcess()->vm_manager; const auto& vm_manager = Core::CurrentProcess()->VMManager();
CheckRegion(vm_manager.GetCodeRegionBaseAddress(), vm_manager.GetCodeRegionEndAddress()); CheckRegion(vm_manager.GetCodeRegionBaseAddress(), vm_manager.GetCodeRegionEndAddress());
CheckRegion(vm_manager.GetHeapRegionBaseAddress(), vm_manager.GetHeapRegionEndAddress()); CheckRegion(vm_manager.GetHeapRegionBaseAddress(), vm_manager.GetHeapRegionEndAddress());
@ -387,7 +387,7 @@ u64 Read64(const VAddr addr) {
void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
const std::size_t size) { const std::size_t size) {
auto& page_table = process.vm_manager.page_table; const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size; std::size_t remaining_size = size;
std::size_t page_index = src_addr >> PAGE_BITS; std::size_t page_index = src_addr >> PAGE_BITS;
@ -452,7 +452,7 @@ void Write64(const VAddr addr, const u64 data) {
void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
const std::size_t size) { const std::size_t size) {
auto& page_table = process.vm_manager.page_table; const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size; std::size_t remaining_size = size;
std::size_t page_index = dest_addr >> PAGE_BITS; std::size_t page_index = dest_addr >> PAGE_BITS;
std::size_t page_offset = dest_addr & PAGE_MASK; std::size_t page_offset = dest_addr & PAGE_MASK;
@ -498,7 +498,7 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t
} }
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) {
auto& page_table = process.vm_manager.page_table; const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size; std::size_t remaining_size = size;
std::size_t page_index = dest_addr >> PAGE_BITS; std::size_t page_index = dest_addr >> PAGE_BITS;
std::size_t page_offset = dest_addr & PAGE_MASK; std::size_t page_offset = dest_addr & PAGE_MASK;
@ -540,7 +540,7 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std:
void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
const std::size_t size) { const std::size_t size) {
auto& page_table = process.vm_manager.page_table; const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size; std::size_t remaining_size = size;
std::size_t page_index = src_addr >> PAGE_BITS; std::size_t page_index = src_addr >> PAGE_BITS;
std::size_t page_offset = src_addr & PAGE_MASK; std::size_t page_offset = src_addr & PAGE_MASK;

View File

@ -16,7 +16,7 @@ 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)) {
Core::CurrentProcess() = Kernel::Process::Create(kernel, ""); Core::CurrentProcess() = Kernel::Process::Create(kernel, "");
page_table = &Core::CurrentProcess()->vm_manager.page_table; page_table = &Core::CurrentProcess()->VMManager().page_table;
std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr); std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr);
page_table->special_regions.clear(); page_table->special_regions.clear();

View File

@ -622,9 +622,9 @@ void GMainWindow::BootGame(const QString& filename) {
std::string title_name; std::string title_name;
const auto res = Core::System::GetInstance().GetGameName(title_name); const auto res = Core::System::GetInstance().GetGameName(title_name);
if (res != Loader::ResultStatus::Success) { if (res != Loader::ResultStatus::Success) {
const u64 program_id = Core::System::GetInstance().CurrentProcess()->program_id; const u64 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
const auto [nacp, icon_file] = FileSys::PatchManager(program_id).GetControlMetadata(); const auto [nacp, icon_file] = FileSys::PatchManager(title_id).GetControlMetadata();
if (nacp != nullptr) if (nacp != nullptr)
title_name = nacp->GetApplicationName(); title_name = nacp->GetApplicationName();