diff --git a/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp b/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp index a51a54b83..2d49a6e82 100644 --- a/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp +++ b/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp @@ -21,7 +21,7 @@ namespace ams::gpio { namespace { struct GpioRemoteManagerTag; - using RemoteAllocator = ams::sf::ExpHeapStaticAllocator<16_KB, GpioRemoteManagerTag>; + using RemoteAllocator = ams::sf::ExpHeapStaticAllocator<3_KB, GpioRemoteManagerTag>; using RemoteObjectFactory = ams::sf::ObjectFactory; class StaticAllocatorInitializer { diff --git a/stratosphere/pm/source/pm_boot_mode_service.hpp b/stratosphere/pm/source/pm_boot_mode_service.hpp index c7b6fc0b7..cea91999a 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.hpp +++ b/stratosphere/pm/source/pm_boot_mode_service.hpp @@ -18,7 +18,7 @@ namespace ams::pm { - class BootModeService final { + class BootModeService { public: void GetBootMode(sf::Out out); void SetMaintenanceBoot(); diff --git a/stratosphere/pm/source/pm_debug_monitor_service.hpp b/stratosphere/pm/source/pm_debug_monitor_service.hpp index 634e61104..2542bfbbb 100644 --- a/stratosphere/pm/source/pm_debug_monitor_service.hpp +++ b/stratosphere/pm/source/pm_debug_monitor_service.hpp @@ -18,7 +18,7 @@ namespace ams::pm { - class DebugMonitorService final { + class DebugMonitorService { public: /* Actual command implementations. */ Result GetModuleIdList(sf::Out out_count, const sf::OutBuffer &out_buf, u64 unused); diff --git a/stratosphere/pm/source/pm_info_service.hpp b/stratosphere/pm/source/pm_info_service.hpp index c22380f6b..fba26ddf5 100644 --- a/stratosphere/pm/source/pm_info_service.hpp +++ b/stratosphere/pm/source/pm_info_service.hpp @@ -18,7 +18,7 @@ namespace ams::pm { - class InformationService final { + class InformationService { public: /* Actual command implementations. */ Result GetProgramId(sf::Out out, os::ProcessId process_id); diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index dedb3f16f..8f6dc8352 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -26,7 +26,7 @@ extern "C" { u32 __nx_applet_type = AppletType_None; - #define INNER_HEAP_SIZE 0x2000 + #define INNER_HEAP_SIZE 0x0 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; @@ -38,6 +38,9 @@ extern "C" { 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_thread_alloc(size_t size); + void __libnx_thread_free(void *mem); } namespace ams { @@ -159,6 +162,15 @@ void __appExit(void) { namespace { + /* pm:shell, pm:dmnt, pm:bm, pm:info. */ + enum PortIndex { + PortIndex_Shell, + PortIndex_DebugMonitor, + PortIndex_BootMode, + PortIndex_Information, + PortIndex_Count, + }; + using ServerOptions = sf::hipc::DefaultServerManagerOptions; constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("pm:shell"); @@ -175,12 +187,64 @@ namespace { static_assert(InformationMaxSessions >= 16, "InformationMaxSessions"); - /* pm:shell, pm:dmnt, pm:bm, pm:info. */ - constexpr size_t NumServers = 4; constexpr size_t MaxSessions = ShellMaxSessions + DebugMonitorMaxSessions + BootModeMaxSessions + InformationMaxSessions; static_assert(MaxSessions == 48, "MaxSessions"); - sf::hipc::ServerManager g_server_manager; + class ServerManager final : public sf::hipc::ServerManager { + private: + virtual ams::Result OnNeedsToAccept(int port_index, Server *server) override; + }; + + ServerManager g_server_manager; + + /* NOTE: Nintendo only uses an unmanaged object for boot mode service, but no pm service has any class members/state, so we'll do it for all. */ + sf::UnmanagedServiceObject g_shell_service; + sf::UnmanagedServiceObject g_deprecated_shell_service; + + sf::UnmanagedServiceObject g_dmnt_service; + sf::UnmanagedServiceObject g_deprecated_dmnt_service; + + sf::UnmanagedServiceObject g_boot_mode_service; + sf::UnmanagedServiceObject g_information_service; + + ams::Result ServerManager::OnNeedsToAccept(int port_index, Server *server) { + switch (port_index) { + case PortIndex_Shell: + if (hos::GetVersion() >= hos::Version_5_0_0) { + return this->AcceptImpl(server, g_shell_service.GetShared()); + } else { + return this->AcceptImpl(server, g_deprecated_shell_service.GetShared()); + } + case PortIndex_DebugMonitor: + if (hos::GetVersion() >= hos::Version_5_0_0) { + return this->AcceptImpl(server, g_dmnt_service.GetShared()); + } else { + return this->AcceptImpl(server, g_deprecated_dmnt_service.GetShared()); + } + case PortIndex_BootMode: + return this->AcceptImpl(server, g_boot_mode_service.GetShared()); + case PortIndex_Information: + return this->AcceptImpl(server, g_information_service.GetShared()); + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + +} + +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_thread_alloc(size_t size) { + AMS_ABORT("__libnx_thread_alloc was called"); +} + +void __libnx_thread_free(void *mem) { + AMS_ABORT("__libnx_thread_free was called"); } int main(int argc, char **argv) @@ -194,16 +258,10 @@ int main(int argc, char **argv) /* Create Services. */ /* NOTE: Extra sessions have been added to pm:bm and pm:info to facilitate access by the rest of stratosphere. */ - /* Also Note: PM was rewritten in 5.0.0, so the shell and dmnt services are different before/after. */ - if (hos::GetVersion() >= hos::Version_5_0_0) { - R_ABORT_UNLESS((g_server_manager.RegisterServer(ShellServiceName, ShellMaxSessions))); - R_ABORT_UNLESS((g_server_manager.RegisterServer(DebugMonitorServiceName, DebugMonitorMaxSessions))); - } else { - R_ABORT_UNLESS((g_server_manager.RegisterServer(ShellServiceName, ShellMaxSessions))); - R_ABORT_UNLESS((g_server_manager.RegisterServer(DebugMonitorServiceName, DebugMonitorMaxSessions))); - } - R_ABORT_UNLESS((g_server_manager.RegisterServer(BootModeServiceName, BootModeMaxSessions))); - R_ABORT_UNLESS((g_server_manager.RegisterServer(InformationServiceName, InformationMaxSessions))); + R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Shell, ShellServiceName, ShellMaxSessions)); + R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_DebugMonitor, DebugMonitorServiceName, DebugMonitorMaxSessions)); + R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_BootMode, BootModeServiceName, BootModeMaxSessions)); + R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Information, InformationServiceName, InformationMaxSessions)); /* Loop forever, servicing our services. */ g_server_manager.LoopProcess(); diff --git a/stratosphere/pm/source/pm_shell_service.hpp b/stratosphere/pm/source/pm_shell_service.hpp index 8794eedd4..c56993a58 100644 --- a/stratosphere/pm/source/pm_shell_service.hpp +++ b/stratosphere/pm/source/pm_shell_service.hpp @@ -18,7 +18,7 @@ namespace ams::pm { - class ShellService final { + class ShellService { public: /* Actual command implementations. */ Result LaunchProgram(sf::Out out_process_id, const ncm::ProgramLocation &loc, u32 flags);