mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-03 11:11:14 +00:00
stratosphere: only hold sm sessions open when needed
This commit is contained in:
parent
c3875796df
commit
b09adb6a34
16 changed files with 432 additions and 403 deletions
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue