Lorenzo DellacĂ
979c59d6f2
* commit 'bb07a7334f064c9512bd7e387dab1b9ef9e228cd': (23 commits) update gitignore and makefile rosalina: ndm + shutdown issue workaround rosalina: ndm doesn't exist on SAFE_FIRM Update bug-report.md, etc rosalina: forgot float suffix in luminance.c rosalina: display min/max luminance hbloader: allow homebrew to write to the shared config page rosalina: minor menu changes rosalina/sm: properly interact with ndm k11ext: refactor ndm:u workaround k11ext: fix oops rosalina: properly rewrite luminance-setting menu, etc. sysmodules: use libctru configmem defs Fix release building (#1454) sysmodules: introduce "luma shared config", rewrite ndmu workaround rosalina: autoclose menu on sleep mode/shell closed to prevent lockup rosalina: prevent disconnect when shell is closed rosalina: properly restore screen filters when lid is reopened rosalina: prevent sleep mode entry if debugger/input redir is enabled to prevent lockup Separate exception dump parser in another repo, add boot.3dsx to release command ... # Conflicts: # .gitignore # exception_dump_parser/luma3ds_exception_dump_parser/__main__.py # sysmodules/rosalina/source/input_redirection.c # sysmodules/rosalina/source/menu.c
277 lines
8.4 KiB
C
277 lines
8.4 KiB
C
/*
|
|
* This file is part of Luma3DS
|
|
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
|
* * Requiring preservation of specified reasonable legal notices or
|
|
* author attributions in that material or in the Appropriate Legal
|
|
* Notices displayed by works containing it.
|
|
* * Prohibiting misrepresentation of the origin of that material,
|
|
* or requiring that modified versions of such material be marked in
|
|
* reasonable ways as different from the original version.
|
|
*/
|
|
|
|
#include <3ds.h>
|
|
#include "memory.h"
|
|
#include "menu.h"
|
|
#include "service_manager.h"
|
|
#include "errdisp.h"
|
|
#include "hbloader.h"
|
|
#include "3dsx.h"
|
|
#include "utils.h"
|
|
#include "MyThread.h"
|
|
#include "menus/miscellaneous.h"
|
|
#include "plgloader.h"
|
|
#include "menus/debugger.h"
|
|
#include "menus/screen_filters.h"
|
|
#include "menus/cheats.h"
|
|
#include "menus/sysconfig.h"
|
|
#include "input_redirection.h"
|
|
#include "minisoc.h"
|
|
#include "draw.h"
|
|
|
|
#include "task_runner.h"
|
|
|
|
bool isN3DS;
|
|
|
|
Result __sync_init(void);
|
|
Result __sync_fini(void);
|
|
void __libc_init_array(void);
|
|
void __libc_fini_array(void);
|
|
|
|
void __ctru_exit(int rc) { (void)rc; } // needed to avoid linking error
|
|
|
|
// this is called after main exits
|
|
void __wrap_exit(int rc)
|
|
{
|
|
(void)rc;
|
|
// TODO: make pm terminate rosalina
|
|
__libc_fini_array();
|
|
|
|
// Kernel will take care of it all
|
|
/*
|
|
pmDbgExit();
|
|
fsExit();
|
|
svcCloseHandle(*fsRegGetSessionHandle());
|
|
srvExit();
|
|
__sync_fini();*/
|
|
|
|
svcExitProcess();
|
|
}
|
|
|
|
// this is called before main
|
|
void initSystem(void)
|
|
{
|
|
s64 out;
|
|
Result res;
|
|
__sync_init();
|
|
mappableInit(0x10000000, 0x14000000);
|
|
|
|
isN3DS = svcGetSystemInfo(&out, 0x10001, 0) == 0;
|
|
|
|
svcGetSystemInfo(&out, 0x10000, 0x100);
|
|
Luma_SharedConfig->hbldr_3dsx_tid = out == 0 ? HBLDR_DEFAULT_3DSX_TID : (u64)out;
|
|
Luma_SharedConfig->use_hbldr = true;
|
|
|
|
svcGetSystemInfo(&out, 0x10000, 0x101);
|
|
menuCombo = out == 0 ? DEFAULT_MENU_COMBO : (u32)out;
|
|
|
|
miscellaneousMenu.items[0].title = Luma_SharedConfig->hbldr_3dsx_tid == HBLDR_DEFAULT_3DSX_TID ?
|
|
"Switch the hb. title to the current app." :
|
|
"Switch the hb. title to hblauncher_loader";
|
|
|
|
for(res = 0xD88007FA; res == (Result)0xD88007FA; svcSleepThread(500 * 1000LL))
|
|
{
|
|
res = srvInit();
|
|
if(R_FAILED(res) && res != (Result)0xD88007FA)
|
|
svcBreak(USERBREAK_PANIC);
|
|
}
|
|
|
|
if (R_FAILED(pmAppInit()) || R_FAILED(pmDbgInit()))
|
|
svcBreak(USERBREAK_PANIC);
|
|
|
|
if (R_FAILED(fsInit()))
|
|
svcBreak(USERBREAK_PANIC);
|
|
|
|
if (R_FAILED(FSUSER_SetPriority(-16)))
|
|
svcBreak(USERBREAK_PANIC);
|
|
|
|
// **** DO NOT init services that don't come from KIPs here ****
|
|
// Instead, init the service only where it's actually init (then deinit it).
|
|
|
|
__libc_init_array();
|
|
|
|
// ROSALINA HACKJOB END
|
|
|
|
// Rosalina specific:
|
|
u32 *tls = (u32 *)getThreadLocalStorage();
|
|
memset(tls, 0, 0x80);
|
|
tls[0] = 0x21545624;
|
|
|
|
// ROSALINA HACKJOB BEGIN
|
|
// NORMAL APPS SHOULD NOT DO THIS, EVER
|
|
srvSetBlockingPolicy(true); // GetServiceHandle nonblocking if service port is full
|
|
}
|
|
|
|
bool menuShouldExit = false;
|
|
bool preTerminationRequested = false;
|
|
Handle preTerminationEvent;
|
|
extern bool isHidInitialized;
|
|
|
|
static void handleTermNotification(u32 notificationId)
|
|
{
|
|
(void)notificationId;
|
|
}
|
|
|
|
static void handleSleepNotification(u32 notificationId)
|
|
{
|
|
ptmSysmInit();
|
|
s32 ackValue = ptmSysmGetNotificationAckValue(notificationId);
|
|
switch (notificationId)
|
|
{
|
|
case PTMNOTIFID_SLEEP_REQUESTED:
|
|
menuShouldExit = true;
|
|
PTMSYSM_ReplyToSleepQuery(miniSocEnabled); // deny sleep request if we have network stuff running
|
|
break;
|
|
case PTMNOTIFID_GOING_TO_SLEEP:
|
|
case PTMNOTIFID_SLEEP_ALLOWED:
|
|
case PTMNOTIFID_FULLY_WAKING_UP:
|
|
case PTMNOTIFID_HALF_AWAKE:
|
|
PTMSYSM_NotifySleepPreparationComplete(ackValue);
|
|
break;
|
|
case PTMNOTIFID_SLEEP_DENIED:
|
|
case PTMNOTIFID_FULLY_AWAKE:
|
|
menuShouldExit = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
ptmSysmExit();
|
|
}
|
|
|
|
static void handleShellNotification(u32 notificationId)
|
|
{
|
|
if (notificationId == 0x213) {
|
|
// Shell opened
|
|
// Note that this notification is fired on system init
|
|
ScreenFiltersMenu_RestoreCct();
|
|
menuShouldExit = false;
|
|
} else {
|
|
// Shell closed
|
|
menuShouldExit = true;
|
|
}
|
|
|
|
}
|
|
|
|
static void handlePreTermNotification(u32 notificationId)
|
|
{
|
|
(void)notificationId;
|
|
// Might be subject to a race condition, but heh.
|
|
|
|
miniSocUnlockState(true);
|
|
|
|
// Disable input redirection
|
|
InputRedirection_Disable(100 * 1000 * 1000LL);
|
|
|
|
// Ask the debugger to terminate in approx 2 * 100ms
|
|
debuggerDisable(100 * 1000 * 1000LL);
|
|
|
|
// Kill the ac session if needed
|
|
if(isConnectionForced)
|
|
{
|
|
acExit();
|
|
isConnectionForced = false;
|
|
SysConfigMenu_UpdateStatus(true);
|
|
}
|
|
|
|
Draw_Lock();
|
|
if (isHidInitialized)
|
|
hidExit();
|
|
|
|
// Termination request
|
|
menuShouldExit = true;
|
|
preTerminationRequested = true;
|
|
svcSignalEvent(preTerminationEvent);
|
|
Draw_Unlock();
|
|
}
|
|
|
|
static void handleNextApplicationDebuggedByForce(u32 notificationId)
|
|
{
|
|
(void)notificationId;
|
|
// Following call needs to be async because pm -> Loader depends on rosalina hb:ldr, handled in this very thread.
|
|
TaskRunner_RunTask(debuggerFetchAndSetNextApplicationDebugHandleTask, NULL, 0);
|
|
}
|
|
|
|
static void handleRestartHbAppNotification(u32 notificationId)
|
|
{
|
|
(void)notificationId;
|
|
TaskRunner_RunTask(HBLDR_RestartHbApplication, NULL, 0);
|
|
}
|
|
|
|
static const ServiceManagerServiceEntry services[] = {
|
|
{ "hb:ldr", 2, HBLDR_HandleCommands, true },
|
|
{ NULL },
|
|
};
|
|
|
|
static const ServiceManagerNotificationEntry notifications[] = {
|
|
{ 0x100 , handleTermNotification },
|
|
{ PTMNOTIFID_SLEEP_REQUESTED, handleSleepNotification },
|
|
{ PTMNOTIFID_SLEEP_DENIED, handleSleepNotification },
|
|
{ PTMNOTIFID_SLEEP_ALLOWED, handleSleepNotification },
|
|
{ PTMNOTIFID_GOING_TO_SLEEP, handleSleepNotification },
|
|
{ PTMNOTIFID_FULLY_WAKING_UP, handleSleepNotification },
|
|
{ PTMNOTIFID_FULLY_AWAKE, handleSleepNotification },
|
|
{ PTMNOTIFID_HALF_AWAKE, handleSleepNotification },
|
|
{ 0x213, handleShellNotification },
|
|
{ 0x214, handleShellNotification },
|
|
{ 0x1000, handleNextApplicationDebuggedByForce },
|
|
{ 0x2000, handlePreTermNotification },
|
|
{ 0x3000, handleRestartHbAppNotification },
|
|
{ 0x000, NULL },
|
|
};
|
|
|
|
int main(void)
|
|
{
|
|
static u8 ipcBuf[0x100] = {0}; // used by both err:f and hb:ldr
|
|
|
|
// Set up static buffers for IPC
|
|
u32* bufPtrs = getThreadStaticBuffers();
|
|
memset(bufPtrs, 0, 16 * 2 * 4);
|
|
bufPtrs[0] = IPC_Desc_StaticBuffer(sizeof(ipcBuf), 0);
|
|
bufPtrs[1] = (u32)ipcBuf;
|
|
bufPtrs[2] = IPC_Desc_StaticBuffer(sizeof(ldrArgvBuf), 1);
|
|
bufPtrs[3] = (u32)ldrArgvBuf;
|
|
|
|
if(R_FAILED(svcCreateEvent(&preTerminationEvent, RESET_STICKY)))
|
|
svcBreak(USERBREAK_ASSERT);
|
|
|
|
Draw_Init();
|
|
Cheat_SeedRng(svcGetSystemTick());
|
|
|
|
MyThread *menuThread = menuCreateThread();
|
|
MyThread *taskRunnerThread = taskRunnerCreateThread();
|
|
MyThread *plgloaderThread = PluginLoader__CreateThread();
|
|
|
|
if (R_FAILED(ServiceManager_Run(services, notifications, NULL)))
|
|
svcBreak(USERBREAK_PANIC);
|
|
|
|
MyThread_Join(menuThread, -1LL);
|
|
MyThread_Join(taskRunnerThread, -1LL);
|
|
MyThread_Join(plgloaderThread, -1LL);
|
|
|
|
return 0;
|
|
}
|