diff --git a/include/stratosphere/cfg/cfg_api.hpp b/include/stratosphere/cfg/cfg_api.hpp index 62431da2..9c5c8efe 100644 --- a/include/stratosphere/cfg/cfg_api.hpp +++ b/include/stratosphere/cfg/cfg_api.hpp @@ -20,8 +20,9 @@ namespace sts::cfg { - /* Is the current proces privileged? */ + /* Privileged Process configuration. */ bool IsInitialProcess(); + void GetInitialProcessRange(u64 *out_min, u64 *out_max); /* SD card configuration. */ bool IsSdCardInitialized(); diff --git a/include/stratosphere/defines.hpp b/include/stratosphere/defines.hpp index 2a76f02a..f054535f 100644 --- a/include/stratosphere/defines.hpp +++ b/include/stratosphere/defines.hpp @@ -25,3 +25,6 @@ #define NON_MOVEABLE(cls) \ cls(cls&&) = delete; \ cls& operator=(cls&&) = delete + +#define ALIGNED(algn) __attribute__((aligned(algn))) +#define WEAK __attribute__((weak)) \ No newline at end of file diff --git a/include/stratosphere/pm.hpp b/include/stratosphere/pm.hpp index 877cdc1b..92d8eef6 100644 --- a/include/stratosphere/pm.hpp +++ b/include/stratosphere/pm.hpp @@ -17,4 +17,7 @@ #pragma once #include -#include "pm/pm_info_api.hpp" \ No newline at end of file +#include "pm/pm_types.hpp" +#include "pm/pm_boot_mode_api.hpp" +#include "pm/pm_info_api.hpp" +#include "pm/pm_shell_api.hpp" \ No newline at end of file diff --git a/include/stratosphere/pm/pm_boot_mode_api.hpp b/include/stratosphere/pm/pm_boot_mode_api.hpp new file mode 100644 index 00000000..dee49a0a --- /dev/null +++ b/include/stratosphere/pm/pm_boot_mode_api.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2019 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 "pm_types.hpp" + +namespace sts::pm::bm { + + /* Boot Mode API. */ + BootMode GetBootMode(); + void SetMaintenanceBoot(); + +} diff --git a/include/stratosphere/pm/pm_info_api.hpp b/include/stratosphere/pm/pm_info_api.hpp index 29f8dc89..04f0fad3 100644 --- a/include/stratosphere/pm/pm_info_api.hpp +++ b/include/stratosphere/pm/pm_info_api.hpp @@ -16,14 +16,16 @@ #pragma once +#include "pm_types.hpp" + namespace sts::pm::info { /* Information API. */ - Result GetTitleId(u64 *out_title_id, u64 process_id); - Result GetProcessId(u64 *out_process_id, u64 title_id); - Result HasLaunchedTitle(bool *out, u64 title_id); + Result GetTitleId(ncm::TitleId *out_title_id, u64 process_id); + Result GetProcessId(u64 *out_process_id, ncm::TitleId title_id); + Result HasLaunchedTitle(bool *out, ncm::TitleId title_id); /* Information convenience API. */ - bool HasLaunchedTitle(u64 title_id); + bool HasLaunchedTitle(ncm::TitleId title_id); } diff --git a/include/stratosphere/pm/pm_shell_api.hpp b/include/stratosphere/pm/pm_shell_api.hpp new file mode 100644 index 00000000..f3f6002c --- /dev/null +++ b/include/stratosphere/pm/pm_shell_api.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2019 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 "../ldr.hpp" +#include "pm_types.hpp" + +namespace sts::pm::shell { + + /* Shell API. */ + Result LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 launch_flags); + +} diff --git a/include/stratosphere/pm/pm_types.hpp b/include/stratosphere/pm/pm_types.hpp new file mode 100644 index 00000000..bb6eb29a --- /dev/null +++ b/include/stratosphere/pm/pm_types.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018-2019 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 sts::pm { + + enum class BootMode { + Normal = 0, + Maintenance = 1, + SafeMode = 2, + }; + + enum ResourceLimitGroup { + ResourceLimitGroup_System = 0, + ResourceLimitGroup_Application = 1, + ResourceLimitGroup_Applet = 2, + ResourceLimitGroup_Count, + }; + + using LimitableResource = ::LimitableResource; + + struct ProcessEventInfo { + u32 event; + u64 process_id; + }; + static_assert(sizeof(ProcessEventInfo) == 0x10 && std::is_pod::value, "ProcessEventInfo definition!"); + +} diff --git a/include/stratosphere/sm/sm_types.hpp b/include/stratosphere/sm/sm_types.hpp index 57b792d8..377c05fc 100644 --- a/include/stratosphere/sm/sm_types.hpp +++ b/include/stratosphere/sm/sm_types.hpp @@ -16,6 +16,7 @@ #pragma once #include +#include namespace sts::sm { diff --git a/include/stratosphere/spl/spl_api.hpp b/include/stratosphere/spl/spl_api.hpp index d24a69c5..b511ad9e 100644 --- a/include/stratosphere/spl/spl_api.hpp +++ b/include/stratosphere/spl/spl_api.hpp @@ -21,6 +21,7 @@ namespace sts::spl { HardwareType GetHardwareType(); + MemoryArrangement GetMemoryArrangement(); bool IsDevelopmentHardware(); bool IsDevelopmentFunctionEnabled(); bool IsMariko(); diff --git a/include/stratosphere/spl/spl_types.hpp b/include/stratosphere/spl/spl_types.hpp index 84680ab5..56ce8fdd 100644 --- a/include/stratosphere/spl/spl_types.hpp +++ b/include/stratosphere/spl/spl_types.hpp @@ -107,6 +107,20 @@ namespace sts::spl { Iowa = 3, }; + enum MemoryArrangement { + MemoryArrangement_Standard = 0, + MemoryArrangement_StandardForAppletDev = 1, + MemoryArrangement_StandardForSystemDev = 2, + MemoryArrangement_Expanded = 3, + MemoryArrangement_ExpandedForAppletDev = 4, + + /* Note: MemoryArrangement_Dynamic is not official. */ + /* Atmosphere uses it to maintain compatibility with firmwares prior to 6.0.0, */ + /* which removed the explicit retrieval of memory arrangement from PM. */ + MemoryArrangement_Dynamic = 5, + MemoryArrangement_Count, + }; + struct BootReasonValue { union { struct { diff --git a/source/cfg/cfg_override.cpp b/source/cfg/cfg_override.cpp index e6f1814a..ab84362e 100644 --- a/source/cfg/cfg_override.cpp +++ b/source/cfg/cfg_override.cpp @@ -219,7 +219,7 @@ namespace sts::cfg { } /* For system modules and anything launched before the home menu, always override. */ - if (static_cast(title_id) < TitleId_AppletStart || !pm::info::HasLaunchedTitle(TitleId_AppletQlaunch)) { + if (static_cast(title_id) < TitleId_AppletStart || !pm::info::HasLaunchedTitle(ncm::TitleId{TitleId_AppletQlaunch})) { return true; } @@ -237,7 +237,7 @@ namespace sts::cfg { } /* For system modules and anything launched before the home menu, always override. */ - if (static_cast(title_id) < TitleId_AppletStart || !pm::info::HasLaunchedTitle(TitleId_AppletQlaunch)) { + if (static_cast(title_id) < TitleId_AppletStart || !pm::info::HasLaunchedTitle(ncm::TitleId{TitleId_AppletQlaunch})) { return true; } @@ -258,7 +258,7 @@ namespace sts::cfg { } /* For system modules and anything launched before the home menu, always override. */ - if (static_cast(title_id) < TitleId_AppletStart || !pm::info::HasLaunchedTitle(TitleId_AppletQlaunch)) { + if (static_cast(title_id) < TitleId_AppletStart || !pm::info::HasLaunchedTitle(ncm::TitleId{TitleId_AppletQlaunch})) { *out_hbl = false; *out_title = true; return; diff --git a/source/cfg/cfg_privileged_process.cpp b/source/cfg/cfg_privileged_process.cpp index e33af937..cab6469b 100644 --- a/source/cfg/cfg_privileged_process.cpp +++ b/source/cfg/cfg_privileged_process.cpp @@ -28,8 +28,9 @@ namespace sts::cfg { /* Privileged process globals. */ HosMutex g_lock; - bool g_detected_privileged_process = false; - bool g_is_privileged_process = false; + bool g_got_privileged_process_status = false; + u64 g_min_initial_process_id = 0, g_max_initial_process_id = 0; + u64 g_cur_process_id = 0; /* SD card helpers. */ void GetPrivilegedProcessIdRange(u64 *out_min, u64 *out_max) { @@ -58,28 +59,37 @@ namespace sts::cfg { return process_id; } - void DetectIsPrivilegedProcess() { - u64 min = 0, max = 0, cur = 0; - GetPrivilegedProcessIdRange(&min, &max); - cur = GetCurrentProcessId(); - g_is_privileged_process = min <= cur && cur <= max; - g_detected_privileged_process = true; + void GetPrivilegedProcessStatus() { + GetPrivilegedProcessIdRange(&g_min_initial_process_id, &g_max_initial_process_id); + g_cur_process_id = GetCurrentProcessId(); + g_got_privileged_process_status = true; } - } - /* SD card utilities. */ - bool IsPrivilegedProcess() { + /* Privileged Process utilities. */ + bool IsInitialProcess() { std::scoped_lock lk(g_lock); - /* If we've already detected, return cached result. */ - if (!g_detected_privileged_process) { - DetectIsPrivilegedProcess(); + /* If we've not detected, do detection. */ + if (!g_got_privileged_process_status) { + GetPrivilegedProcessStatus(); } /* Determine if we're privileged, and return. */ - return g_is_privileged_process; + return g_min_initial_process_id <= g_cur_process_id && g_cur_process_id <= g_max_initial_process_id; + } + + void GetInitialProcessRange(u64 *out_min, u64 *out_max) { + std::scoped_lock lk(g_lock); + + /* If we've not detected, do detection. */ + if (!g_got_privileged_process_status) { + GetPrivilegedProcessStatus(); + } + + *out_min = g_min_initial_process_id; + *out_max = g_max_initial_process_id; } } diff --git a/source/hid/hid_api.cpp b/source/hid/hid_api.cpp index cee7b577..b0560960 100644 --- a/source/hid/hid_api.cpp +++ b/source/hid/hid_api.cpp @@ -39,7 +39,7 @@ namespace sts::hid { Result EnsureHidInitialized() { if (!g_initialized_hid) { if (!serviceIsActive(hidGetSessionService())) { - if (!pm::info::HasLaunchedTitle(TitleId_Hid)) { + if (!pm::info::HasLaunchedTitle(ncm::TitleId{TitleId_Hid})) { return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID); } InitializeHid(); diff --git a/source/pm/pm_boot_mode_api.cpp b/source/pm/pm_boot_mode_api.cpp new file mode 100644 index 00000000..c207b7e7 --- /dev/null +++ b/source/pm/pm_boot_mode_api.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2019 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 +#include + +namespace sts::pm::bm { + + /* Boot Mode API. */ + /* Both functions should be weakly linked, so that they can be overridden by sts::boot2 as needed. */ + BootMode WEAK GetBootMode() { + PmBootMode boot_mode = PmBootMode_Normal; + R_ASSERT(pmbmGetBootMode(&boot_mode)); + return static_cast(boot_mode); + } + + void WEAK SetMaintenanceBoot() { + R_ASSERT(pmbmSetMaintenanceBoot()); + } + +} diff --git a/source/pm/pm_info_api.cpp b/source/pm/pm_info_api.cpp index 3b62c341..379d49c1 100644 --- a/source/pm/pm_info_api.cpp +++ b/source/pm/pm_info_api.cpp @@ -31,37 +31,37 @@ namespace sts::pm::info { } /* Information API. */ - Result GetTitleId(u64 *out_title_id, u64 process_id) { + Result GetTitleId(ncm::TitleId *out_title_id, u64 process_id) { std::scoped_lock lk(g_info_lock); - return pminfoGetTitleId(out_title_id, process_id); + return pminfoGetTitleId(reinterpret_cast(out_title_id), process_id); } - Result GetProcessId(u64 *out_process_id, u64 title_id) { + Result GetProcessId(u64 *out_process_id, ncm::TitleId title_id) { std::scoped_lock lk(g_info_lock); - return pminfoAtmosphereGetProcessId(out_process_id, title_id); + return pminfoAtmosphereGetProcessId(out_process_id, static_cast(title_id)); } - Result __attribute__((weak)) HasLaunchedTitle(bool *out, u64 title_id) { + Result WEAK HasLaunchedTitle(bool *out, ncm::TitleId title_id) { std::scoped_lock lk(g_info_lock); - if (g_cached_launched_titles.find(title_id) != g_cached_launched_titles.end()) { + if (g_cached_launched_titles.find(static_cast(title_id)) != g_cached_launched_titles.end()) { *out = true; return ResultSuccess; } bool has_launched = false; - R_TRY(pminfoAtmosphereHasLaunchedTitle(&has_launched, title_id)); + R_TRY(pminfoAtmosphereHasLaunchedTitle(&has_launched, static_cast(title_id))); if (has_launched) { - g_cached_launched_titles.insert(title_id); + g_cached_launched_titles.insert(static_cast(title_id)); } *out = has_launched; return ResultSuccess; } - bool HasLaunchedTitle(u64 title_id) { + bool HasLaunchedTitle(ncm::TitleId title_id) { bool has_launched = false; R_ASSERT(HasLaunchedTitle(&has_launched, title_id)); return has_launched; diff --git a/source/pm/pm_shell_api.cpp b/source/pm/pm_shell_api.cpp new file mode 100644 index 00000000..09d5e4d2 --- /dev/null +++ b/source/pm/pm_shell_api.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2019 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 +#include + +namespace sts::pm::shell { + + /* Shell API. */ + Result WEAK LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 launch_flags) { + return pmshellLaunchProcess(launch_flags, static_cast(loc.title_id), loc.storage_id, out_process_id); + } + +} diff --git a/source/spl/spl_api.cpp b/source/spl/spl_api.cpp index f3aea6a7..140d44a1 100644 --- a/source/spl/spl_api.cpp +++ b/source/spl/spl_api.cpp @@ -25,6 +25,24 @@ namespace sts::spl { return static_cast(out_val); } + MemoryArrangement GetMemoryArrangement() { + u64 arrange = 0; + R_ASSERT(splGetConfig(SplConfigItem_MemoryArrange, &arrange)); + arrange &= 0x3F; + switch (arrange) { + case 2: + return MemoryArrangement_StandardForAppletDev; + case 3: + return MemoryArrangement_StandardForSystemDev; + case 17: + return MemoryArrangement_Expanded; + case 18: + return MemoryArrangement_ExpandedForAppletDev; + default: + return MemoryArrangement_Standard; + } + } + bool IsDevelopmentHardware() { bool is_dev_hardware; R_ASSERT(splIsDevelopment(&is_dev_hardware));