From 810b094dc785762a42f65ff53a471f9e796828e3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 16 Apr 2020 04:26:59 -0700 Subject: [PATCH] pgl: Implement main() --- .../pgl/sf/pgl_sf_i_shell_interface.hpp | 4 +- .../include/stratosphere/sf.hpp | 19 +++--- .../stratosphere/sf/sf_lmem_utility.hpp | 67 +++++++++++++++++++ stratosphere/pgl/source/pgl_main.cpp | 62 ++++++++++++++++- 4 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/sf/sf_lmem_utility.hpp diff --git a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp index 1d40d1393..c44d72924 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp @@ -36,7 +36,7 @@ namespace ams::pgl::sf { EnableApplicationCrashReport = 8, IsApplicationCrashReportEnabled = 9, EnableApplicationAllThreadDumpOnCrash = 10, - TriggerSnapShotDumper = 12, + TriggerApplicationSnapShotDumper = 12, GetShellEventObserver = 20, }; public: @@ -66,7 +66,7 @@ namespace ams::pgl::sf { MAKE_SERVICE_COMMAND_META(EnableApplicationCrashReport), MAKE_SERVICE_COMMAND_META(IsApplicationCrashReportEnabled), MAKE_SERVICE_COMMAND_META(EnableApplicationAllThreadDumpOnCrash), - MAKE_SERVICE_COMMAND_META(TriggerSnapShotDumper), + MAKE_SERVICE_COMMAND_META(TriggerApplicationSnapShotDumper), MAKE_SERVICE_COMMAND_META(GetShellEventObserver), }; }; diff --git a/libraries/libstratosphere/include/stratosphere/sf.hpp b/libraries/libstratosphere/include/stratosphere/sf.hpp index be8aa5b27..b7bbe4737 100644 --- a/libraries/libstratosphere/include/stratosphere/sf.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf.hpp @@ -16,15 +16,16 @@ #pragma once -#include "sf/sf_common.hpp" -#include "sf/sf_mem_utility.hpp" -#include "sf/sf_service_object.hpp" -#include "sf/hipc/sf_hipc_server_session_manager.hpp" +#include +#include +#include +#include +#include -#include "sf/sf_out.hpp" -#include "sf/sf_buffers.hpp" -#include "sf/impl/sf_impl_command_serialization.hpp" +#include +#include +#include -#include "sf/hipc/sf_hipc_server_manager.hpp" +#include -#include "sf/sf_mitm_dispatch.h" +#include diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_lmem_utility.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_lmem_utility.hpp new file mode 100644 index 000000000..cb06140a6 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_lmem_utility.hpp @@ -0,0 +1,67 @@ +/* + * 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::sf { + + class ExpHeapMemoryResource : public MemoryResource { + private: + lmem::HeapHandle handle; + public: + explicit ExpHeapMemoryResource(lmem::HeapHandle h) : handle(h) { /* ... */ } + + lmem::HeapHandle GetHandle() const { return this->handle; } + private: + virtual void *AllocateImpl(size_t size, size_t alignment) override { + return lmem::AllocateFromExpHeap(this->handle, size, static_cast(alignment)); + } + + virtual void DeallocateImpl(void *buffer, size_t size, size_t alignment) override { + return lmem::FreeToExpHeap(this->handle, buffer); + } + + virtual bool IsEqualImpl(const MemoryResource &resource) const { + return this == std::addressof(resource); + } + }; + + class UnitHeapMemoryResource : public MemoryResource { + private: + lmem::HeapHandle handle; + public: + explicit UnitHeapMemoryResource(lmem::HeapHandle h) : handle(h) { /* ... */ } + + lmem::HeapHandle GetHandle() const { return this->handle; } + private: + virtual void *AllocateImpl(size_t size, size_t alignment) override { + AMS_ASSERT(size <= lmem::GetUnitHeapUnitSize(this->handle)); + AMS_ASSERT(alignment <= static_cast(lmem::GetUnitHeapAlignment(this->handle))); + return lmem::AllocateFromUnitHeap(this->handle); + } + + virtual void DeallocateImpl(void *buffer, size_t size, size_t alignment) override { + return lmem::FreeToUnitHeap(this->handle, buffer); + } + + virtual bool IsEqualImpl(const MemoryResource &resource) const { + return this == std::addressof(resource); + } + }; + +} \ No newline at end of file diff --git a/stratosphere/pgl/source/pgl_main.cpp b/stratosphere/pgl/source/pgl_main.cpp index 05e84bdd8..69b90ed27 100644 --- a/stratosphere/pgl/source/pgl_main.cpp +++ b/stratosphere/pgl/source/pgl_main.cpp @@ -53,6 +53,55 @@ void __libnx_exception_handler(ThreadExceptionDump *ctx) { ams::CrashHandler(ctx); } +namespace ams::pgl { + + namespace { + + /* pgl. */ + constexpr size_t NumServers = 1; + ams::sf::hipc::ServerManager g_server_manager; + + constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("pgl"); + constexpr size_t ShellMaxSessions = 8; /* Official maximum is 8. */ + + /* TODO: C++20 constinit */ pgl::srv::ShellInterface g_shell_interface; + + ALWAYS_INLINE std::shared_ptr GetSharedPointerToShellInterface() { + return ams::sf::ServiceObjectTraits::SharedPointerHelper::GetEmptyDeleteSharedPointer(std::addressof(g_shell_interface)); + } + + void RegisterServiceSession() { + R_ABORT_UNLESS(g_server_manager.RegisterServer(ShellServiceName, ShellMaxSessions, GetSharedPointerToShellInterface())); + } + + void LoopProcess() { + g_server_manager.LoopProcess(); + } + + /* NOTE: Nintendo reserves only 0x2000 bytes for this heap, which is used "mostly" to allocate shell event observers. */ + /* However, we would like very much for homebrew sysmodules to be able to subscribe to events if they so choose */ + /* And so we will use a larger heap (32 KB). */ + /* We should have a smaller memory footprint than N in the end, regardless. */ + u8 g_heap_memory[32_KB]; + TYPED_STORAGE(ams::sf::ExpHeapMemoryResource) g_heap_memory_resource; + + void *Allocate(size_t size) { + return lmem::AllocateFromExpHeap(GetReference(g_heap_memory_resource).GetHandle(), size); + } + + void Deallocate(void *p, size_t size) { + return lmem::FreeToExpHeap(GetReference(g_heap_memory_resource).GetHandle(), p); + } + + void InitializeHeap() { + auto heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_ThreadSafe); + new (GetPointer(g_heap_memory_resource)) ams::sf::ExpHeapMemoryResource(heap_handle); + } + + } + +} + void __libnx_initheap(void) { void* addr = nx_inner_heap; size_t size = nx_inner_heap_size; @@ -63,11 +112,15 @@ void __libnx_initheap(void) { fake_heap_start = (char*)addr; fake_heap_end = (char*)addr + size; + + ams::pgl::InitializeHeap(); } void __appInit(void) { hos::SetVersionForLibnx(); + fs::SetAllocator(pgl::Allocate, pgl::Deallocate); + sm::DoWithSession([&]() { R_ABORT_UNLESS(setInitialize()); R_ABORT_UNLESS(setsysInitialize()); @@ -92,7 +145,14 @@ void __appExit(void) { int main(int argc, char **argv) { - /* TODO */ + /* Register the pgl service. */ + pgl::RegisterServiceSession(); + + /* Initialize the server library. */ + pgl::srv::Initialize(std::addressof(pgl::g_shell_interface), GetPointer(pgl::g_heap_memory_resource)); + + /* Loop forever, servicing our services. */ + pgl::LoopProcess(); /* Cleanup */ return 0;