kernel: Update to use atmosphere macros and correct Result (#7242)

* kernel: Switch to atmosphere style macros

* code: Rename ResultCode to Result

* code: Result constants are lower case

* Address review comments

* core: Remove CASCADE_CODE

* R_TRY replaces completely

* core: Run clang format
This commit is contained in:
GPUCode
2023-12-31 19:01:40 +02:00
committed by GitHub
parent 811303ea54
commit 5a7f615da1
132 changed files with 2807 additions and 2995 deletions

View File

@@ -12,14 +12,10 @@
namespace Service::SM {
static ResultCode ValidateServiceName(const std::string& name) {
if (name.size() <= 0 || name.size() > 8) {
return ERR_INVALID_NAME_SIZE;
}
if (name.find('\0') != std::string::npos) {
return ERR_NAME_CONTAINS_NUL;
}
return RESULT_SUCCESS;
static Result ValidateServiceName(const std::string& name) {
R_UNLESS(name.size() > 0 && name.size() <= 8, ResultInvalidNameSize);
R_UNLESS(name.find('\0') == std::string::npos, ResultNameContainsNul);
return ResultSuccess;
}
ServiceManager::ServiceManager(Core::System& system) : system(system) {}
@@ -32,38 +28,35 @@ void ServiceManager::InstallInterfaces(Core::System& system) {
system.ServiceManager().srv_interface = srv;
}
ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(
std::string name, unsigned int max_sessions) {
CASCADE_CODE(ValidateServiceName(name));
if (registered_services.find(name) != registered_services.end())
return ERR_ALREADY_REGISTERED;
auto [server_port, client_port] = system.Kernel().CreatePortPair(max_sessions, name);
Result ServiceManager::RegisterService(std::shared_ptr<Kernel::ServerPort>* out_server_port,
std::string name, u32 max_sessions) {
R_TRY(ValidateServiceName(name));
R_UNLESS(registered_services.find(name) == registered_services.end(), ResultAlreadyRegistered);
const auto [server_port, client_port] = system.Kernel().CreatePortPair(max_sessions, name);
registered_services_inverse.emplace(client_port->GetObjectId(), name);
registered_services.emplace(std::move(name), std::move(client_port));
return server_port;
*out_server_port = server_port;
return ResultSuccess;
}
ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort(
const std::string& name) {
Result ServiceManager::GetServicePort(std::shared_ptr<Kernel::ClientPort>* out_client_port,
const std::string& name) {
R_TRY(ValidateServiceName(name));
CASCADE_CODE(ValidateServiceName(name));
auto it = registered_services.find(name);
if (it == registered_services.end()) {
return ERR_SERVICE_NOT_REGISTERED;
}
R_UNLESS(it != registered_services.end(), ResultServiceNotRegistered);
return it->second;
*out_client_port = it->second;
return ResultSuccess;
}
ResultVal<std::shared_ptr<Kernel::ClientSession>> ServiceManager::ConnectToService(
const std::string& name) {
CASCADE_RESULT(auto client_port, GetServicePort(name));
return client_port->Connect();
Result ServiceManager::ConnectToService(std::shared_ptr<Kernel::ClientSession>* out_client_session,
const std::string& name) {
std::shared_ptr<Kernel::ClientPort> client_port;
R_TRY(GetServicePort(std::addressof(client_port), name));
return client_port->Connect(out_client_session);
}
std::string ServiceManager::GetServiceNameByPortId(u32 port) const {

View File

@@ -31,19 +31,19 @@ namespace Service::SM {
class SRV;
constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(1, ErrorModule::SRV, ErrorSummary::WouldBlock,
ErrorLevel::Temporary); // 0xD0406401
constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(2, ErrorModule::SRV, ErrorSummary::WouldBlock,
ErrorLevel::Temporary); // 0xD0406402
constexpr ResultCode ERR_INVALID_NAME_SIZE(5, ErrorModule::SRV, ErrorSummary::WrongArgument,
ErrorLevel::Permanent); // 0xD9006405
constexpr ResultCode ERR_ACCESS_DENIED(6, ErrorModule::SRV, ErrorSummary::InvalidArgument,
ErrorLevel::Permanent); // 0xD8E06406
constexpr ResultCode ERR_NAME_CONTAINS_NUL(7, ErrorModule::SRV, ErrorSummary::WrongArgument,
ErrorLevel::Permanent); // 0xD9006407
constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorDescription::AlreadyExists, ErrorModule::OS,
ErrorSummary::WrongArgument,
ErrorLevel::Permanent); // 0xD9001BFC
constexpr Result ResultServiceNotRegistered(1, ErrorModule::SRV, ErrorSummary::WouldBlock,
ErrorLevel::Temporary); // 0xD0406401
constexpr Result ResultMaxConnectionsReached(2, ErrorModule::SRV, ErrorSummary::WouldBlock,
ErrorLevel::Temporary); // 0xD0406402
constexpr Result ResultInvalidNameSize(5, ErrorModule::SRV, ErrorSummary::WrongArgument,
ErrorLevel::Permanent); // 0xD9006405
constexpr Result ResultAccessDenied(6, ErrorModule::SRV, ErrorSummary::InvalidArgument,
ErrorLevel::Permanent); // 0xD8E06406
constexpr Result ResultNameContainsNul(7, ErrorModule::SRV, ErrorSummary::WrongArgument,
ErrorLevel::Permanent); // 0xD9006407
constexpr Result ResultAlreadyRegistered(ErrorDescription::AlreadyExists, ErrorModule::OS,
ErrorSummary::WrongArgument,
ErrorLevel::Permanent); // 0xD9001BFC
class ServiceManager {
public:
@@ -51,10 +51,12 @@ public:
explicit ServiceManager(Core::System& system);
ResultVal<std::shared_ptr<Kernel::ServerPort>> RegisterService(std::string name,
unsigned int max_sessions);
ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name);
ResultVal<std::shared_ptr<Kernel::ClientSession>> ConnectToService(const std::string& name);
Result RegisterService(std::shared_ptr<Kernel::ServerPort>* out_server_port, std::string name,
u32 max_sessions);
Result GetServicePort(std::shared_ptr<Kernel::ClientPort>* out_client_port,
const std::string& name);
Result ConnectToService(std::shared_ptr<Kernel::ClientSession>* out_client_session,
const std::string& name);
// For IPC Recorder
std::string GetServiceNameByPortId(u32 port) const;

View File

@@ -45,7 +45,7 @@ constexpr int MAX_PENDING_NOTIFICATIONS = 16;
* 1: ProcessId Header (must be 0x20)
* Outputs:
* 0: 0x00010040
* 1: ResultCode
* 1: Result
*/
void SRV::RegisterClient(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
@@ -53,13 +53,13 @@ void SRV::RegisterClient(Kernel::HLERequestContext& ctx) {
const auto pid_descriptor = rp.Pop<u32>();
if (pid_descriptor != IPC::CallingPidDesc()) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(IPC::ERR_INVALID_BUFFER_DESCRIPTOR);
rb.Push(IPC::ResultInvalidBufferDescriptor);
return;
}
const auto caller_pid = rp.Pop<u32>();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(ResultSuccess);
LOG_WARNING(Service_SRV, "(STUBBED) called. Caller PID={}", caller_pid);
}
@@ -69,7 +69,7 @@ void SRV::RegisterClient(Kernel::HLERequestContext& ctx) {
* 0: 0x00020000
* Outputs:
* 0: 0x00020042
* 1: ResultCode
* 1: Result
* 2: Translation descriptor: 0x20
* 3: Handle to semaphore signaled on process notification
*/
@@ -80,7 +80,7 @@ void SRV::EnableNotification(Kernel::HLERequestContext& ctx) {
system.Kernel().CreateSemaphore(0, MAX_PENDING_NOTIFICATIONS, "SRV:Notification").Unwrap();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(ResultSuccess);
rb.PushCopyObjects(notification_semaphore);
LOG_WARNING(Service_SRV, "(STUBBED) called");
}
@@ -94,22 +94,23 @@ public:
void WakeUp(std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
Kernel::ThreadWakeupReason reason) {
LOG_ERROR(Service_SRV, "called service={} wakeup", name);
auto client_port = system.ServiceManager().GetServicePort(name);
std::shared_ptr<Kernel::ClientPort> client_port;
R_ASSERT(system.ServiceManager().GetServicePort(std::addressof(client_port), name));
auto session = client_port.Unwrap()->Connect();
if (session.Succeeded()) {
LOG_DEBUG(Service_SRV, "called service={} -> session={}", name,
(*session)->GetObjectId());
std::shared_ptr<Kernel::ClientSession> session;
auto result = client_port->Connect(std::addressof(session));
if (result.IsSuccess()) {
LOG_DEBUG(Service_SRV, "called service={} -> session={}", name, session->GetObjectId());
IPC::RequestBuilder rb(ctx, 0x5, 1, 2);
rb.Push(session.Code());
rb.PushMoveObjects(std::move(session).Unwrap());
} else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED) {
LOG_ERROR(Service_SRV, "called service={} -> ERR_MAX_CONNECTIONS_REACHED", name);
rb.Push(result);
rb.PushMoveObjects(std::move(session));
} else if (result == Kernel::ResultMaxConnectionsReached) {
LOG_ERROR(Service_SRV, "called service={} -> ResultMaxConnectionsReached", name);
UNREACHABLE();
} else {
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, session.Code().raw);
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, result.raw);
IPC::RequestBuilder rb(ctx, 0x5, 1, 0);
rb.Push(session.Code());
rb.Push(result);
}
}
@@ -135,7 +136,7 @@ private:
* 3: Name length
* 4: Flags (bit0: if not set, return port-handle if session-handle unavailable)
* Outputs:
* 1: ResultCode
* 1: Result
* 3: Service handle
*/
void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) {
@@ -148,8 +149,8 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) {
if (name_len > Service::kMaxPortSize) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(ERR_INVALID_NAME_SIZE);
LOG_ERROR(Service_SRV, "called name_len=0x{:X} -> ERR_INVALID_NAME_SIZE", name_len);
rb.Push(ResultInvalidNameSize);
LOG_ERROR(Service_SRV, "called name_len=0x{:X} -> ResultInvalidNameSize", name_len);
return;
}
std::string name(name_buf.data(), name_len);
@@ -158,9 +159,10 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) {
auto get_handle = std::make_shared<ThreadCallback>(system, name);
auto client_port = system.ServiceManager().GetServicePort(name);
if (client_port.Failed()) {
if (wait_until_available && client_port.Code() == ERR_SERVICE_NOT_REGISTERED) {
std::shared_ptr<Kernel::ClientPort> client_port;
auto result = system.ServiceManager().GetServicePort(std::addressof(client_port), name);
if (result.IsError()) {
if (wait_until_available && result == ResultServiceNotRegistered) {
LOG_INFO(Service_SRV, "called service={} delayed", name);
std::shared_ptr<Kernel::Event> get_service_handle_event =
ctx.SleepClientThread("GetServiceHandle", std::chrono::nanoseconds(-1), get_handle);
@@ -168,27 +170,27 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) {
return;
} else {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(client_port.Code());
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name,
client_port.Code().raw);
rb.Push(result);
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, result.raw);
return;
}
}
auto session = client_port.Unwrap()->Connect();
if (session.Succeeded()) {
LOG_DEBUG(Service_SRV, "called service={} -> session={}", name, (*session)->GetObjectId());
std::shared_ptr<Kernel::ClientSession> session;
result = client_port->Connect(std::addressof(session));
if (result.IsSuccess()) {
LOG_DEBUG(Service_SRV, "called service={} -> session={}", name, session->GetObjectId());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(session.Code());
rb.PushMoveObjects(std::move(session).Unwrap());
} else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED && wait_until_available) {
LOG_WARNING(Service_SRV, "called service={} -> ERR_MAX_CONNECTIONS_REACHED", name);
rb.Push(result);
rb.PushMoveObjects(std::move(session));
} else if (result == Kernel::ResultMaxConnectionsReached && wait_until_available) {
LOG_WARNING(Service_SRV, "called service={} -> ResultMaxConnectionsReached", name);
// TODO(Subv): Put the caller guest thread to sleep until this port becomes available again.
UNIMPLEMENTED_MSG("Unimplemented wait until port {} is available.", name);
} else {
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, session.Code().raw);
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, result.raw);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(session.Code());
rb.Push(result);
}
}
@@ -199,14 +201,14 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) {
* 1: Notification ID
* Outputs:
* 0: 0x00090040
* 1: ResultCode
* 1: Result
*/
void SRV::Subscribe(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u32 notification_id = rp.Pop<u32>();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(ResultSuccess);
LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x{:X}", notification_id);
}
@@ -217,14 +219,14 @@ void SRV::Subscribe(Kernel::HLERequestContext& ctx) {
* 1: Notification ID
* Outputs:
* 0: 0x000A0040
* 1: ResultCode
* 1: Result
*/
void SRV::Unsubscribe(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u32 notification_id = rp.Pop<u32>();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(ResultSuccess);
LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x{:X}", notification_id);
}
@@ -236,7 +238,7 @@ void SRV::Unsubscribe(Kernel::HLERequestContext& ctx) {
* 2: Flags (bit0: only fire if not fired, bit1: report errors)
* Outputs:
* 0: 0x000C0040
* 1: ResultCode
* 1: Result
*/
void SRV::PublishToSubscriber(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
@@ -254,7 +256,7 @@ void SRV::PublishToSubscriber(Kernel::HLERequestContext& ctx) {
}
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(ResultSuccess);
}
void SRV::RegisterService(Kernel::HLERequestContext& ctx) {
@@ -266,12 +268,13 @@ void SRV::RegisterService(Kernel::HLERequestContext& ctx) {
std::string name(name_buf.data(), std::min(name_len, name_buf.size()));
auto port = system.ServiceManager().RegisterService(name, max_sessions);
std::shared_ptr<Kernel::ServerPort> port;
auto result = system.ServiceManager().RegisterService(std::addressof(port), name, max_sessions);
if (port.Failed()) {
if (result.IsError()) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(port.Code());
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, port.Code().raw);
rb.Push(result);
LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, result.raw);
return;
}
@@ -282,8 +285,8 @@ void SRV::RegisterService(Kernel::HLERequestContext& ctx) {
}
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMoveObjects(port.Unwrap());
rb.Push(ResultSuccess);
rb.PushMoveObjects(std::move(port));
}
SRV::SRV(Core::System& system) : ServiceFramework("srv:", 64), system(system) {