From b09adb6a34f41c127e6171027e11aed489dd15a0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 22 Apr 2019 12:40:53 -0700 Subject: [PATCH] stratosphere: only hold sm sessions open when needed --- stratosphere/ams_mitm/source/amsmitm_main.cpp | 20 +-- .../ams_mitm/source/ns_mitm/nsmitm_main.cpp | 4 +- stratosphere/ams_mitm/source/utils.cpp | 36 +++-- stratosphere/boot/source/boot_main.cpp | 46 +++--- .../creport/source/creport_crash_report.cpp | 25 ++- stratosphere/creport/source/creport_main.cpp | 26 ++-- stratosphere/dmnt/source/dmnt_main.cpp | 122 ++++++++------- stratosphere/fatal/source/fatal_main.cpp | 142 +++++++++--------- .../fatal/source/fatal_task_error_report.cpp | 25 ++- .../fatal/source/fatal_task_screen.cpp | 93 ++++++------ stratosphere/libstratosphere | 2 +- .../loader/source/ldr_content_management.cpp | 31 ++-- stratosphere/loader/source/ldr_hid.cpp | 18 ++- stratosphere/loader/source/ldr_main.cpp | 51 +++---- stratosphere/pm/source/pm_boot2.cpp | 85 ++++++----- stratosphere/pm/source/pm_main.cpp | 109 +++++++------- 16 files changed, 432 insertions(+), 403 deletions(-) diff --git a/stratosphere/ams_mitm/source/amsmitm_main.cpp b/stratosphere/ams_mitm/source/amsmitm_main.cpp index d244d3246..911c5e561 100644 --- a/stratosphere/ams_mitm/source/amsmitm_main.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_main.cpp @@ -73,15 +73,12 @@ void __appInit(void) { SetFirmwareVersionForLibnx(); - rc = smInitialize(); - if (R_FAILED(rc)) { - fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); - } - - rc = fsInitialize(); - if (R_FAILED(rc)) { - fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); - } + DoWithSmSession([&]() { + rc = fsInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + }); CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); } @@ -89,7 +86,6 @@ void __appInit(void) { void __appExit(void) { /* Cleanup services. */ fsExit(); - smExit(); } int main(int argc, char **argv) @@ -100,10 +96,10 @@ int main(int argc, char **argv) LaunchAllMitmModules(); if (R_FAILED(initializer_thread.Initialize(&Utils::InitializeThreadFunc, NULL, 0x4000, 0x15))) { - /* TODO: Panic. */ + std::abort(); } if (R_FAILED(initializer_thread.Start())) { - /* TODO: Panic. */ + std::abort(); } /* Wait for all mitm modules to end. */ diff --git a/stratosphere/ams_mitm/source/ns_mitm/nsmitm_main.cpp b/stratosphere/ams_mitm/source/ns_mitm/nsmitm_main.cpp index 92a9c632b..256ca76e1 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/nsmitm_main.cpp +++ b/stratosphere/ams_mitm/source/ns_mitm/nsmitm_main.cpp @@ -35,12 +35,12 @@ void NsMitmMain(void *arg) { Utils::WaitSdInitialized(); /* Ensure we can talk to NS. */ - { + DoWithSmSession([&]() { if (R_FAILED(nsInitialize())) { std::abort(); } nsExit(); - } + }); /* Create server manager */ auto server_manager = new WaitableManager(1); diff --git a/stratosphere/ams_mitm/source/utils.cpp b/stratosphere/ams_mitm/source/utils.cpp index 5d50fa178..7c406495a 100644 --- a/stratosphere/ams_mitm/source/utils.cpp +++ b/stratosphere/ams_mitm/source/utils.cpp @@ -78,15 +78,17 @@ static bool IsHexadecimal(const char *str) { void Utils::InitializeThreadFunc(void *args) { /* Get required services. */ - Handle tmp_hnd = 0; - static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; - for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { - if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { - /* TODO: Panic */ - } else { - svcCloseHandle(tmp_hnd); + DoWithSmSession([&]() { + Handle tmp_hnd = 0; + static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; + for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { + if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { + /* TODO: Panic */ + } else { + svcCloseHandle(tmp_hnd); + } } - } + }); /* Mount SD. */ while (R_FAILED(fsMountSdcard(&g_sd_filesystem))) { @@ -197,7 +199,11 @@ void Utils::InitializeThreadFunc(void *args) { Utils::RefreshConfiguration(); /* Initialize set:sys. */ - setsysInitialize(); + DoWithSmSession([&]() { + if (R_FAILED(setsysInitialize())) { + std::abort(); + } + }); /* Signal SD is initialized. */ g_has_initialized = true; @@ -209,13 +215,15 @@ void Utils::InitializeThreadFunc(void *args) { g_sd_signal.Signal(); /* Initialize HID. */ - { - - while (R_FAILED(hidInitialize())) { + while (!g_has_hid_session) { + DoWithSmSession([&]() { + if (R_SUCCEEDED(hidInitialize())) { + g_has_hid_session = true; + } + }); + if (!g_has_hid_session) { svcSleepThread(1000000ULL); } - - g_has_hid_session = true; } } diff --git a/stratosphere/boot/source/boot_main.cpp b/stratosphere/boot/source/boot_main.cpp index 862809d76..a1bd831af 100644 --- a/stratosphere/boot/source/boot_main.cpp +++ b/stratosphere/boot/source/boot_main.cpp @@ -80,30 +80,27 @@ void __appInit(void) { SetFirmwareVersionForLibnx(); /* Initialize services we need (TODO: NCM) */ - rc = smInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = fsInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = splInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = pmshellInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = fsdevMountSdmc(); - if (R_FAILED(rc)) { - std::abort(); - } + DoWithSmSession([&]() { + rc = fsInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = splInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = pmshellInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = fsdevMountSdmc(); + if (R_FAILED(rc)) { + std::abort(); + } + }); CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); } @@ -114,7 +111,6 @@ void __appExit(void) { pmshellExit(); splExit(); fsExit(); - smExit(); } typedef enum { diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index 908897161..e13982f4a 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -240,19 +240,28 @@ bool CrashReport::GetCurrentTime(u64 *out) { /* Verify that pcv isn't dead. */ { - Handle dummy; - if (R_SUCCEEDED(smRegisterService(&dummy, "time:s", false, 0x20))) { - svcCloseHandle(dummy); + bool has_time_service; + DoWithSmSession([&]() { + Handle dummy; + if (R_SUCCEEDED(smRegisterService(&dummy, "time:s", false, 0x20))) { + svcCloseHandle(dummy); + has_time_service = false; + } else { + has_time_service = true; + } + }); + if (!has_time_service) { return false; } } /* Try to get the current time. */ - bool success = false; - if (R_SUCCEEDED(timeInitialize())) { - if (R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out))) { - success = true; - } + bool success = true; + DoWithSmSession([&]() { + success &= R_SUCCEEDED(timeInitialize()); + }); + if (success) { + success &= R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out)); timeExit(); } return success; diff --git a/stratosphere/creport/source/creport_main.cpp b/stratosphere/creport/source/creport_main.cpp index 662705fbc..6d3423c18 100644 --- a/stratosphere/creport/source/creport_main.cpp +++ b/stratosphere/creport/source/creport_main.cpp @@ -68,16 +68,13 @@ void __appInit(void) { Result rc; SetFirmwareVersionForLibnx(); - - rc = smInitialize(); - if (R_FAILED(rc)) { - fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); - } - rc = fsInitialize(); - if (R_FAILED(rc)) { - fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); - } + DoWithSmSession([&]() { + rc = fsInitialize(); + if (R_FAILED(rc)) { + fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); + } + }); rc = fsdevMountSdmc(); if (R_FAILED(rc)) { @@ -89,7 +86,6 @@ void __appExit(void) { /* Cleanup services. */ fsdevUnmountAll(); fsExit(); - smExit(); } static u64 creport_parse_u64(char *s) { @@ -127,10 +123,12 @@ int main(int argc, char **argv) { if (g_Creport.WasSuccessful()) { g_Creport.SaveReport(); - if (R_SUCCEEDED(nsdevInitialize())) { - nsdevTerminateProcess(crashed_pid); - nsdevExit(); - } + DoWithSmSession([&]() { + if (R_SUCCEEDED(nsdevInitialize())) { + nsdevTerminateProcess(crashed_pid); + nsdevExit(); + } + }); /* Don't fatal if we have extra info. */ if (kernelAbove500()) { diff --git a/stratosphere/dmnt/source/dmnt_main.cpp b/stratosphere/dmnt/source/dmnt_main.cpp index eb864e8ce..6745a8673 100644 --- a/stratosphere/dmnt/source/dmnt_main.cpp +++ b/stratosphere/dmnt/source/dmnt_main.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -36,7 +36,7 @@ extern "C" { #define INNER_HEAP_SIZE 0x80000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; - + void __libnx_initheap(void); void __appInit(void); void __appExit(void); @@ -68,64 +68,61 @@ void __libnx_initheap(void) { void __appInit(void) { Result rc; - + SetFirmwareVersionForLibnx(); - - rc = smInitialize(); - if (R_FAILED(rc)) { - fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); - } - - rc = pmdmntInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = ldrDmntInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = roDmntInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = nsdevInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = lrInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = setInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = setsysInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = hidInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - - rc = fsInitialize(); - if (R_FAILED(rc)) { - fatalSimple(rc); - } - + + DoWithSmSession([&]() { + rc = pmdmntInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = ldrDmntInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = roDmntInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = nsdevInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = lrInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = setInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = setsysInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = hidInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + + rc = fsInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + }); + rc = fsdevMountSdmc(); if (R_FAILED(rc)) { fatalSimple(rc); } - + CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); } @@ -141,28 +138,27 @@ void __appExit(void) { roDmntExit(); ldrDmntExit(); pmdmntExit(); - smExit(); } int main(int argc, char **argv) { consoleDebugInit(debugDevice_SVC); - + /* Initialize configuration manager. */ DmntConfigManager::RefreshConfiguration(); - + /* Start cheat manager. */ DmntCheatManager::InitializeCheatManager(); - + /* Nintendo uses four threads. Add a fifth for our cheat service. */ auto server_manager = new WaitableManager(5); - + /* Create services. */ - + /* TODO: Implement rest of dmnt:- in ams.tma development branch. */ /* server_manager->AddWaitable(new ServiceServer("dmnt:-", 4)); */ - - + + server_manager->AddWaitable(new ServiceServer("dmnt:cht", 1)); /* Loop forever, servicing our services. */ diff --git a/stratosphere/fatal/source/fatal_main.cpp b/stratosphere/fatal/source/fatal_main.cpp index 2f49576f7..4600b951d 100644 --- a/stratosphere/fatal/source/fatal_main.cpp +++ b/stratosphere/fatal/source/fatal_main.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -38,10 +38,10 @@ extern "C" { #define INNER_HEAP_SIZE 0x2A0000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; - + u32 __nx_nv_transfermem_size = 0x40000; ViLayerFlags __nx_vi_stray_layer_flags = (ViLayerFlags)0; - + void __libnx_initheap(void); void __appInit(void); void __appExit(void); @@ -73,79 +73,76 @@ void __libnx_initheap(void) { void __appInit(void) { Result rc; - + SetFirmwareVersionForLibnx(); - - rc = smInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = setInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = setsysInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = pminfoInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = i2cInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = bpcInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = pcvInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = lblInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = psmInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = spsmInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = plInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = gpioInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = fsInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - + + DoWithSmSession([&]() { + rc = setInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = setsysInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = pminfoInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = i2cInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = bpcInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = pcvInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = lblInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = psmInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = spsmInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = plInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = gpioInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = fsInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + }); + rc = fsdevMountSdmc(); if (R_FAILED(rc)) { std::abort(); } - + /* fatal cannot throw fatal, so don't do: CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); */ } @@ -164,14 +161,13 @@ void __appExit(void) { pminfoExit(); setsysExit(); setExit(); - smExit(); } int main(int argc, char **argv) { /* Load settings from set:sys. */ InitializeFatalConfig(); - + /* Load shared font. */ if (R_FAILED(FontManager::InitializeSharedFont())) { std::abort(); diff --git a/stratosphere/fatal/source/fatal_task_error_report.cpp b/stratosphere/fatal/source/fatal_task_error_report.cpp index 869adcb43..9efcb3e12 100644 --- a/stratosphere/fatal/source/fatal_task_error_report.cpp +++ b/stratosphere/fatal/source/fatal_task_error_report.cpp @@ -38,19 +38,28 @@ bool ErrorReportTask::GetCurrentTime(u64 *out) { /* Verify that pcv isn't dead. */ { - Handle dummy; - if (R_SUCCEEDED(smRegisterService(&dummy, "time:s", false, 0x20))) { - svcCloseHandle(dummy); + bool has_time_service; + DoWithSmSession([&]() { + Handle dummy; + if (R_SUCCEEDED(smRegisterService(&dummy, "time:s", false, 0x20))) { + svcCloseHandle(dummy); + has_time_service = false; + } else { + has_time_service = true; + } + }); + if (!has_time_service) { return false; } } /* Try to get the current time. */ - bool success = false; - if (R_SUCCEEDED(timeInitialize())) { - if (R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out))) { - success = true; - } + bool success = true; + DoWithSmSession([&]() { + success &= R_SUCCEEDED(timeInitialize()); + }); + if (success) { + success &= R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out)); timeExit(); } return success; diff --git a/stratosphere/fatal/source/fatal_task_screen.cpp b/stratosphere/fatal/source/fatal_task_screen.cpp index d9d138f96..ab7937b6a 100644 --- a/stratosphere/fatal/source/fatal_task_screen.cpp +++ b/stratosphere/fatal/source/fatal_task_screen.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include @@ -55,17 +55,17 @@ Result ShowFatalTask::SetupDisplayInternal() { } /* Guarantee we close the display. */ ON_SCOPE_EXIT { viCloseDisplay(&display); }; - + /* Turn on the screen. */ if (R_FAILED((rc = viSetDisplayPowerState(&display, ViPowerState_On)))) { return rc; } - + /* Set alpha to 1.0f. */ if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) { return rc; } - + return rc; } @@ -82,54 +82,57 @@ Result ShowFatalTask::SetupDisplayExternal() { } /* Guarantee we close the display. */ ON_SCOPE_EXIT { viCloseDisplay(&display); }; - + /* Set alpha to 1.0f. */ if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) { return rc; } - + return rc; } Result ShowFatalTask::PrepareScreenForDrawing() { Result rc = ResultSuccess; - + /* Connect to vi. */ - if (R_FAILED((rc = viInitialize(ViServiceType_Manager)))) { + DoWithSmSession([&]() { + rc = viInitialize(ViServiceType_Manager); + }); + if (R_FAILED(rc)) { return rc; } - + /* Close other content. */ viSetContentVisibility(false); - + /* Setup the two displays. */ if (R_FAILED((rc = SetupDisplayInternal())) || R_FAILED((rc = SetupDisplayExternal()))) { return rc; } - + /* Open the default display. */ if (R_FAILED((rc = viOpenDefaultDisplay(&this->display)))) { return rc; } - + /* Reset the display magnification to its default value. */ u32 display_width, display_height; if (R_FAILED((rc = viGetDisplayLogicalResolution(&this->display, &display_width, &display_height)))) { return rc; } - + /* viSetDisplayMagnification was added in 3.0.0. */ if (GetRuntimeFirmwareVersion() >= FirmwareVersion_300) { if (R_FAILED((rc = viSetDisplayMagnification(&this->display, 0, 0, display_width, display_height)))) { return rc; } } - + /* Create layer to draw to. */ if (R_FAILED((rc = viCreateLayer(&this->display, &this->layer)))) { return rc; } - + /* Setup the layer. */ { /* Display a layer of 1280 x 720 at 1.5x magnification */ @@ -139,15 +142,15 @@ Result ShowFatalTask::PrepareScreenForDrawing() { constexpr u32 raw_height = FatalScreenHeight; constexpr u32 layer_width = ((raw_width) * 3) / 2; constexpr u32 layer_height = ((raw_height) * 3) / 2; - + const float layer_x = static_cast((display_width - layer_width) / 2); const float layer_y = static_cast((display_height - layer_height) / 2); u64 layer_z; - + if (R_FAILED((rc = viSetLayerSize(&this->layer, layer_width, layer_height)))) { return rc; } - + /* Set the layer's Z at display maximum, to be above everything else .*/ /* NOTE: Fatal hardcodes 100 here. */ if (R_SUCCEEDED((rc = viGetDisplayMaximumZ(&this->display, &layer_z)))) { @@ -155,12 +158,12 @@ Result ShowFatalTask::PrepareScreenForDrawing() { return rc; } } - + /* Center the layer in the screen. */ if (R_FAILED((rc = viSetLayerPosition(&this->layer, layer_x, layer_y)))) { return rc; } - + /* Create framebuffer. */ if (R_FAILED(rc = nwindowCreateFromLayer(&this->win, &this->layer))) { return rc; @@ -169,7 +172,7 @@ Result ShowFatalTask::PrepareScreenForDrawing() { return rc; } } - + return rc; } @@ -182,29 +185,29 @@ Result ShowFatalTask::ShowFatal() { *(volatile u32 *)(0xCAFEBABE) = rc; return rc; } - + /* Dequeue a buffer. */ u16 *tiled_buf = reinterpret_cast(framebufferBegin(&this->fb, NULL)); if (tiled_buf == nullptr) { return ResultFatalNullGraphicsBuffer; } - + /* Let the font manager know about our framebuffer. */ FontManager::ConfigureFontFramebuffer(tiled_buf, GetPixelOffset); FontManager::SetFontColor(0xFFFF); - + /* Draw a background. */ for (size_t i = 0; i < this->fb.fb_size / sizeof(*tiled_buf); i++) { tiled_buf[i] = 0x39C9; } - + /* Draw the atmosphere logo in the bottom right corner. */ for (size_t y = 0; y < AMS_LOGO_HEIGHT; y++) { for (size_t x = 0; x < AMS_LOGO_WIDTH; x++) { tiled_buf[GetPixelOffset(FatalScreenWidth - AMS_LOGO_WIDTH - 32 + x, 32 + y)] = AMS_LOGO_BIN[y * AMS_LOGO_WIDTH + x]; } } - + /* TODO: Actually draw meaningful shit here. */ FontManager::SetPosition(32, 64); FontManager::SetFontSize(16.0f); @@ -225,18 +228,18 @@ Result ShowFatalTask::ShowFatal() { u8"Please ensure that all Atmosphère components are updated.\n" u8"github.com/Atmosphere-NX/Atmosphere/releases\n"); } - + /* Add a line. */ for (size_t x = 32; x < FatalScreenWidth - 32; x++) { tiled_buf[GetPixelOffset(x, FontManager::GetY())] = 0xFFFF; } - - + + FontManager::AddSpacingLines(1.5f); - + u32 backtrace_y = FontManager::GetY(); u32 backtrace_x = 0; - + /* Print GPRs. */ FontManager::SetFontSize(14.0f); FontManager::Print("General Purpose Registers "); @@ -278,7 +281,7 @@ Result ShowFatalTask::ShowFatal() { FontManager::Print(" "); backtrace_x = FontManager::GetX(); } - + FontManager::PrintLine(""); FontManager::SetPosition(32, FontManager::GetY()); } @@ -306,12 +309,12 @@ Result ShowFatalTask::ShowFatal() { FontManager::Print(" "); backtrace_x = FontManager::GetX(); } - + FontManager::PrintLine(""); FontManager::SetPosition(32, FontManager::GetY()); } } - + /* Print Backtrace. */ u32 bt_size; if (this->ctx->cpu_ctx.is_aarch32) { @@ -319,8 +322,8 @@ Result ShowFatalTask::ShowFatal() { } else { bt_size = this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size; } - - + + FontManager::SetPosition(backtrace_x, backtrace_y); if (bt_size == 0) { if (this->ctx->cpu_ctx.is_aarch32) { @@ -346,7 +349,7 @@ Result ShowFatalTask::ShowFatal() { if (i + Aarch32CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch32_ctx.stack_trace_size) { bt_next = this->ctx->cpu_ctx.aarch32_ctx.stack_trace[i + Aarch32CpuContext::MaxStackTraceDepth / 2]; } - + if (i < this->ctx->cpu_ctx.aarch32_ctx.stack_trace_size) { u32 x = FontManager::GetX(); FontManager::PrintFormat("BT[%02d]: ", i); @@ -354,14 +357,14 @@ Result ShowFatalTask::ShowFatal() { FontManager::PrintMonospaceU32(bt_cur); FontManager::Print(" "); } - + if (i + Aarch32CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch32_ctx.stack_trace_size) { u32 x = FontManager::GetX(); FontManager::PrintFormat("BT[%02d]: ", i + Aarch32CpuContext::MaxStackTraceDepth / 2); FontManager::SetPosition(x + 72, FontManager::GetY()); FontManager::PrintMonospaceU32(bt_next); } - + FontManager::PrintLine(""); FontManager::SetPosition(backtrace_x, FontManager::GetY()); } @@ -378,7 +381,7 @@ Result ShowFatalTask::ShowFatal() { if (i + Aarch64CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) { bt_next = this->ctx->cpu_ctx.aarch64_ctx.stack_trace[i + Aarch64CpuContext::MaxStackTraceDepth / 2]; } - + if (i < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) { u32 x = FontManager::GetX(); FontManager::PrintFormat("BT[%02d]: ", i); @@ -386,24 +389,24 @@ Result ShowFatalTask::ShowFatal() { FontManager::PrintMonospaceU64(bt_cur); FontManager::Print(" "); } - + if (i + Aarch64CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) { u32 x = FontManager::GetX(); FontManager::PrintFormat("BT[%02d]: ", i + Aarch64CpuContext::MaxStackTraceDepth / 2); FontManager::SetPosition(x + 72, FontManager::GetY()); FontManager::PrintMonospaceU64(bt_next); } - + FontManager::PrintLine(""); FontManager::SetPosition(backtrace_x, FontManager::GetY()); } } } - - + + /* Enqueue the buffer. */ framebufferEnd(&fb); - + return rc; } diff --git a/stratosphere/libstratosphere b/stratosphere/libstratosphere index 880bce909..79bc9bf8d 160000 --- a/stratosphere/libstratosphere +++ b/stratosphere/libstratosphere @@ -1 +1 @@ -Subproject commit 880bce9092fbef0bcbf101b8ec2e3d2c5af3fb98 +Subproject commit 79bc9bf8d87dddcfc2d080626eb8c817c7339fd0 diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index b47eaf881..f5f660ab2 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -94,19 +94,20 @@ Result ContentManagement::MountCode(u64 tid, FsStorageId sid) { } /* Always re-initialize fsp-ldr, in case it's closed */ - if (R_FAILED(rc = fsldrInitialize())) { + DoWithSmSession([&]() { + rc = fsldrInitialize(); + }); + if (R_FAILED(rc)) { return rc; } + ON_SCOPE_EXIT { fsldrExit(); }; if (R_FAILED(rc = fsldrOpenCodeFileSystem(tid, path, &g_CodeFileSystem))) { - fsldrExit(); return rc; } fsdevMountDevice("code", g_CodeFileSystem); TryMountHblNspOnSd(); - - fsldrExit(); return rc; } @@ -372,17 +373,21 @@ void ContentManagement::RefreshConfigurationData() { void ContentManagement::TryMountSdCard() { /* Mount SD card, if psc, bus, and pcv have been created. */ if (!g_has_initialized_fs_dev && HasCreatedTitle(TitleId_Psc) && HasCreatedTitle(TitleId_Bus) && HasCreatedTitle(TitleId_Pcv)) { - Handle tmp_hnd = 0; - static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; - for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { - if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { - return; - } else { - svcCloseHandle(tmp_hnd); + bool can_mount = true; + DoWithSmSession([&]() { + Handle tmp_hnd = 0; + static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; + for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { + if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { + can_mount = false; + break; + } else { + svcCloseHandle(tmp_hnd); + } } - } + }); - if (R_SUCCEEDED(fsdevMountSdmc())) { + if (can_mount && R_SUCCEEDED(fsdevMountSdmc())) { g_has_initialized_fs_dev = true; } } diff --git a/stratosphere/loader/source/ldr_hid.cpp b/stratosphere/loader/source/ldr_hid.cpp index 2109539a2..bc103f56c 100644 --- a/stratosphere/loader/source/ldr_hid.cpp +++ b/stratosphere/loader/source/ldr_hid.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include @@ -24,13 +24,19 @@ Result HidManagement::GetKeysHeld(u64 *keys) { if (!ContentManagement::HasCreatedTitle(TitleId_Hid)) { return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID); } - - if (!serviceIsActive(hidGetSessionService()) && R_FAILED(hidInitialize())) { - return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID); + + if (!serviceIsActive(hidGetSessionService())) { + Result rc; + DoWithSmSession([&]() { + rc = hidInitialize(); + }); + if (R_FAILED(rc)) { + return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID); + } } - + hidScanInput(); *keys = hidKeysHeld(CONTROLLER_P1_AUTO); - + return ResultSuccess; } diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index a278f6295..9b248344e 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -36,7 +36,7 @@ extern "C" { #define INNER_HEAP_SIZE 0x30000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; - + void __libnx_initheap(void); void __appInit(void); void __appExit(void); @@ -68,30 +68,28 @@ void __libnx_initheap(void) { void __appInit(void) { Result rc; - + SetFirmwareVersionForLibnx(); /* Initialize services we need (TODO: SPL) */ - rc = smInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = fsInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = lrInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = fsldrInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - + DoWithSmSession([&]() { + rc = fsInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = lrInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = fsldrInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + }); + + CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); } @@ -101,7 +99,6 @@ void __appExit(void) { fsldrExit(); lrExit(); fsExit(); - smExit(); } struct LoaderServerOptions { @@ -124,12 +121,12 @@ int main(int argc, char **argv) /* On 1.0.0-2.3.0, Loader services ldr:ro instead of ro. */ server_manager->AddWaitable(new ServiceServer("ldr:ro", 0x20)); } - + /* Loop forever, servicing our services. */ server_manager->Process(); - + delete server_manager; - + return 0; } diff --git a/stratosphere/pm/source/pm_boot2.cpp b/stratosphere/pm/source/pm_boot2.cpp index 410eab8fc..3fc033db7 100644 --- a/stratosphere/pm/source/pm_boot2.cpp +++ b/stratosphere/pm/source/pm_boot2.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -54,12 +54,12 @@ static void ClearLaunchedTitles() { static void LaunchTitle(u64 title_id, FsStorageId storage_id, u32 launch_flags, u64 *pid) { u64 local_pid = 0; - + /* Don't launch a title twice during boot2. */ if (HasLaunchedTitle(title_id)) { return; } - + Result rc = Registration::LaunchProcessByTidSid(Registration::TidSid{title_id, storage_id}, launch_flags, &local_pid); switch (rc) { case ResultKernelResourceExhausted: @@ -81,7 +81,7 @@ static void LaunchTitle(u64 title_id, FsStorageId storage_id, u32 launch_flags, if (pid) { *pid = local_pid; } - + if (R_SUCCEEDED(rc)) { SetLaunchedTitle(title_id); } @@ -92,22 +92,26 @@ static bool GetGpioPadLow(GpioPadName pad) { if (R_FAILED(gpioOpenSession(&button, pad))) { return false; } - + /* Ensure we close even on early return. */ ON_SCOPE_EXIT { gpioPadClose(&button); }; - + /* Set direction input. */ gpioPadSetDirection(&button, GpioDirection_Input); - + GpioValue val; return R_SUCCEEDED(gpioPadGetValue(&button, &val)) && val == GpioValue_Low; } static bool IsMaintenanceMode() { /* Contact set:sys, retrieve boot!force_maintenance. */ - if (R_SUCCEEDED(setsysInitialize())) { + Result rc; + DoWithSmSession([&]() { + rc = setsysInitialize(); + }); + if (R_SUCCEEDED(rc)) { ON_SCOPE_EXIT { setsysExit(); }; - + u8 force_maintenance = 1; setsysGetSettingsItemValue("boot", "force_maintenance", &force_maintenance, sizeof(force_maintenance)); if (force_maintenance != 0) { @@ -116,12 +120,15 @@ static bool IsMaintenanceMode() { } /* Contact GPIO, read plus/minus buttons. */ - if (R_SUCCEEDED(gpioInitialize())) { + DoWithSmSession([&]() { + rc = gpioInitialize(); + }); + if (R_SUCCEEDED(rc)) { ON_SCOPE_EXIT { gpioExit(); }; - + return GetGpioPadLow(GpioPadName_ButtonVolUp) && GetGpioPadLow(GpioPadName_ButtonVolDown); } - + return false; } @@ -168,42 +175,48 @@ static const std::tuple g_additional_launch_programs[] = { }; static void MountSdCard() { - Handle tmp_hnd = 0; - static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; - for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { - if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { - /* TODO: Panic */ - } else { - svcCloseHandle(tmp_hnd); + DoWithSmSession([&]() { + Handle tmp_hnd = 0; + static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; + for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { + if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { + /* TODO: Panic */ + } else { + svcCloseHandle(tmp_hnd); + } } - } + }); fsdevMountSdmc(); } static void WaitForMitm(const char *service) { bool mitm_installed = false; - Result rc = smManagerAmsInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } + Result rc; + DoWithSmSession([&]() { + if (R_FAILED((rc = smManagerAmsInitialize()))) { + std::abort(); + } + }); + while (R_FAILED((rc = smManagerAmsHasMitm(&mitm_installed, service))) || !mitm_installed) { if (R_FAILED(rc)) { std::abort(); } svcSleepThread(1000000ull); } + smManagerAmsExit(); } void EmbeddedBoot2::Main() { /* Wait until fs.mitm has installed itself. We want this to happen as early as possible. */ WaitForMitm("fsp-srv"); - + /* Clear titles. */ ClearLaunchedTitles(); - /* psc, bus, pcv is the minimal set of required titles to get SD card. */ + /* psc, bus, pcv is the minimal set of required titles to get SD card. */ /* bus depends on pcie, and pcv depends on settings. */ /* Launch psc. */ LaunchTitle(TitleId_Psc, FsStorageId_NandSystem, 0, NULL); @@ -215,16 +228,16 @@ void EmbeddedBoot2::Main() { LaunchTitle(TitleId_Settings, FsStorageId_NandSystem, 0, NULL); /* Launch pcv. */ LaunchTitle(TitleId_Pcv, FsStorageId_NandSystem, 0, NULL); - + /* At this point, the SD card can be mounted. */ MountSdCard(); - + /* Find out whether we are maintenance mode. */ bool maintenance = IsMaintenanceMode(); if (maintenance) { BootModeService::SetMaintenanceBootForEmbeddedBoot2(); } - + /* Wait for other atmosphere mitm modules to initialize. */ WaitForMitm("set:sys"); if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) { @@ -232,16 +245,16 @@ void EmbeddedBoot2::Main() { } else { WaitForMitm("bpc:c"); } - + /* Launch usb. */ LaunchTitle(TitleId_Usb, FsStorageId_NandSystem, 0, NULL); - + /* Launch tma. */ LaunchTitle(TitleId_Tma, FsStorageId_NandSystem, 0, NULL); - + /* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */ LaunchTitle(TitleId_Dmnt, FsStorageId_None, 0, NULL); - + /* Launch default programs. */ for (auto &launch_program : g_additional_launch_programs) { if (!maintenance || std::get(launch_program)) { @@ -253,7 +266,7 @@ void EmbeddedBoot2::Main() { LaunchTitle(TitleId_Npns, FsStorageId_NandSystem, 0, NULL); } } - + /* Allow for user-customizable programs. */ DIR *titles_dir = opendir("sdmc:/atmosphere/titles"); struct dirent *ent; @@ -288,10 +301,10 @@ void EmbeddedBoot2::Main() { } closedir(titles_dir); } - + /* We no longer need the SD card. */ fsdevUnmountAll(); - + /* Free the memory used to track what boot2 launches. */ ClearLaunchedTitles(); } diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index 5c53aa250..f380e39cf 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -38,7 +38,7 @@ extern "C" { #define INNER_HEAP_SIZE 0x30000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; - + void __libnx_initheap(void); void __appInit(void); void __appExit(void); @@ -72,10 +72,10 @@ void RegisterPrivilegedProcessesWithFs() { /* Ensures that all privileged processes are registered with full FS permissions. */ constexpr u64 PRIVILEGED_PROCESS_MIN = 0; constexpr u64 PRIVILEGED_PROCESS_MAX = 0x4F; - + const u32 PRIVILEGED_FAH[0x1C/sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000}; const u32 PRIVILEGED_FAC[0x2C/sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}; - + u32 num_pids; u64 pids[PRIVILEGED_PROCESS_MAX+1]; if (R_SUCCEEDED(svcGetProcessList(&num_pids, pids, sizeof(pids)/sizeof(pids[0])))) { @@ -96,54 +96,52 @@ void RegisterPrivilegedProcessesWithFs() { void __appInit(void) { Result rc; - + SetFirmwareVersionForLibnx(); - rc = smInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = fsprInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - /* This works around a bug with process permissions on < 4.0.0. */ - RegisterPrivilegedProcessesWithFs(); - - rc = smManagerAmsInitialize(); - if (R_SUCCEEDED(rc)) { - smManagerAmsEndInitialDefers(); - } else { - std::abort(); - } - - rc = smManagerInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = lrInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = ldrPmInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = splInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - - rc = fsInitialize(); - if (R_FAILED(rc)) { - std::abort(); - } - + DoWithSmSession([&]() { + rc = fsprInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + /* This works around a bug with process permissions on < 4.0.0. */ + RegisterPrivilegedProcessesWithFs(); + + rc = smManagerAmsInitialize(); + if (R_SUCCEEDED(rc)) { + smManagerAmsEndInitialDefers(); + smManagerAmsExit(); + } else { + std::abort(); + } + + rc = smManagerInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = lrInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = ldrPmInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = splInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + + rc = fsInitialize(); + if (R_FAILED(rc)) { + std::abort(); + } + }); + CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); } @@ -156,14 +154,13 @@ void __appExit(void) { fsprExit(); lrExit(); fsExit(); - smExit(); } int main(int argc, char **argv) { HosThread process_track_thread; consoleDebugInit(debugDevice_SVC); - + /* Initialize and spawn the Process Tracking thread. */ Registration::InitializeSystemResources(); if (R_FAILED(process_track_thread.Initialize(&ProcessTracking::MainLoop, NULL, 0x4000, 0x15))) { @@ -172,19 +169,19 @@ int main(int argc, char **argv) if (R_FAILED(process_track_thread.Start())) { /* TODO: Panic. */ } - + /* TODO: What's a good timeout value to use here? */ auto server_manager = new WaitableManager(1); - + /* TODO: Create services. */ server_manager->AddWaitable(new ServiceServer("pm:shell", 3)); server_manager->AddWaitable(new ServiceServer("pm:dmnt", 2)); server_manager->AddWaitable(new ServiceServer("pm:bm", 6)); server_manager->AddWaitable(new ServiceServer("pm:info", 1)); - + /* Loop forever, servicing our services. */ server_manager->Process(); - + /* Cleanup. */ delete server_manager; return 0;