Merge commit 'bb07a7334f064c9512bd7e387dab1b9ef9e228cd' into 3gx-master

* 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
This commit is contained in:
Lorenzo Dellacà
2020-07-21 11:27:18 +02:00
40 changed files with 883 additions and 412 deletions

View File

@@ -89,7 +89,7 @@ void signalSvcReturn(u8 *pageEnd)
void postprocessSvc(void)
{
KThread *currentThread = currentCoreContext->objectContext.currentThread;
if(!currentThread->shallTerminate && rosalinaThreadLockPredicate(currentThread))
if(!currentThread->shallTerminate && rosalinaThreadLockPredicate(currentThread, rosalinaState & 5))
rosalinaRescheduleThread(currentThread, true);
officialPostProcessSvc();

View File

@@ -105,14 +105,22 @@ Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3)
__ldrex((s32 *)&rosalinaState);
}
while(__strex((s32 *)&rosalinaState, (s32)(rosalinaState ^ varg1)));
__dmb();
if(rosalinaState & 2)
if(rosalinaState & 0x10)
hasStartedRosalinaNetworkFuncsOnce = true;
if(rosalinaState & 1)
rosalinaLockAllThreads();
else if(varg1 & 1)
rosalinaUnlockAllThreads();
// 1: all applet/app/dsp/csnd... threads 2: gsp 4: hid/ir
for (u32 v = 4; v != 0; v >>= 1)
{
if (varg1 & v)
{
if (rosalinaState & v)
rosalinaLockThreads(v);
else
rosalinaUnlockThreads(v);
}
}
break;
}

View File

@@ -28,9 +28,16 @@
#include "svc/SendSyncRequest.h"
#include "ipc.h"
static inline bool isNdmuWorkaround(const SessionInfo *info, u32 pid)
{
return info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce && pid >= nbSection0Modules;
}
Result SendSyncRequestHook(Handle handle)
{
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
KProcessHandleTable *handleTable = handleTableOfProcess(currentProcess);
u32 pid = idOfProcess(currentProcess);
KClientSession *clientSession = (KClientSession *)KProcessHandleTable__ToKAutoObject(handleTable, handle);
u32 *cmdbuf = (u32 *)((u8 *)currentCoreContext->objectContext.currentThread->threadLocalStorage + 0x80);
@@ -47,7 +54,7 @@ Result SendSyncRequestHook(Handle handle)
case 0x10042:
{
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce)
if(isNdmuWorkaround(info, pid))
{
cmdbuf[0] = 0x10040;
cmdbuf[1] = 0;
@@ -87,7 +94,7 @@ Result SendSyncRequestHook(Handle handle)
case 0x20002:
{
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce)
if(isNdmuWorkaround(info, pid))
{
cmdbuf[0] = 0x20040;
cmdbuf[1] = 0;
@@ -129,7 +136,7 @@ Result SendSyncRequestHook(Handle handle)
if(!hasStartedRosalinaNetworkFuncsOnce)
break;
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
skip = info != NULL && strcmp(info->name, "ndm:u") == 0; // SuspendScheduler
skip = isNdmuWorkaround(info, pid); // SuspendScheduler
if(skip)
cmdbuf[1] = 0;
break;
@@ -140,7 +147,7 @@ Result SendSyncRequestHook(Handle handle)
if(!hasStartedRosalinaNetworkFuncsOnce)
break;
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
if(info != NULL && strcmp(info->name, "ndm:u") == 0) // ResumeScheduler
if(isNdmuWorkaround(info, pid)) // ResumeScheduler
{
cmdbuf[0] = 0x90040;
cmdbuf[1] = 0;

View File

@@ -66,17 +66,12 @@ void KThread__DebugReschedule(KThread *this, bool lock)
KRecursiveLock__Unlock(criticalSectionLock);
}
bool rosalinaThreadLockPredicate(KThread *thread)
static void rosalinaLockThread(KThread *thread)
{
KProcess *process = thread->ownerProcess;
if(process == NULL)
return false;
KThread *syncThread = synchronizationMutex->owner;
u64 titleId = codeSetOfProcess(process)->titleId;
u32 highTitleId = (u32)(titleId >> 32), lowTitleId = (u32)(titleId & ~0xF0000001); // clear N3DS and SAFE_FIRM bits
return
((rosalinaState & 1) && idOfProcess(process) >= nbSection0Modules &&
(highTitleId != 0x00040130 || (highTitleId == 0x00040130 && (lowTitleId == 0x1A02 || lowTitleId == 0x1C02))));
if(syncThread == NULL || syncThread != thread)
rosalinaRescheduleThread(thread, true);
}
void rosalinaRescheduleThread(KThread *thread, bool lock)
@@ -89,20 +84,45 @@ void rosalinaRescheduleThread(KThread *thread, bool lock)
else
thread->schedulingMask &= ~0x40;
KScheduler__AdjustThread(currentCoreContext->objectContext.currentScheduler, thread, oldSchedulingMask);
if (oldSchedulingMask != thread->schedulingMask)
KScheduler__AdjustThread(currentCoreContext->objectContext.currentScheduler, thread, oldSchedulingMask);
KRecursiveLock__Unlock(criticalSectionLock);
}
void rosalinaLockThread(KThread *thread)
bool rosalinaThreadLockPredicate(KThread *thread, u32 mask)
{
KThread *syncThread = synchronizationMutex->owner;
KProcess *process = thread->ownerProcess;
if(process == NULL || idOfProcess(process) < nbSection0Modules)
return false;
if(syncThread == NULL || syncThread != thread)
rosalinaRescheduleThread(thread, true);
u64 titleId = codeSetOfProcess(process)->titleId;
u32 highTitleId = (u32)(titleId >> 32), lowTitleId = (u32)(titleId & ~0xF0000001); // clear N3DS and SAFE_FIRM bits
if (mask & 1)
{
if (highTitleId != 0x00040130) // non-sysmodules
return true;
else
return lowTitleId == 0x1A02 || lowTitleId == 0x2702; // dsp, csnd
}
if (mask & 2)
{
if (highTitleId != 0x00040130) // non-sysmodules
false;
return lowTitleId == 0x1C02; // gsp
}
if (mask & 4)
{
if (highTitleId != 0x00040130) // non-sysmodules
return false;
return lowTitleId == 0x1D02 || lowTitleId == 0x3302;
}
return false;
}
void rosalinaLockAllThreads(void)
void rosalinaLockThreads(u32 mask)
{
bool currentThreadsFound = false;
@@ -110,7 +130,7 @@ void rosalinaLockAllThreads(void)
for(KLinkedListNode *node = threadList->list.nodes.first; node != (KLinkedListNode *)&threadList->list.nodes; node = node->next)
{
KThread *thread = (KThread *)node->key;
if(!rosalinaThreadLockPredicate(thread))
if(!rosalinaThreadLockPredicate(thread, mask))
continue;
if(thread == coreCtxs[thread->coreId].objectContext.currentThread)
currentThreadsFound = true;
@@ -123,7 +143,7 @@ void rosalinaLockAllThreads(void)
for(KLinkedListNode *node = threadList->list.nodes.first; node != (KLinkedListNode *)&threadList->list.nodes; node = node->next)
{
KThread *thread = (KThread *)node->key;
if(!rosalinaThreadLockPredicate(thread))
if(!rosalinaThreadLockPredicate(thread, mask))
continue;
if(!(thread->schedulingMask & 0x40))
{
@@ -145,7 +165,7 @@ void rosalinaLockAllThreads(void)
KRecursiveLock__Unlock(criticalSectionLock);
}
void rosalinaUnlockAllThreads(void)
void rosalinaUnlockThreads(u32 mask)
{
for(KLinkedListNode *node = threadList->list.nodes.first; node != (KLinkedListNode *)&threadList->list.nodes; node = node->next)
{
@@ -154,7 +174,7 @@ void rosalinaUnlockAllThreads(void)
if((thread->schedulingMask & 0xF) == 2) // thread is terminating
continue;
if(thread->schedulingMask & 0x40)
if((thread->schedulingMask & 0x40) && rosalinaThreadLockPredicate(thread, mask))
rosalinaRescheduleThread(thread, false);
}
}