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:
@@ -36,11 +36,12 @@ void executeFunctionOnCores(SGI0Handler_t func, u8 targetList, u8 targetListFilt
|
||||
|
||||
void KScheduler__TriggerCrossCoreInterrupt(KScheduler *this);
|
||||
void KThread__DebugReschedule(KThread *this, bool lock);
|
||||
bool rosalinaThreadLockPredicate(KThread *thread);
|
||||
|
||||
bool rosalinaThreadLockPredicate(KThread *thread, u32 mask);
|
||||
void rosalinaRescheduleThread(KThread *thread, bool lock);
|
||||
void rosalinaLockThread(KThread *thread);
|
||||
void rosalinaLockAllThreads(void);
|
||||
void rosalinaUnlockAllThreads(void);
|
||||
|
||||
void rosalinaLockThreads(u32 mask);
|
||||
void rosalinaUnlockThreads(u32 mask);
|
||||
|
||||
// Taken from ctrulib:
|
||||
|
||||
@@ -49,6 +50,11 @@ static inline void __dsb(void)
|
||||
__asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (0) : "memory");
|
||||
}
|
||||
|
||||
static inline void __dmb(void)
|
||||
{
|
||||
__asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 5" :: [val] "r" (0) : "memory");
|
||||
}
|
||||
|
||||
static inline void __clrex(void)
|
||||
{
|
||||
__asm__ __volatile__("clrex" ::: "memory");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user