mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #1417 from lioncash/context
svc: Implement svcGetThreadContext
This commit is contained in:
		
						commit
						5e2f23e2b1
					
				| @ -22,10 +22,16 @@ public: | ||||
|         std::array<u64, 31> cpu_registers; | ||||
|         u64 sp; | ||||
|         u64 pc; | ||||
|         u64 pstate; | ||||
|         u32 pstate; | ||||
|         std::array<u8, 4> padding; | ||||
|         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
 | ||||
|     virtual void Run() = 0; | ||||
|  | ||||
| @ -130,7 +130,7 @@ public: | ||||
| 
 | ||||
| std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { | ||||
|     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; | ||||
| 
 | ||||
| @ -139,7 +139,7 @@ std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { | ||||
| 
 | ||||
|     // Memory
 | ||||
|     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; | ||||
| 
 | ||||
|     // Multi-process state
 | ||||
| @ -247,15 +247,19 @@ void ARM_Dynarmic::SaveContext(ThreadContext& ctx) { | ||||
|     ctx.pstate = jit->GetPstate(); | ||||
|     ctx.vector_registers = jit->GetVectors(); | ||||
|     ctx.fpcr = jit->GetFpcr(); | ||||
|     ctx.fpsr = jit->GetFpsr(); | ||||
|     ctx.tpidr = cb->tpidr_el0; | ||||
| } | ||||
| 
 | ||||
| void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) { | ||||
|     jit->SetRegisters(ctx.cpu_registers); | ||||
|     jit->SetSP(ctx.sp); | ||||
|     jit->SetPC(ctx.pc); | ||||
|     jit->SetPstate(static_cast<u32>(ctx.pstate)); | ||||
|     jit->SetPstate(ctx.pstate); | ||||
|     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() { | ||||
|  | ||||
| @ -34,7 +34,7 @@ ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() { | ||||
|     if (!updatable) | ||||
|         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)); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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
 | ||||
|     // be interpreted as the title id of the current process.
 | ||||
|     if (type == SaveDataType::SaveData && title_id == 0) | ||||
|         title_id = Core::CurrentProcess()->program_id; | ||||
|         title_id = Core::CurrentProcess()->GetTitleID(); | ||||
| 
 | ||||
|     std::string out; | ||||
| 
 | ||||
|  | ||||
| @ -250,7 +250,7 @@ static void RegWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr) | ||||
|     } else if (id == PC_REGISTER) { | ||||
|         thread->context.pc = val; | ||||
|     } else if (id == PSTATE_REGISTER) { | ||||
|         thread->context.pstate = val; | ||||
|         thread->context.pstate = static_cast<u32>(val); | ||||
|     } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) { | ||||
|         thread->context.vector_registers[id - (PSTATE_REGISTER + 1)][0] = val; | ||||
|     } | ||||
| @ -587,7 +587,7 @@ static void HandleQuery() { | ||||
|                        strlen("Xfer:features:read:target.xml:")) == 0) { | ||||
|         SendReply(target_xml); | ||||
|     } 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); | ||||
|         SendReply(buffer.c_str()); | ||||
|     } else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) { | ||||
| @ -909,7 +909,7 @@ static void ReadMemory() { | ||||
|         SendReply("E01"); | ||||
|     } | ||||
| 
 | ||||
|     const auto& vm_manager = Core::CurrentProcess()->vm_manager; | ||||
|     const auto& vm_manager = Core::CurrentProcess()->VMManager(); | ||||
|     if (addr < vm_manager.GetCodeRegionBaseAddress() || | ||||
|         addr >= vm_manager.GetMapRegionEndAddress()) { | ||||
|         return SendReply("E00"); | ||||
|  | ||||
| @ -31,6 +31,7 @@ enum { | ||||
|     TooLarge = 119, | ||||
|     InvalidEnumValue = 120, | ||||
|     NoSuchEntry = 121, | ||||
|     AlreadyRegistered = 122, | ||||
|     InvalidState = 125, | ||||
|     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_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); | ||||
| 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_THREAD_PRIORITY(ErrorModule::Kernel, | ||||
|                                                  ErrCodes::InvalidThreadPriority); | ||||
|  | ||||
| @ -47,6 +47,7 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { | ||||
| 
 | ||||
| void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | ||||
|     program_id = metadata.GetTitleID(); | ||||
|     is_64bit_process = metadata.Is64BitProgram(); | ||||
|     vm_manager.Reset(metadata.GetAddressSpaceType()); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -135,6 +135,16 @@ public: | ||||
|         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
 | ||||
|     ProcessStatus GetStatus() const { | ||||
|         return status; | ||||
| @ -145,6 +155,45 @@ public: | ||||
|         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 | ||||
|      * by an executable. | ||||
| @ -153,30 +202,6 @@ public: | ||||
|      */ | ||||
|     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 | ||||
|      * to this process. | ||||
| @ -212,18 +237,43 @@ public: | ||||
| 
 | ||||
|     ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); | ||||
| 
 | ||||
|     VMManager vm_manager; | ||||
| 
 | ||||
| private: | ||||
|     explicit Process(KernelCore& kernel); | ||||
|     ~Process() override; | ||||
| 
 | ||||
|     /// Memory manager for this process.
 | ||||
|     Kernel::VMManager vm_manager; | ||||
| 
 | ||||
|     /// Current status of the process
 | ||||
|     ProcessStatus status; | ||||
| 
 | ||||
|     /// The ID of this process
 | ||||
|     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
 | ||||
|     // 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
 | ||||
| @ -242,6 +292,11 @@ private: | ||||
|     /// This vector will grow as more pages are allocated for new threads.
 | ||||
|     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; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -88,7 +88,7 @@ void Scheduler::SwitchContext(Thread* new_thread) { | ||||
| 
 | ||||
|         if (previous_process != 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); | ||||
|  | ||||
| @ -35,11 +35,11 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, SharedPtr<Proce | ||||
| 
 | ||||
|         // Refresh the address mappings for the current process.
 | ||||
|         if (Core::CurrentProcess() != nullptr) { | ||||
|             Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings( | ||||
|             Core::CurrentProcess()->VMManager().RefreshMemoryBlockMappings( | ||||
|                 shared_memory->backing_block.get()); | ||||
|         } | ||||
|     } 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.
 | ||||
|         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_offset = offset; | ||||
|     shared_memory->base_address = | ||||
|         kernel.CurrentProcess()->vm_manager.GetHeapRegionBaseAddress() + offset; | ||||
|         kernel.CurrentProcess()->VMManager().GetHeapRegionBaseAddress() + offset; | ||||
| 
 | ||||
|     return shared_memory; | ||||
| } | ||||
| @ -107,7 +107,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi | ||||
|     VAddr target_address = address; | ||||
| 
 | ||||
|     // 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); | ||||
|     if (result.Failed()) { | ||||
|         LOG_ERROR( | ||||
| @ -117,14 +117,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi | ||||
|         return result.Code(); | ||||
|     } | ||||
| 
 | ||||
|     return target_process->vm_manager.ReprotectRange(target_address, size, | ||||
|                                                      ConvertPermissions(permissions)); | ||||
|     return target_process->VMManager().ReprotectRange(target_address, size, | ||||
|                                                       ConvertPermissions(permissions)); | ||||
| } | ||||
| 
 | ||||
| ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) { | ||||
|     // TODO(Subv): Verify what happens if the application tries to unmap an address that is not
 | ||||
|     // mapped to a SharedMemory.
 | ||||
|     return target_process->vm_manager.UnmapRange(address, size); | ||||
|     return target_process->VMManager().UnmapRange(address, size); | ||||
| } | ||||
| 
 | ||||
| VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -64,6 +64,11 @@ void SvcWrap() { | ||||
|     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)> | ||||
| void SvcWrap() { | ||||
|     u64 param_1 = 0; | ||||
|  | ||||
| @ -259,10 +259,10 @@ void Thread::BoostPriority(u32 priority) { | ||||
| SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, | ||||
|                                   Process& owner_process) { | ||||
|     // 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
 | ||||
|     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, | ||||
|                                      stack_top, &owner_process); | ||||
| 
 | ||||
|  | ||||
| @ -51,7 +51,7 @@ enum class FatalType : u32 { | ||||
| }; | ||||
| 
 | ||||
| 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 = | ||||
|         fmt::format("Yuzu {}-{} crash report\n" | ||||
|                     "Title ID:                        {:016x}\n" | ||||
|  | ||||
| @ -317,9 +317,9 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) { | ||||
| 
 | ||||
| void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { | ||||
|     // Map backing memory for the font data
 | ||||
|     Core::CurrentProcess()->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0, | ||||
|                                                       SHARED_FONT_MEM_SIZE, | ||||
|                                                       Kernel::MemoryState::Shared); | ||||
|     Core::CurrentProcess()->VMManager().MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0, | ||||
|                                                        SHARED_FONT_MEM_SIZE, | ||||
|                                                        Kernel::MemoryState::Shared); | ||||
| 
 | ||||
|     // Create shared font memory object
 | ||||
|     auto& kernel = Core::System::GetInstance().Kernel(); | ||||
|  | ||||
| @ -132,7 +132,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | ||||
|     process.LoadFromMetadata(metadata); | ||||
| 
 | ||||
|     // Load NSO modules
 | ||||
|     const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); | ||||
|     const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | ||||
|     VAddr next_load_addr = base_address; | ||||
|     for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", | ||||
|                                "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { | ||||
|  | ||||
| @ -395,7 +395,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::Process& process) { | ||||
|     if (buffer.size() != file->GetSize()) | ||||
|         return ResultStatus::ErrorIncorrectELFFileSize; | ||||
| 
 | ||||
|     const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); | ||||
|     const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | ||||
|     ElfReader elf_reader(&buffer[0]); | ||||
|     SharedPtr<CodeSet> codeset = elf_reader.LoadInto(base_address); | ||||
|     codeset->name = file->GetName(); | ||||
|  | ||||
| @ -181,7 +181,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::Process& process) { | ||||
|     } | ||||
| 
 | ||||
|     // Load NRO
 | ||||
|     const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); | ||||
|     const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | ||||
| 
 | ||||
|     if (!LoadNro(file, base_address)) { | ||||
|         return ResultStatus::ErrorLoadingNRO; | ||||
|  | ||||
| @ -159,7 +159,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::Process& process) { | ||||
|     } | ||||
| 
 | ||||
|     // Load module
 | ||||
|     const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress(); | ||||
|     const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | ||||
|     LoadModule(file, base_address); | ||||
|     LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address); | ||||
| 
 | ||||
|  | ||||
| @ -119,7 +119,7 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin | ||||
| static u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) { | ||||
|     u8* direct_pointer = nullptr; | ||||
| 
 | ||||
|     auto& vm_manager = process.vm_manager; | ||||
|     auto& vm_manager = process.VMManager(); | ||||
| 
 | ||||
|     auto it = vm_manager.FindVMA(vaddr); | ||||
|     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) { | ||||
|     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]; | ||||
|     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.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, | ||||
|                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 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, | ||||
|                 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 page_index = dest_addr >> PAGE_BITS; | ||||
|     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) { | ||||
|     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 page_index = dest_addr >> PAGE_BITS; | ||||
|     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, | ||||
|                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 page_index = src_addr >> PAGE_BITS; | ||||
|     std::size_t page_offset = src_addr & PAGE_MASK; | ||||
|  | ||||
| @ -16,7 +16,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) | ||||
|     : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) { | ||||
| 
 | ||||
|     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); | ||||
|     page_table->special_regions.clear(); | ||||
|  | ||||
| @ -622,9 +622,9 @@ void GMainWindow::BootGame(const QString& filename) { | ||||
|     std::string title_name; | ||||
|     const auto res = Core::System::GetInstance().GetGameName(title_name); | ||||
|     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) | ||||
|             title_name = nacp->GetApplicationName(); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei