mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	HLE/IPC: pass in kernel & memory reference from parent to avoid global state reference
This commit is contained in:
		
							parent
							
								
									0a424b86d2
								
							
						
					
					
						commit
						3f86be88f0
					
				
					 4 changed files with 26 additions and 21 deletions
				
			
		|  | @ -48,7 +48,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | ||||||
|         // the translation might need to read from it in order to retrieve the StaticBuffer
 |         // the translation might need to read from it in order to retrieve the StaticBuffer
 | ||||||
|         // target addresses.
 |         // target addresses.
 | ||||||
|         std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff; |         std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff; | ||||||
|         Memory::MemorySystem& memory = Core::System::GetInstance().Memory(); |         Memory::MemorySystem& memory = context.kernel.memory; | ||||||
|         memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), |         memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), | ||||||
|                          cmd_buff.size() * sizeof(u32)); |                          cmd_buff.size() * sizeof(u32)); | ||||||
|         context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); |         context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); | ||||||
|  | @ -57,8 +57,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | ||||||
|                           cmd_buff.size() * sizeof(u32)); |                           cmd_buff.size() * sizeof(u32)); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     auto event = Core::System::GetInstance().Kernel().CreateEvent(Kernel::ResetType::OneShot, |     auto event = kernel.CreateEvent(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); | ||||||
|                                                                   "HLE Pause Event: " + reason); |  | ||||||
|     thread->status = ThreadStatus::WaitHleEvent; |     thread->status = ThreadStatus::WaitHleEvent; | ||||||
|     thread->wait_objects = {event}; |     thread->wait_objects = {event}; | ||||||
|     event->AddWaitingThread(thread); |     event->AddWaitingThread(thread); | ||||||
|  | @ -69,8 +68,8 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | ||||||
|     return event; |     return event; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HLERequestContext::HLERequestContext(SharedPtr<ServerSession> session) | HLERequestContext::HLERequestContext(KernelSystem& kernel, SharedPtr<ServerSession> session) | ||||||
|     : session(std::move(session)) { |     : kernel(kernel), session(std::move(session)) { | ||||||
|     cmd_buf[0] = 0; |     cmd_buf[0] = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -143,8 +142,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr | ||||||
| 
 | 
 | ||||||
|             // Copy the input buffer into our own vector and store it.
 |             // Copy the input buffer into our own vector and store it.
 | ||||||
|             std::vector<u8> data(buffer_info.size); |             std::vector<u8> data(buffer_info.size); | ||||||
|             Core::System::GetInstance().Memory().ReadBlock(src_process, source_address, data.data(), |             kernel.memory.ReadBlock(src_process, source_address, data.data(), data.size()); | ||||||
|                                                            data.size()); |  | ||||||
| 
 | 
 | ||||||
|             AddStaticBuffer(buffer_info.buffer_id, std::move(data)); |             AddStaticBuffer(buffer_info.buffer_id, std::move(data)); | ||||||
|             cmd_buf[i++] = source_address; |             cmd_buf[i++] = source_address; | ||||||
|  | @ -152,7 +150,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr | ||||||
|         } |         } | ||||||
|         case IPC::DescriptorType::MappedBuffer: { |         case IPC::DescriptorType::MappedBuffer: { | ||||||
|             u32 next_id = static_cast<u32>(request_mapped_buffers.size()); |             u32 next_id = static_cast<u32>(request_mapped_buffers.size()); | ||||||
|             request_mapped_buffers.emplace_back(src_process, descriptor, src_cmdbuf[i], next_id); |             request_mapped_buffers.emplace_back(kernel.memory, src_process, descriptor, | ||||||
|  |                                                 src_cmdbuf[i], next_id); | ||||||
|             cmd_buf[i++] = next_id; |             cmd_buf[i++] = next_id; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | @ -211,8 +210,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, | ||||||
| 
 | 
 | ||||||
|             ASSERT_MSG(target_descriptor.size >= data.size(), "Static buffer data is too big"); |             ASSERT_MSG(target_descriptor.size >= data.size(), "Static buffer data is too big"); | ||||||
| 
 | 
 | ||||||
|             Core::System::GetInstance().Memory().WriteBlock(dst_process, target_address, |             kernel.memory.WriteBlock(dst_process, target_address, data.data(), data.size()); | ||||||
|                                                             data.data(), data.size()); |  | ||||||
| 
 | 
 | ||||||
|             dst_cmdbuf[i++] = target_address; |             dst_cmdbuf[i++] = target_address; | ||||||
|             break; |             break; | ||||||
|  | @ -235,8 +233,9 @@ MappedBuffer& HLERequestContext::GetMappedBuffer(u32 id_from_cmdbuf) { | ||||||
|     return request_mapped_buffers[id_from_cmdbuf]; |     return request_mapped_buffers[id_from_cmdbuf]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MappedBuffer::MappedBuffer(const Process& process, u32 descriptor, VAddr address, u32 id) | MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, | ||||||
|     : id(id), address(address), process(&process) { |                            VAddr address, u32 id) | ||||||
|  |     : memory(&memory), id(id), address(address), process(&process) { | ||||||
|     IPC::MappedBufferDescInfo desc{descriptor}; |     IPC::MappedBufferDescInfo desc{descriptor}; | ||||||
|     size = desc.size; |     size = desc.size; | ||||||
|     perms = desc.perms; |     perms = desc.perms; | ||||||
|  | @ -245,15 +244,13 @@ MappedBuffer::MappedBuffer(const Process& process, u32 descriptor, VAddr address | ||||||
| void MappedBuffer::Read(void* dest_buffer, std::size_t offset, std::size_t size) { | void MappedBuffer::Read(void* dest_buffer, std::size_t offset, std::size_t size) { | ||||||
|     ASSERT(perms & IPC::R); |     ASSERT(perms & IPC::R); | ||||||
|     ASSERT(offset + size <= this->size); |     ASSERT(offset + size <= this->size); | ||||||
|     Core::System::GetInstance().Memory().ReadBlock(*process, address + static_cast<VAddr>(offset), |     memory->ReadBlock(*process, address + static_cast<VAddr>(offset), dest_buffer, size); | ||||||
|                                                    dest_buffer, size); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t size) { | void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t size) { | ||||||
|     ASSERT(perms & IPC::W); |     ASSERT(perms & IPC::W); | ||||||
|     ASSERT(offset + size <= this->size); |     ASSERT(offset + size <= this->size); | ||||||
|     Core::System::GetInstance().Memory().WriteBlock(*process, address + static_cast<VAddr>(offset), |     memory->WriteBlock(*process, address + static_cast<VAddr>(offset), src_buffer, size); | ||||||
|                                                     src_buffer, size); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace Kernel
 | } // namespace Kernel
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,10 @@ namespace Service { | ||||||
| class ServiceFrameworkBase; | class ServiceFrameworkBase; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | namespace Memory { | ||||||
|  | class MemorySystem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| class HandleTable; | class HandleTable; | ||||||
|  | @ -28,6 +32,7 @@ class Process; | ||||||
| class Thread; | class Thread; | ||||||
| class Event; | class Event; | ||||||
| class HLERequestContext; | class HLERequestContext; | ||||||
|  | class KernelSystem; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Interface implemented by HLE Session handlers. |  * Interface implemented by HLE Session handlers. | ||||||
|  | @ -93,7 +98,8 @@ protected: | ||||||
| 
 | 
 | ||||||
| class MappedBuffer { | class MappedBuffer { | ||||||
| public: | public: | ||||||
|     MappedBuffer(const Process& process, u32 descriptor, VAddr address, u32 id); |     MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, | ||||||
|  |                  VAddr address, u32 id); | ||||||
| 
 | 
 | ||||||
|     // interface for service
 |     // interface for service
 | ||||||
|     void Read(void* dest_buffer, std::size_t offset, std::size_t size); |     void Read(void* dest_buffer, std::size_t offset, std::size_t size); | ||||||
|  | @ -113,6 +119,7 @@ public: | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     friend class HLERequestContext; |     friend class HLERequestContext; | ||||||
|  |     Memory::MemorySystem* memory; | ||||||
|     u32 id; |     u32 id; | ||||||
|     VAddr address; |     VAddr address; | ||||||
|     const Process* process; |     const Process* process; | ||||||
|  | @ -151,7 +158,7 @@ private: | ||||||
|  */ |  */ | ||||||
| class HLERequestContext { | class HLERequestContext { | ||||||
| public: | public: | ||||||
|     HLERequestContext(SharedPtr<ServerSession> session); |     HLERequestContext(KernelSystem& kernel, SharedPtr<ServerSession> session); | ||||||
|     ~HLERequestContext(); |     ~HLERequestContext(); | ||||||
| 
 | 
 | ||||||
|     /// Returns a pointer to the IPC command buffer for this request.
 |     /// Returns a pointer to the IPC command buffer for this request.
 | ||||||
|  | @ -228,6 +235,7 @@ public: | ||||||
|     ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; |     ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |     KernelSystem& kernel; | ||||||
|     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | ||||||
|     SharedPtr<ServerSession> session; |     SharedPtr<ServerSession> session; | ||||||
|     // TODO(yuriks): Check common usage of this and optimize size accordingly
 |     // TODO(yuriks): Check common usage of this and optimize size accordingly
 | ||||||
|  |  | ||||||
|  | @ -71,7 +71,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | ||||||
|         kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), |         kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), | ||||||
|                                 cmd_buf.size() * sizeof(u32)); |                                 cmd_buf.size() * sizeof(u32)); | ||||||
| 
 | 
 | ||||||
|         Kernel::HLERequestContext context(this); |         Kernel::HLERequestContext context(kernel, this); | ||||||
|         context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); |         context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); | ||||||
| 
 | 
 | ||||||
|         hle_handler->HandleSyncRequest(context); |         hle_handler->HandleSyncRequest(context); | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel | ||||||
|     auto memory = std::make_unique<Memory::MemorySystem>(); |     auto memory = std::make_unique<Memory::MemorySystem>(); | ||||||
|     Kernel::KernelSystem kernel(*memory, 0); |     Kernel::KernelSystem kernel(*memory, 0); | ||||||
|     auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); |     auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); | ||||||
|     HLERequestContext context(std::move(session)); |     HLERequestContext context(kernel, std::move(session)); | ||||||
| 
 | 
 | ||||||
|     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); |     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); | ||||||
| 
 | 
 | ||||||
|  | @ -239,7 +239,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { | ||||||
|     auto memory = std::make_unique<Memory::MemorySystem>(); |     auto memory = std::make_unique<Memory::MemorySystem>(); | ||||||
|     Kernel::KernelSystem kernel(*memory, 0); |     Kernel::KernelSystem kernel(*memory, 0); | ||||||
|     auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); |     auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); | ||||||
|     HLERequestContext context(std::move(session)); |     HLERequestContext context(kernel, std::move(session)); | ||||||
| 
 | 
 | ||||||
|     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); |     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); | ||||||
|     auto* input = context.CommandBuffer(); |     auto* input = context.CommandBuffer(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue