mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	HLE/IPC: move command buffer translation into kernel as TODO says
This commit is contained in:
		
							parent
							
								
									de1128c60d
								
							
						
					
					
						commit
						36c8e1d7a9
					
				
					 5 changed files with 31 additions and 36 deletions
				
			
		|  | @ -27,6 +27,7 @@ class HandleTable; | |||
| class Process; | ||||
| class Thread; | ||||
| class Event; | ||||
| class HLERequestContext; | ||||
| 
 | ||||
| /**
 | ||||
|  * Interface implemented by HLE Session handlers. | ||||
|  | @ -39,13 +40,10 @@ public: | |||
| 
 | ||||
|     /**
 | ||||
|      * Handles a sync request from the emulated application. | ||||
|      * @param server_session The ServerSession that was triggered for this sync request, | ||||
|      * it should be used to differentiate which client (As in ClientSession) we're answering to. | ||||
|      * TODO(Subv): Use a wrapper structure to hold all the information relevant to | ||||
|      * this request (ServerSession, Originator thread, Translated command buffer, etc). | ||||
|      * @returns ResultCode the result code of the translate operation. | ||||
|      * @param context holds all the information relevant to his request (ServerSession, Translated | ||||
|      * command buffer, etc). | ||||
|      */ | ||||
|     virtual void HandleSyncRequest(SharedPtr<ServerSession> server_session) = 0; | ||||
|     virtual void HandleSyncRequest(Kernel::HLERequestContext& context) = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Signals that a client has just connected to this HLE handler and keeps the | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel) {} | ||||
| ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} | ||||
| ServerSession::~ServerSession() { | ||||
|     // This destructor will be called automatically when the last ServerSession handle is closed by
 | ||||
|     // the emulated application.
 | ||||
|  | @ -66,7 +66,25 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | |||
| 
 | ||||
|     // If this ServerSession has an associated HLE handler, forward the request to it.
 | ||||
|     if (hle_handler != nullptr) { | ||||
|         hle_handler->HandleSyncRequest(SharedPtr<ServerSession>(this)); | ||||
|         // TODO(wwylele): avoid GetPointer
 | ||||
|         u32* cmd_buf = | ||||
|             reinterpret_cast<u32*>(kernel.memory.GetPointer(thread->GetCommandBufferAddress())); | ||||
| 
 | ||||
|         Kernel::Process* current_process = thread->owner_process; | ||||
| 
 | ||||
|         Kernel::HLERequestContext context(this); | ||||
|         context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process); | ||||
| 
 | ||||
|         hle_handler->HandleSyncRequest(context); | ||||
| 
 | ||||
|         ASSERT(thread->status == Kernel::ThreadStatus::Running || | ||||
|                thread->status == Kernel::ThreadStatus::WaitHleEvent); | ||||
|         // Only write the response immediately if the thread is still running. If the HLE handler
 | ||||
|         // put the thread to sleep then the writing of the command buffer will be deferred to the
 | ||||
|         // wakeup callback.
 | ||||
|         if (thread->status == Kernel::ThreadStatus::Running) { | ||||
|             context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (thread->status == ThreadStatus::Running) { | ||||
|  |  | |||
|  | @ -102,6 +102,7 @@ private: | |||
|                                                       std::string name = "Unknown"); | ||||
| 
 | ||||
|     friend class KernelSystem; | ||||
|     KernelSystem& kernel; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  |  | |||
|  | @ -169,39 +169,17 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(u32* cmd_buf, const Funct | |||
|     cmd_buf[1] = 0; | ||||
| } | ||||
| 
 | ||||
| void ServiceFrameworkBase::HandleSyncRequest( | ||||
|     Kernel::SharedPtr<Kernel::ServerSession> server_session) { | ||||
|     Kernel::KernelSystem& kernel = Core::System::GetInstance().Kernel(); | ||||
|     auto thread = kernel.GetThreadManager().GetCurrentThread(); | ||||
|     // TODO(wwylele): avoid GetPointer
 | ||||
|     u32* cmd_buf = reinterpret_cast<u32*>( | ||||
|         Core::System::GetInstance().Memory().GetPointer(thread->GetCommandBufferAddress())); | ||||
| 
 | ||||
|     u32 header_code = cmd_buf[0]; | ||||
| void ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& context) { | ||||
|     u32 header_code = context.CommandBuffer()[0]; | ||||
|     auto itr = handlers.find(header_code); | ||||
|     const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second; | ||||
|     if (info == nullptr || info->handler_callback == nullptr) { | ||||
|         return ReportUnimplementedFunction(cmd_buf, info); | ||||
|         return ReportUnimplementedFunction(context.CommandBuffer(), info); | ||||
|     } | ||||
| 
 | ||||
|     Kernel::SharedPtr<Kernel::Process> current_process = kernel.GetCurrentProcess(); | ||||
| 
 | ||||
|     // TODO(yuriks): The kernel should be the one handling this as part of translation after
 | ||||
|     // everything else is migrated
 | ||||
|     Kernel::HLERequestContext context(std::move(server_session)); | ||||
|     context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process); | ||||
| 
 | ||||
|     LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf)); | ||||
|     LOG_TRACE(Service, "{}", | ||||
|               MakeFunctionString(info->name, GetServiceName().c_str(), context.CommandBuffer())); | ||||
|     handler_invoker(this, info->handler_callback, context); | ||||
| 
 | ||||
|     ASSERT(thread->status == Kernel::ThreadStatus::Running || | ||||
|            thread->status == Kernel::ThreadStatus::WaitHleEvent); | ||||
|     // Only write the response immediately if the thread is still running. If the HLE handler put
 | ||||
|     // the thread to sleep then the writing of the command buffer will be deferred to the wakeup
 | ||||
|     // callback.
 | ||||
|     if (thread->status == Kernel::ThreadStatus::Running) { | ||||
|         context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|  |  | |||
|  | @ -61,7 +61,7 @@ public: | |||
|     /// Creates a port pair and registers it on the kernel's global port registry.
 | ||||
|     void InstallAsNamedPort(Kernel::KernelSystem& kernel); | ||||
| 
 | ||||
|     void HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) override; | ||||
|     void HandleSyncRequest(Kernel::HLERequestContext& context) override; | ||||
| 
 | ||||
| protected: | ||||
|     /// Member-function pointer type of SyncRequest handlers.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue