kernel: Add basic support for Domain object.
This commit is contained in:
		| @@ -29,6 +29,7 @@ set(SRCS | ||||
|             hle/kernel/address_arbiter.cpp | ||||
|             hle/kernel/client_port.cpp | ||||
|             hle/kernel/client_session.cpp | ||||
|             hle/kernel/domain.cpp | ||||
|             hle/kernel/event.cpp | ||||
|             hle/kernel/handle_table.cpp | ||||
|             hle/kernel/hle_ipc.cpp | ||||
| @@ -118,6 +119,7 @@ set(HEADERS | ||||
|             hle/kernel/address_arbiter.h | ||||
|             hle/kernel/client_port.h | ||||
|             hle/kernel/client_session.h | ||||
|             hle/kernel/domain.h | ||||
|             hle/kernel/errors.h | ||||
|             hle/kernel/event.h | ||||
|             hle/kernel/handle_table.h | ||||
|   | ||||
							
								
								
									
										44
									
								
								src/core/hle/kernel/domain.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/core/hle/kernel/domain.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "core/hle/kernel/client_port.h" | ||||
| #include "core/hle/kernel/domain.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/session.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| ResultVal<SharedPtr<Domain>> Domain::Create(std::string name) { | ||||
|     SharedPtr<Domain> domain(new Domain); | ||||
|     domain->name = std::move(name); | ||||
|     return MakeResult(std::move(domain)); | ||||
| } | ||||
|  | ||||
| ResultVal<SharedPtr<Domain>> Domain::CreateFromSession(const Session& session) { | ||||
|     auto res = Create(session.port->GetName() + "_Domain"); | ||||
|     auto& domain = res.Unwrap(); | ||||
|     domain->request_handlers.push_back(std::move(session.server->hle_handler)); | ||||
|     Kernel::g_handle_table.ConvertSessionToDomain(session, domain); | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| ResultCode Domain::SendSyncRequest(SharedPtr<Thread> thread) { | ||||
|     Kernel::HLERequestContext context(this); | ||||
|     u32* cmd_buf = (u32*)Memory::GetPointer(Kernel::GetCurrentThread()->GetTLSAddress()); | ||||
|     context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process, | ||||
|                                               Kernel::g_handle_table); | ||||
|  | ||||
|     auto& domain_message_header = context.GetDomainMessageHeader(); | ||||
|     if (domain_message_header) { | ||||
|         // If there is a DomainMessageHeader, then this is CommandType "Request" | ||||
|         const u32 object_id{context.GetDomainMessageHeader()->object_id}; | ||||
|         return request_handlers[object_id - 1]->HandleSyncRequest(context); | ||||
|     } | ||||
|     return request_handlers.front()->HandleSyncRequest(context); | ||||
| } | ||||
|  | ||||
| } // namespace Kernel | ||||
							
								
								
									
										45
									
								
								src/core/hle/kernel/domain.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/core/hle/kernel/domain.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include "core/hle/kernel/sync_object.h" | ||||
| #include "core/hle/result.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class Session; | ||||
| class SessionRequestHandler; | ||||
|  | ||||
| class Domain final : public SyncObject { | ||||
| public: | ||||
|     std::string GetTypeName() const override { | ||||
|         return "Domain"; | ||||
|     } | ||||
|  | ||||
|     static const HandleType HANDLE_TYPE = HandleType::Domain; | ||||
|     HandleType GetHandleType() const override { | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
|  | ||||
|     static ResultVal<SharedPtr<Domain>> CreateFromSession(const Session& server); | ||||
|  | ||||
|     ResultCode SendSyncRequest(SharedPtr<Thread> thread) override; | ||||
|  | ||||
|     /// The name of this domain (optional) | ||||
|     std::string name; | ||||
|  | ||||
|     std::vector<std::shared_ptr<SessionRequestHandler>> request_handlers; | ||||
|  | ||||
| private: | ||||
|     Domain() = default; | ||||
|     ~Domain() override = default; | ||||
|  | ||||
|     static ResultVal<SharedPtr<Domain>> Create(std::string name = "Unknown"); | ||||
| }; | ||||
|  | ||||
| } // namespace Kernel | ||||
| @@ -31,6 +31,7 @@ enum class HandleType : u32 { | ||||
|     ServerPort, | ||||
|     ClientSession, | ||||
|     ServerSession, | ||||
|     Domain, | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| @@ -83,12 +84,28 @@ public: | ||||
|         case HandleType::CodeSet: | ||||
|         case HandleType::ClientPort: | ||||
|         case HandleType::ClientSession: | ||||
|         case HandleType::Domain: | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         UNREACHABLE(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if svcSendSyncRequest can be called on the object | ||||
|      * @return True svcSendSyncRequest can be called on the object, otherwise false | ||||
|      */ | ||||
|     bool IsSyncable() const { | ||||
|         switch (GetHandleType()) { | ||||
|         case HandleType::ClientSession: | ||||
|         case HandleType::Domain: | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         UNREACHABLE(); | ||||
|     } | ||||
|  | ||||
|  | ||||
| public: | ||||
|     static unsigned int next_object_id; | ||||
|  | ||||
|   | ||||
| @@ -16,10 +16,10 @@ class Thread; | ||||
| class SyncObject : public Object { | ||||
| public: | ||||
|     /** | ||||
|     * Handle a sync request from the emulated application. | ||||
|     * @param thread Thread that initiated the request. | ||||
|     * @returns ResultCode from the operation. | ||||
|     */ | ||||
|      * Handle a sync request from the emulated application. | ||||
|      * @param thread Thread that initiated the request. | ||||
|      * @returns ResultCode from the operation. | ||||
|      */ | ||||
|     virtual ResultCode SendSyncRequest(SharedPtr<Thread> thread) = 0; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user