kernel: Add basic support for Domain object.

This commit is contained in:
bunnei 2017-12-28 23:30:21 -05:00
parent 834fa5db65
commit e17c0019c5
5 changed files with 112 additions and 4 deletions

View File

@ -29,6 +29,7 @@ set(SRCS
hle/kernel/address_arbiter.cpp hle/kernel/address_arbiter.cpp
hle/kernel/client_port.cpp hle/kernel/client_port.cpp
hle/kernel/client_session.cpp hle/kernel/client_session.cpp
hle/kernel/domain.cpp
hle/kernel/event.cpp hle/kernel/event.cpp
hle/kernel/handle_table.cpp hle/kernel/handle_table.cpp
hle/kernel/hle_ipc.cpp hle/kernel/hle_ipc.cpp
@ -118,6 +119,7 @@ set(HEADERS
hle/kernel/address_arbiter.h hle/kernel/address_arbiter.h
hle/kernel/client_port.h hle/kernel/client_port.h
hle/kernel/client_session.h hle/kernel/client_session.h
hle/kernel/domain.h
hle/kernel/errors.h hle/kernel/errors.h
hle/kernel/event.h hle/kernel/event.h
hle/kernel/handle_table.h hle/kernel/handle_table.h

View 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

View 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

View File

@ -31,6 +31,7 @@ enum class HandleType : u32 {
ServerPort, ServerPort,
ClientSession, ClientSession,
ServerSession, ServerSession,
Domain,
}; };
enum { enum {
@ -83,12 +84,28 @@ public:
case HandleType::CodeSet: case HandleType::CodeSet:
case HandleType::ClientPort: case HandleType::ClientPort:
case HandleType::ClientSession: case HandleType::ClientSession:
case HandleType::Domain:
return false; return false;
} }
UNREACHABLE(); 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: public:
static unsigned int next_object_id; static unsigned int next_object_id;

View File

@ -16,10 +16,10 @@ class Thread;
class SyncObject : public Object { class SyncObject : public Object {
public: public:
/** /**
* Handle a sync request from the emulated application. * Handle a sync request from the emulated application.
* @param thread Thread that initiated the request. * @param thread Thread that initiated the request.
* @returns ResultCode from the operation. * @returns ResultCode from the operation.
*/ */
virtual ResultCode SendSyncRequest(SharedPtr<Thread> thread) = 0; virtual ResultCode SendSyncRequest(SharedPtr<Thread> thread) = 0;
}; };