diff --git a/libraries/libstratosphere/include/stratosphere.hpp b/libraries/libstratosphere/include/stratosphere.hpp index d032cab3c..2e0743841 100644 --- a/libraries/libstratosphere/include/stratosphere.hpp +++ b/libraries/libstratosphere/include/stratosphere.hpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp index bf7210586..3cec1f265 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp @@ -144,6 +144,19 @@ namespace ams::impl { AMS_DEFINE_SYSTEM_THREAD(10, tma, BridgePcieDriver); + /* cs/scs. */ + AMS_DEFINE_SYSTEM_THREAD(20, cs, Main); + AMS_DEFINE_SYSTEM_THREAD(20, cs, HidctlService); + AMS_DEFINE_SYSTEM_THREAD(20, cs, HidctlLegacyServer); + AMS_DEFINE_SYSTEM_THREAD(20, cs, AudioServer); + AMS_DEFINE_SYSTEM_THREAD(10, cs, GrcVideoSender); + AMS_DEFINE_SYSTEM_THREAD(10, cs, GrcVideoReader); + AMS_DEFINE_SYSTEM_THREAD(10, cs, GrcAudioSender); + AMS_DEFINE_SYSTEM_THREAD(10, cs, GrcAudioReader); + + AMS_DEFINE_SYSTEM_THREAD(21, scs, ShellServer); + AMS_DEFINE_SYSTEM_THREAD(21, scs, ShellEventHandler); + /* DevServer/TioServer. */ AMS_DEFINE_SYSTEM_THREAD(21, TioServer, Main); AMS_DEFINE_SYSTEM_THREAD(21, TioServer, FileServerHtcsServer); diff --git a/libraries/libstratosphere/include/stratosphere/cs.hpp b/libraries/libstratosphere/include/stratosphere/cs.hpp new file mode 100644 index 000000000..9e2c0cbee --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/cs.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include +#include +#include +#include + +#include diff --git a/libraries/libstratosphere/include/stratosphere/cs/cs_audio_server.hpp b/libraries/libstratosphere/include/stratosphere/cs/cs_audio_server.hpp new file mode 100644 index 000000000..ccb5088d4 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/cs/cs_audio_server.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::cs { + + void InitializeAudioServer(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/cs/cs_command_processor.hpp b/libraries/libstratosphere/include/stratosphere/cs/cs_command_processor.hpp new file mode 100644 index 000000000..22912c523 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/cs/cs_command_processor.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::cs { + + using CommandHeader = scs::CommandHeader; + using ResponseHeader = scs::ResponseHeader; + + class CommandProcessor : public scs::CommandProcessor { + public: + virtual bool ProcessCommand(const CommandHeader &header, const u8 *body, s32 socket) override; + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/cs/cs_hid_server.hpp b/libraries/libstratosphere/include/stratosphere/cs/cs_hid_server.hpp new file mode 100644 index 000000000..4d2c95070 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/cs/cs_hid_server.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::cs { + + void InitializeHidServer(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/cs/cs_remote_video_server.hpp b/libraries/libstratosphere/include/stratosphere/cs/cs_remote_video_server.hpp new file mode 100644 index 000000000..a38ce23de --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/cs/cs_remote_video_server.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::cs { + + void InitializeRemoteVideoServer(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/cs/cs_target_io_server.hpp b/libraries/libstratosphere/include/stratosphere/cs/cs_target_io_server.hpp new file mode 100644 index 000000000..a163b661c --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/cs/cs_target_io_server.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::cs { + + void InitializeTargetIoServer(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/htc.hpp b/libraries/libstratosphere/include/stratosphere/htc.hpp index 748ba3f6b..6a77b25f0 100644 --- a/libraries/libstratosphere/include/stratosphere/htc.hpp +++ b/libraries/libstratosphere/include/stratosphere/htc.hpp @@ -17,3 +17,7 @@ #include #include + +#include +#include +#include diff --git a/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv.hpp b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv.hpp new file mode 100644 index 000000000..24825d2c5 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::htc::tenv { + + void Initialize(AllocateFunction allocate, DeallocateFunction deallocate); + Result RegisterDefinitionFilePath(os::ProcessId process_id, const char *path, size_t size); + void UnregisterDefinitionFilePath(os::ProcessId process_id); + +} diff --git a/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_i_service.hpp b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_i_service.hpp new file mode 100644 index 000000000..dcf1742ee --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_i_service.hpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +#define AMS_HTC_TENV_I_SERVICE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, GetVariable, (sf::Out out_size, const sf::OutBuffer &out_buffer, const htc::tenv::VariableName &name), (out_size, out_buffer, name)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetVariableLength, (sf::Out out_size,const htc::tenv::VariableName &name), (out_size, name)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, WaitUntilVariableAvailable, (s64 timeout_ms), (timeout_ms)) + +AMS_SF_DEFINE_INTERFACE(ams::htc::tenv, IService, AMS_HTC_TENV_I_SERVICE_INTERFACE_INFO) diff --git a/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_i_service_manager.hpp b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_i_service_manager.hpp new file mode 100644 index 000000000..f0a11accf --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_i_service_manager.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include + +#define AMS_HTC_TENV_I_SERVICE_MANAGER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, GetServiceInterface, (sf::Out> out, const sf::ClientProcessId &process_id), (out, process_id)) + +AMS_SF_DEFINE_INTERFACE(ams::htc::tenv, IServiceManager, AMS_HTC_TENV_I_SERVICE_MANAGER_INTERFACE_INFO) diff --git a/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_service_manager.hpp b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_service_manager.hpp new file mode 100644 index 000000000..ecfae7ea9 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_service_manager.hpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::htc::tenv { + + constexpr inline sm::ServiceName ServiceName = sm::ServiceName::Encode("htc:tenv"); + + class ServiceManager { + public: + Result GetServiceInterface(sf::Out> out, const sf::ClientProcessId &process_id); + }; + static_assert(htc::tenv::IsIServiceManager); + +} diff --git a/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_types.hpp b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_types.hpp new file mode 100644 index 000000000..fbfcaaa33 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htc/tenv/htc_tenv_types.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::htc::tenv { + + struct VariableName { + char str[0x40]; + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/scs.hpp b/libraries/libstratosphere/include/stratosphere/scs.hpp new file mode 100644 index 000000000..e3a7902fd --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/scs.hpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include +#include + +#include +#include + +#include diff --git a/libraries/libstratosphere/include/stratosphere/scs/scs_command_processor.hpp b/libraries/libstratosphere/include/stratosphere/scs/scs_command_processor.hpp new file mode 100644 index 000000000..adfe97b39 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/scs/scs_command_processor.hpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::scs { + + struct CommandHeader { + u64 id; + u32 command; + u32 body_size; + }; + + struct ResponseHeader { + u64 id; + u32 response; + u32 body_size; + }; + + class CommandProcessor { + protected: + enum Command { + Command_None = 0, + Command_LaunchProgramFromHost = 1, + Command_TerminateProcesses = 2, + Command_GetFirmwareVersion = 3, + Command_Reboot = 4, + Command_SetSafeMode = 5, + Command_RegisterTenvDefinitionFilePath = 6, + Command_TerminateApplication = 7, + Command_Shutdown = 8, + Command_SubscribeProcessEvent = 9, + Command_GetTitleName = 10, + Command_ControlVirtualTemperature = 11, + Command_LaunchInstalledApplication = 12, + Command_LaunchGameCardApplication = 13, + Command_LaunchInstalledSystemProcess = 14, + Command_TakeScreenShot = 15, + Command_TakeForegroundScreenShot = 16, + Command_SimulateGameCardDetection = 17, + Command_SimulateSdCardDetection = 18, + Command_DumpRunningApplication = 19, + }; + + enum Response { + Response_None = 0, + Response_Success = 1, + Response_Error = 2, + /* ... */ + }; + public: + constexpr CommandProcessor() = default; + + void Initialize(); + public: + virtual bool ProcessCommand(const CommandHeader &header, const u8 *body, s32 socket); + protected: + static void SendSuccess(s32 socket, const CommandHeader &header); + static void SendErrorResult(s32 socket, const CommandHeader &header, Result result); + private: + static void SendErrorResult(s32 socket, u64 id, Result result); + + static void OnProcessStart(u64 id, s32 socket, os::ProcessId process_id); + static void OnProcessExit(u64 id, s32 socket, os::ProcessId process_id); + static void OnProcessJitDebug(u64 id, s32 socket, os::ProcessId process_id); + }; + + os::SdkMutex &GetHtcsSendMutex(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/scs/scs_server_manager.hpp b/libraries/libstratosphere/include/stratosphere/scs/scs_server_manager.hpp new file mode 100644 index 000000000..b86865c31 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/scs/scs_server_manager.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::scs { + + enum Port { + Port_HtcTenv, + Port_Count, + }; + + constexpr inline int SessionCount[Port_Count] = { + 6, + }; + + constexpr inline auto MaxSessions = [] { + auto total = 0; + for (const auto sessions : SessionCount) { + total += sessions; + } + return total; + }(); + + struct ServerOptions { + static constexpr size_t PointerBufferSize = 0; + static constexpr size_t MaxDomains = 6; + static constexpr size_t MaxDomainObjects = 16; + }; + + class ServerManager final : public sf::hipc::ServerManager { + /* ... */ + }; + + ServerManager *GetServerManager(); + void StartServer(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/scs/scs_shell.hpp b/libraries/libstratosphere/include/stratosphere/scs/scs_shell.hpp new file mode 100644 index 000000000..9ba1caf22 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/scs/scs_shell.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::scs { + + using ProcessEventHandler = void(*)(u64 id, s32 socket, os::ProcessId process_id); + + void InitializeShell(); + + void RegisterCommonProcessEventHandler(ProcessEventHandler on_start, ProcessEventHandler on_exit, ProcessEventHandler on_jit_debug); + + bool RegisterSocket(s32 socket); + void UnregisterSocket(s32 socket); + + Result LaunchProgram(os::ProcessId *out, ncm::ProgramId program_id, const void *args, size_t args_size, u32 process_flags); + + Result SubscribeProcessEvent(s32 socket, bool is_register, u64 id); + +} diff --git a/libraries/libstratosphere/include/stratosphere/scs/scs_shell_server.hpp b/libraries/libstratosphere/include/stratosphere/scs/scs_shell_server.hpp new file mode 100644 index 000000000..2cba7808e --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/scs/scs_shell_server.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include + +namespace ams::scs { + + class ShellServer { + private: + htcs::HtcsPortName m_port_name; + os::ThreadType m_thread; + u8 m_buffer[64_KB]; + CommandProcessor *m_command_processor; + private: + static void ThreadEntry(void *arg) { reinterpret_cast(arg)->DoShellServer(); } + + void DoShellServer(); + public: + constexpr ShellServer() = default; + public: + void Initialize(const char *port_name, void *stack, size_t stack_size, CommandProcessor *command_processor); + void Start(); + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/scs/scs_tenv.hpp b/libraries/libstratosphere/include/stratosphere/scs/scs_tenv.hpp new file mode 100644 index 000000000..8a06ceb3e --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/scs/scs_tenv.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::scs { + + void InitializeTenvServiceManager(); + +} diff --git a/libraries/libstratosphere/source/boot2/boot2_api.cpp b/libraries/libstratosphere/source/boot2/boot2_api.cpp index 6e2879b86..5c5c16ed7 100644 --- a/libraries/libstratosphere/source/boot2/boot2_api.cpp +++ b/libraries/libstratosphere/source/boot2/boot2_api.cpp @@ -397,6 +397,7 @@ namespace ams::boot2 { /* Device whether to launch tma or htc. */ if (svc::IsKernelMesosphere() && IsHtcEnabled()) { LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Htc, ncm::StorageId::None), 0); + LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Cs, ncm::StorageId::None), 0); } else { LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Tma, ncm::StorageId::BuiltInSystem), 0); } diff --git a/libraries/libstratosphere/source/cs/cs_audio_server.cpp b/libraries/libstratosphere/source/cs/cs_audio_server.cpp new file mode 100644 index 000000000..bd716364e --- /dev/null +++ b/libraries/libstratosphere/source/cs/cs_audio_server.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::cs { + + void InitializeAudioServer() { + /* TODO: Support audio server. */ + } + +} diff --git a/libraries/libstratosphere/source/cs/cs_command_processor.cpp b/libraries/libstratosphere/source/cs/cs_command_processor.cpp new file mode 100644 index 000000000..2fd4e9e6d --- /dev/null +++ b/libraries/libstratosphere/source/cs/cs_command_processor.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::cs { + + bool CommandProcessor::ProcessCommand(const CommandHeader &header, const u8 *body, s32 socket) { + switch (header.command) { + /* TODO: Command support. */ + default: + scs::CommandProcessor::ProcessCommand(header, body, socket); + break; + } + + return true; + } + +} diff --git a/libraries/libstratosphere/source/cs/cs_hid_server.cpp b/libraries/libstratosphere/source/cs/cs_hid_server.cpp new file mode 100644 index 000000000..2aabab5df --- /dev/null +++ b/libraries/libstratosphere/source/cs/cs_hid_server.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::cs { + + void InitializeHidServer() { + /* TODO: Support hid redirection server. */ + } + +} diff --git a/libraries/libstratosphere/source/cs/cs_remote_video_server.cpp b/libraries/libstratosphere/source/cs/cs_remote_video_server.cpp new file mode 100644 index 000000000..f00454fa0 --- /dev/null +++ b/libraries/libstratosphere/source/cs/cs_remote_video_server.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::cs { + + void InitializeRemoteVideoServer() { + /* TODO: Support remote video server. */ + } + +} diff --git a/libraries/libstratosphere/source/cs/cs_target_io_server.cpp b/libraries/libstratosphere/source/cs/cs_target_io_server.cpp new file mode 100644 index 000000000..284b8fb04 --- /dev/null +++ b/libraries/libstratosphere/source/cs/cs_target_io_server.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::cs { + + void InitializeTargetIoServer() { + /* Launch target io server. */ + os::ProcessId process_id; + scs::LaunchProgram(std::addressof(process_id), ncm::SystemProgramId::DevServer, nullptr, 0, 0); + } + +} diff --git a/libraries/libstratosphere/source/htc/tenv/htc_tenv.cpp b/libraries/libstratosphere/source/htc/tenv/htc_tenv.cpp new file mode 100644 index 000000000..4e31262a3 --- /dev/null +++ b/libraries/libstratosphere/source/htc/tenv/htc_tenv.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "impl/htc_tenv_allocator.hpp" + +namespace ams::htc::tenv { + + void Initialize(AllocateFunction allocate, DeallocateFunction deallocate) { + /* Initialize the library allocator. */ + impl::InitializeAllocator(allocate, deallocate); + } + +} diff --git a/libraries/libstratosphere/source/htc/tenv/htc_tenv_service.cpp b/libraries/libstratosphere/source/htc/tenv/htc_tenv_service.cpp new file mode 100644 index 000000000..ad316748e --- /dev/null +++ b/libraries/libstratosphere/source/htc/tenv/htc_tenv_service.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "htc_tenv_service.hpp" + +namespace ams::htc::tenv { + + Result Service::GetVariable(sf::Out out_size, const sf::OutBuffer &out_buffer, const htc::tenv::VariableName &name) { + /* TODO */ + AMS_ABORT("Service::GetVariable"); + } + + Result Service::GetVariableLength(sf::Out out_size,const htc::tenv::VariableName &name) { + /* TODO */ + AMS_ABORT("Service::GetVariableLength"); + } + + Result Service::WaitUntilVariableAvailable(s64 timeout_ms) { + /* TODO */ + AMS_ABORT("Service::WaitUntilVariableAvailable"); + } + +} diff --git a/libraries/libstratosphere/source/htc/tenv/htc_tenv_service.hpp b/libraries/libstratosphere/source/htc/tenv/htc_tenv_service.hpp new file mode 100644 index 000000000..9ce3230bb --- /dev/null +++ b/libraries/libstratosphere/source/htc/tenv/htc_tenv_service.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::htc::tenv { + + class Service { + private: + os::ProcessId m_process_id; + public: + constexpr Service(os::ProcessId pid) : m_process_id(pid) { /* ... */ } + public: + Result GetVariable(sf::Out out_size, const sf::OutBuffer &out_buffer, const htc::tenv::VariableName &name); + Result GetVariableLength(sf::Out out_size,const htc::tenv::VariableName &name); + Result WaitUntilVariableAvailable(s64 timeout_ms); + }; + static_assert(htc::tenv::IsIService); + +} diff --git a/libraries/libstratosphere/source/htc/tenv/htc_tenv_service_manager.cpp b/libraries/libstratosphere/source/htc/tenv/htc_tenv_service_manager.cpp new file mode 100644 index 000000000..1a954712f --- /dev/null +++ b/libraries/libstratosphere/source/htc/tenv/htc_tenv_service_manager.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "impl/htc_tenv_allocator.hpp" +#include "htc_tenv_service.hpp" + +namespace ams::htc::tenv { + + Result ServiceManager::GetServiceInterface(sf::Out> out, const sf::ClientProcessId &process_id) { + *out = impl::SfObjectFactory::CreateSharedEmplaced(process_id.GetValue()); + return ResultSuccess(); + } + +} diff --git a/libraries/libstratosphere/source/htc/tenv/impl/htc_tenv_allocator.cpp b/libraries/libstratosphere/source/htc/tenv/impl/htc_tenv_allocator.cpp new file mode 100644 index 000000000..93c2cc86b --- /dev/null +++ b/libraries/libstratosphere/source/htc/tenv/impl/htc_tenv_allocator.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "htc_tenv_allocator.hpp" + +namespace ams::htc::tenv::impl { + + namespace { + + constinit AllocateFunction g_allocate = nullptr; + constinit DeallocateFunction g_deallocate = nullptr; + + } + + void InitializeAllocator(AllocateFunction allocate, DeallocateFunction deallocate) { + /* Check that we don't already have allocator functions. */ + AMS_ASSERT(g_allocate == nullptr); + AMS_ASSERT(g_deallocate == nullptr); + + /* Set our allocator functions. */ + g_allocate = allocate; + g_deallocate = deallocate; + + /* Check that we have allocator functions. */ + AMS_ASSERT(g_allocate != nullptr); + AMS_ASSERT(g_deallocate != nullptr); + } + + void *Allocate(size_t size) { + /* Check that we have an allocator. */ + AMS_ASSERT(g_allocate != nullptr); + + return g_allocate(size); + } + + void Deallocate(void *p, size_t size) { + /* Check that we have a deallocator. */ + AMS_ASSERT(g_deallocate != nullptr); + + return g_deallocate(p, size); + } + +} diff --git a/libraries/libstratosphere/source/htc/tenv/impl/htc_tenv_allocator.hpp b/libraries/libstratosphere/source/htc/tenv/impl/htc_tenv_allocator.hpp new file mode 100644 index 000000000..f48f2056a --- /dev/null +++ b/libraries/libstratosphere/source/htc/tenv/impl/htc_tenv_allocator.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::htc::tenv::impl { + + void InitializeAllocator(AllocateFunction allocate, DeallocateFunction deallocate); + + void *Allocate(size_t size); + void Deallocate(void *p, size_t size); + + class SfAllocator { + public: + constexpr ALWAYS_INLINE SfAllocator() { /* ... */ } + + void *Allocate(size_t size) { + return ::ams::htc::tenv::impl::Allocate(size); + } + + void Deallocate(void *p, size_t size) { + return ::ams::htc::tenv::impl::Deallocate(p, size); + } + }; + + using SfPolicy = sf::StatelessAllocationPolicy; + using SfObjectFactory = sf::ObjectFactory; + +} diff --git a/libraries/libstratosphere/source/htcs/client/htcs_session.cpp b/libraries/libstratosphere/source/htcs/client/htcs_session.cpp index 37fc6d749..c41276bb0 100644 --- a/libraries/libstratosphere/source/htcs/client/htcs_session.cpp +++ b/libraries/libstratosphere/source/htcs/client/htcs_session.cpp @@ -150,13 +150,13 @@ namespace ams::htcs::client { } Result RemoteSocket::Connect(sf::Out out_err, sf::Out out_res, const htcs::SockAddrHtcs &address) { - static_assert(sizeof(htcs::SockAddrHtcs) == sizeof(::SockAddrHtcs)); - return ::htcsSocketConnect(std::addressof(m_s), out_err.GetPointer(), out_res.GetPointer(), reinterpret_cast(std::addressof(address))); + static_assert(sizeof(htcs::SockAddrHtcs) == sizeof(::HtcsSockAddr)); + return ::htcsSocketConnect(std::addressof(m_s), out_err.GetPointer(), out_res.GetPointer(), reinterpret_cast(std::addressof(address))); } Result RemoteSocket::Bind(sf::Out out_err, sf::Out out_res, const htcs::SockAddrHtcs &address) { - static_assert(sizeof(htcs::SockAddrHtcs) == sizeof(::SockAddrHtcs)); - return ::htcsSocketBind(std::addressof(m_s), out_err.GetPointer(), out_res.GetPointer(), reinterpret_cast(std::addressof(address))); + static_assert(sizeof(htcs::SockAddrHtcs) == sizeof(::HtcsSockAddr)); + return ::htcsSocketBind(std::addressof(m_s), out_err.GetPointer(), out_res.GetPointer(), reinterpret_cast(std::addressof(address))); } Result RemoteSocket::Listen(sf::Out out_err, sf::Out out_res, s32 backlog_count) { @@ -176,9 +176,9 @@ namespace ams::htcs::client { } Result RemoteSocket::AcceptResults(sf::Out out_err, sf::Out> out, sf::Out out_address, u32 task_id) { - static_assert(sizeof(htcs::SockAddrHtcs) == sizeof(::SockAddrHtcs)); + static_assert(sizeof(htcs::SockAddrHtcs) == sizeof(::HtcsSockAddr)); ::HtcsSocket libnx_socket; - R_TRY(::htcsSocketAcceptResults(std::addressof(m_s), out_err.GetPointer(), std::addressof(libnx_socket), reinterpret_cast<::SockAddrHtcs *>(out_address.GetPointer()), task_id)); + R_TRY(::htcsSocketAcceptResults(std::addressof(m_s), out_err.GetPointer(), std::addressof(libnx_socket), reinterpret_cast<::HtcsSockAddr *>(out_address.GetPointer()), task_id)); R_SUCCEED_IF(*out_err != 0); diff --git a/libraries/libstratosphere/source/scs/scs_command_processor.cpp b/libraries/libstratosphere/source/scs/scs_command_processor.cpp new file mode 100644 index 000000000..b3da75937 --- /dev/null +++ b/libraries/libstratosphere/source/scs/scs_command_processor.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::scs { + + namespace { + + struct ResponseError { + ResponseHeader header; + u32 result; + }; + + constinit os::SdkMutex g_htcs_send_mutex; + + } + + os::SdkMutex &GetHtcsSendMutex() { + return g_htcs_send_mutex; + } + + void CommandProcessor::SendSuccess(s32 socket, const CommandHeader &header) { + /* Build the response. */ + const ResponseHeader response = { + .id = header.id, + .response = Response_Success, + .body_size = 0, + }; + + /* Send the response. */ + std::scoped_lock lk(GetHtcsSendMutex()); + htcs::Send(socket, std::addressof(response), sizeof(response), 0); + } + + void CommandProcessor::SendErrorResult(s32 socket, const CommandHeader &header, Result result) { + return SendErrorResult(socket, header.id, result); + } + + void CommandProcessor::SendErrorResult(s32 socket, u64 id, Result result) { + /* Build the response. */ + const ResponseError response = { + .header = { + .id = id, + .response = Response_Error, + .body_size = sizeof(response) - sizeof(response.header), + }, + .result = result.GetValue(), + }; + + /* Send the response. */ + std::scoped_lock lk(GetHtcsSendMutex()); + htcs::Send(socket, std::addressof(response), sizeof(response), 0); + } + + void CommandProcessor::OnProcessStart(u64 id, s32 socket, os::ProcessId process_id) { + /* TODO */ + AMS_ABORT("CommandProcessor::OnProcessStart"); + } + + void CommandProcessor::OnProcessExit(u64 id, s32 socket, os::ProcessId process_id) { + /* TODO */ + AMS_ABORT("CommandProcessor::OnProcessExit"); + } + + void CommandProcessor::OnProcessJitDebug(u64 id, s32 socket, os::ProcessId process_id) { + /* TODO */ + AMS_ABORT("CommandProcessor::OnProcessJitDebug"); + } + + void CommandProcessor::Initialize() { + /* Register our process event handlers. */ + scs::RegisterCommonProcessEventHandler(OnProcessStart, OnProcessExit, OnProcessJitDebug); + } + + bool CommandProcessor::ProcessCommand(const CommandHeader &header, const u8 *body, s32 socket) { + switch (header.command) { + /* TODO: Support commands. */ + default: + SendErrorResult(socket, header, scs::ResultUnknownCommand()); + break; + } + + return true; + } + +} diff --git a/libraries/libstratosphere/source/scs/scs_server_manager.cpp b/libraries/libstratosphere/source/scs/scs_server_manager.cpp new file mode 100644 index 000000000..0a9fd2d94 --- /dev/null +++ b/libraries/libstratosphere/source/scs/scs_server_manager.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::scs { + + namespace { + + ServerManager g_server_manager; + + } + + ServerManager *GetServerManager() { + return std::addressof(g_server_manager); + } + + void StartServer() { + /* Start the server. */ + g_server_manager.ResumeProcessing(); + + /* Loop processing the server. */ + g_server_manager.LoopProcess(); + } + +} diff --git a/libraries/libstratosphere/source/scs/scs_shell.cpp b/libraries/libstratosphere/source/scs/scs_shell.cpp new file mode 100644 index 000000000..0f511064f --- /dev/null +++ b/libraries/libstratosphere/source/scs/scs_shell.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::scs { + + namespace { + + struct SocketInfo { + u64 id; + s32 socket; + }; + + struct ProgramInfo { + os::ProcessId process_id; + u64 id; + s32 socket; + s32 info_id; + bool _18; + bool _19; + bool _1A; + }; + + constexpr inline auto MaxSocketInfo = 2; + constexpr inline auto MaxProgramInfo = 64; + + class SocketInfoManager { + private: + SocketInfo m_infos[MaxProgramInfo]; + int m_count; + public: + constexpr SocketInfoManager() = default; + + void Initialize() { + /* Clear our count. */ + m_count = 0; + } + }; + + class ProgramInfoManager { + private: + s32 m_next_info_id; + ProgramInfo m_infos[MaxProgramInfo]; + int m_count; + public: + constexpr ProgramInfoManager() = default; + + void Initialize() { + /* Reset our next id. */ + m_next_info_id = 1; + + /* Clear our count. */ + m_count = 0; + } + }; + + alignas(os::ThreadStackAlignment) constinit u8 g_thread_stack[os::MemoryPageSize]; + constinit os::ThreadType g_thread; + + constinit ProcessEventHandler g_common_start_handler; + constinit ProcessEventHandler g_common_exit_handler; + constinit ProcessEventHandler g_common_jit_debug_handler; + + constinit SocketInfoManager g_socket_info_manager; + constinit ProgramInfoManager g_program_info_manager; + + void EventHandlerThread(void *) { + /* TODO */ + AMS_ABORT("scs::EventHandlerThread"); + } + + void StartEventHandlerThread() { + /* Create the handler thread. */ + R_ABORT_UNLESS(os::CreateThread(std::addressof(g_thread), EventHandlerThread, nullptr, g_thread_stack, sizeof(g_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(scs, ShellEventHandler))); + + /* Set the handler thread's name. */ + os::SetThreadNamePointer(std::addressof(g_thread), AMS_GET_SYSTEM_THREAD_NAME(scs, ShellEventHandler)); + + /* Start the handler thread. */ + os::StartThread(std::addressof(g_thread)); + } + + Result PrepareToLaunchProgram(ncm::ProgramId program_id, const void *args, size_t args_size) { + /* Set the arguments. */ + R_TRY_CATCH(ldr::SetProgramArgument(program_id, args, args_size)) { + R_CATCH(ldr::ResultTooManyArguments) { + /* There are too many arguments already registered. Flush the arguments queue. */ + R_TRY(ldr::FlushArguments()); + + /* Try again. */ + R_TRY(ldr::SetProgramArgument(program_id, args, args_size)); + } + } R_END_TRY_CATCH; + + return ResultSuccess(); + } + + void FlushProgramArgument(ncm::ProgramId program_id) { + /* Ensure there are no arguments for the program. */ + ldr::SetProgramArgument(program_id, "", 1); + } + + } + + void InitializeShell() { + /* Initialize our managers. */ + g_socket_info_manager.Initialize(); + g_program_info_manager.Initialize(); + + /* Start our event handler. */ + StartEventHandlerThread(); + } + + void RegisterCommonProcessEventHandler(ProcessEventHandler on_start, ProcessEventHandler on_exit, ProcessEventHandler on_jit_debug) { + g_common_start_handler = on_start; + g_common_exit_handler = on_exit; + g_common_jit_debug_handler = on_jit_debug; + } + + bool RegisterSocket(s32 socket); + void UnregisterSocket(s32 socket); + + Result LaunchProgram(os::ProcessId *out, ncm::ProgramId program_id, const void *args, size_t args_size, u32 process_flags) { + /* Set up the arguments. */ + PrepareToLaunchProgram(program_id, args, args_size); + + /* Ensure arguments are managed correctly. */ + ON_SCOPE_EXIT { FlushProgramArgument(program_id); }; + + /* Launch the program. */ + const ncm::ProgramLocation loc = ncm::ProgramLocation::Make(program_id, ncm::StorageId::BuiltInSystem); + R_TRY(pgl::LaunchProgram(out, loc, process_flags | pm::LaunchFlags_SignalOnExit, 0)); + + return ResultSuccess(); + } + + Result SubscribeProcessEvent(s32 socket, bool is_register, u64 id); + +} diff --git a/libraries/libstratosphere/source/scs/scs_shell_server.cpp b/libraries/libstratosphere/source/scs/scs_shell_server.cpp new file mode 100644 index 000000000..286fa31d9 --- /dev/null +++ b/libraries/libstratosphere/source/scs/scs_shell_server.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::scs { + + void ShellServer::Initialize(const char *port_name, void *stack, size_t stack_size, CommandProcessor *command_processor) { + /* Set our variables. */ + m_command_processor = command_processor; + std::strcpy(m_port_name.name, port_name); + + /* Create our thread. */ + R_ABORT_UNLESS(os::CreateThread(std::addressof(m_thread), ThreadEntry, this, stack, stack_size, AMS_GET_SYSTEM_THREAD_PRIORITY(scs, ShellServer))); + + /* Set our thread's name. */ + os::SetThreadNamePointer(std::addressof(m_thread), AMS_GET_SYSTEM_THREAD_NAME(scs, ShellServer)); + } + + void ShellServer::Start() { + os::StartThread(std::addressof(m_thread)); + } + + void ShellServer::DoShellServer() { + /* TODO */ + AMS_ABORT("ShellServer::DoShellServer"); + } + +} diff --git a/libraries/libstratosphere/source/scs/scs_tenv.cpp b/libraries/libstratosphere/source/scs/scs_tenv.cpp new file mode 100644 index 000000000..7569517d8 --- /dev/null +++ b/libraries/libstratosphere/source/scs/scs_tenv.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::scs { + + namespace { + + alignas(os::MemoryPageSize) constinit u8 g_tenv_heap_storage[48_KB]; + constinit lmem::HeapHandle g_tenv_heap_handle = nullptr; + constinit os::SdkMutex g_mutex; + + void InitializeExpHeap() { + std::scoped_lock lk(g_mutex); + g_tenv_heap_handle = lmem::CreateExpHeap(g_tenv_heap_storage, sizeof(g_tenv_heap_storage), lmem::CreateOption_None); + } + + void *Allocate(size_t size) { + std::scoped_lock lk(g_mutex); + void *mem = lmem::AllocateFromExpHeap(g_tenv_heap_handle, size); + return mem; + } + + void Deallocate(void *p, size_t size) { + std::scoped_lock lk(g_mutex); + lmem::FreeToExpHeap(g_tenv_heap_handle, p); + } + + } + + void InitializeTenvServiceManager() { + /* Initialize the tenv heap. */ + InitializeExpHeap(); + + /* Initialize the tenv library. */ + htc::tenv::Initialize(Allocate, Deallocate); + } + +} diff --git a/libraries/libvapours/include/vapours/results.hpp b/libraries/libvapours/include/vapours/results.hpp index ad89ea157..7786f7f23 100644 --- a/libraries/libvapours/include/vapours/results.hpp +++ b/libraries/libvapours/include/vapours/results.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libvapours/include/vapours/results/cs_results.hpp b/libraries/libvapours/include/vapours/results/cs_results.hpp new file mode 100644 index 000000000..0c1a67ab4 --- /dev/null +++ b/libraries/libvapours/include/vapours/results/cs_results.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +namespace ams::cs { + + R_DEFINE_NAMESPACE_RESULT_MODULE(204); + + R_DEFINE_ERROR_RESULT(UnknownCommand, 2); + R_DEFINE_ERROR_RESULT(OutOfResource, 4); + R_DEFINE_ERROR_RESULT(NoSocket, 7); + +} diff --git a/libraries/libvapours/include/vapours/results/scs_results.hpp b/libraries/libvapours/include/vapours/results/scs_results.hpp new file mode 100644 index 000000000..8981847a8 --- /dev/null +++ b/libraries/libvapours/include/vapours/results/scs_results.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +namespace ams::scs { + + R_DEFINE_NAMESPACE_RESULT_MODULE(204); + + R_DEFINE_ERROR_RESULT(UnknownCommand, 2); + R_DEFINE_ERROR_RESULT(OutOfResource, 4); + R_DEFINE_ERROR_RESULT(NoSocket, 7); + +} diff --git a/stratosphere/cs/Makefile b/stratosphere/cs/Makefile new file mode 100644 index 000000000..aab86a63a --- /dev/null +++ b/stratosphere/cs/Makefile @@ -0,0 +1,113 @@ +#--------------------------------------------------------------------------------- +# pull in common stratosphere sysmodule configuration +#--------------------------------------------------------------------------------- +include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) +CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) +SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) + +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC) + +ifeq ($(strip $(CONFIG_JSON)),) + jsons := $(wildcard *.json) + ifneq (,$(findstring $(TARGET).json,$(jsons))) + export APP_JSON := $(TOPDIR)/$(TARGET).json + else + ifneq (,$(findstring config.json,$(jsons))) + export APP_JSON := $(TOPDIR)/config.json + endif + endif +else + export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) +endif + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).nsp $(TARGET).npdm $(TARGET).nso $(TARGET).elf + + +#--------------------------------------------------------------------------------- +else +.PHONY: all + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +all : $(OUTPUT).nsp + +ifeq ($(strip $(APP_JSON)),) +$(OUTPUT).nsp : $(OUTPUT).nso +else +$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm +endif + +$(OUTPUT).nso : $(OUTPUT).elf + +$(OUTPUT).elf : $(OFILES) + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/stratosphere/cs/cs.json b/stratosphere/cs/cs.json new file mode 100644 index 000000000..4cd06eb68 --- /dev/null +++ b/stratosphere/cs/cs.json @@ -0,0 +1,89 @@ +{ + "name": "cs", + "title_id": "0x0100000000000017", + "title_id_range_min": "0x0100000000000017", + "title_id_range_max": "0x0100000000000017", + "main_thread_stack_size": "0x00004000", + "main_thread_priority": 48, + "default_cpu_id": 3, + "process_category": 0, + "is_retail": false, + "pool_partition": 2, + "is_64_bit": true, + "address_space_type": 3, + "disable_device_address_space_merge": true, + "filesystem_access": { + "permissions": "0xFFFFFFFFFFFFFFFF" + }, + "service_access": ["appletAE", "lr", "ldr:shel", "pgl", "ns:am2", "ns:dev", "htcs", "hid", "hid:dbg", "hid:sys", "set", "set:sys", "lr", "ldr:shel", "ncm", "arp:r", "fsp-srv", "bpc", "tc", "fatal:u", "caps:sc", "audrec:u", "auddev", "grc:d"], + "service_host": ["htc:tenv"], + "kernel_capabilities": [{ + "type": "kernel_flags", + "value": { + "highest_thread_priority": 63, + "lowest_thread_priority": 24, + "lowest_cpu_id": 3, + "highest_cpu_id": 3 + } + }, { + "type": "syscalls", + "value": { + "svcSetHeapSize": "0x01", + "svcSetMemoryPermission": "0x02", + "svcSetMemoryAttribute": "0x03", + "svcMapMemory": "0x04", + "svcUnmapMemory": "0x05", + "svcQueryMemory": "0x06", + "svcExitProcess": "0x07", + "svcCreateThread": "0x08", + "svcStartThread": "0x09", + "svcExitThread": "0x0a", + "svcSleepThread": "0x0b", + "svcGetThreadPriority": "0x0c", + "svcSetThreadPriority": "0x0d", + "svcGetThreadCoreMask": "0x0e", + "svcSetThreadCoreMask": "0x0f", + "svcGetCurrentProcessorNumber": "0x10", + "svcSignalEvent": "0x11", + "svcClearEvent": "0x12", + "svcMapSharedMemory": "0x13", + "svcUnmapSharedMemory": "0x14", + "svcCreateTransferMemory": "0x15", + "svcCloseHandle": "0x16", + "svcResetSignal": "0x17", + "svcWaitSynchronization": "0x18", + "svcCancelSynchronization": "0x19", + "svcArbitrateLock": "0x1a", + "svcArbitrateUnlock": "0x1b", + "svcWaitProcessWideKeyAtomic": "0x1c", + "svcSignalProcessWideKey": "0x1d", + "svcGetSystemTick": "0x1e", + "svcConnectToNamedPort": "0x1f", + "svcSendSyncRequestLight": "0x20", + "svcSendSyncRequest": "0x21", + "svcSendSyncRequestWithUserBuffer": "0x22", + "svcSendAsyncRequestWithUserBuffer": "0x23", + "svcGetProcessId": "0x24", + "svcGetThreadId": "0x25", + "svcBreak": "0x26", + "svcOutputDebugString": "0x27", + "svcReturnFromException": "0x28", + "svcGetInfo": "0x29", + "svcWaitForAddress": "0x34", + "svcSignalToAddress": "0x35", + "svcCreateSession": "0x40", + "svcAcceptSession": "0x41", + "svcReplyAndReceiveLight": "0x42", + "svcReplyAndReceive": "0x43", + "svcReplyAndReceiveWithUserBuffer": "0x44", + "svcCreateEvent": "0x45", + "svcCallSecureMonitor": "0x7f" + } + }, { + "type": "min_kernel_version", + "value": "0x0030" + }, { + "type": "handle_table_size", + "value": 0 + }] +} \ No newline at end of file diff --git a/stratosphere/cs/source/cs_main.cpp b/stratosphere/cs/source/cs_main.cpp new file mode 100644 index 000000000..479f82012 --- /dev/null +++ b/stratosphere/cs/source/cs_main.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +extern "C" { + extern u32 __start__; + + u32 __nx_applet_type = AppletType_None; + u32 __nx_fs_num_sessions = 1; + + #define INNER_HEAP_SIZE 0x0 + size_t nx_inner_heap_size = INNER_HEAP_SIZE; + char nx_inner_heap[INNER_HEAP_SIZE]; + + void __libnx_initheap(void); + void __appInit(void); + void __appExit(void); + + void *__libnx_alloc(size_t size); + void *__libnx_aligned_alloc(size_t alignment, size_t size); + void __libnx_free(void *mem); +} + +namespace ams { + + ncm::ProgramId CurrentProgramId = ncm::SystemProgramId::Cs; + +} + +using namespace ams; + +#define AMS_CS_SERVER_USE_FATAL_ERROR 1 + +#if AMS_CS_SERVER_USE_FATAL_ERROR + +extern "C" { + + /* Exception handling. */ + alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize]; + u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); + void __libnx_exception_handler(ThreadExceptionDump *ctx); + +} + +void __libnx_exception_handler(ThreadExceptionDump *ctx) { + ams::CrashHandler(ctx); +} + +#endif + +namespace ams::cs { + + namespace { + + alignas(os::ThreadStackAlignment) constinit u8 g_shell_stack[4_KB]; + alignas(os::ThreadStackAlignment) constinit u8 g_runner_stack[4_KB]; + + alignas(os::MemoryPageSize) constinit u8 g_heap_memory[32_KB]; + + alignas(0x40) constinit u8 g_htcs_buffer[1_KB]; + + constinit os::SdkMutex g_heap_mutex; + constinit lmem::HeapHandle g_heap_handle; + + void *Allocate(size_t size) { + std::scoped_lock lk(g_heap_mutex); + void *mem = lmem::AllocateFromExpHeap(g_heap_handle, size); + return mem; + } + + void Deallocate(void *p, size_t size) { + std::scoped_lock lk(g_heap_mutex); + lmem::FreeToExpHeap(g_heap_handle, p); + } + + void InitializeHeap() { + std::scoped_lock lk(g_heap_mutex); + g_heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_None); + } + + } + +} + +void __libnx_initheap(void) { + void* addr = nx_inner_heap; + size_t size = nx_inner_heap_size; + + /* Newlib */ + extern char* fake_heap_start; + extern char* fake_heap_end; + + fake_heap_start = (char*)addr; + fake_heap_end = (char*)addr + size; + + cs::InitializeHeap(); +} + +void __appInit(void) { + hos::InitializeForStratosphere(); + + fs::SetAllocator(cs::Allocate, cs::Deallocate); + + sm::DoWithSession([&]() { + R_ABORT_UNLESS(fsInitialize()); + lr::Initialize(); + R_ABORT_UNLESS(ldr::InitializeForShell()); + R_ABORT_UNLESS(pgl::Initialize()); + /* TODO: Other services? */ + }); + + ams::CheckApiVersion(); +} + +void __appExit(void) { + /* TODO: Other services? */ + pgl::Finalize(); + ldr::FinalizeForShell(); + lr::Finalize(); + fsExit(); +} + +namespace ams { + + void *Malloc(size_t size) { + AMS_ABORT("ams::Malloc was called"); + } + + void Free(void *ptr) { + AMS_ABORT("ams::Free was called"); + } + +} + +void *operator new(size_t size) { + AMS_ABORT("operator new(size_t) was called"); +} + +void operator delete(void *p) { + AMS_ABORT("operator delete(void *) was called"); +} + +void *__libnx_alloc(size_t size) { + AMS_ABORT("__libnx_alloc was called"); +} + +void *__libnx_aligned_alloc(size_t alignment, size_t size) { + AMS_ABORT("__libnx_aligned_alloc was called"); +} + +void __libnx_free(void *mem) { + AMS_ABORT("__libnx_free was called"); +} + +namespace ams::cs { + + namespace { + + constinit ::ams::cs::CommandProcessor g_command_processor; + + constinit ::ams::scs::ShellServer g_shell_server; + constinit ::ams::scs::ShellServer g_runner_server; + + constinit sf::UnmanagedServiceObject g_tenv_service_manager; + + } + +} + +int main(int argc, char **argv) +{ + using namespace ams::cs; + + /* Set thread name. */ + os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(cs, Main)); + AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(cs, Main)); + + /* Initialize htcs. */ + constexpr auto HtcsSocketCountMax = 6; + const size_t buffer_size = htcs::GetWorkingMemorySize(2 * HtcsSocketCountMax); + AMS_ABORT_UNLESS(sizeof(g_htcs_buffer) >= buffer_size); + htcs::InitializeForSystem(g_htcs_buffer, buffer_size, HtcsSocketCountMax); + + /* Initialize audio server. */ + cs::InitializeAudioServer(); + + /* Initialize remote video server. */ + cs::InitializeRemoteVideoServer(); + + /* Initialize hid server. */ + cs::InitializeHidServer(); + + /* Initialize target io server. */ + cs::InitializeTargetIoServer(); + + /* Initialize command processor. */ + g_command_processor.Initialize(); + + /* Setup scs. */ + scs::InitializeShell(); + + /* Setup target environment service. */ + scs::InitializeTenvServiceManager(); + + /* Initialize the shell servers. */ + g_shell_server.Initialize("iywys@$cs", g_shell_stack, sizeof(g_shell_stack), std::addressof(g_command_processor)); + g_shell_server.Start(); + + g_runner_server.Initialize("iywys@$csForRunnerTools", g_runner_stack, sizeof(g_runner_stack), std::addressof(g_command_processor)); + g_runner_server.Start(); + + /* Register htc:tenv. */ + R_ABORT_UNLESS(scs::GetServerManager()->RegisterObjectForServer(g_tenv_service_manager.GetShared(), htc::tenv::ServiceName, scs::SessionCount[scs::Port_HtcTenv])); + + /* Start the scs ipc server. */ + scs::StartServer(); + + return 0; +}