mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 23:49:01 -05:00 
			
		
		
		
	Merge pull request #3169 from lioncash/memory
core/memory: Deglobalize memory management code
This commit is contained in:
		| @@ -67,23 +67,27 @@ ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) { | ||||
|  | ||||
| ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, | ||||
|                                                               s32 num_to_wake) { | ||||
|     auto& memory = system.Memory(); | ||||
|  | ||||
|     // Ensure that we can write to the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|     if (!memory.IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|     if (static_cast<s32>(Memory::Read32(address)) != value) { | ||||
|     if (static_cast<s32>(memory.Read32(address)) != value) { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|  | ||||
|     Memory::Write32(address, static_cast<u32>(value + 1)); | ||||
|     memory.Write32(address, static_cast<u32>(value + 1)); | ||||
|     return SignalToAddressOnly(address, num_to_wake); | ||||
| } | ||||
|  | ||||
| ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, | ||||
|                                                                          s32 num_to_wake) { | ||||
|     auto& memory = system.Memory(); | ||||
|  | ||||
|     // Ensure that we can write to the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|     if (!memory.IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
| @@ -109,11 +113,11 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (static_cast<s32>(Memory::Read32(address)) != value) { | ||||
|     if (static_cast<s32>(memory.Read32(address)) != value) { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|  | ||||
|     Memory::Write32(address, static_cast<u32>(updated_value)); | ||||
|     memory.Write32(address, static_cast<u32>(updated_value)); | ||||
|     WakeThreads(waiting_threads, num_to_wake); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| @@ -134,18 +138,20 @@ ResultCode AddressArbiter::WaitForAddress(VAddr address, ArbitrationType type, s | ||||
|  | ||||
| ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, | ||||
|                                                     bool should_decrement) { | ||||
|     auto& memory = system.Memory(); | ||||
|  | ||||
|     // Ensure that we can read the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|     if (!memory.IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|     const s32 cur_value = static_cast<s32>(Memory::Read32(address)); | ||||
|     const s32 cur_value = static_cast<s32>(memory.Read32(address)); | ||||
|     if (cur_value >= value) { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|  | ||||
|     if (should_decrement) { | ||||
|         Memory::Write32(address, static_cast<u32>(cur_value - 1)); | ||||
|         memory.Write32(address, static_cast<u32>(cur_value - 1)); | ||||
|     } | ||||
|  | ||||
|     // Short-circuit without rescheduling, if timeout is zero. | ||||
| @@ -157,15 +163,19 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6 | ||||
| } | ||||
|  | ||||
| ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { | ||||
|     auto& memory = system.Memory(); | ||||
|  | ||||
|     // Ensure that we can read the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|     if (!memory.IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|     // Only wait for the address if equal. | ||||
|     if (static_cast<s32>(Memory::Read32(address)) != value) { | ||||
|     if (static_cast<s32>(memory.Read32(address)) != value) { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|     // Short-circuit without rescheduling, if timeout is zero. | ||||
|  | ||||
|     // Short-circuit without rescheduling if timeout is zero. | ||||
|     if (timeout == 0) { | ||||
|         return RESULT_TIMEOUT; | ||||
|     } | ||||
|   | ||||
| @@ -21,10 +21,10 @@ ClientSession::~ClientSession() { | ||||
|     } | ||||
| } | ||||
|  | ||||
| ResultCode ClientSession::SendSyncRequest(Thread* thread) { | ||||
| ResultCode ClientSession::SendSyncRequest(Thread* thread, Memory::Memory& memory) { | ||||
|     // Signal the server session that new data is available | ||||
|     if (auto server = parent->server.lock()) { | ||||
|         return server->HandleSyncRequest(SharedFrom(thread)); | ||||
|         return server->HandleSyncRequest(SharedFrom(thread), memory); | ||||
|     } | ||||
|  | ||||
|     return ERR_SESSION_CLOSED_BY_REMOTE; | ||||
|   | ||||
| @@ -10,6 +10,10 @@ | ||||
|  | ||||
| union ResultCode; | ||||
|  | ||||
| namespace Memory { | ||||
| class Memory; | ||||
| } | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class KernelCore; | ||||
| @@ -37,7 +41,7 @@ public: | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
|  | ||||
|     ResultCode SendSyncRequest(Thread* thread); | ||||
|     ResultCode SendSyncRequest(Thread* thread, Memory::Memory& memory); | ||||
|  | ||||
| private: | ||||
|     /// The parent session, which links to the server endpoint. | ||||
|   | ||||
| @@ -214,10 +214,11 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTabl | ||||
| ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { | ||||
|     auto& owner_process = *thread.GetOwnerProcess(); | ||||
|     auto& handle_table = owner_process.GetHandleTable(); | ||||
|     auto& memory = Core::System::GetInstance().Memory(); | ||||
|  | ||||
|     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf; | ||||
|     Memory::ReadBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), | ||||
|                       dst_cmdbuf.size() * sizeof(u32)); | ||||
|     memory.ReadBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), | ||||
|                      dst_cmdbuf.size() * sizeof(u32)); | ||||
|  | ||||
|     // The header was already built in the internal command buffer. Attempt to parse it to verify | ||||
|     // the integrity and then copy it over to the target command buffer. | ||||
| @@ -273,8 +274,8 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { | ||||
|     } | ||||
|  | ||||
|     // Copy the translated command buffer back into the thread's command buffer area. | ||||
|     Memory::WriteBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), | ||||
|                        dst_cmdbuf.size() * sizeof(u32)); | ||||
|     memory.WriteBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), | ||||
|                       dst_cmdbuf.size() * sizeof(u32)); | ||||
|  | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| @@ -282,15 +283,14 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { | ||||
| std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { | ||||
|     std::vector<u8> buffer; | ||||
|     const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; | ||||
|     auto& memory = Core::System::GetInstance().Memory(); | ||||
|  | ||||
|     if (is_buffer_a) { | ||||
|         buffer.resize(BufferDescriptorA()[buffer_index].Size()); | ||||
|         Memory::ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), | ||||
|                           buffer.size()); | ||||
|         memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size()); | ||||
|     } else { | ||||
|         buffer.resize(BufferDescriptorX()[buffer_index].Size()); | ||||
|         Memory::ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), | ||||
|                           buffer.size()); | ||||
|         memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size()); | ||||
|     } | ||||
|  | ||||
|     return buffer; | ||||
| @@ -311,10 +311,11 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, | ||||
|         size = buffer_size; // TODO(bunnei): This needs to be HW tested | ||||
|     } | ||||
|  | ||||
|     auto& memory = Core::System::GetInstance().Memory(); | ||||
|     if (is_buffer_b) { | ||||
|         Memory::WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); | ||||
|         memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); | ||||
|     } else { | ||||
|         Memory::WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size); | ||||
|         memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size); | ||||
|     } | ||||
|  | ||||
|     return size; | ||||
|   | ||||
| @@ -154,6 +154,16 @@ struct KernelCore::Impl { | ||||
|         system.CoreTiming().ScheduleEvent(time_interval, preemption_event); | ||||
|     } | ||||
|  | ||||
|     void MakeCurrentProcess(Process* process) { | ||||
|         current_process = process; | ||||
|  | ||||
|         if (process == nullptr) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         system.Memory().SetCurrentPageTable(*process); | ||||
|     } | ||||
|  | ||||
|     std::atomic<u32> next_object_id{0}; | ||||
|     std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; | ||||
|     std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; | ||||
| @@ -208,13 +218,7 @@ void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { | ||||
| } | ||||
|  | ||||
| void KernelCore::MakeCurrentProcess(Process* process) { | ||||
|     impl->current_process = process; | ||||
|  | ||||
|     if (process == nullptr) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     Memory::SetCurrentPageTable(*process); | ||||
|     impl->MakeCurrentProcess(process); | ||||
| } | ||||
|  | ||||
| Process* KernelCore::CurrentProcess() { | ||||
|   | ||||
| @@ -79,7 +79,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, | ||||
|     // thread. | ||||
|     ASSERT(requesting_thread == current_thread); | ||||
|  | ||||
|     const u32 addr_value = Memory::Read32(address); | ||||
|     const u32 addr_value = system.Memory().Read32(address); | ||||
|  | ||||
|     // If the mutex isn't being held, just return success. | ||||
|     if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) { | ||||
| @@ -117,7 +117,7 @@ ResultCode Mutex::Release(VAddr address) { | ||||
|  | ||||
|     // There are no more threads waiting for the mutex, release it completely. | ||||
|     if (thread == nullptr) { | ||||
|         Memory::Write32(address, 0); | ||||
|         system.Memory().Write32(address, 0); | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
|  | ||||
| @@ -132,7 +132,7 @@ ResultCode Mutex::Release(VAddr address) { | ||||
|     } | ||||
|  | ||||
|     // Grant the mutex to the next waiting thread and resume it. | ||||
|     Memory::Write32(address, mutex_value); | ||||
|     system.Memory().Write32(address, mutex_value); | ||||
|  | ||||
|     ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex); | ||||
|     thread->ResumeFromWait(); | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
| #include "core/hle/kernel/server_session.h" | ||||
| #include "core/hle/kernel/session.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| @@ -127,12 +128,13 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) { | ||||
| ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread, | ||||
|                                             Memory::Memory& memory) { | ||||
|     // The ServerSession received a sync request, this means that there's new data available | ||||
|     // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or | ||||
|     // similar. | ||||
|     Kernel::HLERequestContext context(SharedFrom(this), thread); | ||||
|     u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress()); | ||||
|     u32* cmd_buf = (u32*)memory.GetPointer(thread->GetTLSAddress()); | ||||
|     context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); | ||||
|  | ||||
|     ResultCode result = RESULT_SUCCESS; | ||||
|   | ||||
| @@ -13,6 +13,10 @@ | ||||
| #include "core/hle/kernel/wait_object.h" | ||||
| #include "core/hle/result.h" | ||||
|  | ||||
| namespace Memory { | ||||
| class Memory; | ||||
| } | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class ClientPort; | ||||
| @@ -85,10 +89,13 @@ public: | ||||
|  | ||||
|     /** | ||||
|      * Handle a sync request from the emulated application. | ||||
|      * | ||||
|      * @param thread Thread that initiated the request. | ||||
|      * @param memory Memory context to handle the sync request under. | ||||
|      * | ||||
|      * @returns ResultCode from the operation. | ||||
|      */ | ||||
|     ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread); | ||||
|     ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread, Memory::Memory& memory); | ||||
|  | ||||
|     bool ShouldWait(const Thread* thread) const override; | ||||
|  | ||||
|   | ||||
| @@ -332,7 +332,9 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad | ||||
| /// Connect to an OS service given the port name, returns the handle to the port to out | ||||
| static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | ||||
|                                      VAddr port_name_address) { | ||||
|     if (!Memory::IsValidVirtualAddress(port_name_address)) { | ||||
|     auto& memory = system.Memory(); | ||||
|  | ||||
|     if (!memory.IsValidVirtualAddress(port_name_address)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", | ||||
|                   port_name_address); | ||||
| @@ -341,7 +343,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | ||||
|  | ||||
|     static constexpr std::size_t PortNameMaxLength = 11; | ||||
|     // Read 1 char beyond the max allowed port name to detect names that are too long. | ||||
|     std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); | ||||
|     const std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1); | ||||
|     if (port_name.size() > PortNameMaxLength) { | ||||
|         LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength, | ||||
|                   port_name.size()); | ||||
| @@ -383,7 +385,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | ||||
|  | ||||
|     // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server | ||||
|     // responds and cause a reschedule. | ||||
|     return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread()); | ||||
|     return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread(), system.Memory()); | ||||
| } | ||||
|  | ||||
| /// Get the ID for the specified thread. | ||||
| @@ -452,7 +454,8 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | ||||
|     LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", | ||||
|               handles_address, handle_count, nano_seconds); | ||||
|  | ||||
|     if (!Memory::IsValidVirtualAddress(handles_address)) { | ||||
|     auto& memory = system.Memory(); | ||||
|     if (!memory.IsValidVirtualAddress(handles_address)) { | ||||
|         LOG_ERROR(Kernel_SVC, | ||||
|                   "Handle address is not a valid virtual address, handle_address=0x{:016X}", | ||||
|                   handles_address); | ||||
| @@ -474,7 +477,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|  | ||||
|     for (u64 i = 0; i < handle_count; ++i) { | ||||
|         const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); | ||||
|         const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); | ||||
|         const auto object = handle_table.Get<WaitObject>(handle); | ||||
|  | ||||
|         if (object == nullptr) { | ||||
| @@ -616,13 +619,15 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         auto& memory = system.Memory(); | ||||
|  | ||||
|         // This typically is an error code so we're going to assume this is the case | ||||
|         if (sz == sizeof(u32)) { | ||||
|             LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr)); | ||||
|             LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", memory.Read32(addr)); | ||||
|         } else { | ||||
|             // We don't know what's in here so we'll hexdump it | ||||
|             debug_buffer.resize(sz); | ||||
|             Memory::ReadBlock(addr, debug_buffer.data(), sz); | ||||
|             memory.ReadBlock(addr, debug_buffer.data(), sz); | ||||
|             std::string hexdump; | ||||
|             for (std::size_t i = 0; i < debug_buffer.size(); i++) { | ||||
|                 hexdump += fmt::format("{:02X} ", debug_buffer[i]); | ||||
| @@ -712,7 +717,7 @@ static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr addre | ||||
|     } | ||||
|  | ||||
|     std::string str(len, '\0'); | ||||
|     Memory::ReadBlock(address, str.data(), str.size()); | ||||
|     system.Memory().ReadBlock(address, str.data(), str.size()); | ||||
|     LOG_DEBUG(Debug_Emulated, "{}", str); | ||||
| } | ||||
|  | ||||
| @@ -1115,7 +1120,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H | ||||
|         std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{}); | ||||
|     } | ||||
|  | ||||
|     Memory::WriteBlock(thread_context, &ctx, sizeof(ctx)); | ||||
|     system.Memory().WriteBlock(thread_context, &ctx, sizeof(ctx)); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| @@ -1275,20 +1280,21 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | ||||
|         return ERR_INVALID_HANDLE; | ||||
|     } | ||||
|  | ||||
|     auto& memory = system.Memory(); | ||||
|     const auto& vm_manager = process->VMManager(); | ||||
|     const MemoryInfo memory_info = vm_manager.QueryMemory(address); | ||||
|  | ||||
|     Memory::Write64(memory_info_address, memory_info.base_address); | ||||
|     Memory::Write64(memory_info_address + 8, memory_info.size); | ||||
|     Memory::Write32(memory_info_address + 16, memory_info.state); | ||||
|     Memory::Write32(memory_info_address + 20, memory_info.attributes); | ||||
|     Memory::Write32(memory_info_address + 24, memory_info.permission); | ||||
|     Memory::Write32(memory_info_address + 32, memory_info.ipc_ref_count); | ||||
|     Memory::Write32(memory_info_address + 28, memory_info.device_ref_count); | ||||
|     Memory::Write32(memory_info_address + 36, 0); | ||||
|     memory.Write64(memory_info_address, memory_info.base_address); | ||||
|     memory.Write64(memory_info_address + 8, memory_info.size); | ||||
|     memory.Write32(memory_info_address + 16, memory_info.state); | ||||
|     memory.Write32(memory_info_address + 20, memory_info.attributes); | ||||
|     memory.Write32(memory_info_address + 24, memory_info.permission); | ||||
|     memory.Write32(memory_info_address + 32, memory_info.ipc_ref_count); | ||||
|     memory.Write32(memory_info_address + 28, memory_info.device_ref_count); | ||||
|     memory.Write32(memory_info_address + 36, 0); | ||||
|  | ||||
|     // Page info appears to be currently unused by the kernel and is always set to zero. | ||||
|     Memory::Write32(page_info_address, 0); | ||||
|     memory.Write32(page_info_address, 0); | ||||
|  | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| @@ -1672,6 +1678,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | ||||
|  | ||||
|         const std::size_t current_core = system.CurrentCoreIndex(); | ||||
|         auto& monitor = system.Monitor(); | ||||
|         auto& memory = system.Memory(); | ||||
|  | ||||
|         // Atomically read the value of the mutex. | ||||
|         u32 mutex_val = 0; | ||||
| @@ -1681,7 +1688,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | ||||
|             monitor.SetExclusive(current_core, mutex_address); | ||||
|  | ||||
|             // If the mutex is not yet acquired, acquire it. | ||||
|             mutex_val = Memory::Read32(mutex_address); | ||||
|             mutex_val = memory.Read32(mutex_address); | ||||
|  | ||||
|             if (mutex_val != 0) { | ||||
|                 update_val = mutex_val | Mutex::MutexHasWaitersFlag; | ||||
| @@ -2284,12 +2291,13 @@ static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|     auto& memory = system.Memory(); | ||||
|     const auto& process_list = kernel.GetProcessList(); | ||||
|     const auto num_processes = process_list.size(); | ||||
|     const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); | ||||
|  | ||||
|     for (std::size_t i = 0; i < copy_amount; ++i) { | ||||
|         Memory::Write64(out_process_ids, process_list[i]->GetProcessID()); | ||||
|         memory.Write64(out_process_ids, process_list[i]->GetProcessID()); | ||||
|         out_process_ids += sizeof(u64); | ||||
|     } | ||||
|  | ||||
| @@ -2323,13 +2331,14 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|     auto& memory = system.Memory(); | ||||
|     const auto& thread_list = current_process->GetThreadList(); | ||||
|     const auto num_threads = thread_list.size(); | ||||
|     const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); | ||||
|  | ||||
|     auto list_iter = thread_list.cbegin(); | ||||
|     for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { | ||||
|         Memory::Write64(out_thread_ids, (*list_iter)->GetThreadID()); | ||||
|         memory.Write64(out_thread_ids, (*list_iter)->GetThreadID()); | ||||
|         out_thread_ids += sizeof(u64); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -162,13 +162,13 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::strin | ||||
|         return ERR_INVALID_PROCESSOR_ID; | ||||
|     } | ||||
|  | ||||
|     if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) { | ||||
|     auto& system = Core::System::GetInstance(); | ||||
|     if (!system.Memory().IsValidVirtualAddress(owner_process, entry_point)) { | ||||
|         LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); | ||||
|         // TODO (bunnei): Find the correct error code to use here | ||||
|         return RESULT_UNKNOWN; | ||||
|     } | ||||
|  | ||||
|     auto& system = Core::System::GetInstance(); | ||||
|     std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel); | ||||
|  | ||||
|     thread->thread_id = kernel.CreateNewThreadID(); | ||||
|   | ||||
| @@ -16,7 +16,6 @@ | ||||
| #include "core/hle/kernel/resource_limit.h" | ||||
| #include "core/hle/kernel/vm_manager.h" | ||||
| #include "core/memory.h" | ||||
| #include "core/memory_setup.h" | ||||
|  | ||||
| namespace Kernel { | ||||
| namespace { | ||||
| @@ -786,19 +785,21 @@ void VMManager::MergeAdjacentVMA(VirtualMemoryArea& left, const VirtualMemoryAre | ||||
| } | ||||
|  | ||||
| void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { | ||||
|     auto& memory = system.Memory(); | ||||
|  | ||||
|     switch (vma.type) { | ||||
|     case VMAType::Free: | ||||
|         Memory::UnmapRegion(page_table, vma.base, vma.size); | ||||
|         memory.UnmapRegion(page_table, vma.base, vma.size); | ||||
|         break; | ||||
|     case VMAType::AllocatedMemoryBlock: | ||||
|         Memory::MapMemoryRegion(page_table, vma.base, vma.size, | ||||
|                                 vma.backing_block->data() + vma.offset); | ||||
|         memory.MapMemoryRegion(page_table, vma.base, vma.size, | ||||
|                                vma.backing_block->data() + vma.offset); | ||||
|         break; | ||||
|     case VMAType::BackingMemory: | ||||
|         Memory::MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory); | ||||
|         memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory); | ||||
|         break; | ||||
|     case VMAType::MMIO: | ||||
|         Memory::MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler); | ||||
|         memory.MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -43,7 +43,8 @@ public: | ||||
|     IAudioOut(Core::System& system, AudoutParams audio_params, AudioCore::AudioOut& audio_core, | ||||
|               std::string&& device_name, std::string&& unique_name) | ||||
|         : ServiceFramework("IAudioOut"), audio_core(audio_core), | ||||
|           device_name(std::move(device_name)), audio_params(audio_params) { | ||||
|           device_name(std::move(device_name)), | ||||
|           audio_params(audio_params), main_memory{system.Memory()} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, | ||||
| @@ -137,7 +138,7 @@ private: | ||||
|         const u64 tag{rp.Pop<u64>()}; | ||||
|  | ||||
|         std::vector<s16> samples(audio_buffer.buffer_size / sizeof(s16)); | ||||
|         Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size); | ||||
|         main_memory.ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size); | ||||
|  | ||||
|         if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) { | ||||
|             IPC::ResponseBuilder rb{ctx, 2}; | ||||
| @@ -209,6 +210,7 @@ private: | ||||
|  | ||||
|     /// This is the event handle used to check if the audio buffer was released | ||||
|     Kernel::EventPair buffer_event; | ||||
|     Memory::Memory& main_memory; | ||||
| }; | ||||
|  | ||||
| AudOutU::AudOutU(Core::System& system_) : ServiceFramework("audout:u"), system{system_} { | ||||
|   | ||||
| @@ -49,8 +49,9 @@ public: | ||||
|  | ||||
|         system_event = | ||||
|             Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent"); | ||||
|         renderer = std::make_unique<AudioCore::AudioRenderer>( | ||||
|             system.CoreTiming(), audren_params, system_event.writable, instance_number); | ||||
|         renderer = std::make_unique<AudioCore::AudioRenderer>(system.CoreTiming(), system.Memory(), | ||||
|                                                               audren_params, system_event.writable, | ||||
|                                                               instance_number); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|   | ||||
| @@ -391,13 +391,10 @@ public: | ||||
|     } | ||||
|  | ||||
|     void RenameFile(Kernel::HLERequestContext& ctx) { | ||||
|         std::vector<u8> buffer; | ||||
|         buffer.resize(ctx.BufferDescriptorX()[0].Size()); | ||||
|         Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), buffer.data(), buffer.size()); | ||||
|         std::vector<u8> buffer = ctx.ReadBuffer(0); | ||||
|         const std::string src_name = Common::StringFromBuffer(buffer); | ||||
|  | ||||
|         buffer.resize(ctx.BufferDescriptorX()[1].Size()); | ||||
|         Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size()); | ||||
|         buffer = ctx.ReadBuffer(1); | ||||
|         const std::string dst_name = Common::StringFromBuffer(buffer); | ||||
|  | ||||
|         LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name); | ||||
|   | ||||
| @@ -140,9 +140,10 @@ public: | ||||
|             rb.Push(ERROR_INVALID_SIZE); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Read NRR data from memory | ||||
|         std::vector<u8> nrr_data(nrr_size); | ||||
|         Memory::ReadBlock(nrr_address, nrr_data.data(), nrr_size); | ||||
|         system.Memory().ReadBlock(nrr_address, nrr_data.data(), nrr_size); | ||||
|         NRRHeader header; | ||||
|         std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader)); | ||||
|  | ||||
| @@ -291,7 +292,7 @@ public: | ||||
|  | ||||
|         // Read NRO data from memory | ||||
|         std::vector<u8> nro_data(nro_size); | ||||
|         Memory::ReadBlock(nro_address, nro_data.data(), nro_size); | ||||
|         system.Memory().ReadBlock(nro_address, nro_data.data(), nro_size); | ||||
|  | ||||
|         SHA256Hash hash{}; | ||||
|         mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0); | ||||
|   | ||||
| @@ -17,7 +17,8 @@ namespace Service::LM { | ||||
|  | ||||
| class ILogger final : public ServiceFramework<ILogger> { | ||||
| public: | ||||
|     ILogger(Manager& manager) : ServiceFramework("ILogger"), manager(manager) { | ||||
|     explicit ILogger(Manager& manager_, Memory::Memory& memory_) | ||||
|         : ServiceFramework("ILogger"), manager{manager_}, memory{memory_} { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &ILogger::Log, "Log"}, | ||||
|             {1, &ILogger::SetDestination, "SetDestination"}, | ||||
| @@ -35,15 +36,15 @@ private: | ||||
|         MessageHeader header{}; | ||||
|         VAddr addr{ctx.BufferDescriptorX()[0].Address()}; | ||||
|         const VAddr end_addr{addr + ctx.BufferDescriptorX()[0].size}; | ||||
|         Memory::ReadBlock(addr, &header, sizeof(MessageHeader)); | ||||
|         memory.ReadBlock(addr, &header, sizeof(MessageHeader)); | ||||
|         addr += sizeof(MessageHeader); | ||||
|  | ||||
|         FieldMap fields; | ||||
|         while (addr < end_addr) { | ||||
|             const auto field = static_cast<Field>(Memory::Read8(addr++)); | ||||
|             const auto length = Memory::Read8(addr++); | ||||
|             const auto field = static_cast<Field>(memory.Read8(addr++)); | ||||
|             const auto length = memory.Read8(addr++); | ||||
|  | ||||
|             if (static_cast<Field>(Memory::Read8(addr)) == Field::Skip) { | ||||
|             if (static_cast<Field>(memory.Read8(addr)) == Field::Skip) { | ||||
|                 ++addr; | ||||
|             } | ||||
|  | ||||
| @@ -54,7 +55,7 @@ private: | ||||
|             } | ||||
|  | ||||
|             std::vector<u8> data(length); | ||||
|             Memory::ReadBlock(addr, data.data(), length); | ||||
|             memory.ReadBlock(addr, data.data(), length); | ||||
|             fields.emplace(field, std::move(data)); | ||||
|         } | ||||
|  | ||||
| @@ -74,11 +75,13 @@ private: | ||||
|     } | ||||
|  | ||||
|     Manager& manager; | ||||
|     Memory::Memory& memory; | ||||
| }; | ||||
|  | ||||
| class LM final : public ServiceFramework<LM> { | ||||
| public: | ||||
|     explicit LM(Manager& manager) : ServiceFramework{"lm"}, manager(manager) { | ||||
|     explicit LM(Manager& manager_, Memory::Memory& memory_) | ||||
|         : ServiceFramework{"lm"}, manager{manager_}, memory{memory_} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &LM::OpenLogger, "OpenLogger"}, | ||||
| @@ -94,14 +97,16 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.PushIpcInterface<ILogger>(manager); | ||||
|         rb.PushIpcInterface<ILogger>(manager, memory); | ||||
|     } | ||||
|  | ||||
|     Manager& manager; | ||||
|     Memory::Memory& memory; | ||||
| }; | ||||
|  | ||||
| void InstallInterfaces(Core::System& system) { | ||||
|     std::make_shared<LM>(system.GetLogManager())->InstallAsService(system.ServiceManager()); | ||||
|     std::make_shared<LM>(system.GetLogManager(), system.Memory()) | ||||
|         ->InstallAsService(system.ServiceManager()); | ||||
| } | ||||
|  | ||||
| } // namespace Service::LM | ||||
|   | ||||
| @@ -191,8 +191,8 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output, | ||||
|         std::memcpy(entries.data(), input2.data(), | ||||
|                     params.num_entries * sizeof(Tegra::CommandListHeader)); | ||||
|     } else { | ||||
|         Memory::ReadBlock(params.address, entries.data(), | ||||
|                           params.num_entries * sizeof(Tegra::CommandListHeader)); | ||||
|         system.Memory().ReadBlock(params.address, entries.data(), | ||||
|                                   params.num_entries * sizeof(Tegra::CommandListHeader)); | ||||
|     } | ||||
|     UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0); | ||||
|     UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bunnei
					bunnei