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;