From 5a52014d1cb07c754fd93683e9f516aa0f3905fc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 16 Apr 2020 22:57:01 -0700 Subject: [PATCH] hos: change initialization API This was needed to make stratosphere buildable with debugging on. os:: assertions rely on GetCurrentThread() working, and this requires the global os resource manager to be constructed. However, __appInit executes before global constructors. We now require that hos::InitializeForStratosphere() be called before anything else is done. This initializes the os resource manager, sets the hos version for libnx, and may do more things in the future. TODO: Consider replacing __appInit/__appExit with ams:: namespace functions in general, and wrap them so that we guarantee hos::InitializeForStratosphere is called first, and generally ensure a consistent stratosphere environment. --- libstratosphere/include/stratosphere/hos.hpp | 5 +-- .../stratosphere/hos/hos_stratosphere_api.hpp | 24 +++++++++++++ .../stratosphere/hos/hos_version_api.hpp | 3 +- .../source/hos/hos_stratosphere_api.cpp | 35 +++++++++++++++++++ .../source/hos/hos_version_api.cpp | 4 +-- .../source/hos/hos_version_api_private.hpp | 23 ++++++++++++ .../source/os/impl/os_resource_manager.cpp | 2 +- .../source/os/impl/os_resource_manager.hpp | 9 +++-- .../source/os/os_stratosphere_api.cpp | 26 ++++++++++++++ 9 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 libstratosphere/include/stratosphere/hos/hos_stratosphere_api.hpp create mode 100644 libstratosphere/source/hos/hos_stratosphere_api.cpp create mode 100644 libstratosphere/source/hos/hos_version_api_private.hpp create mode 100644 libstratosphere/source/os/os_stratosphere_api.cpp diff --git a/libstratosphere/include/stratosphere/hos.hpp b/libstratosphere/include/stratosphere/hos.hpp index 312e7b30..f5e10d8b 100644 --- a/libstratosphere/include/stratosphere/hos.hpp +++ b/libstratosphere/include/stratosphere/hos.hpp @@ -16,5 +16,6 @@ #pragma once -#include "hos/hos_types.hpp" -#include "hos/hos_version_api.hpp" +#include +#include +#include diff --git a/libstratosphere/include/stratosphere/hos/hos_stratosphere_api.hpp b/libstratosphere/include/stratosphere/hos/hos_stratosphere_api.hpp new file mode 100644 index 00000000..30e090e4 --- /dev/null +++ b/libstratosphere/include/stratosphere/hos/hos_stratosphere_api.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 + +namespace ams::hos { + + void InitializeForStratosphere(); + +} diff --git a/libstratosphere/include/stratosphere/hos/hos_version_api.hpp b/libstratosphere/include/stratosphere/hos/hos_version_api.hpp index 62f1a8d6..c4e97efa 100644 --- a/libstratosphere/include/stratosphere/hos/hos_version_api.hpp +++ b/libstratosphere/include/stratosphere/hos/hos_version_api.hpp @@ -15,11 +15,10 @@ */ #pragma once -#include "hos_types.hpp" +#include namespace ams::hos { ::ams::hos::Version GetVersion(); - void SetVersionForLibnx(); } diff --git a/libstratosphere/source/hos/hos_stratosphere_api.cpp b/libstratosphere/source/hos/hos_stratosphere_api.cpp new file mode 100644 index 00000000..f0a4a029 --- /dev/null +++ b/libstratosphere/source/hos/hos_stratosphere_api.cpp @@ -0,0 +1,35 @@ +/* + * 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 "hos_version_api_private.hpp" + +namespace ams::os { + + void InitializeForStratosphereInternal(); + +} + +namespace ams::hos { + + void InitializeForStratosphere() { + /* Initialize the global os resource managers. This *must* be done before anything else in stratosphere. */ + os::InitializeForStratosphereInternal(); + + /* Initialize hos::Version API. */ + hos::SetVersionForLibnxInternal(); + } + +} diff --git a/libstratosphere/source/hos/hos_version_api.cpp b/libstratosphere/source/hos/hos_version_api.cpp index d295250a..b11d56c8 100644 --- a/libstratosphere/source/hos/hos_version_api.cpp +++ b/libstratosphere/source/hos/hos_version_api.cpp @@ -13,8 +13,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include +#include "hos_version_api_private.hpp" namespace ams::hos { @@ -86,7 +86,7 @@ namespace ams::hos { return g_hos_version; } - void SetVersionForLibnx() { + void SetVersionForLibnxInternal() { u32 major = 0, minor = 0, micro = 0; switch (hos::GetVersion()) { case hos::Version_1_0_0: diff --git a/libstratosphere/source/hos/hos_version_api_private.hpp b/libstratosphere/source/hos/hos_version_api_private.hpp new file mode 100644 index 00000000..ed0cb895 --- /dev/null +++ b/libstratosphere/source/hos/hos_version_api_private.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::hos { + + void SetVersionForLibnxInternal(); + +} diff --git a/libstratosphere/source/os/impl/os_resource_manager.cpp b/libstratosphere/source/os/impl/os_resource_manager.cpp index 539f9e17..6585ea6c 100644 --- a/libstratosphere/source/os/impl/os_resource_manager.cpp +++ b/libstratosphere/source/os/impl/os_resource_manager.cpp @@ -19,6 +19,6 @@ namespace ams::os::impl { /* TODO: C++20 constinit */ - OsResourceManager ResourceManagerHolder::s_resource_manager = {}; + TYPED_STORAGE(OsResourceManager) ResourceManagerHolder::s_resource_manager_storage = {}; } diff --git a/libstratosphere/source/os/impl/os_resource_manager.hpp b/libstratosphere/source/os/impl/os_resource_manager.hpp index 11e5209b..473b3ddb 100644 --- a/libstratosphere/source/os/impl/os_resource_manager.hpp +++ b/libstratosphere/source/os/impl/os_resource_manager.hpp @@ -39,12 +39,17 @@ namespace ams::os::impl { class ResourceManagerHolder { private: - static /* TODO: C++20 constinit */ OsResourceManager s_resource_manager; + static TYPED_STORAGE(OsResourceManager) s_resource_manager_storage; private: constexpr ResourceManagerHolder() { /* ... */ } public: + static ALWAYS_INLINE void InitializeResourceManagerInstance() { + /* Construct the resource manager instance. */ + new (GetPointer(s_resource_manager_storage)) OsResourceManager; + } + static ALWAYS_INLINE OsResourceManager &GetResourceManagerInstance() { - return s_resource_manager; + return GetReference(s_resource_manager_storage); } }; diff --git a/libstratosphere/source/os/os_stratosphere_api.cpp b/libstratosphere/source/os/os_stratosphere_api.cpp new file mode 100644 index 00000000..f081fdbf --- /dev/null +++ b/libstratosphere/source/os/os_stratosphere_api.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/os_resource_manager.hpp" + +namespace ams::os { + + void InitializeForStratosphereInternal() { + /* Initialize the global os resource manager. */ + os::impl::ResourceManagerHolder::InitializeResourceManagerInstance(); + } + +}