pgl: Implement main()

This commit is contained in:
Michael Scire 2020-04-16 04:26:59 -07:00
parent c2bf630c40
commit 810b094dc7
4 changed files with 140 additions and 12 deletions

View file

@ -36,7 +36,7 @@ namespace ams::pgl::sf {
EnableApplicationCrashReport = 8, EnableApplicationCrashReport = 8,
IsApplicationCrashReportEnabled = 9, IsApplicationCrashReportEnabled = 9,
EnableApplicationAllThreadDumpOnCrash = 10, EnableApplicationAllThreadDumpOnCrash = 10,
TriggerSnapShotDumper = 12, TriggerApplicationSnapShotDumper = 12,
GetShellEventObserver = 20, GetShellEventObserver = 20,
}; };
public: public:
@ -66,7 +66,7 @@ namespace ams::pgl::sf {
MAKE_SERVICE_COMMAND_META(EnableApplicationCrashReport), MAKE_SERVICE_COMMAND_META(EnableApplicationCrashReport),
MAKE_SERVICE_COMMAND_META(IsApplicationCrashReportEnabled), MAKE_SERVICE_COMMAND_META(IsApplicationCrashReportEnabled),
MAKE_SERVICE_COMMAND_META(EnableApplicationAllThreadDumpOnCrash), MAKE_SERVICE_COMMAND_META(EnableApplicationAllThreadDumpOnCrash),
MAKE_SERVICE_COMMAND_META(TriggerSnapShotDumper), MAKE_SERVICE_COMMAND_META(TriggerApplicationSnapShotDumper),
MAKE_SERVICE_COMMAND_META(GetShellEventObserver), MAKE_SERVICE_COMMAND_META(GetShellEventObserver),
}; };
}; };

View file

@ -16,15 +16,16 @@
#pragma once #pragma once
#include "sf/sf_common.hpp" #include <stratosphere/sf/sf_common.hpp>
#include "sf/sf_mem_utility.hpp" #include <stratosphere/sf/sf_lmem_utility.hpp>
#include "sf/sf_service_object.hpp" #include <stratosphere/sf/sf_mem_utility.hpp>
#include "sf/hipc/sf_hipc_server_session_manager.hpp" #include <stratosphere/sf/sf_service_object.hpp>
#include <stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp>
#include "sf/sf_out.hpp" #include <stratosphere/sf/sf_out.hpp>
#include "sf/sf_buffers.hpp" #include <stratosphere/sf/sf_buffers.hpp>
#include "sf/impl/sf_impl_command_serialization.hpp" #include <stratosphere/sf/impl/sf_impl_command_serialization.hpp>
#include "sf/hipc/sf_hipc_server_manager.hpp" #include <stratosphere/sf/hipc/sf_hipc_server_manager.hpp>
#include "sf/sf_mitm_dispatch.h" #include <stratosphere/sf/sf_mitm_dispatch.h>

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/sf/sf_common.hpp>
#include <stratosphere/lmem.hpp>
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<int>(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<size_t>(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);
}
};
}

View file

@ -53,6 +53,55 @@ void __libnx_exception_handler(ThreadExceptionDump *ctx) {
ams::CrashHandler(ctx); ams::CrashHandler(ctx);
} }
namespace ams::pgl {
namespace {
/* pgl. */
constexpr size_t NumServers = 1;
ams::sf::hipc::ServerManager<NumServers> 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<pgl::srv::ShellInterface> GetSharedPointerToShellInterface() {
return ams::sf::ServiceObjectTraits<pgl::srv::ShellInterface>::SharedPointerHelper::GetEmptyDeleteSharedPointer(std::addressof(g_shell_interface));
}
void RegisterServiceSession() {
R_ABORT_UNLESS(g_server_manager.RegisterServer<pgl::srv::ShellInterface>(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 __libnx_initheap(void) {
void* addr = nx_inner_heap; void* addr = nx_inner_heap;
size_t size = nx_inner_heap_size; size_t size = nx_inner_heap_size;
@ -63,11 +112,15 @@ void __libnx_initheap(void) {
fake_heap_start = (char*)addr; fake_heap_start = (char*)addr;
fake_heap_end = (char*)addr + size; fake_heap_end = (char*)addr + size;
ams::pgl::InitializeHeap();
} }
void __appInit(void) { void __appInit(void) {
hos::SetVersionForLibnx(); hos::SetVersionForLibnx();
fs::SetAllocator(pgl::Allocate, pgl::Deallocate);
sm::DoWithSession([&]() { sm::DoWithSession([&]() {
R_ABORT_UNLESS(setInitialize()); R_ABORT_UNLESS(setInitialize());
R_ABORT_UNLESS(setsysInitialize()); R_ABORT_UNLESS(setsysInitialize());
@ -92,7 +145,14 @@ void __appExit(void) {
int main(int argc, char **argv) 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 */ /* Cleanup */
return 0; return 0;