stratosphere: only hold sm sessions open when needed

This commit is contained in:
Michael Scire 2019-04-22 12:40:53 -07:00
parent c3875796df
commit b09adb6a34
16 changed files with 432 additions and 403 deletions

View file

@ -73,15 +73,12 @@ void __appInit(void) {
SetFirmwareVersionForLibnx(); SetFirmwareVersionForLibnx();
rc = smInitialize(); DoWithSmSession([&]() {
if (R_FAILED(rc)) { rc = fsInitialize();
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); if (R_FAILED(rc)) {
} std::abort();
}
rc = fsInitialize(); });
if (R_FAILED(rc)) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
}
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
} }
@ -89,7 +86,6 @@ void __appInit(void) {
void __appExit(void) { void __appExit(void) {
/* Cleanup services. */ /* Cleanup services. */
fsExit(); fsExit();
smExit();
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -100,10 +96,10 @@ int main(int argc, char **argv)
LaunchAllMitmModules(); LaunchAllMitmModules();
if (R_FAILED(initializer_thread.Initialize(&Utils::InitializeThreadFunc, NULL, 0x4000, 0x15))) { if (R_FAILED(initializer_thread.Initialize(&Utils::InitializeThreadFunc, NULL, 0x4000, 0x15))) {
/* TODO: Panic. */ std::abort();
} }
if (R_FAILED(initializer_thread.Start())) { if (R_FAILED(initializer_thread.Start())) {
/* TODO: Panic. */ std::abort();
} }
/* Wait for all mitm modules to end. */ /* Wait for all mitm modules to end. */

View file

@ -35,12 +35,12 @@ void NsMitmMain(void *arg) {
Utils::WaitSdInitialized(); Utils::WaitSdInitialized();
/* Ensure we can talk to NS. */ /* Ensure we can talk to NS. */
{ DoWithSmSession([&]() {
if (R_FAILED(nsInitialize())) { if (R_FAILED(nsInitialize())) {
std::abort(); std::abort();
} }
nsExit(); nsExit();
} });
/* Create server manager */ /* Create server manager */
auto server_manager = new WaitableManager(1); auto server_manager = new WaitableManager(1);

View file

@ -78,15 +78,17 @@ static bool IsHexadecimal(const char *str) {
void Utils::InitializeThreadFunc(void *args) { void Utils::InitializeThreadFunc(void *args) {
/* Get required services. */ /* Get required services. */
Handle tmp_hnd = 0; DoWithSmSession([&]() {
static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; Handle tmp_hnd = 0;
for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"};
if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) {
/* TODO: Panic */ if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) {
} else { /* TODO: Panic */
svcCloseHandle(tmp_hnd); } else {
svcCloseHandle(tmp_hnd);
}
} }
} });
/* Mount SD. */ /* Mount SD. */
while (R_FAILED(fsMountSdcard(&g_sd_filesystem))) { while (R_FAILED(fsMountSdcard(&g_sd_filesystem))) {
@ -197,7 +199,11 @@ void Utils::InitializeThreadFunc(void *args) {
Utils::RefreshConfiguration(); Utils::RefreshConfiguration();
/* Initialize set:sys. */ /* Initialize set:sys. */
setsysInitialize(); DoWithSmSession([&]() {
if (R_FAILED(setsysInitialize())) {
std::abort();
}
});
/* Signal SD is initialized. */ /* Signal SD is initialized. */
g_has_initialized = true; g_has_initialized = true;
@ -209,13 +215,15 @@ void Utils::InitializeThreadFunc(void *args) {
g_sd_signal.Signal(); g_sd_signal.Signal();
/* Initialize HID. */ /* Initialize HID. */
{ while (!g_has_hid_session) {
DoWithSmSession([&]() {
while (R_FAILED(hidInitialize())) { if (R_SUCCEEDED(hidInitialize())) {
g_has_hid_session = true;
}
});
if (!g_has_hid_session) {
svcSleepThread(1000000ULL); svcSleepThread(1000000ULL);
} }
g_has_hid_session = true;
} }
} }

View file

@ -80,30 +80,27 @@ void __appInit(void) {
SetFirmwareVersionForLibnx(); SetFirmwareVersionForLibnx();
/* Initialize services we need (TODO: NCM) */ /* Initialize services we need (TODO: NCM) */
rc = smInitialize(); DoWithSmSession([&]() {
if (R_FAILED(rc)) { rc = fsInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = fsInitialize();
if (R_FAILED(rc)) { rc = splInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = splInitialize();
if (R_FAILED(rc)) { rc = pmshellInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = pmshellInitialize();
if (R_FAILED(rc)) { rc = fsdevMountSdmc();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = fsdevMountSdmc(); });
if (R_FAILED(rc)) {
std::abort();
}
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
} }
@ -114,7 +111,6 @@ void __appExit(void) {
pmshellExit(); pmshellExit();
splExit(); splExit();
fsExit(); fsExit();
smExit();
} }
typedef enum { typedef enum {

View file

@ -240,19 +240,28 @@ bool CrashReport::GetCurrentTime(u64 *out) {
/* Verify that pcv isn't dead. */ /* Verify that pcv isn't dead. */
{ {
Handle dummy; bool has_time_service;
if (R_SUCCEEDED(smRegisterService(&dummy, "time:s", false, 0x20))) { DoWithSmSession([&]() {
svcCloseHandle(dummy); 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; return false;
} }
} }
/* Try to get the current time. */ /* Try to get the current time. */
bool success = false; bool success = true;
if (R_SUCCEEDED(timeInitialize())) { DoWithSmSession([&]() {
if (R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out))) { success &= R_SUCCEEDED(timeInitialize());
success = true; });
} if (success) {
success &= R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out));
timeExit(); timeExit();
} }
return success; return success;

View file

@ -68,16 +68,13 @@ void __appInit(void) {
Result rc; Result rc;
SetFirmwareVersionForLibnx(); SetFirmwareVersionForLibnx();
rc = smInitialize();
if (R_FAILED(rc)) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
}
rc = fsInitialize(); DoWithSmSession([&]() {
if (R_FAILED(rc)) { rc = fsInitialize();
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); if (R_FAILED(rc)) {
} fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
}
});
rc = fsdevMountSdmc(); rc = fsdevMountSdmc();
if (R_FAILED(rc)) { if (R_FAILED(rc)) {
@ -89,7 +86,6 @@ void __appExit(void) {
/* Cleanup services. */ /* Cleanup services. */
fsdevUnmountAll(); fsdevUnmountAll();
fsExit(); fsExit();
smExit();
} }
static u64 creport_parse_u64(char *s) { static u64 creport_parse_u64(char *s) {
@ -127,10 +123,12 @@ int main(int argc, char **argv) {
if (g_Creport.WasSuccessful()) { if (g_Creport.WasSuccessful()) {
g_Creport.SaveReport(); g_Creport.SaveReport();
if (R_SUCCEEDED(nsdevInitialize())) { DoWithSmSession([&]() {
nsdevTerminateProcess(crashed_pid); if (R_SUCCEEDED(nsdevInitialize())) {
nsdevExit(); nsdevTerminateProcess(crashed_pid);
} nsdevExit();
}
});
/* Don't fatal if we have extra info. */ /* Don't fatal if we have extra info. */
if (kernelAbove500()) { if (kernelAbove500()) {

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> #include <cstdlib>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
@ -36,7 +36,7 @@ extern "C" {
#define INNER_HEAP_SIZE 0x80000 #define INNER_HEAP_SIZE 0x80000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE]; char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void); void __libnx_initheap(void);
void __appInit(void); void __appInit(void);
void __appExit(void); void __appExit(void);
@ -68,64 +68,61 @@ void __libnx_initheap(void) {
void __appInit(void) { void __appInit(void) {
Result rc; Result rc;
SetFirmwareVersionForLibnx(); SetFirmwareVersionForLibnx();
rc = smInitialize(); DoWithSmSession([&]() {
if (R_FAILED(rc)) { rc = pmdmntInitialize();
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = pmdmntInitialize();
if (R_FAILED(rc)) { rc = ldrDmntInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = ldrDmntInitialize();
if (R_FAILED(rc)) { rc = roDmntInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = roDmntInitialize();
if (R_FAILED(rc)) { rc = nsdevInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = nsdevInitialize();
if (R_FAILED(rc)) { rc = lrInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = lrInitialize();
if (R_FAILED(rc)) { rc = setInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = setInitialize();
if (R_FAILED(rc)) { rc = setsysInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = setsysInitialize();
if (R_FAILED(rc)) { rc = hidInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = hidInitialize();
if (R_FAILED(rc)) { rc = fsInitialize();
fatalSimple(rc); if (R_FAILED(rc)) {
} fatalSimple(rc);
}
rc = fsInitialize(); });
if (R_FAILED(rc)) {
fatalSimple(rc);
}
rc = fsdevMountSdmc(); rc = fsdevMountSdmc();
if (R_FAILED(rc)) { if (R_FAILED(rc)) {
fatalSimple(rc); fatalSimple(rc);
} }
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
} }
@ -141,28 +138,27 @@ void __appExit(void) {
roDmntExit(); roDmntExit();
ldrDmntExit(); ldrDmntExit();
pmdmntExit(); pmdmntExit();
smExit();
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
consoleDebugInit(debugDevice_SVC); consoleDebugInit(debugDevice_SVC);
/* Initialize configuration manager. */ /* Initialize configuration manager. */
DmntConfigManager::RefreshConfiguration(); DmntConfigManager::RefreshConfiguration();
/* Start cheat manager. */ /* Start cheat manager. */
DmntCheatManager::InitializeCheatManager(); DmntCheatManager::InitializeCheatManager();
/* Nintendo uses four threads. Add a fifth for our cheat service. */ /* Nintendo uses four threads. Add a fifth for our cheat service. */
auto server_manager = new WaitableManager(5); auto server_manager = new WaitableManager(5);
/* Create services. */ /* Create services. */
/* TODO: Implement rest of dmnt:- in ams.tma development branch. */ /* TODO: Implement rest of dmnt:- in ams.tma development branch. */
/* server_manager->AddWaitable(new ServiceServer<DebugMonitorService>("dmnt:-", 4)); */ /* server_manager->AddWaitable(new ServiceServer<DebugMonitorService>("dmnt:-", 4)); */
server_manager->AddWaitable(new ServiceServer<DmntCheatService>("dmnt:cht", 1)); server_manager->AddWaitable(new ServiceServer<DmntCheatService>("dmnt:cht", 1));
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> #include <cstdlib>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
@ -38,10 +38,10 @@ extern "C" {
#define INNER_HEAP_SIZE 0x2A0000 #define INNER_HEAP_SIZE 0x2A0000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE]; char nx_inner_heap[INNER_HEAP_SIZE];
u32 __nx_nv_transfermem_size = 0x40000; u32 __nx_nv_transfermem_size = 0x40000;
ViLayerFlags __nx_vi_stray_layer_flags = (ViLayerFlags)0; ViLayerFlags __nx_vi_stray_layer_flags = (ViLayerFlags)0;
void __libnx_initheap(void); void __libnx_initheap(void);
void __appInit(void); void __appInit(void);
void __appExit(void); void __appExit(void);
@ -73,79 +73,76 @@ void __libnx_initheap(void) {
void __appInit(void) { void __appInit(void) {
Result rc; Result rc;
SetFirmwareVersionForLibnx(); SetFirmwareVersionForLibnx();
rc = smInitialize(); DoWithSmSession([&]() {
if (R_FAILED(rc)) { rc = setInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = setInitialize();
if (R_FAILED(rc)) { rc = setsysInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = setsysInitialize();
if (R_FAILED(rc)) { rc = pminfoInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = pminfoInitialize();
if (R_FAILED(rc)) { rc = i2cInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = i2cInitialize();
if (R_FAILED(rc)) { rc = bpcInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = bpcInitialize();
if (R_FAILED(rc)) { rc = pcvInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = pcvInitialize();
if (R_FAILED(rc)) { rc = lblInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = lblInitialize();
if (R_FAILED(rc)) { rc = psmInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = psmInitialize();
if (R_FAILED(rc)) { rc = spsmInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = spsmInitialize();
if (R_FAILED(rc)) { rc = plInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = plInitialize();
if (R_FAILED(rc)) { rc = gpioInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = gpioInitialize();
if (R_FAILED(rc)) { rc = fsInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = fsInitialize(); });
if (R_FAILED(rc)) {
std::abort();
}
rc = fsdevMountSdmc(); rc = fsdevMountSdmc();
if (R_FAILED(rc)) { if (R_FAILED(rc)) {
std::abort(); std::abort();
} }
/* fatal cannot throw fatal, so don't do: CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); */ /* fatal cannot throw fatal, so don't do: CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); */
} }
@ -164,14 +161,13 @@ void __appExit(void) {
pminfoExit(); pminfoExit();
setsysExit(); setsysExit();
setExit(); setExit();
smExit();
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
/* Load settings from set:sys. */ /* Load settings from set:sys. */
InitializeFatalConfig(); InitializeFatalConfig();
/* Load shared font. */ /* Load shared font. */
if (R_FAILED(FontManager::InitializeSharedFont())) { if (R_FAILED(FontManager::InitializeSharedFont())) {
std::abort(); std::abort();

View file

@ -38,19 +38,28 @@ bool ErrorReportTask::GetCurrentTime(u64 *out) {
/* Verify that pcv isn't dead. */ /* Verify that pcv isn't dead. */
{ {
Handle dummy; bool has_time_service;
if (R_SUCCEEDED(smRegisterService(&dummy, "time:s", false, 0x20))) { DoWithSmSession([&]() {
svcCloseHandle(dummy); 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; return false;
} }
} }
/* Try to get the current time. */ /* Try to get the current time. */
bool success = false; bool success = true;
if (R_SUCCEEDED(timeInitialize())) { DoWithSmSession([&]() {
if (R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out))) { success &= R_SUCCEEDED(timeInitialize());
success = true; });
} if (success) {
success &= R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out));
timeExit(); timeExit();
} }
return success; return success;

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <switch.h> #include <switch.h>
#include <atmosphere/version.h> #include <atmosphere/version.h>
@ -55,17 +55,17 @@ Result ShowFatalTask::SetupDisplayInternal() {
} }
/* Guarantee we close the display. */ /* Guarantee we close the display. */
ON_SCOPE_EXIT { viCloseDisplay(&display); }; ON_SCOPE_EXIT { viCloseDisplay(&display); };
/* Turn on the screen. */ /* Turn on the screen. */
if (R_FAILED((rc = viSetDisplayPowerState(&display, ViPowerState_On)))) { if (R_FAILED((rc = viSetDisplayPowerState(&display, ViPowerState_On)))) {
return rc; return rc;
} }
/* Set alpha to 1.0f. */ /* Set alpha to 1.0f. */
if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) { if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) {
return rc; return rc;
} }
return rc; return rc;
} }
@ -82,54 +82,57 @@ Result ShowFatalTask::SetupDisplayExternal() {
} }
/* Guarantee we close the display. */ /* Guarantee we close the display. */
ON_SCOPE_EXIT { viCloseDisplay(&display); }; ON_SCOPE_EXIT { viCloseDisplay(&display); };
/* Set alpha to 1.0f. */ /* Set alpha to 1.0f. */
if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) { if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) {
return rc; return rc;
} }
return rc; return rc;
} }
Result ShowFatalTask::PrepareScreenForDrawing() { Result ShowFatalTask::PrepareScreenForDrawing() {
Result rc = ResultSuccess; Result rc = ResultSuccess;
/* Connect to vi. */ /* Connect to vi. */
if (R_FAILED((rc = viInitialize(ViServiceType_Manager)))) { DoWithSmSession([&]() {
rc = viInitialize(ViServiceType_Manager);
});
if (R_FAILED(rc)) {
return rc; return rc;
} }
/* Close other content. */ /* Close other content. */
viSetContentVisibility(false); viSetContentVisibility(false);
/* Setup the two displays. */ /* Setup the two displays. */
if (R_FAILED((rc = SetupDisplayInternal())) || R_FAILED((rc = SetupDisplayExternal()))) { if (R_FAILED((rc = SetupDisplayInternal())) || R_FAILED((rc = SetupDisplayExternal()))) {
return rc; return rc;
} }
/* Open the default display. */ /* Open the default display. */
if (R_FAILED((rc = viOpenDefaultDisplay(&this->display)))) { if (R_FAILED((rc = viOpenDefaultDisplay(&this->display)))) {
return rc; return rc;
} }
/* Reset the display magnification to its default value. */ /* Reset the display magnification to its default value. */
u32 display_width, display_height; u32 display_width, display_height;
if (R_FAILED((rc = viGetDisplayLogicalResolution(&this->display, &display_width, &display_height)))) { if (R_FAILED((rc = viGetDisplayLogicalResolution(&this->display, &display_width, &display_height)))) {
return rc; return rc;
} }
/* viSetDisplayMagnification was added in 3.0.0. */ /* viSetDisplayMagnification was added in 3.0.0. */
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_300) { if (GetRuntimeFirmwareVersion() >= FirmwareVersion_300) {
if (R_FAILED((rc = viSetDisplayMagnification(&this->display, 0, 0, display_width, display_height)))) { if (R_FAILED((rc = viSetDisplayMagnification(&this->display, 0, 0, display_width, display_height)))) {
return rc; return rc;
} }
} }
/* Create layer to draw to. */ /* Create layer to draw to. */
if (R_FAILED((rc = viCreateLayer(&this->display, &this->layer)))) { if (R_FAILED((rc = viCreateLayer(&this->display, &this->layer)))) {
return rc; return rc;
} }
/* Setup the layer. */ /* Setup the layer. */
{ {
/* Display a layer of 1280 x 720 at 1.5x magnification */ /* 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 raw_height = FatalScreenHeight;
constexpr u32 layer_width = ((raw_width) * 3) / 2; constexpr u32 layer_width = ((raw_width) * 3) / 2;
constexpr u32 layer_height = ((raw_height) * 3) / 2; constexpr u32 layer_height = ((raw_height) * 3) / 2;
const float layer_x = static_cast<float>((display_width - layer_width) / 2); const float layer_x = static_cast<float>((display_width - layer_width) / 2);
const float layer_y = static_cast<float>((display_height - layer_height) / 2); const float layer_y = static_cast<float>((display_height - layer_height) / 2);
u64 layer_z; u64 layer_z;
if (R_FAILED((rc = viSetLayerSize(&this->layer, layer_width, layer_height)))) { if (R_FAILED((rc = viSetLayerSize(&this->layer, layer_width, layer_height)))) {
return rc; return rc;
} }
/* Set the layer's Z at display maximum, to be above everything else .*/ /* Set the layer's Z at display maximum, to be above everything else .*/
/* NOTE: Fatal hardcodes 100 here. */ /* NOTE: Fatal hardcodes 100 here. */
if (R_SUCCEEDED((rc = viGetDisplayMaximumZ(&this->display, &layer_z)))) { if (R_SUCCEEDED((rc = viGetDisplayMaximumZ(&this->display, &layer_z)))) {
@ -155,12 +158,12 @@ Result ShowFatalTask::PrepareScreenForDrawing() {
return rc; return rc;
} }
} }
/* Center the layer in the screen. */ /* Center the layer in the screen. */
if (R_FAILED((rc = viSetLayerPosition(&this->layer, layer_x, layer_y)))) { if (R_FAILED((rc = viSetLayerPosition(&this->layer, layer_x, layer_y)))) {
return rc; return rc;
} }
/* Create framebuffer. */ /* Create framebuffer. */
if (R_FAILED(rc = nwindowCreateFromLayer(&this->win, &this->layer))) { if (R_FAILED(rc = nwindowCreateFromLayer(&this->win, &this->layer))) {
return rc; return rc;
@ -169,7 +172,7 @@ Result ShowFatalTask::PrepareScreenForDrawing() {
return rc; return rc;
} }
} }
return rc; return rc;
} }
@ -182,29 +185,29 @@ Result ShowFatalTask::ShowFatal() {
*(volatile u32 *)(0xCAFEBABE) = rc; *(volatile u32 *)(0xCAFEBABE) = rc;
return rc; return rc;
} }
/* Dequeue a buffer. */ /* Dequeue a buffer. */
u16 *tiled_buf = reinterpret_cast<u16 *>(framebufferBegin(&this->fb, NULL)); u16 *tiled_buf = reinterpret_cast<u16 *>(framebufferBegin(&this->fb, NULL));
if (tiled_buf == nullptr) { if (tiled_buf == nullptr) {
return ResultFatalNullGraphicsBuffer; return ResultFatalNullGraphicsBuffer;
} }
/* Let the font manager know about our framebuffer. */ /* Let the font manager know about our framebuffer. */
FontManager::ConfigureFontFramebuffer(tiled_buf, GetPixelOffset); FontManager::ConfigureFontFramebuffer(tiled_buf, GetPixelOffset);
FontManager::SetFontColor(0xFFFF); FontManager::SetFontColor(0xFFFF);
/* Draw a background. */ /* Draw a background. */
for (size_t i = 0; i < this->fb.fb_size / sizeof(*tiled_buf); i++) { for (size_t i = 0; i < this->fb.fb_size / sizeof(*tiled_buf); i++) {
tiled_buf[i] = 0x39C9; tiled_buf[i] = 0x39C9;
} }
/* Draw the atmosphere logo in the bottom right corner. */ /* Draw the atmosphere logo in the bottom right corner. */
for (size_t y = 0; y < AMS_LOGO_HEIGHT; y++) { for (size_t y = 0; y < AMS_LOGO_HEIGHT; y++) {
for (size_t x = 0; x < AMS_LOGO_WIDTH; x++) { 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]; 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. */ /* TODO: Actually draw meaningful shit here. */
FontManager::SetPosition(32, 64); FontManager::SetPosition(32, 64);
FontManager::SetFontSize(16.0f); FontManager::SetFontSize(16.0f);
@ -225,18 +228,18 @@ Result ShowFatalTask::ShowFatal() {
u8"Please ensure that all Atmosphère components are updated.\n" u8"Please ensure that all Atmosphère components are updated.\n"
u8"github.com/Atmosphere-NX/Atmosphere/releases\n"); u8"github.com/Atmosphere-NX/Atmosphere/releases\n");
} }
/* Add a line. */ /* Add a line. */
for (size_t x = 32; x < FatalScreenWidth - 32; x++) { for (size_t x = 32; x < FatalScreenWidth - 32; x++) {
tiled_buf[GetPixelOffset(x, FontManager::GetY())] = 0xFFFF; tiled_buf[GetPixelOffset(x, FontManager::GetY())] = 0xFFFF;
} }
FontManager::AddSpacingLines(1.5f); FontManager::AddSpacingLines(1.5f);
u32 backtrace_y = FontManager::GetY(); u32 backtrace_y = FontManager::GetY();
u32 backtrace_x = 0; u32 backtrace_x = 0;
/* Print GPRs. */ /* Print GPRs. */
FontManager::SetFontSize(14.0f); FontManager::SetFontSize(14.0f);
FontManager::Print("General Purpose Registers "); FontManager::Print("General Purpose Registers ");
@ -278,7 +281,7 @@ Result ShowFatalTask::ShowFatal() {
FontManager::Print(" "); FontManager::Print(" ");
backtrace_x = FontManager::GetX(); backtrace_x = FontManager::GetX();
} }
FontManager::PrintLine(""); FontManager::PrintLine("");
FontManager::SetPosition(32, FontManager::GetY()); FontManager::SetPosition(32, FontManager::GetY());
} }
@ -306,12 +309,12 @@ Result ShowFatalTask::ShowFatal() {
FontManager::Print(" "); FontManager::Print(" ");
backtrace_x = FontManager::GetX(); backtrace_x = FontManager::GetX();
} }
FontManager::PrintLine(""); FontManager::PrintLine("");
FontManager::SetPosition(32, FontManager::GetY()); FontManager::SetPosition(32, FontManager::GetY());
} }
} }
/* Print Backtrace. */ /* Print Backtrace. */
u32 bt_size; u32 bt_size;
if (this->ctx->cpu_ctx.is_aarch32) { if (this->ctx->cpu_ctx.is_aarch32) {
@ -319,8 +322,8 @@ Result ShowFatalTask::ShowFatal() {
} else { } else {
bt_size = this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size; bt_size = this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size;
} }
FontManager::SetPosition(backtrace_x, backtrace_y); FontManager::SetPosition(backtrace_x, backtrace_y);
if (bt_size == 0) { if (bt_size == 0) {
if (this->ctx->cpu_ctx.is_aarch32) { 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) { 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]; 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) { if (i < this->ctx->cpu_ctx.aarch32_ctx.stack_trace_size) {
u32 x = FontManager::GetX(); u32 x = FontManager::GetX();
FontManager::PrintFormat("BT[%02d]: ", i); FontManager::PrintFormat("BT[%02d]: ", i);
@ -354,14 +357,14 @@ Result ShowFatalTask::ShowFatal() {
FontManager::PrintMonospaceU32(bt_cur); FontManager::PrintMonospaceU32(bt_cur);
FontManager::Print(" "); FontManager::Print(" ");
} }
if (i + Aarch32CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch32_ctx.stack_trace_size) { if (i + Aarch32CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch32_ctx.stack_trace_size) {
u32 x = FontManager::GetX(); u32 x = FontManager::GetX();
FontManager::PrintFormat("BT[%02d]: ", i + Aarch32CpuContext::MaxStackTraceDepth / 2); FontManager::PrintFormat("BT[%02d]: ", i + Aarch32CpuContext::MaxStackTraceDepth / 2);
FontManager::SetPosition(x + 72, FontManager::GetY()); FontManager::SetPosition(x + 72, FontManager::GetY());
FontManager::PrintMonospaceU32(bt_next); FontManager::PrintMonospaceU32(bt_next);
} }
FontManager::PrintLine(""); FontManager::PrintLine("");
FontManager::SetPosition(backtrace_x, FontManager::GetY()); 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) { 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]; 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) { if (i < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) {
u32 x = FontManager::GetX(); u32 x = FontManager::GetX();
FontManager::PrintFormat("BT[%02d]: ", i); FontManager::PrintFormat("BT[%02d]: ", i);
@ -386,24 +389,24 @@ Result ShowFatalTask::ShowFatal() {
FontManager::PrintMonospaceU64(bt_cur); FontManager::PrintMonospaceU64(bt_cur);
FontManager::Print(" "); FontManager::Print(" ");
} }
if (i + Aarch64CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) { if (i + Aarch64CpuContext::MaxStackTraceDepth / 2 < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) {
u32 x = FontManager::GetX(); u32 x = FontManager::GetX();
FontManager::PrintFormat("BT[%02d]: ", i + Aarch64CpuContext::MaxStackTraceDepth / 2); FontManager::PrintFormat("BT[%02d]: ", i + Aarch64CpuContext::MaxStackTraceDepth / 2);
FontManager::SetPosition(x + 72, FontManager::GetY()); FontManager::SetPosition(x + 72, FontManager::GetY());
FontManager::PrintMonospaceU64(bt_next); FontManager::PrintMonospaceU64(bt_next);
} }
FontManager::PrintLine(""); FontManager::PrintLine("");
FontManager::SetPosition(backtrace_x, FontManager::GetY()); FontManager::SetPosition(backtrace_x, FontManager::GetY());
} }
} }
} }
/* Enqueue the buffer. */ /* Enqueue the buffer. */
framebufferEnd(&fb); framebufferEnd(&fb);
return rc; return rc;
} }

@ -1 +1 @@
Subproject commit 880bce9092fbef0bcbf101b8ec2e3d2c5af3fb98 Subproject commit 79bc9bf8d87dddcfc2d080626eb8c817c7339fd0

View file

@ -94,19 +94,20 @@ Result ContentManagement::MountCode(u64 tid, FsStorageId sid) {
} }
/* Always re-initialize fsp-ldr, in case it's closed */ /* Always re-initialize fsp-ldr, in case it's closed */
if (R_FAILED(rc = fsldrInitialize())) { DoWithSmSession([&]() {
rc = fsldrInitialize();
});
if (R_FAILED(rc)) {
return rc; return rc;
} }
ON_SCOPE_EXIT { fsldrExit(); };
if (R_FAILED(rc = fsldrOpenCodeFileSystem(tid, path, &g_CodeFileSystem))) { if (R_FAILED(rc = fsldrOpenCodeFileSystem(tid, path, &g_CodeFileSystem))) {
fsldrExit();
return rc; return rc;
} }
fsdevMountDevice("code", g_CodeFileSystem); fsdevMountDevice("code", g_CodeFileSystem);
TryMountHblNspOnSd(); TryMountHblNspOnSd();
fsldrExit();
return rc; return rc;
} }
@ -372,17 +373,21 @@ void ContentManagement::RefreshConfigurationData() {
void ContentManagement::TryMountSdCard() { void ContentManagement::TryMountSdCard() {
/* Mount SD card, if psc, bus, and pcv have been created. */ /* 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)) { if (!g_has_initialized_fs_dev && HasCreatedTitle(TitleId_Psc) && HasCreatedTitle(TitleId_Bus) && HasCreatedTitle(TitleId_Pcv)) {
Handle tmp_hnd = 0; bool can_mount = true;
static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; DoWithSmSession([&]() {
for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { Handle tmp_hnd = 0;
if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"};
return; for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) {
} else { if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) {
svcCloseHandle(tmp_hnd); can_mount = false;
break;
} else {
svcCloseHandle(tmp_hnd);
}
} }
} });
if (R_SUCCEEDED(fsdevMountSdmc())) { if (can_mount && R_SUCCEEDED(fsdevMountSdmc())) {
g_has_initialized_fs_dev = true; g_has_initialized_fs_dev = true;
} }
} }

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <switch.h> #include <switch.h>
#include <string.h> #include <string.h>
@ -24,13 +24,19 @@ Result HidManagement::GetKeysHeld(u64 *keys) {
if (!ContentManagement::HasCreatedTitle(TitleId_Hid)) { if (!ContentManagement::HasCreatedTitle(TitleId_Hid)) {
return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID); return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID);
} }
if (!serviceIsActive(hidGetSessionService()) && R_FAILED(hidInitialize())) { if (!serviceIsActive(hidGetSessionService())) {
return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID); Result rc;
DoWithSmSession([&]() {
rc = hidInitialize();
});
if (R_FAILED(rc)) {
return MAKERESULT(Module_Libnx, LibnxError_InitFail_HID);
}
} }
hidScanInput(); hidScanInput();
*keys = hidKeysHeld(CONTROLLER_P1_AUTO); *keys = hidKeysHeld(CONTROLLER_P1_AUTO);
return ResultSuccess; return ResultSuccess;
} }

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> #include <cstdlib>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
@ -36,7 +36,7 @@ extern "C" {
#define INNER_HEAP_SIZE 0x30000 #define INNER_HEAP_SIZE 0x30000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE]; char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void); void __libnx_initheap(void);
void __appInit(void); void __appInit(void);
void __appExit(void); void __appExit(void);
@ -68,30 +68,28 @@ void __libnx_initheap(void) {
void __appInit(void) { void __appInit(void) {
Result rc; Result rc;
SetFirmwareVersionForLibnx(); SetFirmwareVersionForLibnx();
/* Initialize services we need (TODO: SPL) */ /* Initialize services we need (TODO: SPL) */
rc = smInitialize(); DoWithSmSession([&]() {
if (R_FAILED(rc)) { rc = fsInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = fsInitialize();
if (R_FAILED(rc)) { rc = lrInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = lrInitialize();
if (R_FAILED(rc)) { rc = fsldrInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = fsldrInitialize(); });
if (R_FAILED(rc)) {
std::abort();
}
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
} }
@ -101,7 +99,6 @@ void __appExit(void) {
fsldrExit(); fsldrExit();
lrExit(); lrExit();
fsExit(); fsExit();
smExit();
} }
struct LoaderServerOptions { 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. */ /* On 1.0.0-2.3.0, Loader services ldr:ro instead of ro. */
server_manager->AddWaitable(new ServiceServer<RelocatableObjectsService>("ldr:ro", 0x20)); server_manager->AddWaitable(new ServiceServer<RelocatableObjectsService>("ldr:ro", 0x20));
} }
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
server_manager->Process(); server_manager->Process();
delete server_manager; delete server_manager;
return 0; return 0;
} }

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> #include <cstdlib>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
@ -54,12 +54,12 @@ static void ClearLaunchedTitles() {
static void LaunchTitle(u64 title_id, FsStorageId storage_id, u32 launch_flags, u64 *pid) { static void LaunchTitle(u64 title_id, FsStorageId storage_id, u32 launch_flags, u64 *pid) {
u64 local_pid = 0; u64 local_pid = 0;
/* Don't launch a title twice during boot2. */ /* Don't launch a title twice during boot2. */
if (HasLaunchedTitle(title_id)) { if (HasLaunchedTitle(title_id)) {
return; return;
} }
Result rc = Registration::LaunchProcessByTidSid(Registration::TidSid{title_id, storage_id}, launch_flags, &local_pid); Result rc = Registration::LaunchProcessByTidSid(Registration::TidSid{title_id, storage_id}, launch_flags, &local_pid);
switch (rc) { switch (rc) {
case ResultKernelResourceExhausted: case ResultKernelResourceExhausted:
@ -81,7 +81,7 @@ static void LaunchTitle(u64 title_id, FsStorageId storage_id, u32 launch_flags,
if (pid) { if (pid) {
*pid = local_pid; *pid = local_pid;
} }
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
SetLaunchedTitle(title_id); SetLaunchedTitle(title_id);
} }
@ -92,22 +92,26 @@ static bool GetGpioPadLow(GpioPadName pad) {
if (R_FAILED(gpioOpenSession(&button, pad))) { if (R_FAILED(gpioOpenSession(&button, pad))) {
return false; return false;
} }
/* Ensure we close even on early return. */ /* Ensure we close even on early return. */
ON_SCOPE_EXIT { gpioPadClose(&button); }; ON_SCOPE_EXIT { gpioPadClose(&button); };
/* Set direction input. */ /* Set direction input. */
gpioPadSetDirection(&button, GpioDirection_Input); gpioPadSetDirection(&button, GpioDirection_Input);
GpioValue val; GpioValue val;
return R_SUCCEEDED(gpioPadGetValue(&button, &val)) && val == GpioValue_Low; return R_SUCCEEDED(gpioPadGetValue(&button, &val)) && val == GpioValue_Low;
} }
static bool IsMaintenanceMode() { static bool IsMaintenanceMode() {
/* Contact set:sys, retrieve boot!force_maintenance. */ /* Contact set:sys, retrieve boot!force_maintenance. */
if (R_SUCCEEDED(setsysInitialize())) { Result rc;
DoWithSmSession([&]() {
rc = setsysInitialize();
});
if (R_SUCCEEDED(rc)) {
ON_SCOPE_EXIT { setsysExit(); }; ON_SCOPE_EXIT { setsysExit(); };
u8 force_maintenance = 1; u8 force_maintenance = 1;
setsysGetSettingsItemValue("boot", "force_maintenance", &force_maintenance, sizeof(force_maintenance)); setsysGetSettingsItemValue("boot", "force_maintenance", &force_maintenance, sizeof(force_maintenance));
if (force_maintenance != 0) { if (force_maintenance != 0) {
@ -116,12 +120,15 @@ static bool IsMaintenanceMode() {
} }
/* Contact GPIO, read plus/minus buttons. */ /* Contact GPIO, read plus/minus buttons. */
if (R_SUCCEEDED(gpioInitialize())) { DoWithSmSession([&]() {
rc = gpioInitialize();
});
if (R_SUCCEEDED(rc)) {
ON_SCOPE_EXIT { gpioExit(); }; ON_SCOPE_EXIT { gpioExit(); };
return GetGpioPadLow(GpioPadName_ButtonVolUp) && GetGpioPadLow(GpioPadName_ButtonVolDown); return GetGpioPadLow(GpioPadName_ButtonVolUp) && GetGpioPadLow(GpioPadName_ButtonVolDown);
} }
return false; return false;
} }
@ -168,42 +175,48 @@ static const std::tuple<u64, bool> g_additional_launch_programs[] = {
}; };
static void MountSdCard() { static void MountSdCard() {
Handle tmp_hnd = 0; DoWithSmSession([&]() {
static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"}; Handle tmp_hnd = 0;
for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) { static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"};
if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) { for (unsigned int i = 0; i < sizeof(required_active_services) / sizeof(required_active_services[0]); i++) {
/* TODO: Panic */ if (R_FAILED(smGetServiceOriginal(&tmp_hnd, smEncodeName(required_active_services[i])))) {
} else { /* TODO: Panic */
svcCloseHandle(tmp_hnd); } else {
svcCloseHandle(tmp_hnd);
}
} }
} });
fsdevMountSdmc(); fsdevMountSdmc();
} }
static void WaitForMitm(const char *service) { static void WaitForMitm(const char *service) {
bool mitm_installed = false; bool mitm_installed = false;
Result rc = smManagerAmsInitialize(); Result rc;
if (R_FAILED(rc)) { DoWithSmSession([&]() {
std::abort(); if (R_FAILED((rc = smManagerAmsInitialize()))) {
} std::abort();
}
});
while (R_FAILED((rc = smManagerAmsHasMitm(&mitm_installed, service))) || !mitm_installed) { while (R_FAILED((rc = smManagerAmsHasMitm(&mitm_installed, service))) || !mitm_installed) {
if (R_FAILED(rc)) { if (R_FAILED(rc)) {
std::abort(); std::abort();
} }
svcSleepThread(1000000ull); svcSleepThread(1000000ull);
} }
smManagerAmsExit(); smManagerAmsExit();
} }
void EmbeddedBoot2::Main() { void EmbeddedBoot2::Main() {
/* Wait until fs.mitm has installed itself. We want this to happen as early as possible. */ /* Wait until fs.mitm has installed itself. We want this to happen as early as possible. */
WaitForMitm("fsp-srv"); WaitForMitm("fsp-srv");
/* Clear titles. */ /* Clear titles. */
ClearLaunchedTitles(); 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. */ /* bus depends on pcie, and pcv depends on settings. */
/* Launch psc. */ /* Launch psc. */
LaunchTitle(TitleId_Psc, FsStorageId_NandSystem, 0, NULL); LaunchTitle(TitleId_Psc, FsStorageId_NandSystem, 0, NULL);
@ -215,16 +228,16 @@ void EmbeddedBoot2::Main() {
LaunchTitle(TitleId_Settings, FsStorageId_NandSystem, 0, NULL); LaunchTitle(TitleId_Settings, FsStorageId_NandSystem, 0, NULL);
/* Launch pcv. */ /* Launch pcv. */
LaunchTitle(TitleId_Pcv, FsStorageId_NandSystem, 0, NULL); LaunchTitle(TitleId_Pcv, FsStorageId_NandSystem, 0, NULL);
/* At this point, the SD card can be mounted. */ /* At this point, the SD card can be mounted. */
MountSdCard(); MountSdCard();
/* Find out whether we are maintenance mode. */ /* Find out whether we are maintenance mode. */
bool maintenance = IsMaintenanceMode(); bool maintenance = IsMaintenanceMode();
if (maintenance) { if (maintenance) {
BootModeService::SetMaintenanceBootForEmbeddedBoot2(); BootModeService::SetMaintenanceBootForEmbeddedBoot2();
} }
/* Wait for other atmosphere mitm modules to initialize. */ /* Wait for other atmosphere mitm modules to initialize. */
WaitForMitm("set:sys"); WaitForMitm("set:sys");
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) { if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) {
@ -232,16 +245,16 @@ void EmbeddedBoot2::Main() {
} else { } else {
WaitForMitm("bpc:c"); WaitForMitm("bpc:c");
} }
/* Launch usb. */ /* Launch usb. */
LaunchTitle(TitleId_Usb, FsStorageId_NandSystem, 0, NULL); LaunchTitle(TitleId_Usb, FsStorageId_NandSystem, 0, NULL);
/* Launch tma. */ /* Launch tma. */
LaunchTitle(TitleId_Tma, FsStorageId_NandSystem, 0, NULL); LaunchTitle(TitleId_Tma, FsStorageId_NandSystem, 0, NULL);
/* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */ /* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */
LaunchTitle(TitleId_Dmnt, FsStorageId_None, 0, NULL); LaunchTitle(TitleId_Dmnt, FsStorageId_None, 0, NULL);
/* Launch default programs. */ /* Launch default programs. */
for (auto &launch_program : g_additional_launch_programs) { for (auto &launch_program : g_additional_launch_programs) {
if (!maintenance || std::get<bool>(launch_program)) { if (!maintenance || std::get<bool>(launch_program)) {
@ -253,7 +266,7 @@ void EmbeddedBoot2::Main() {
LaunchTitle(TitleId_Npns, FsStorageId_NandSystem, 0, NULL); LaunchTitle(TitleId_Npns, FsStorageId_NandSystem, 0, NULL);
} }
} }
/* Allow for user-customizable programs. */ /* Allow for user-customizable programs. */
DIR *titles_dir = opendir("sdmc:/atmosphere/titles"); DIR *titles_dir = opendir("sdmc:/atmosphere/titles");
struct dirent *ent; struct dirent *ent;
@ -288,10 +301,10 @@ void EmbeddedBoot2::Main() {
} }
closedir(titles_dir); closedir(titles_dir);
} }
/* We no longer need the SD card. */ /* We no longer need the SD card. */
fsdevUnmountAll(); fsdevUnmountAll();
/* Free the memory used to track what boot2 launches. */ /* Free the memory used to track what boot2 launches. */
ClearLaunchedTitles(); ClearLaunchedTitles();
} }

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> #include <cstdlib>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
@ -38,7 +38,7 @@ extern "C" {
#define INNER_HEAP_SIZE 0x30000 #define INNER_HEAP_SIZE 0x30000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE]; char nx_inner_heap[INNER_HEAP_SIZE];
void __libnx_initheap(void); void __libnx_initheap(void);
void __appInit(void); void __appInit(void);
void __appExit(void); void __appExit(void);
@ -72,10 +72,10 @@ void RegisterPrivilegedProcessesWithFs() {
/* Ensures that all privileged processes are registered with full FS permissions. */ /* Ensures that all privileged processes are registered with full FS permissions. */
constexpr u64 PRIVILEGED_PROCESS_MIN = 0; constexpr u64 PRIVILEGED_PROCESS_MIN = 0;
constexpr u64 PRIVILEGED_PROCESS_MAX = 0x4F; constexpr u64 PRIVILEGED_PROCESS_MAX = 0x4F;
const u32 PRIVILEGED_FAH[0x1C/sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000}; 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}; const u32 PRIVILEGED_FAC[0x2C/sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
u32 num_pids; u32 num_pids;
u64 pids[PRIVILEGED_PROCESS_MAX+1]; u64 pids[PRIVILEGED_PROCESS_MAX+1];
if (R_SUCCEEDED(svcGetProcessList(&num_pids, pids, sizeof(pids)/sizeof(pids[0])))) { if (R_SUCCEEDED(svcGetProcessList(&num_pids, pids, sizeof(pids)/sizeof(pids[0])))) {
@ -96,54 +96,52 @@ void RegisterPrivilegedProcessesWithFs() {
void __appInit(void) { void __appInit(void) {
Result rc; Result rc;
SetFirmwareVersionForLibnx(); SetFirmwareVersionForLibnx();
rc = smInitialize(); DoWithSmSession([&]() {
if (R_FAILED(rc)) { rc = fsprInitialize();
std::abort(); if (R_FAILED(rc)) {
} std::abort();
}
rc = fsprInitialize();
if (R_FAILED(rc)) { /* This works around a bug with process permissions on < 4.0.0. */
std::abort(); RegisterPrivilegedProcessesWithFs();
}
rc = smManagerAmsInitialize();
/* This works around a bug with process permissions on < 4.0.0. */ if (R_SUCCEEDED(rc)) {
RegisterPrivilegedProcessesWithFs(); smManagerAmsEndInitialDefers();
smManagerAmsExit();
rc = smManagerAmsInitialize(); } else {
if (R_SUCCEEDED(rc)) { std::abort();
smManagerAmsEndInitialDefers(); }
} else {
std::abort(); rc = smManagerInitialize();
} if (R_FAILED(rc)) {
std::abort();
rc = smManagerInitialize(); }
if (R_FAILED(rc)) {
std::abort(); rc = lrInitialize();
} if (R_FAILED(rc)) {
std::abort();
rc = lrInitialize(); }
if (R_FAILED(rc)) {
std::abort(); rc = ldrPmInitialize();
} if (R_FAILED(rc)) {
std::abort();
rc = ldrPmInitialize(); }
if (R_FAILED(rc)) {
std::abort(); rc = splInitialize();
} if (R_FAILED(rc)) {
std::abort();
rc = splInitialize(); }
if (R_FAILED(rc)) {
std::abort(); rc = fsInitialize();
} if (R_FAILED(rc)) {
std::abort();
rc = fsInitialize(); }
if (R_FAILED(rc)) { });
std::abort();
}
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
} }
@ -156,14 +154,13 @@ void __appExit(void) {
fsprExit(); fsprExit();
lrExit(); lrExit();
fsExit(); fsExit();
smExit();
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
HosThread process_track_thread; HosThread process_track_thread;
consoleDebugInit(debugDevice_SVC); consoleDebugInit(debugDevice_SVC);
/* Initialize and spawn the Process Tracking thread. */ /* Initialize and spawn the Process Tracking thread. */
Registration::InitializeSystemResources(); Registration::InitializeSystemResources();
if (R_FAILED(process_track_thread.Initialize(&ProcessTracking::MainLoop, NULL, 0x4000, 0x15))) { 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())) { if (R_FAILED(process_track_thread.Start())) {
/* TODO: Panic. */ /* TODO: Panic. */
} }
/* TODO: What's a good timeout value to use here? */ /* TODO: What's a good timeout value to use here? */
auto server_manager = new WaitableManager(1); auto server_manager = new WaitableManager(1);
/* TODO: Create services. */ /* TODO: Create services. */
server_manager->AddWaitable(new ServiceServer<ShellService>("pm:shell", 3)); server_manager->AddWaitable(new ServiceServer<ShellService>("pm:shell", 3));
server_manager->AddWaitable(new ServiceServer<DebugMonitorService>("pm:dmnt", 2)); server_manager->AddWaitable(new ServiceServer<DebugMonitorService>("pm:dmnt", 2));
server_manager->AddWaitable(new ServiceServer<BootModeService>("pm:bm", 6)); server_manager->AddWaitable(new ServiceServer<BootModeService>("pm:bm", 6));
server_manager->AddWaitable(new ServiceServer<InformationService>("pm:info", 1)); server_manager->AddWaitable(new ServiceServer<InformationService>("pm:info", 1));
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
server_manager->Process(); server_manager->Process();
/* Cleanup. */ /* Cleanup. */
delete server_manager; delete server_manager;
return 0; return 0;