From 991f51831dd16f648712bd3b9180bd05e545eb2e Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Tue, 7 Jul 2020 23:27:15 +0100 Subject: [PATCH 01/23] kext: add hid/ir thread locking --- k11_extension/include/synchronization.h | 14 +++++-- k11_extension/source/svc.c | 2 +- k11_extension/source/svc/KernelSetState.c | 20 +++++++-- k11_extension/source/synchronization.c | 50 ++++++++++++++--------- 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/k11_extension/include/synchronization.h b/k11_extension/include/synchronization.h index 32635a7..b577e2e 100644 --- a/k11_extension/include/synchronization.h +++ b/k11_extension/include/synchronization.h @@ -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"); diff --git a/k11_extension/source/svc.c b/k11_extension/source/svc.c index 9f929bc..3045794 100644 --- a/k11_extension/source/svc.c +++ b/k11_extension/source/svc.c @@ -78,7 +78,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(); diff --git a/k11_extension/source/svc/KernelSetState.c b/k11_extension/source/svc/KernelSetState.c index 7bf6048..2b944aa 100644 --- a/k11_extension/source/svc/KernelSetState.c +++ b/k11_extension/source/svc/KernelSetState.c @@ -104,14 +104,26 @@ Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3) __ldrex((s32 *)&rosalinaState); } while(__strex((s32 *)&rosalinaState, (s32)(rosalinaState ^ varg1))); + __dmb(); if(rosalinaState & 2) hasStartedRosalinaNetworkFuncsOnce = true; - if(rosalinaState & 1) - rosalinaLockAllThreads(); - else if(varg1 & 1) - rosalinaUnlockAllThreads(); + // 1: all applet/app/gsp/dsp... threads 4: hid/ir + if(varg1 & 1) + { + if (rosalinaState & 1) + rosalinaLockThreads(1); + else + rosalinaUnlockThreads(1); + } + if(varg1 & 4) + { + if (rosalinaState & 4) + rosalinaLockThreads(4); + else + rosalinaUnlockThreads(4); + } break; } diff --git a/k11_extension/source/synchronization.c b/k11_extension/source/synchronization.c index eb88c6a..d6dc6cb 100644 --- a/k11_extension/source/synchronization.c +++ b/k11_extension/source/synchronization.c @@ -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,37 @@ 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 == 0x1C02 || lowTitleId == 0x2702; // dsp, gsp, csnd + } + if (mask & 4) + { + return lowTitleId == 0x1D02 || lowTitleId == 0x3302; + } + + return false; } -void rosalinaLockAllThreads(void) +void rosalinaLockThreads(u32 mask) { bool currentThreadsFound = false; @@ -110,7 +122,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 +135,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 +157,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 +166,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); } } From 9ca52054cf274495b49166c73c962d81c585ce32 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Tue, 7 Jul 2020 23:27:26 +0100 Subject: [PATCH 02/23] rosalina: bump FS priority --- sysmodules/rosalina/source/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index c835049..e2ebe61 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -103,6 +103,9 @@ void initSystem(void) 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). From b17eb66d55fe0df891d50bfb493062cb61a76104 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 8 Jul 2020 22:08:57 +0100 Subject: [PATCH 03/23] rosalina inputredir: Use ir patch from @Nanquitas ; also refactor the code Fixes #1428, #1438 (I think) --- .../rosalina/source/input_redirection.c | 459 ++++++++++-------- 1 file changed, 268 insertions(+), 191 deletions(-) diff --git a/sysmodules/rosalina/source/input_redirection.c b/sysmodules/rosalina/source/input_redirection.c index 631cca4..d329391 100644 --- a/sysmodules/rosalina/source/input_redirection.c +++ b/sysmodules/rosalina/source/input_redirection.c @@ -168,6 +168,246 @@ void inputRedirectionThreadMain(void) void hidCodePatchFunc(void); void irCodePatchFunc(void); +static Result InputRedirection_DoUndoIrPatches(Handle processHandle, bool doPatch) +{ + static u32* hookLoc = NULL; + static u32* syncLoc = NULL; + static u32* cppFlagLoc = NULL; + static u32 origIrSync = 0; + static u32 origCppFlag = 0; + + static bool patchPrepared = false; + + static u32 irOrigReadingCode[5] = { + 0xE5940000, // ldr r0, [r4] + 0xE1A01005, // mov r1, r5 + 0xE3A03005, // mov r3, #5 + 0xE3A02011, // mov r2, #17 + 0x00000000 // (bl i2c_read_raw goes here) + }; + + static u32 irHook[] = { + 0xE5940000, // ldr r0, [r4] + 0xE1A01005, // mov r1, r5 + 0xE59FC000, // ldr r12, [pc] (actually +8) + 0xE12FFF3C, // blx r12 + 0x00000000 // irCodePhys goes here + }; + + static u32 syncHookCode[] = { + 0xE5900000, // ldr r0, [r0] + 0xEF000024, // svc 0x24 + 0xE3A00000, // mov r0, #0 + 0xE51FF004, // ldr pc, [pc, #-4] + 0x00000000, // (return address goes here) + }; + + // Find offsets for required patches + s64 startAddress, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize; + u32 totalSize; + Result res; + + svcGetProcessInfo(&textTotalRoundedSize, processHandle, 0x10002); // only patch .text + .data + svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003); + svcGetProcessInfo(&dataTotalRoundedSize, processHandle, 0x10004); + + totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); + + svcGetProcessInfo(&startAddress, processHandle, 0x10005); + res = svcMapProcessMemoryEx(processHandle, 0x00100000, (u32) startAddress, totalSize); + + if(R_SUCCEEDED(res) && !patchPrepared) + { + static const u32 irOrigWaitSyncCode[] = { + 0xEF000024, // svc 0x24 (WaitSynchronization) + 0xE1B01FA0, // movs r1, r0, lsr#31 + 0xE1A0A000, // mov r10, r0 + }, irOrigWaitSyncCodeOld[] = { + 0xE0AC6000, // adc r6, r12, r0 + 0xE5D70000, // ldrb r0, [r7] + }; // pattern for 8.1 + + static const u32 irOrigCppFlagCode[] = { + 0xE3550000, // cmp r5, #0 + 0xE3A0B080, // mov r11, #0x80 + }; + + u32 irDataPhys = (u32)PA_FROM_VA_PTR(irData); + u32 irCodePhys = (u32)PA_FROM_VA_PTR(&irCodePatchFunc); + + u32 *off = (u32 *)memsearch((u8 *)0x00100000, &irOrigReadingCode, totalSize, sizeof(irOrigReadingCode) - 4); + if(off == NULL) + { + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return -1; + } + + u32 *off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCode, totalSize, sizeof(irOrigWaitSyncCode)); + if(off2 == NULL) + { + off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCodeOld, totalSize, sizeof(irOrigWaitSyncCodeOld)); + if(off2 == NULL) + { + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return -2; + } + } + + u32 *off3 = (u32 *)memsearch((u8 *)0x00100000, &irOrigCppFlagCode, totalSize, sizeof(irOrigCppFlagCode)); + if(off3 == NULL) + { + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return -3; + } + + origIrSync = *off2; + origCppFlag = *off3; + + *(void **)(irCodePhys + 8) = decodeArmBranch(off + 4); + *(void **)(irCodePhys + 12) = (void*)irDataPhys; + + irHook[4] = irCodePhys; + irOrigReadingCode[4] = off[4]; // Copy the branch. + syncHookCode[4] = (u32)off2 + 4; // Hook return address + + hookLoc = PA_FROM_VA_PTR(off); + syncLoc = PA_FROM_VA_PTR(off2); + cppFlagLoc = PA_FROM_VA_PTR(off3); + + patchPrepared = true; + } + + if (R_SUCCEEDED(res)) + { + if (doPatch) + { + memcpy(hookLoc, &irHook, sizeof(irHook)); + + // We keep the WaitSynchronization1 to avoid general slowdown because of the high cpu load + if (*syncLoc == 0xEF000024) // svc 0x24 (WaitSynchronization) + { + syncLoc[-1] = 0xE51FF004; + syncLoc[0] = (u32)PA_FROM_VA_PTR(&syncHookCode); + } + else + { + // This "NOP"s out a WaitSynchronisation1 (on the event bound to the 'IR' interrupt) or the check of a previous one + *syncLoc = 0xE3A00000; // mov r0, #0 + } + + // This NOPs out a flag check in ir:user's CPP emulation + *cppFlagLoc = 0xE3150000; // tst r5, #0 + } + else + { + memcpy(hookLoc, irOrigReadingCode, sizeof(irOrigReadingCode)); + + if (*syncLoc == 0xE3A00000) + *syncLoc = origIrSync; + else + { + syncLoc[-1] = 0xE5900000; // ldr r0, [r0] + syncLoc[0] = 0xEF000024; // svc 0x24 + } + + *cppFlagLoc = origCppFlag; + } + } + + svcInvalidateEntireInstructionCache(); + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + + return res; +} + +static Result InputRedirection_DoUndoHidPatches(Handle processHandle, bool doPatches) +{ + static const u32 hidOrigRegisterAndValue[] = { 0x1EC46000, 0x4001 }; + static const u32 hidOrigCode[] = { + 0xE92D4070, // push {r4-r6, lr} + 0xE1A05001, // mov r5, r1 + 0xEE1D4F70, // mrc p15, 0, r4, c13, c0, 3 + 0xE3A01801, // mov r1, #0x10000 + 0xE5A41080, // str r1, [r4,#0x80]! + }; + + static bool patchPrepared = false; + static u32 *hidRegPatchOffsets[2]; + static u32 *hidPatchJumpLoc; + + // Find offsets for required patches + s64 startAddress, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize; + u32 totalSize; + Result res; + + svcGetProcessInfo(&textTotalRoundedSize, processHandle, 0x10002); // only patch .text + .data + svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003); + svcGetProcessInfo(&dataTotalRoundedSize, processHandle, 0x10004); + + totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); + + svcGetProcessInfo(&startAddress, processHandle, 0x10005); + res = svcMapProcessMemoryEx(processHandle, 0x00100000, (u32) startAddress, totalSize); + + if (R_SUCCEEDED(res) && !patchPrepared) + { + u32 *off = (u32 *)memsearch((u8 *)0x00100000, &hidOrigRegisterAndValue, totalSize, sizeof(hidOrigRegisterAndValue)); + if(off == NULL) + { + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return -1; + } + + u32 *off2 = (u32 *)memsearch((u8 *)off + sizeof(hidOrigRegisterAndValue), &hidOrigRegisterAndValue, totalSize - ((u32)off - 0x00100000), sizeof(hidOrigRegisterAndValue)); + if(off2 == NULL) + { + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return -2; + } + + u32 *off3 = (u32 *)memsearch((u8 *)0x00100000, &hidOrigCode, totalSize, sizeof(hidOrigCode)); + if(off3 == NULL) + { + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return -3; + } + + hidRegPatchOffsets[0] = off; + hidRegPatchOffsets[1] = off2; + hidPatchJumpLoc = off3; + + patchPrepared = true; + } + + if(R_SUCCEEDED(res)) + { + if (doPatches) + { + u32 hidDataPhys = (u32)PA_FROM_VA_PTR(hidData); + u32 hidCodePhys = (u32)PA_FROM_VA_PTR(&hidCodePatchFunc); + u32 hidHook[] = { + 0xE59F3004, // ldr r3, [pc, #4] + 0xE59FC004, // ldr r12, [pc, #4] + 0xE12FFF1C, // bx r12 + hidDataPhys, + hidCodePhys, + }; + + *hidRegPatchOffsets[0] = *hidRegPatchOffsets[1] = hidDataPhys; + memcpy(hidPatchJumpLoc, &hidHook, sizeof(hidHook)); + } + else + { + memcpy(hidRegPatchOffsets[0], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue)); + memcpy(hidRegPatchOffsets[1], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue)); + memcpy(hidPatchJumpLoc, &hidOrigCode, sizeof(hidOrigCode)); + } + } + + svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + return res; +} + Result InputRedirection_Disable(s64 timeout) { if(!inputRedirectionEnabled) @@ -186,209 +426,46 @@ Result InputRedirection_Disable(s64 timeout) Result InputRedirection_DoOrUndoPatches(void) { - s64 startAddress, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize; - u32 totalSize; - Handle processHandle; - - Result res = OpenProcessByName("hid", &processHandle); static bool hidPatched = false; static bool irPatched = false; + Handle hidProcHandle = 0, irProcHandle = 0; + + // Prevent hid and ir from running, in any case + + svcKernelSetState(0x10000, 4); + + Result res = OpenProcessByName("hid", &hidProcHandle); + if (R_FAILED(res)) + goto cleanup; + + res = OpenProcessByName("ir", &irProcHandle); + if (R_FAILED(res)) + goto cleanup; + if(R_SUCCEEDED(res)) { - svcGetProcessInfo(&textTotalRoundedSize, processHandle, 0x10002); // only patch .text + .data - svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003); - svcGetProcessInfo(&dataTotalRoundedSize, processHandle, 0x10004); - - totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); - - svcGetProcessInfo(&startAddress, processHandle, 0x10005); - res = svcMapProcessMemoryEx(processHandle, 0x00100000, (u32) startAddress, totalSize); - - if(R_SUCCEEDED(res)) - { - static const u32 hidOrigRegisterAndValue[] = { 0x1EC46000, 0x4001 }; - static const u32 hidOrigCode[] = { - 0xE92D4070, // push {r4-r6, lr} - 0xE1A05001, // mov r5, r1 - 0xEE1D4F70, // mrc p15, 0, r4, c13, c0, 3 - 0xE3A01801, // mov r1, #0x10000 - 0xE5A41080, // str r1, [r4,#0x80]! - }; - - static u32 *hidRegPatchOffsets[2]; - static u32 *hidPatchJumpLoc; - - if(hidPatched) - { - memcpy(hidRegPatchOffsets[0], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue)); - memcpy(hidRegPatchOffsets[1], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue)); - memcpy(hidPatchJumpLoc, &hidOrigCode, sizeof(hidOrigCode)); - hidPatched = false; - } - else - { - u32 hidDataPhys = (u32)PA_FROM_VA_PTR(hidData); - u32 hidCodePhys = (u32)PA_FROM_VA_PTR(&hidCodePatchFunc); - u32 hidHook[] = { - 0xE59F3004, // ldr r3, [pc, #4] - 0xE59FC004, // ldr r12, [pc, #4] - 0xE12FFF1C, // bx r12 - hidDataPhys, - hidCodePhys, - }; - - u32 *off = (u32 *)memsearch((u8 *)0x00100000, &hidOrigRegisterAndValue, totalSize, sizeof(hidOrigRegisterAndValue)); - if(off == NULL) - { - svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); - return -1; - } - - u32 *off2 = (u32 *)memsearch((u8 *)off + sizeof(hidOrigRegisterAndValue), &hidOrigRegisterAndValue, totalSize - ((u32)off - 0x00100000), sizeof(hidOrigRegisterAndValue)); - if(off2 == NULL) - { - svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); - return -2; - } - - u32 *off3 = (u32 *)memsearch((u8 *)0x00100000, &hidOrigCode, totalSize, sizeof(hidOrigCode)); - if(off3 == NULL) - { - svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); - return -3; - } - - hidRegPatchOffsets[0] = off; - hidRegPatchOffsets[1] = off2; - hidPatchJumpLoc = off3; - - *off = *off2 = hidDataPhys; - memcpy(off3, &hidHook, sizeof(hidHook)); - hidPatched = true; - } - } - - res = svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); + res = InputRedirection_DoUndoHidPatches(hidProcHandle, !hidPatched); + if (R_SUCCEEDED(res)) + hidPatched = !hidPatched; } - svcCloseHandle(processHandle); - res = OpenProcessByName("ir", &processHandle); if(R_SUCCEEDED(res) && GET_VERSION_MINOR(osGetKernelVersion()) >= 44) { - svcGetProcessInfo(&textTotalRoundedSize, processHandle, 0x10002); // only patch .text + .data - svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003); - svcGetProcessInfo(&dataTotalRoundedSize, processHandle, 0x10004); - - totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); - - svcGetProcessInfo(&startAddress, processHandle, 0x10005); - res = svcMapProcessMemoryEx(processHandle, 0x00100000, (u32) startAddress, totalSize); - - if(R_SUCCEEDED(res)) + res = InputRedirection_DoUndoIrPatches(irProcHandle, !irPatched); + if (R_SUCCEEDED(res)) + irPatched = !irPatched; + else if (!irPatched) { - static bool useOldSyncCode; - static u32 irOrigReadingCode[5] = { - 0xE5940000, // ldr r0, [r4] - 0xE1A01005, // mov r1, r5 - 0xE3A03005, // mov r3, #5 - 0xE3A02011, // mov r2, #17 - 0x00000000 // (bl i2c_read_raw goes here) - }; - - static const u32 irOrigWaitSyncCode[] = { - 0xEF000024, // svc 0x24 (WaitSynchronization) - 0xE1B01FA0, // movs r1, r0, lsr#31 - 0xE1A0A000, // mov r10, r0 - }, irOrigWaitSyncCodeOld[] = { - 0xE0AC6000, // adc r6, r12, r0 - 0xE5D70000, // ldrb r0, [r7] - }; // pattern for 8.1 - - static const u32 irOrigCppFlagCode[] = { - 0xE3550000, // cmp r5, #0 - 0xE3A0B080, // mov r11, #0x80 - }; - - static u32 *irHookLoc, *irWaitSyncLoc, *irCppFlagLoc; - - if(irPatched) - { - memcpy(irHookLoc, &irOrigReadingCode, sizeof(irOrigReadingCode)); - if(useOldSyncCode) - memcpy(irWaitSyncLoc, &irOrigWaitSyncCodeOld, sizeof(irOrigWaitSyncCodeOld)); - else - memcpy(irWaitSyncLoc, &irOrigWaitSyncCode, sizeof(irOrigWaitSyncCode)); - memcpy(irCppFlagLoc, &irOrigCppFlagCode, sizeof(irOrigCppFlagCode)); - - irPatched = false; - } - else - { - u32 irDataPhys = (u32)PA_FROM_VA_PTR(irData); - u32 irCodePhys = (u32)PA_FROM_VA_PTR(&irCodePatchFunc); - - u32 irHook[] = { - 0xE5940000, // ldr r0, [r4] - 0xE1A01005, // mov r1, r5 - 0xE59FC000, // ldr r12, [pc] (actually +8) - 0xE12FFF3C, // blx r12 - irCodePhys, - }; - - u32 *off = (u32 *)memsearch((u8 *)0x00100000, &irOrigReadingCode, totalSize, sizeof(irOrigReadingCode) - 4); - if(off == NULL) - { - svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); - return -4; - } - - u32 *off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCode, totalSize, sizeof(irOrigWaitSyncCode)); - if(off2 == NULL) - { - off2 = (u32 *)memsearch((u8 *)0x00100000, &irOrigWaitSyncCodeOld, totalSize, sizeof(irOrigWaitSyncCodeOld)); - if(off2 == NULL) - { - svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); - return -5; - } - - useOldSyncCode = true; - } - else - useOldSyncCode = false; - - u32 *off3 = (u32 *)memsearch((u8 *)0x00100000, &irOrigCppFlagCode, totalSize, sizeof(irOrigCppFlagCode)); - if(off3 == NULL) - { - svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); - return -6; - } - - *(void **)(irCodePhys + 8) = decodeArmBranch(off + 4); - *(void **)(irCodePhys + 12) = (void*)irDataPhys; - - irHookLoc = off; - irWaitSyncLoc = off2; - irCppFlagLoc = off3; - - irOrigReadingCode[4] = off[4]; // Copy the branch. - - memcpy(irHookLoc, &irHook, sizeof(irHook)); - - // This "NOP"s out a WaitSynchronisation1 (on the event bound to the 'IR' interrupt) or the check of a previous one - *irWaitSyncLoc = 0xE3A00000; // mov r0, #0 - - // This NOPs out a flag check in ir:user's CPP emulation - *irCppFlagLoc = 0xE3150000; // tst r5, #0 - - irPatched = true; - } + InputRedirection_DoUndoHidPatches(hidProcHandle, false); + hidPatched = false; } - - res = svcUnmapProcessMemoryEx(processHandle, 0x00100000, totalSize); } - svcCloseHandle(processHandle); +cleanup: + svcKernelSetState(0x10000, 4); + + svcCloseHandle(hidProcHandle); + svcCloseHandle(irProcHandle); return res; } From 555286ea473684566f0b628873a74358c1d226ce Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Thu, 9 Jul 2020 19:52:55 +0100 Subject: [PATCH 04/23] Separate exception dump parser in another repo, add boot.3dsx to release command https://github.com/LumaTeam/luma3ds_exception_dump_parser --- Makefile | 3 +- arm9/source/exceptions.c | 2 + .../luma3ds_exception_dump_parser/__init__.py | 0 .../luma3ds_exception_dump_parser/__main__.py | 188 ------------------ exception_dump_parser/setup.py | 13 -- 5 files changed, 4 insertions(+), 202 deletions(-) delete mode 100644 exception_dump_parser/luma3ds_exception_dump_parser/__init__.py delete mode 100755 exception_dump_parser/luma3ds_exception_dump_parser/__main__.py delete mode 100644 exception_dump_parser/setup.py diff --git a/Makefile b/Makefile index 7dae32d..760f2e7 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,8 @@ clean: @$(foreach dir, $(SUBFOLDERS), $(MAKE) -C $(dir) clean &&) true @rm -rf *.firm *.zip -$(NAME)$(REVISION).zip: boot.firm exception_dump_parser +# boot.3dsx comes from https://github.com/fincs/new-hbmenu/releases +$(NAME)$(REVISION).zip: boot.firm boot.3dsx @zip -r $@ $^ -x "*.DS_Store*" "*__MACOSX*" boot.firm: $(SUBFOLDERS) diff --git a/arm9/source/exceptions.c b/arm9/source/exceptions.c index ca45a77..e21bb03 100644 --- a/arm9/source/exceptions.c +++ b/arm9/source/exceptions.c @@ -34,6 +34,8 @@ #include "buttons.h" #include "arm9_exception_handlers.h" +// See https://github.com/LumaTeam/luma3ds_exception_dump_parser + void installArm9Handlers(void) { vu32 *dstVeneers = (vu32 *)0x08000000; diff --git a/exception_dump_parser/luma3ds_exception_dump_parser/__init__.py b/exception_dump_parser/luma3ds_exception_dump_parser/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/exception_dump_parser/luma3ds_exception_dump_parser/__main__.py b/exception_dump_parser/luma3ds_exception_dump_parser/__main__.py deleted file mode 100755 index 1a57791..0000000 --- a/exception_dump_parser/luma3ds_exception_dump_parser/__main__.py +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env python -# Requires Python >= 3.2 or >= 2.7 - -# 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 . -# -# Additional Terms 7.b of GPLv3 applies 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. - -__author__ = "TuxSH" -__copyright__ = "Copyright (c) 2016-2020 TuxSH" -__license__ = "GPLv3" -__version__ = "v1.2" - -""" -Parses Luma3DS exception dumps -""" - -import argparse -from struct import unpack_from - -import os -import subprocess - -# Source of hexdump: https://gist.github.com/ImmortalPC/c340564823f283fe530b -# Credits for hexdump go to the original authors -# Slightly edited by TuxSH - -def hexdump(addr, src, length=16, sep='.' ): - ''' - @brief Return {src} in hex dump. - @param[in] length {Int} Nb Bytes by row. - @param[in] sep {Char} For the text part, {sep} will be used for non ASCII char. - @return {Str} The hexdump - @note Full support for python2 and python3 ! - ''' - result = [] - - # Python3 support - try: - xrange(0,1) - except NameError: - xrange = range - - for i in xrange(0, len(src), length): - subSrc = src[i:i+length] - hexa = '' - isMiddle = False - for h in xrange(0,len(subSrc)): - if h == length/2: - hexa += ' ' - h = subSrc[h] - if not isinstance(h, int): - h = ord(h) - h = hex(h).replace('0x','') - if len(h) == 1: - h = '0'+h - hexa += h+' ' - hexa = hexa.strip(' ') - text = '' - for c in subSrc: - if not isinstance(c, int): - c = ord(c) - if 0x20 <= c < 0x7F: - text += chr(c) - else: - text += sep - result.append(('%08x: %-'+str(length*(2+1)+1)+'s |%s|') % (addr + i, hexa, text)) - - return '\n'.join(result) - - -def makeRegisterLine(A, rA, B, rB): - return "{0:<15}{1:<20}{2:<15}{3:<20}".format(A, "{0:08x}".format(rA), B, "{0:08x}".format(rB)) - -handledExceptionNames = ("FIQ", "undefined instruction", "prefetch abort", "data abort") -registerNames = tuple("r{0}".format(i) for i in range(13)) + ("sp", "lr", "pc", "cpsr") + ("dfsr", "ifsr", "far") + ("fpexc", "fpinst", "fpinst2") -svcBreakReasons = ("(svcBreak: panic)", "(svcBreak: assertion failed)", "(svcBreak: user-related)") -faultStatusSources = { - 0b1:'Alignment', 0b100:'Instruction cache maintenance operation fault', - 0b1100:'External Abort on translation - First-level', 0b1110:'External Abort on translation - Second-level', - 0b101:'Translation - Section', 0b111:'Translation - Page', 0b11:'Access bit - Section', 0b110:'Access bit - Page', - 0b1001:'Domain - Section', 0b1011:'Domain - Page', 0b1101:'Permission - Section', 0b1111:'Permission - Page', - 0b1000:'Precise External Abort', 0b10110:'Imprecise External Abort', 0b10:'Debug event' -} - -def main(args=None): - parser = argparse.ArgumentParser(description="Parse Luma3DS exception dumps") - parser.add_argument("filename") - args = parser.parse_args() - data = b"" - with open(args.filename, "rb") as f: data = f.read() - if unpack_from("<2I", data) != (0xdeadc0de, 0xdeadcafe): - raise SystemExit("Invalid file format") - - version, processor, exceptionType, _, nbRegisters, codeDumpSize, stackDumpSize, additionalDataSize = unpack_from("<8I", data, 8) - nbRegisters //= 4 - - if version < (1 << 16) | 2: - raise SystemExit("Incompatible format version, please use the appropriate parser.") - - registers = unpack_from("<{0}I".format(nbRegisters), data, 40) - codeOffset = 40 + 4 * nbRegisters - codeDump = data[codeOffset : codeOffset + codeDumpSize] - stackOffset = codeOffset + codeDumpSize - stackDump = data[stackOffset : stackOffset + stackDumpSize] - addtionalDataOffset = stackOffset + stackDumpSize - additionalData = data[addtionalDataOffset : addtionalDataOffset + additionalDataSize] - - if processor == 9: print("Processor: Arm9") - else: print("Processor: Arm11 (core {0})".format(processor >> 16)) - - typeDetailsStr = "" - if exceptionType == 2: - if (registers[16] & 0x20) == 0 and codeDumpSize >= 4: - instr = unpack_from("= 2: - instr = unpack_from("= len(handledExceptionNames) else handledExceptionNames[exceptionType], typeDetailsStr)) - - if processor == 11 and exceptionType >= 2: - xfsr = registers[18] if exceptionType == 2 else registers[17] - print("Fault status: " + faultStatusSources[xfsr & 0xf]) - - if additionalDataSize != 0: - print("Current process: {0} ({1:016x})".format(additionalData[:8].decode("ascii"), unpack_from(" Date: Thu, 9 Jul 2020 22:20:29 +0100 Subject: [PATCH 05/23] rosalina: prevent sleep mode entry if debugger/input redir is enabled to prevent lockup --- sysmodules/rosalina/source/main.c | 39 +++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index e2ebe61..91a0cfe 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -133,6 +133,29 @@ static void handleTermNotification(u32 notificationId) (void)notificationId; } +static void handleSleepNotification(u32 notificationId) +{ + ptmSysmInit(); + s32 ackValue = ptmSysmGetNotificationAckValue(notificationId); + switch (notificationId) + { + case PTMNOTIFID_SLEEP_REQUESTED: + 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: + default: + break; + } + ptmSysmExit(); +} + static void handlePreTermNotification(u32 notificationId) { (void)notificationId; @@ -182,11 +205,17 @@ static const ServiceManagerServiceEntry services[] = { }; static const ServiceManagerNotificationEntry notifications[] = { - { 0x100 , handleTermNotification }, - //{ 0x103 , handlePreTermNotification }, // Sleep mode entry <=== causes issues - { 0x1000, handleNextApplicationDebuggedByForce }, - { 0x2000, handlePreTermNotification }, - { 0x3000, handleRestartHbAppNotification }, + { 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 }, + { 0x1000, handleNextApplicationDebuggedByForce }, + { 0x2000, handlePreTermNotification }, + { 0x3000, handleRestartHbAppNotification }, { 0x000, NULL }, }; From dc67d438dc43e3b8192b035cad2b742eb802cfc2 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Fri, 10 Jul 2020 22:58:07 +0100 Subject: [PATCH 06/23] rosalina: properly restore screen filters when lid is reopened --- .../rosalina/include/menus/screen_filters.h | 2 + sysmodules/rosalina/source/main.c | 9 +++++ .../rosalina/source/menus/screen_filters.c | 38 +++++++++++++------ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/sysmodules/rosalina/include/menus/screen_filters.h b/sysmodules/rosalina/include/menus/screen_filters.h index 72323b9..d624cb4 100644 --- a/sysmodules/rosalina/include/menus/screen_filters.h +++ b/sysmodules/rosalina/include/menus/screen_filters.h @@ -32,6 +32,8 @@ extern Menu screenFiltersMenu; extern int screenFiltersCurrentTemperature; +void ScreenFiltersMenu_RestoreCct(void); + void ScreenFiltersMenu_SetDefault(void); // 6500K (default) void ScreenFiltersMenu_SetAquarium(void); // 10000K diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 91a0cfe..297b8e4 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -156,6 +156,14 @@ static void handleSleepNotification(u32 notificationId) ptmSysmExit(); } +static void handleShellOpenedNotification(u32 notificationId) +{ + (void)notificationId; + + // Note that this is called on system init + ScreenFiltersMenu_RestoreCct(); +} + static void handlePreTermNotification(u32 notificationId) { (void)notificationId; @@ -213,6 +221,7 @@ static const ServiceManagerNotificationEntry notifications[] = { { PTMNOTIFID_FULLY_WAKING_UP, handleSleepNotification }, { PTMNOTIFID_FULLY_AWAKE, handleSleepNotification }, { PTMNOTIFID_HALF_AWAKE, handleSleepNotification }, + { 0x213, handleShellOpenedNotification }, { 0x1000, handleNextApplicationDebuggedByForce }, { 0x2000, handlePreTermNotification }, { 0x3000, handleRestartHbAppNotification }, diff --git a/sysmodules/rosalina/source/menus/screen_filters.c b/sysmodules/rosalina/source/menus/screen_filters.c index 7fe3f9e..1d3d257 100644 --- a/sysmodules/rosalina/source/menus/screen_filters.c +++ b/sysmodules/rosalina/source/menus/screen_filters.c @@ -32,26 +32,29 @@ #include "redshift/redshift.h" #include "redshift/colorramp.h" -typedef struct { - u8 r; - u8 g; - u8 b; - u8 z; +typedef union { + struct { + u8 r; + u8 g; + u8 b; + u8 z; + }; + u32 raw; } Pixel; static u16 g_c[0x600]; static Pixel g_px[0x400]; -int screenFiltersCurrentTemperature = 6500; +int screenFiltersCurrentTemperature = -1; -static void ScreenFiltersMenu_WriteLut(const u32* lut) +static void ScreenFiltersMenu_WriteLut(const Pixel* lut) { GPU_FB_TOP_COL_LUT_INDEX = 0; GPU_FB_BOTTOM_COL_LUT_INDEX = 0; for (int i = 0; i <= 255; i++) { - GPU_FB_TOP_COL_LUT_ELEM = *lut; - GPU_FB_BOTTOM_COL_LUT_ELEM = *lut; + GPU_FB_TOP_COL_LUT_ELEM = lut->raw; + GPU_FB_BOTTOM_COL_LUT_ELEM = lut->raw; lut++; } } @@ -84,7 +87,7 @@ static void ScreenFiltersMenu_ApplyColorSettings(color_setting_t* cs) g_px[i].b = *(g_c + i + 0x200) >> 8; } while(++i); - ScreenFiltersMenu_WriteLut((u32*)g_px); + ScreenFiltersMenu_WriteLut(g_px); } static void ScreenFiltersMenu_SetCct(int cct) @@ -101,7 +104,6 @@ static void ScreenFiltersMenu_SetCct(int cct) ScreenFiltersMenu_ApplyColorSettings(&cs); } - Menu screenFiltersMenu = { "Screen filters menu", { @@ -126,6 +128,20 @@ void ScreenFiltersMenu_Set##name(void)\ ScreenFiltersMenu_SetCct(temp);\ } +void ScreenFiltersMenu_RestoreCct(void) +{ + // Not initialized: return + if (screenFiltersCurrentTemperature == -1) + return; + + // Wait for GSP to restore the CCT table + while (GPU_FB_TOP_COL_LUT_ELEM != g_px[0].raw) + svcSleepThread(10 * 1000 * 1000LL); + + svcSleepThread(10 * 1000 * 1000LL); + ScreenFiltersMenu_WriteLut(g_px); +} + DEF_CCT_SETTER(6500, Default) DEF_CCT_SETTER(10000, Aquarium) From 4c01bb453c1666e02085ff7311c23c34b51ebc4b Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 11 Jul 2020 21:39:36 +0100 Subject: [PATCH 07/23] rosalina: prevent disconnect when shell is closed Fuck ndm, fuck StreetPass --- sysmodules/rosalina/include/minisoc.h | 2 ++ sysmodules/rosalina/source/main.c | 2 +- sysmodules/rosalina/source/minisoc.c | 2 ++ sysmodules/sm/source/common.h | 1 + sysmodules/sm/source/notifications.c | 21 +++++++++++++++++++-- sysmodules/sm/source/services.c | 5 +++++ 6 files changed, 30 insertions(+), 3 deletions(-) diff --git a/sysmodules/rosalina/include/minisoc.h b/sysmodules/rosalina/include/minisoc.h index 6040bc8..9a97878 100644 --- a/sysmodules/rosalina/include/minisoc.h +++ b/sysmodules/rosalina/include/minisoc.h @@ -17,6 +17,8 @@ #define _REENT_ONLY #include +#define ROSALINA_PREVENT_DISCONNECT (*(volatile bool*)0x1FF81108) + #define SYNC_ERROR ENODEV extern bool miniSocEnabled; diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 297b8e4..9ef643b 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -140,7 +140,7 @@ static void handleSleepNotification(u32 notificationId) switch (notificationId) { case PTMNOTIFID_SLEEP_REQUESTED: - PTMSYSM_ReplyToSleepQuery(miniSocEnabled); // deny sleep request if we have network stuff running + PTMSYSM_ReplyToSleepQuery(ROSALINA_PREVENT_DISCONNECT); // deny sleep request if we have network stuff running break; case PTMNOTIFID_GOING_TO_SLEEP: case PTMNOTIFID_SLEEP_ALLOWED: diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index d52d48c..2cf5c68 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -91,6 +91,7 @@ Result miniSocInit(void) svcKernelSetState(0x10000, 2); miniSocEnabled = true; + ROSALINA_PREVENT_DISCONNECT = true; return 0; cleanup: @@ -134,6 +135,7 @@ Result miniSocExitDirect(void) { svcKernelSetState(0x10000, 2); miniSocEnabled = false; + ROSALINA_PREVENT_DISCONNECT = false; } return ret; } diff --git a/sysmodules/sm/source/common.h b/sysmodules/sm/source/common.h index 7ee7f6b..c750ece 100644 --- a/sysmodules/sm/source/common.h +++ b/sysmodules/sm/source/common.h @@ -17,6 +17,7 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for extern u32 nbSection0Modules; extern Handle resumeGetServiceHandleOrPortRegisteredSemaphore; +extern u32 ndmuServicePid; struct SessionDataList; diff --git a/sysmodules/sm/source/notifications.c b/sysmodules/sm/source/notifications.c index 84cd9ad..a9128c6 100644 --- a/sysmodules/sm/source/notifications.c +++ b/sysmodules/sm/source/notifications.c @@ -8,6 +8,23 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for #include "notifications.h" #include "processes.h" +// 0 by default +#define ROSALINA_PREVENT_DISCONNECT (*(volatile bool*)0x1FF81108) + +static bool isNotificationInhibited(const ProcessData *processData, u32 notificationId) +{ + u32 pid = processData->pid; + switch(notificationId) + { + // Shell opened, shell closed + case 0x213: + case 0x214: + return pid == ndmuServicePid && ROSALINA_PREVENT_DISCONNECT; + default: + return false; + } +} + static bool doPublishNotification(ProcessData *processData, u32 notificationId, u32 flags) { if((flags & 1) && processData->nbPendingNotifications != 0) // only send if not already pending @@ -118,7 +135,7 @@ Result PublishToSubscriber(u32 notificationId, u32 flags) { for(ProcessData *node = processDataInUseList.first; node != NULL; node = node->next) { - if(!node->notificationEnabled) + if(!node->notificationEnabled || isNotificationInhibited(node, notificationId)) continue; u16 i; @@ -138,7 +155,7 @@ Result PublishAndGetSubscriber(u32 *pidCount, u32 *pidList, u32 notificationId, u32 nb = 0; for(ProcessData *node = processDataInUseList.first; node != NULL; node = node->next) { - if(!node->notificationEnabled) + if(!node->notificationEnabled || isNotificationInhibited(node, notificationId)) continue; u16 i; diff --git a/sysmodules/sm/source/services.c b/sysmodules/sm/source/services.c index a81af7c..67274b4 100644 --- a/sysmodules/sm/source/services.c +++ b/sysmodules/sm/source/services.c @@ -13,6 +13,8 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for ServiceInfo servicesInfo[0xA0] = { 0 }; u32 nbServices = 0; // including "ports" registered with getPort +u32 ndmuServicePid = 3; // use our PID as default. + static Result checkServiceName(const char *name, s32 nameSize) { if(nameSize <= 0 || nameSize > 8) @@ -96,6 +98,9 @@ static Result doRegisterServiceOrPort(u32 pid, Handle *serverPort, Handle client if(!isNamedPort) *serverPort = portServer; + if(R_SUCCEEDED(res) && strcmp(name, "ndm:u") == 0) + ndmuServicePid = pid; + return res; } From e3bb1c1b6343b887d31b59864952147cc1d08bbe Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 11 Jul 2020 22:04:13 +0100 Subject: [PATCH 08/23] rosalina: autoclose menu on sleep mode/shell closed to prevent lockup --- sysmodules/rosalina/source/main.c | 20 +++++++++++++++----- sysmodules/rosalina/source/menu.c | 3 +-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 9ef643b..d0c3e7b 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -140,6 +140,7 @@ static void handleSleepNotification(u32 notificationId) switch (notificationId) { case PTMNOTIFID_SLEEP_REQUESTED: + menuShouldExit = true; PTMSYSM_ReplyToSleepQuery(ROSALINA_PREVENT_DISCONNECT); // deny sleep request if we have network stuff running break; case PTMNOTIFID_GOING_TO_SLEEP: @@ -150,18 +151,26 @@ static void handleSleepNotification(u32 notificationId) break; case PTMNOTIFID_SLEEP_DENIED: case PTMNOTIFID_FULLY_AWAKE: + menuShouldExit = false; + break; default: break; } ptmSysmExit(); } -static void handleShellOpenedNotification(u32 notificationId) +static void handleShellNotification(u32 notificationId) { - (void)notificationId; + if (notificationId == 0x213) { + // Shell opened + // Note that this notification is fired on system init + ScreenFiltersMenu_RestoreCct(); + menuShouldExit = false; + } else { + // Shell closed + menuShouldExit = true; + } - // Note that this is called on system init - ScreenFiltersMenu_RestoreCct(); } static void handlePreTermNotification(u32 notificationId) @@ -221,7 +230,8 @@ static const ServiceManagerNotificationEntry notifications[] = { { PTMNOTIFID_FULLY_WAKING_UP, handleSleepNotification }, { PTMNOTIFID_FULLY_AWAKE, handleSleepNotification }, { PTMNOTIFID_HALF_AWAKE, handleSleepNotification }, - { 0x213, handleShellOpenedNotification }, + { 0x213, handleShellNotification }, + { 0x214, handleShellNotification }, { 0x1000, handleNextApplicationDebuggedByForce }, { 0x2000, handlePreTermNotification }, { 0x3000, handleRestartHbAppNotification }, diff --git a/sysmodules/rosalina/source/menu.c b/sysmodules/rosalina/source/menu.c index 28bed67..04c9779 100644 --- a/sysmodules/rosalina/source/menu.c +++ b/sysmodules/rosalina/source/menu.c @@ -188,6 +188,7 @@ void menuThreadMain(void) while(!preTerminationRequested) { + svcSleepThread(50 * 1000 * 1000LL); if (menuShouldExit) continue; @@ -200,8 +201,6 @@ void menuThreadMain(void) menuShow(&rosalinaMenu); menuLeave(); } - - svcSleepThread(50 * 1000 * 1000LL); } } From 768e587b76a3b007e845e04cef66102b888facba Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sun, 12 Jul 2020 19:36:18 +0100 Subject: [PATCH 09/23] sysmodules: introduce "luma shared config", rewrite ndmu workaround --- sysmodules/loader/source/hbldr.h | 2 -- sysmodules/loader/source/loader.c | 17 ++++++----- sysmodules/loader/source/luma_shared_config.h | 28 +++++++++++++++++ sysmodules/rosalina/include/hbloader.h | 1 - .../rosalina/include/luma_shared_config.h | 30 +++++++++++++++++++ sysmodules/rosalina/include/minisoc.h | 2 -- sysmodules/rosalina/include/utils.h | 1 + sysmodules/rosalina/source/main.c | 10 ++++--- .../rosalina/source/menus/miscellaneous.c | 8 ++--- sysmodules/rosalina/source/minisoc.c | 30 ++++++++++++++----- sysmodules/sm/source/notifications.c | 14 +++++++-- sysmodules/sm/source/notifications.h | 2 ++ sysmodules/sm/source/srv.c | 8 +++++ 13 files changed, 122 insertions(+), 31 deletions(-) create mode 100644 sysmodules/loader/source/luma_shared_config.h create mode 100644 sysmodules/rosalina/include/luma_shared_config.h diff --git a/sysmodules/loader/source/hbldr.h b/sysmodules/loader/source/hbldr.h index 34e22c4..4da0c12 100644 --- a/sysmodules/loader/source/hbldr.h +++ b/sysmodules/loader/source/hbldr.h @@ -2,8 +2,6 @@ #include <3ds/exheader.h> -#define HBLDR_3DSX_TID (*(vu64 *)0x1FF81100) - Result hbldrInit(void); void hbldrExit(void); diff --git a/sysmodules/loader/source/loader.c b/sysmodules/loader/source/loader.c index d9f1dfc..d0d8a28 100644 --- a/sysmodules/loader/source/loader.c +++ b/sysmodules/loader/source/loader.c @@ -4,6 +4,7 @@ #include "ifile.h" #include "util.h" #include "hbldr.h" +#include "luma_shared_config.h" extern u32 config, multiConfig, bootConfig; extern bool isN3DS, isSdMode; @@ -91,6 +92,11 @@ static int lzss_decompress(u8 *end) return ret; } +static inline bool hbldrIs3dsxTitle(u64 tid) +{ + return Luma_SharedConfig->use_hbldr && tid == Luma_SharedConfig->hbldr_3dsx_tid; +} + static Result allocateSharedMem(prog_addrs_t *shared, prog_addrs_t *vaddr, int flags) { u32 dummy; @@ -169,11 +175,8 @@ static Result GetProgramInfo(ExHeader_Info *exheaderInfo, u64 programHandle) } } - s64 nbSection0Modules; - svcGetSystemInfo(&nbSection0Modules, 26, 0); - // Tweak 3dsx placeholder title exheaderInfo - if (nbSection0Modules == 6 && exheaderInfo->aci.local_caps.title_id == HBLDR_3DSX_TID) + if (hbldrIs3dsxTitle(exheaderInfo->aci.local_caps.title_id)) { assertSuccess(hbldrInit()); HBLDR_PatchExHeaderInfo(exheaderInfo); @@ -204,7 +207,7 @@ static Result LoadProcess(Handle *process, u64 programHandle) u64 titleId; // make sure the cached info corrosponds to the current programHandle - if (g_cached_programHandle != programHandle || g_exheaderInfo.aci.local_caps.title_id == HBLDR_3DSX_TID) + if (g_cached_programHandle != programHandle || hbldrIs3dsxTitle(g_exheaderInfo.aci.local_caps.title_id)) { res = GetProgramInfo(&g_exheaderInfo, programHandle); g_cached_programHandle = programHandle; @@ -230,7 +233,7 @@ static Result LoadProcess(Handle *process, u64 programHandle) titleId = g_exheaderInfo.aci.local_caps.title_id; ExHeader_CodeSetInfo *csi = &g_exheaderInfo.sci.codeset_info; - if (titleId == HBLDR_3DSX_TID) + if (hbldrIs3dsxTitle(titleId)) { assertSuccess(hbldrInit()); assertSuccess(HBLDR_LoadProcess(&codeset, csi->text.address, flags & 0xF00, titleId, csi->name)); @@ -377,7 +380,7 @@ void loaderHandleCommands(void *ctx) break; case 4: // GetProgramInfo memcpy(&programHandle, &cmdbuf[1], 8); - if (programHandle != g_cached_programHandle || g_exheaderInfo.aci.local_caps.title_id == HBLDR_3DSX_TID) + if (programHandle != g_cached_programHandle || hbldrIs3dsxTitle(g_exheaderInfo.aci.local_caps.title_id)) { res = GetProgramInfo(&g_exheaderInfo, programHandle); g_cached_programHandle = R_SUCCEEDED(res) ? programHandle : 0; diff --git a/sysmodules/loader/source/luma_shared_config.h b/sysmodules/loader/source/luma_shared_config.h new file mode 100644 index 0000000..f956a83 --- /dev/null +++ b/sysmodules/loader/source/luma_shared_config.h @@ -0,0 +1,28 @@ +/* This paricular file is licensed under the following terms: */ + +/* +* This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable +* for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it +* and redistribute it freely, subject to the following restrictions: +* +* The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +* If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +* +* Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +* This notice may not be removed or altered from any source distribution. +*/ + +#pragma once + +#include <3ds/types.h> + +/// Luma shared config type. +typedef struct LumaSharedConfig { + u64 hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading. + bool use_hbldr; ///< Whether or not Loader should use hb:ldr (Rosalina writes 1). +} LumaSharedConfig; + +/// Luma shared config. +#define Luma_SharedConfig ((volatile LumaSharedConfig *)(OS_SHAREDCFG_VADDR + 0x800)) diff --git a/sysmodules/rosalina/include/hbloader.h b/sysmodules/rosalina/include/hbloader.h index a6fb94d..b2fbcca 100644 --- a/sysmodules/rosalina/include/hbloader.h +++ b/sysmodules/rosalina/include/hbloader.h @@ -31,7 +31,6 @@ #include "MyThread.h" #define HBLDR_DEFAULT_3DSX_TID 0x000400000D921E00ULL -#define HBLDR_3DSX_TID (*(vu64 *)0x1FF81100) void HBLDR_RestartHbApplication(void *p); void HBLDR_HandleCommands(void *ctx); diff --git a/sysmodules/rosalina/include/luma_shared_config.h b/sysmodules/rosalina/include/luma_shared_config.h new file mode 100644 index 0000000..b63c433 --- /dev/null +++ b/sysmodules/rosalina/include/luma_shared_config.h @@ -0,0 +1,30 @@ +/* This paricular file is licensed under the following terms: */ + +/* +* This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable +* for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it +* and redistribute it freely, subject to the following restrictions: +* +* The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +* If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +* +* Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +* This notice may not be removed or altered from any source distribution. +*/ + +#pragma once + +#include <3ds/types.h> + +#include <3ds/types.h> + +/// Luma shared config type. +typedef struct LumaSharedConfig { + u64 hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading. + bool use_hbldr; ///< Whether or not Loader should use hb:ldr (Rosalina writes 1). +} LumaSharedConfig; + +/// Luma shared config. +#define Luma_SharedConfig ((volatile LumaSharedConfig *)(OS_SHAREDCFG_VADDR + 0x800)) diff --git a/sysmodules/rosalina/include/minisoc.h b/sysmodules/rosalina/include/minisoc.h index 9a97878..6040bc8 100644 --- a/sysmodules/rosalina/include/minisoc.h +++ b/sysmodules/rosalina/include/minisoc.h @@ -17,8 +17,6 @@ #define _REENT_ONLY #include -#define ROSALINA_PREVENT_DISCONNECT (*(volatile bool*)0x1FF81108) - #define SYNC_ERROR ENODEV extern bool miniSocEnabled; diff --git a/sysmodules/rosalina/include/utils.h b/sysmodules/rosalina/include/utils.h index 8c1a6a1..6155308 100644 --- a/sysmodules/rosalina/include/utils.h +++ b/sysmodules/rosalina/include/utils.h @@ -30,6 +30,7 @@ #include <3ds/srv.h> #include <3ds/result.h> #include "csvc.h" +#include "luma_shared_config.h" // For accessing physmem uncached (and directly) #define PA_PTR(addr) (void *)((u32)(addr) | 1 << 31) diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index d0c3e7b..390f09d 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -82,13 +82,15 @@ void initSystem(void) isN3DS = svcGetSystemInfo(&out, 0x10001, 0) == 0; svcGetSystemInfo(&out, 0x10000, 0x100); - HBLDR_3DSX_TID = out == 0 ? HBLDR_DEFAULT_3DSX_TID : (u64)out; + 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 = HBLDR_3DSX_TID == HBLDR_DEFAULT_3DSX_TID ? "Switch the hb. title to the current app." : - "Switch the hb. title to hblauncher_loader"; + 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)) { @@ -141,7 +143,7 @@ static void handleSleepNotification(u32 notificationId) { case PTMNOTIFID_SLEEP_REQUESTED: menuShouldExit = true; - PTMSYSM_ReplyToSleepQuery(ROSALINA_PREVENT_DISCONNECT); // deny sleep request if we have network stuff running + PTMSYSM_ReplyToSleepQuery(miniSocEnabled); // deny sleep request if we have network stuff running break; case PTMNOTIFID_GOING_TO_SLEEP: case PTMNOTIFID_SLEEP_ALLOWED: diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index 809275b..64f9882 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -54,7 +54,7 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void) Result res; char failureReason[64]; - if(HBLDR_3DSX_TID == HBLDR_DEFAULT_3DSX_TID) + if(Luma_SharedConfig->hbldr_3dsx_tid == HBLDR_DEFAULT_3DSX_TID) { FS_ProgramInfo progInfo; u32 pid; @@ -62,7 +62,7 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void) res = PMDBG_GetCurrentAppInfo(&progInfo, &pid, &launchFlags); if(R_SUCCEEDED(res)) { - HBLDR_3DSX_TID = progInfo.programId; + Luma_SharedConfig->hbldr_3dsx_tid = progInfo.programId; miscellaneousMenu.items[0].title = "Switch the hb. title to hblauncher_loader"; } else @@ -74,7 +74,7 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void) else { res = 0; - HBLDR_3DSX_TID = HBLDR_DEFAULT_3DSX_TID; + Luma_SharedConfig->hbldr_3dsx_tid = HBLDR_DEFAULT_3DSX_TID; miscellaneousMenu.items[0].title = "Switch the hb. title to the current app."; } @@ -202,7 +202,7 @@ void MiscellaneousMenu_SaveSettings(void) configData.config = config; configData.multiConfig = multiConfig; configData.bootConfig = bootConfig; - configData.hbldr3dsxTitleId = HBLDR_3DSX_TID; + configData.hbldr3dsxTitleId = Luma_SharedConfig->hbldr_3dsx_tid; configData.rosalinaMenuCombo = menuCombo; FS_ArchiveID archiveId = isSdMode ? ARCHIVE_SDMC : ARCHIVE_NAND_RW; diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index 2cf5c68..4d698be 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -7,12 +7,9 @@ #include "minisoc.h" #include -#include <3ds/ipc.h> -#include <3ds/os.h> -#include <3ds/synchronization.h> -#include <3ds/result.h> +#include <3ds.h> #include -#include "csvc.h" +#include "utils.h" s32 miniSocRefCount = 0; static u32 socContextAddr = 0x08000000; @@ -24,6 +21,22 @@ bool miniSocEnabled = false; s32 _net_convert_error(s32 sock_retval); +// To prevent ndm:u from disconnecting us +static Result srvExtAddToNdmuWorkaroundCount(s32 count) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x1000,1,0); + cmdbuf[1] = (u32)count; + + ret = svcSendSyncRequest(*srvGetSessionHandle()); + if(ret != 0) + return ret; + + return cmdbuf[1]; +} + static Result SOCU_Initialize(Handle memhandle, u32 memsize) { Result ret = 0; @@ -91,7 +104,8 @@ Result miniSocInit(void) svcKernelSetState(0x10000, 2); miniSocEnabled = true; - ROSALINA_PREVENT_DISCONNECT = true; + srvExtAddToNdmuWorkaroundCount(1); + return 0; cleanup: @@ -133,9 +147,9 @@ Result miniSocExitDirect(void) svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE); if(ret == 0) { - svcKernelSetState(0x10000, 2); miniSocEnabled = false; - ROSALINA_PREVENT_DISCONNECT = false; + srvExtAddToNdmuWorkaroundCount(-1); + svcKernelSetState(0x10000, 2); } return ret; } diff --git a/sysmodules/sm/source/notifications.c b/sysmodules/sm/source/notifications.c index a9128c6..ce8e015 100644 --- a/sysmodules/sm/source/notifications.c +++ b/sysmodules/sm/source/notifications.c @@ -8,8 +8,9 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for #include "notifications.h" #include "processes.h" -// 0 by default -#define ROSALINA_PREVENT_DISCONNECT (*(volatile bool*)0x1FF81108) +#include + +static atomic_int ndmuWorkaroundCount; static bool isNotificationInhibited(const ProcessData *processData, u32 notificationId) { @@ -19,7 +20,7 @@ static bool isNotificationInhibited(const ProcessData *processData, u32 notifica // Shell opened, shell closed case 0x213: case 0x214: - return pid == ndmuServicePid && ROSALINA_PREVENT_DISCONNECT; + return pid == ndmuServicePid && atomic_load(&ndmuWorkaroundCount) > 0; default: return false; } @@ -206,3 +207,10 @@ Result PublishToAll(u32 notificationId) return 0; } + +Result AddToNdmuWorkaroundCount(s32 count) +{ + // Note: no check is made to (current value)+count + atomic_fetch_add(&ndmuWorkaroundCount, count); + return 0; +} diff --git a/sysmodules/sm/source/notifications.h b/sysmodules/sm/source/notifications.h index 42b640f..40855e7 100644 --- a/sysmodules/sm/source/notifications.h +++ b/sysmodules/sm/source/notifications.h @@ -17,3 +17,5 @@ Result PublishToSubscriber(u32 notificationId, u32 flags); Result PublishAndGetSubscriber(u32 *pidCount, u32 *pidList, u32 notificationId, u32 flags); Result PublishToProcess(Handle process, u32 notificationId); Result PublishToAll(u32 notificationId); + +Result AddToNdmuWorkaroundCount(s32 count); diff --git a/sysmodules/sm/source/srv.c b/sysmodules/sm/source/srv.c index 5afb505..a27a6fa 100644 --- a/sysmodules/sm/source/srv.c +++ b/sysmodules/sm/source/srv.c @@ -167,6 +167,14 @@ Result srvHandleCommands(SessionData *sessionData) break; } + case 0x1000: // Custom command: AddToNdmuWorkaroundCount + { + res = AddToNdmuWorkaroundCount((s32)cmdbuf[1]); + cmdbuf[0] = IPC_MakeHeader(0x1000, 1, 0);; + cmdbuf[1] = (u32)res; + break; + } + default: goto invalid_command; break; From 95fd4e763b09ac14fb48b898e49220ba6d002c55 Mon Sep 17 00:00:00 2001 From: Death Mask Salesman Date: Sun, 12 Jul 2020 20:39:03 +0200 Subject: [PATCH 10/23] Fix release building (#1454) `boot.3dsx` is downloaded from a static URL via `curl`. Fixes #1453 --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 760f2e7..72cca2e 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ release: $(NAME)$(REVISION).zip clean: @$(foreach dir, $(SUBFOLDERS), $(MAKE) -C $(dir) clean &&) true - @rm -rf *.firm *.zip + @rm -rf *.firm *.zip *.3dsx # boot.3dsx comes from https://github.com/fincs/new-hbmenu/releases $(NAME)$(REVISION).zip: boot.firm boot.3dsx @@ -26,5 +26,8 @@ boot.firm: $(SUBFOLDERS) -A 0x18180000 -C XDMA XDMA NDMA XDMA @echo built... $(notdir $@) +boot.3dsx: + @curl -sSL "https://github.com/fincs/new-hbmenu/releases/latest/download/boot.3dsx" -o "boot.3dsx" + $(SUBFOLDERS): @$(MAKE) -C $@ all From 362c4ffff13509d1aca3f40b1e221ff397233af3 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sun, 12 Jul 2020 21:26:02 +0100 Subject: [PATCH 11/23] sysmodules: use libctru configmem defs --- sysmodules/pm/source/launch.c | 13 ++++++++----- sysmodules/pm/source/process_monitor.c | 2 +- sysmodules/pm/source/reslimit.c | 9 +++++---- sysmodules/pm/source/util.h | 8 +------- sysmodules/rosalina/source/hbloader.c | 14 ++++++-------- 5 files changed, 21 insertions(+), 25 deletions(-) diff --git a/sysmodules/pm/source/launch.c b/sysmodules/pm/source/launch.c index be6accf..efc40a4 100644 --- a/sysmodules/pm/source/launch.c +++ b/sysmodules/pm/source/launch.c @@ -218,8 +218,9 @@ static Result launchTitleImpl(Handle *debug, ProcessData **outProcessData, const programInfoUpdate = (launchFlags & PMLAUNCHFLAG_USE_UPDATE_TITLE) ? programInfoUpdate : programInfo; TRY(registerProgram(&programHandle, programInfo, programInfoUpdate)); + u32 coreVer = OS_KernelConfig->kernel_syscore_ver; res = LOADER_GetProgramInfo(exheaderInfo, programHandle); - res = R_SUCCEEDED(res) && SYSCOREVER == 2 && exheaderInfo->aci.local_caps.core_info.core_version != SYSCOREVER ? (Result)0xC8A05800 : res; + res = R_SUCCEEDED(res) && coreVer == 2 && exheaderInfo->aci.local_caps.core_info.core_version != coreVer ? (Result)0xC8A05800 : res; if (R_FAILED(res)) { LOADER_UnregisterProgram(programHandle); @@ -227,7 +228,7 @@ static Result launchTitleImpl(Handle *debug, ProcessData **outProcessData, const } // Change APPMEMALLOC if needed - if (IS_N3DS && APPMEMTYPE == 6 && (launchFlags & PMLAUNCHFLAG_NORMAL_APPLICATION) != 0) { + if (IS_N3DS && OS_KernelConfig->app_memtype == 6 && (launchFlags & PMLAUNCHFLAG_NORMAL_APPLICATION) != 0) { u32 limitMb; SystemMode n3dsSystemMode = exheaderInfo->aci.local_caps.core_info.n3ds_system_mode; bool forceO3dsAppMem = (launchFlags & PMLAUNCHFLAG_FORCE_USE_O3DS_APP_MEM) != 0; @@ -332,9 +333,11 @@ Result LaunchTitle(u32 *outPid, const FS_ProgramInfo *programInfo, u32 launchFla u32 tidh = (u32)(programInfo->programId >> 32); u32 tidl = (u32)programInfo->programId; - if ((tidh == 0x00040030 || tidh == 0x00040130) && (tidl & 0xFF) != SYSCOREVER) { + u32 coreVer = OS_KernelConfig->kernel_syscore_ver; + if (coreVer == 2 && (tidh == 0x00040030 || tidh == 0x00040130) && (tidl & 0xFF) != coreVer) { // Panic if launching SAFE_MODE sysmodules or applets (note: exheader syscorever check above only done for applications in official PM) // Official PM also hardcodes SYSCOREVER = 2 here. + // NATIVE_FIRM-only. panic(4); } @@ -520,8 +523,8 @@ Result autolaunchSysmodules(void) FS_ProgramInfo programInfo = { .mediaType = MEDIATYPE_NAND }; // Launch NS - if (NSTID != 0) { - programInfo.programId = NSTID; + if (OS_KernelConfig->ns_tid != 0) { + programInfo.programId = OS_KernelConfig->ns_tid; TRY(launchTitleImplWrapper(NULL, NULL, &programInfo, &programInfo, PMLAUNCHFLAG_LOAD_DEPENDENCIES)); } diff --git a/sysmodules/pm/source/process_monitor.c b/sysmodules/pm/source/process_monitor.c index cf65958..c2847d6 100644 --- a/sysmodules/pm/source/process_monitor.c +++ b/sysmodules/pm/source/process_monitor.c @@ -29,7 +29,7 @@ static void cleanupProcess(ProcessData *process) ProcessList_Lock(&g_manager.processList); if (g_manager.runningApplicationData != NULL && process->handle == g_manager.runningApplicationData->handle) { - if (IS_N3DS && APPMEMTYPE == 6) { + if (IS_N3DS && OS_KernelConfig->app_memtype == 6) { assertSuccess(resetAppMemLimit()); } g_manager.runningApplicationData = NULL; diff --git a/sysmodules/pm/source/reslimit.c b/sysmodules/pm/source/reslimit.c index 824c1aa..4dad971 100644 --- a/sysmodules/pm/source/reslimit.c +++ b/sysmodules/pm/source/reslimit.c @@ -252,7 +252,8 @@ static ReslimitValues *fixupReslimitValues(void) // Note: we lie in the reslimit and make as if neither KExt nor Roslina existed, to avoid breakage - u32 sysmemalloc = SYSMEMALLOC + (hasKExt() ? getStolenSystemMemRegionSize() : 0); + u32 appmemalloc = OS_KernelConfig->memregion_sz[0]; + u32 sysmemalloc = OS_KernelConfig->memregion_sz[1] + (hasKExt() ? getStolenSystemMemRegionSize() : 0); ReslimitValues *values = !IS_N3DS ? g_o3dsReslimitValues : g_n3dsReslimitValues; static const u32 minAppletMemAmount = 0x1200000; @@ -261,7 +262,7 @@ static ReslimitValues *fixupReslimitValues(void) u32 baseRegionSize = !IS_N3DS ? 0x1400000 : 0x2000000; if (sysmemalloc < minAppletMemAmount) { - values[1][0] = SYSMEMALLOC - minAppletMemAmount / 3; + values[1][0] = sysmemalloc - minAppletMemAmount / 3; values[2][0] = 0; values[3][0] = baseRegionSize + otherMinOvercommitAmount; } else { @@ -271,8 +272,8 @@ static ReslimitValues *fixupReslimitValues(void) values[3][0] = baseRegionSize + (otherMinOvercommitAmount + excess / 4); } - values[0][0] = APPMEMALLOC; - g_defaultAppMemLimit = APPMEMALLOC; + values[0][0] = appmemalloc; + g_defaultAppMemLimit = appmemalloc; return values; } diff --git a/sysmodules/pm/source/util.h b/sysmodules/pm/source/util.h index 0a3cf20..4618a4c 100644 --- a/sysmodules/pm/source/util.h +++ b/sysmodules/pm/source/util.h @@ -8,13 +8,7 @@ #define REG32(reg) (*(vu32 *)reg) #define REG64(reg) (*(vu64 *)reg) -#define NSTID REG64(0x1FF80008) -#define SYSCOREVER REG32(0x1FF80010) -#define APPMEMTYPE REG32(0x1FF80030) -#define APPMEMALLOC REG32(0x1FF80040) -#define SYSMEMALLOC REG32(0x1FF80044) - -#define IS_N3DS (*(vu32 *)0x1FF80030 >= 6) // APPMEMTYPE. Hacky but doesn't use APT +#define IS_N3DS (OS_KernelConfig->app_memtype >= 6) // APPMEMTYPE. Hacky but doesn't use APT #define N3DS_TID_MASK 0xF0000000ULL #define N3DS_TID_BIT 0x20000000ULL diff --git a/sysmodules/rosalina/source/hbloader.c b/sysmodules/rosalina/source/hbloader.c index de2c08d..3352089 100644 --- a/sysmodules/rosalina/source/hbloader.c +++ b/sysmodules/rosalina/source/hbloader.c @@ -36,9 +36,6 @@ #include "gdb/server.h" #include "pmdbgext.h" -#define SYSCOREVER (*(vu32 *)0x1FF80010) -#define APPMEMTYPE (*(vu32 *)0x1FF80030) - extern GDBContext *nextApplicationGdbCtx; extern GDBServer gdbServer; @@ -322,21 +319,22 @@ void HBLDR_HandleCommands(void *ctx) memcpy(&exhi->sci.codeset_info.stack_size, &stacksize, 4); memset(&exhi->sci.dependencies, 0, sizeof(exhi->sci.dependencies)); - if (SYSCOREVER == 2) + u32 coreVer = OS_KernelConfig->kernel_syscore_ver; + if (coreVer == 2) memcpy(exhi->sci.dependencies, dependencyListNativeFirm, sizeof(dependencyListNativeFirm)); - else if (SYSCOREVER == 3) + else if (coreVer == 3) memcpy(exhi->sci.dependencies, dependencyListSafeFirm, sizeof(dependencyListSafeFirm)); ExHeader_Arm11SystemLocalCapabilities* localcaps0 = &exhi->aci.local_caps; - localcaps0->core_info.core_version = SYSCOREVER; + localcaps0->core_info.core_version = coreVer; localcaps0->core_info.use_cpu_clockrate_804MHz = false; localcaps0->core_info.enable_l2c = false; localcaps0->core_info.ideal_processor = 0; localcaps0->core_info.affinity_mask = BIT(0); localcaps0->core_info.priority = 0x30; - u32 appmemtype = APPMEMTYPE; + u32 appmemtype = OS_KernelConfig->app_memtype; localcaps0->core_info.o3ds_system_mode = appmemtype < 6 ? (SystemMode)appmemtype : SYSMODE_O3DS_PROD; localcaps0->core_info.n3ds_system_mode = appmemtype >= 6 ? (SystemMode)(appmemtype - 6 + 1) : SYSMODE_N3DS_PROD; @@ -363,7 +361,7 @@ void HBLDR_HandleCommands(void *ctx) // Set kernel release version to the current kernel version kcaps0->descriptors[0] = 0xFC000000 | (osGetKernelVersion() >> 16); - if (GET_VERSION_MINOR(osGetKernelVersion()) >= 50 && SYSCOREVER == 2) // 9.6+ NFIRM + if (GET_VERSION_MINOR(osGetKernelVersion()) >= 50 && coreVer == 2) // 9.6+ NFIRM { u64 lastdep = sizeof(dependencyListNativeFirm)/8; exhi->sci.dependencies[lastdep++] = 0x0004013000004002ULL; // nfc From 2af05220c22e5d5b2562a34e64fd30acf56c0df7 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Tue, 14 Jul 2020 22:10:13 +0100 Subject: [PATCH 12/23] rosalina: properly rewrite luminance-setting menu, etc. --- k11_extension/source/svc/KernelSetState.c | 22 ++- k11_extension/source/synchronization.c | 10 +- sysmodules/rosalina/include/luminance.h | 31 +++++ sysmodules/rosalina/source/luminance.c | 110 +++++++++++++++ sysmodules/rosalina/source/menu.c | 6 +- sysmodules/rosalina/source/menus.c | 144 +++++++++----------- sysmodules/rosalina/source/menus/debugger.c | 1 - sysmodules/rosalina/source/minisoc.c | 4 +- 8 files changed, 229 insertions(+), 99 deletions(-) create mode 100644 sysmodules/rosalina/include/luminance.h create mode 100644 sysmodules/rosalina/source/luminance.c diff --git a/k11_extension/source/svc/KernelSetState.c b/k11_extension/source/svc/KernelSetState.c index 2b944aa..aeb6372 100644 --- a/k11_extension/source/svc/KernelSetState.c +++ b/k11_extension/source/svc/KernelSetState.c @@ -109,20 +109,16 @@ Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3) if(rosalinaState & 2) hasStartedRosalinaNetworkFuncsOnce = true; - // 1: all applet/app/gsp/dsp... threads 4: hid/ir - if(varg1 & 1) + // 1: all applet/app/dsp/csnd... threads 2: gsp 4: hid/ir + for (u32 v = 4; v != 0; v >>= 1) { - if (rosalinaState & 1) - rosalinaLockThreads(1); - else - rosalinaUnlockThreads(1); - } - if(varg1 & 4) - { - if (rosalinaState & 4) - rosalinaLockThreads(4); - else - rosalinaUnlockThreads(4); + if (varg1 & v) + { + if (rosalinaState & v) + rosalinaLockThreads(v); + else + rosalinaUnlockThreads(v); + } } break; diff --git a/k11_extension/source/synchronization.c b/k11_extension/source/synchronization.c index d6dc6cb..4b00072 100644 --- a/k11_extension/source/synchronization.c +++ b/k11_extension/source/synchronization.c @@ -104,10 +104,18 @@ bool rosalinaThreadLockPredicate(KThread *thread, u32 mask) if (highTitleId != 0x00040130) // non-sysmodules return true; else - return lowTitleId == 0x1A02 || lowTitleId == 0x1C02 || lowTitleId == 0x2702; // dsp, gsp, csnd + 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; } diff --git a/sysmodules/rosalina/include/luminance.h b/sysmodules/rosalina/include/luminance.h new file mode 100644 index 0000000..3590cc3 --- /dev/null +++ b/sysmodules/rosalina/include/luminance.h @@ -0,0 +1,31 @@ +/* +* 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 . +* +* 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. +*/ + +#pragma once + +#include <3ds/types.h> + +u32 getCurrentLuminance(bool top); diff --git a/sysmodules/rosalina/source/luminance.c b/sysmodules/rosalina/source/luminance.c new file mode 100644 index 0000000..3e3ea8c --- /dev/null +++ b/sysmodules/rosalina/source/luminance.c @@ -0,0 +1,110 @@ +/* +* 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 . +* +* 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 +#include "luminance.h" +#include "utils.h" + +extern bool isN3DS; + +typedef struct BlPwmData +{ + float coeffs[3][3]; + u8 numLevels; + u8 unk; + u16 luminanceLevels[7]; + u16 brightnessMax; + u16 brightnessMin; +} BlPwmData; + +// Calibration, with (dubious) default values as fallback +static BlPwmData s_blPwmData = { + .coeffs = { + { 0.00111639f, 1.41412f, 0.07178809f }, + { 0.000418169f, 0.66567f, 0.06098654f }, + { 0.00208543f, 1.55639f, 0.0385939 } + }, + .numLevels = 5, + .unk = 0, + .luminanceLevels = { 20, 43, 73, 95, 117, 172, 172 }, + .brightnessMax = 512, + .brightnessMin = 13, +}; + +static inline float getPwmRatio(u32 brightnessMax, u32 pwmCnt) +{ + u32 val = (pwmCnt & 0x10000) ? pwmCnt & 0x3FF : 511; // check pwm enabled flag + return (float)brightnessMax / (val + 1); +} + +// nn's asm has rounding errors (originally at 10^-3) +static inline u32 luminanceToBrightness(u32 luminance, const float coeffs[3], u32 minLuminance, float pwmRatio) +{ + float x = (float)luminance; + float y = coeffs[0]*x*x + coeffs[1]*x + coeffs[2]; + y = (y <= minLuminance ? (float)minLuminance : y) / pwmRatio; + + return (u32)(y + 0.5f); +} + +static inline u32 brightnessToLuminance(u32 brightness, const float coeffs[3], float pwmRatio) +{ + // Find polynomial root of ax^2 + bx + c = y + + float y = (float)brightness * pwmRatio; + float a = coeffs[0]; + float b = coeffs[1]; + float c = coeffs[2] - y; + + float x0 = (-b + sqrtf(b*b - 4.0f*a*c)) / (a + a); + + return (u32)(x0 + 0.5f); +} + +static void readCalibration(void) +{ + static bool calibRead = false; + + if (!calibRead) { + cfguInit(); + calibRead = R_SUCCEEDED(CFG_GetConfigInfoBlk8(sizeof(BlPwmData), 0x50002, &s_blPwmData)); + cfguExit(); + } +} + +u32 getCurrentLuminance(bool top) +{ + u32 regbase = top ? 0x10202200 : 0x10202A00; + + readCalibration(); + + const float *coeffs = s_blPwmData.coeffs[top ? (isN3DS ? 2 : 1) : 0]; + u32 brightness = REG32(regbase + 0x40); + float ratio = getPwmRatio(s_blPwmData.brightnessMax, REG32(regbase + 0x44)); + + return brightnessToLuminance(brightness, coeffs, ratio); +} diff --git a/sysmodules/rosalina/source/menu.c b/sysmodules/rosalina/source/menu.c index 04c9779..9825461 100644 --- a/sysmodules/rosalina/source/menu.c +++ b/sysmodules/rosalina/source/menu.c @@ -211,13 +211,13 @@ void menuEnter(void) if(!menuShouldExit && menuRefCount == 0) { menuRefCount++; - svcKernelSetState(0x10000, 1); + svcKernelSetState(0x10000, 2 | 1); svcSleepThread(5 * 1000 * 100LL); if (R_FAILED(Draw_AllocateFramebufferCache(FB_BOTTOM_SIZE))) { // Oops menuRefCount = 0; - svcKernelSetState(0x10000, 1); + svcKernelSetState(0x10000, 2 | 1); svcSleepThread(5 * 1000 * 100LL); } else @@ -235,7 +235,7 @@ void menuLeave(void) { Draw_RestoreFramebuffer(); Draw_FreeFramebufferCache(); - svcKernelSetState(0x10000, 1); + svcKernelSetState(0x10000, 2 | 1); } Draw_Unlock(); } diff --git a/sysmodules/rosalina/source/menus.c b/sysmodules/rosalina/source/menus.c index 0986802..901329a 100644 --- a/sysmodules/rosalina/source/menus.c +++ b/sysmodules/rosalina/source/menus.c @@ -39,6 +39,7 @@ #include "memory.h" #include "fmt.h" #include "process_patches.h" +#include "luminance.h" Menu rosalinaMenu = { "Rosalina menu", @@ -155,107 +156,92 @@ void RosalinaMenu_Reboot(void) while(!menuShouldExit); } -static u32 gspPatchAddrN3ds, gspPatchValuesN3ds[2]; -static bool gspPatchDoneN3ds; - -static Result RosalinaMenu_PatchN3dsGspForBrightness(u32 size) -{ - u32 *off = (u32 *)0x00100000; - u32 *end = (u32 *)(0x00100000 + size); - - for (; off < end && (off[0] != 0xE92D4030 || off[1] != 0xE1A04000 || off[2] != 0xE2805C01 || off[3] != 0xE5D0018C); off++); - - if (off >= end) { - return -1; - } - - gspPatchAddrN3ds = (u32)off; - gspPatchValuesN3ds[0] = off[26]; - gspPatchValuesN3ds[1] = off[50]; - - // NOP brightness changing in GSP - off[26] = 0xE1A00000; - off[50] = 0xE1A00000; - - return 0; -} -static Result RosalinaMenu_RevertN3dsGspPatch(u32 size) -{ - (void)size; - - u32 *off = (u32 *)gspPatchAddrN3ds; - off[26] = gspPatchValuesN3ds[0]; - off[50] = gspPatchValuesN3ds[1]; - - return 0; -} - void RosalinaMenu_ChangeScreenBrightness(void) { - Result patchResult = 0; - if (isN3DS && !gspPatchDoneN3ds) - { - patchResult = PatchProcessByName("gsp", RosalinaMenu_PatchN3dsGspForBrightness); - gspPatchDoneN3ds = R_SUCCEEDED(patchResult); - } - Draw_Lock(); Draw_ClearFramebuffer(); Draw_FlushFramebuffer(); Draw_Unlock(); + // gsp:LCD GetLuminance is stubbed on O3DS so we have to implement it ourselves... damn it. + // Assume top and bottom screen luminances are the same (should be; if not, we'll set them to the same values). + u32 luminance = getCurrentLuminance(false); + do { - // Assume the current brightness for both screens are the same. - s32 brightness = (s32)(LCD_TOP_BRIGHTNESS & 0xFF); - Draw_Lock(); Draw_DrawString(10, 10, COLOR_TITLE, "Rosalina menu"); u32 posY = 30; - posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Current brightness (0..255): %3lu\n\n", brightness); - if (R_SUCCEEDED(patchResult)) - { - posY = Draw_DrawString(10, posY, COLOR_WHITE, "Press Up/Down for +-1, Right/Left for +-10.\n"); - posY = Draw_DrawString(10, posY, COLOR_WHITE, "Press Y to revert the GSP patch and exit.\n\n"); - - posY = Draw_DrawString(10, posY, COLOR_RED, "WARNING: \n"); - posY = Draw_DrawString(10, posY, COLOR_WHITE, " * avoid using values far higher than the presets.\n"); - posY = Draw_DrawString(10, posY, COLOR_WHITE, " * normal brightness mngmt. is now broken on N3DS.\nYou'll need to press Y to revert"); - } - else - Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Failed to patch GSP (0x%08lx).", (u32)patchResult); + posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Current luminance: %lu\n\n", luminance); + posY = Draw_DrawString(10, posY, COLOR_WHITE, "Controls: Up/Down for +-1, Right/Left for +-10.\n"); + posY = Draw_DrawString(10, posY, COLOR_WHITE, "Press A to start, B to exit.\n\n"); + posY = Draw_DrawString(10, posY, COLOR_RED, "WARNING: \n"); + posY = Draw_DrawString(10, posY, COLOR_WHITE, " * value will be limited by the presets.\n"); + posY = Draw_DrawString(10, posY, COLOR_WHITE, " * bottom framebuffer will be restored until\nyou exit."); Draw_FlushFramebuffer(); Draw_Unlock(); u32 pressed = waitInputWithTimeout(1000); - if ((pressed & DIRECTIONAL_KEYS) && R_SUCCEEDED(patchResult)) - { - if (pressed & KEY_UP) - brightness += 1; - else if (pressed & KEY_DOWN) - brightness -= 1; - else if (pressed & KEY_RIGHT) - brightness += 10; - else if (pressed & KEY_LEFT) - brightness -= 10; + if (pressed & KEY_A) + break; - brightness = brightness < 0 ? 0 : brightness; - brightness = brightness > 255 ? 255 : brightness; - LCD_TOP_BRIGHTNESS = (u32)brightness; - LCD_BOT_BRIGHTNESS = (u32)brightness; - } - else if ((pressed & KEY_Y) && gspPatchDoneN3ds) - { - patchResult = PatchProcessByName("gsp", RosalinaMenu_RevertN3dsGspPatch); - gspPatchDoneN3ds = !R_SUCCEEDED(patchResult); - return; - } - else if (pressed & KEY_B) + if (pressed & KEY_B) return; } while (!menuShouldExit); + + Draw_Lock(); + + Draw_RestoreFramebuffer(); + Draw_FreeFramebufferCache(); + + svcKernelSetState(0x10000, 2); // unblock gsp + gspLcdInit(); // assume it doesn't fail. If it does, brightness won't change, anyway. + + // gsp:LCD will normalize the brightness between top/bottom screen, handle PWM, etc. + + s32 lum = (s32)luminance; + + do + { + u32 pressed = waitInputWithTimeout(1000); + if (pressed & DIRECTIONAL_KEYS) + { + if (pressed & KEY_UP) + lum += 1; + else if (pressed & KEY_DOWN) + lum -= 1; + else if (pressed & KEY_RIGHT) + lum += 10; + else if (pressed & KEY_LEFT) + lum -= 10; + + lum = lum < 0 ? 0 : lum; + + // We need to call gsp here because updating the active duty LUT is a bit tedious (plus, GSP has internal state). + // This is actually SetLuminance: + GSPLCD_SetBrightnessRaw(BIT(GSP_SCREEN_TOP) | BIT(GSP_SCREEN_BOTTOM), lum); + } + + if (pressed & KEY_B) + break; + } + while (!menuShouldExit); + + gspLcdExit(); + svcKernelSetState(0x10000, 2); // block gsp again + + if (R_FAILED(Draw_AllocateFramebufferCache(FB_BOTTOM_SIZE))) + { + // Shouldn't happen + __builtin_trap(); + } + else + Draw_SetupFramebuffer(); + + Draw_Unlock(); } void RosalinaMenu_PowerOff(void) // Soft shutdown. diff --git a/sysmodules/rosalina/source/menus/debugger.c b/sysmodules/rosalina/source/menus/debugger.c index 70bf67a..0a00ebf 100644 --- a/sysmodules/rosalina/source/menus/debugger.c +++ b/sysmodules/rosalina/source/menus/debugger.c @@ -102,7 +102,6 @@ Result debuggerDisable(s64 timeout) svcCloseHandle(dummy); PMDBG_DebugNextApplicationByForce(false); nextApplicationGdbCtx = NULL; - svcKernelSetState(0x10000, 2); } return res; diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index 4d698be..77ef571 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -102,7 +102,7 @@ Result miniSocInit(void) ret = SOCU_Initialize(miniSocMemHandle, socContextSize); if(ret != 0) goto cleanup; - svcKernelSetState(0x10000, 2); + svcKernelSetState(0x10000, 0x10); miniSocEnabled = true; srvExtAddToNdmuWorkaroundCount(1); @@ -149,7 +149,7 @@ Result miniSocExitDirect(void) { miniSocEnabled = false; srvExtAddToNdmuWorkaroundCount(-1); - svcKernelSetState(0x10000, 2); + svcKernelSetState(0x10000, 0x10); } return ret; } From 786adf0268b5746e848ee7b5333bc452c36b6103 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 15 Jul 2020 00:56:25 +0100 Subject: [PATCH 13/23] k11ext: fix oops --- k11_extension/source/svc/KernelSetState.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k11_extension/source/svc/KernelSetState.c b/k11_extension/source/svc/KernelSetState.c index aeb6372..629a983 100644 --- a/k11_extension/source/svc/KernelSetState.c +++ b/k11_extension/source/svc/KernelSetState.c @@ -106,7 +106,7 @@ Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3) while(__strex((s32 *)&rosalinaState, (s32)(rosalinaState ^ varg1))); __dmb(); - if(rosalinaState & 2) + if(rosalinaState & 0x10) hasStartedRosalinaNetworkFuncsOnce = true; // 1: all applet/app/dsp/csnd... threads 2: gsp 4: hid/ir From ba26ae0f1c9311c185a438ceafc862206b02a420 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 15 Jul 2020 17:33:47 +0100 Subject: [PATCH 14/23] k11ext: refactor ndm:u workaround --- k11_extension/source/svc/SendSyncRequest.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/k11_extension/source/svc/SendSyncRequest.c b/k11_extension/source/svc/SendSyncRequest.c index 0834254..507b32e 100644 --- a/k11_extension/source/svc/SendSyncRequest.c +++ b/k11_extension/source/svc/SendSyncRequest.c @@ -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; From e096aaabc4c987319600d628591255adf9a84e42 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 15 Jul 2020 18:57:53 +0100 Subject: [PATCH 15/23] rosalina/sm: properly interact with ndm --- sysmodules/rosalina/source/minisoc.c | 40 +++++++++++++++------------- sysmodules/sm/source/common.h | 1 - sysmodules/sm/source/notifications.c | 15 +---------- sysmodules/sm/source/services.c | 5 ---- sysmodules/sm/source/srv.c | 8 ------ 5 files changed, 22 insertions(+), 47 deletions(-) diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index 77ef571..50c96bd 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -16,27 +16,12 @@ static u32 socContextAddr = 0x08000000; static u32 socContextSize = 0x60000; static Handle miniSocHandle; static Handle miniSocMemHandle; +static bool exclusiveStateEntered = false; bool miniSocEnabled = false; s32 _net_convert_error(s32 sock_retval); -// To prevent ndm:u from disconnecting us -static Result srvExtAddToNdmuWorkaroundCount(s32 count) -{ - Result ret = 0; - u32 *cmdbuf = getThreadCommandBuffer(); - - cmdbuf[0] = IPC_MakeHeader(0x1000,1,0); - cmdbuf[1] = (u32)count; - - ret = svcSendSyncRequest(*srvGetSessionHandle()); - if(ret != 0) - return ret; - - return cmdbuf[1]; -} - static Result SOCU_Initialize(Handle memhandle, u32 memsize) { Result ret = 0; @@ -102,9 +87,18 @@ Result miniSocInit(void) ret = SOCU_Initialize(miniSocMemHandle, socContextSize); if(ret != 0) goto cleanup; + if (!exclusiveStateEntered) + { + ndmuInit(); + ret = NDMU_EnterExclusiveState(NDM_EXCLUSIVE_STATE_INFRASTRUCTURE); + if (R_SUCCEEDED(ret)) + ret = NDMU_LockState(); // prevents ndm from switching to StreetPass when the lid is closed + //ndmuExit(); + exclusiveStateEntered = R_SUCCEEDED(ret); + } + svcKernelSetState(0x10000, 0x10); miniSocEnabled = true; - srvExtAddToNdmuWorkaroundCount(1); return 0; @@ -132,7 +126,6 @@ cleanup: Result miniSocExitDirect(void) { - //if (miniSocRefCount != 0) __builtin_trap(); Result ret = 0; u32 tmp; @@ -147,8 +140,17 @@ Result miniSocExitDirect(void) svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE); if(ret == 0) { + if (exclusiveStateEntered) + { + //ndmuInit(); + ret = NDMU_UnlockState(); + if (R_SUCCEEDED(ret)) + ret = NDMU_LeaveExclusiveState(); + ndmuExit(); + exclusiveStateEntered = R_FAILED(ret); + } + miniSocEnabled = false; - srvExtAddToNdmuWorkaroundCount(-1); svcKernelSetState(0x10000, 0x10); } return ret; diff --git a/sysmodules/sm/source/common.h b/sysmodules/sm/source/common.h index c750ece..7ee7f6b 100644 --- a/sysmodules/sm/source/common.h +++ b/sysmodules/sm/source/common.h @@ -17,7 +17,6 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for extern u32 nbSection0Modules; extern Handle resumeGetServiceHandleOrPortRegisteredSemaphore; -extern u32 ndmuServicePid; struct SessionDataList; diff --git a/sysmodules/sm/source/notifications.c b/sysmodules/sm/source/notifications.c index ce8e015..18465a7 100644 --- a/sysmodules/sm/source/notifications.c +++ b/sysmodules/sm/source/notifications.c @@ -10,17 +10,11 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for #include -static atomic_int ndmuWorkaroundCount; - static bool isNotificationInhibited(const ProcessData *processData, u32 notificationId) { - u32 pid = processData->pid; + (void)processData; switch(notificationId) { - // Shell opened, shell closed - case 0x213: - case 0x214: - return pid == ndmuServicePid && atomic_load(&ndmuWorkaroundCount) > 0; default: return false; } @@ -207,10 +201,3 @@ Result PublishToAll(u32 notificationId) return 0; } - -Result AddToNdmuWorkaroundCount(s32 count) -{ - // Note: no check is made to (current value)+count - atomic_fetch_add(&ndmuWorkaroundCount, count); - return 0; -} diff --git a/sysmodules/sm/source/services.c b/sysmodules/sm/source/services.c index 67274b4..a81af7c 100644 --- a/sysmodules/sm/source/services.c +++ b/sysmodules/sm/source/services.c @@ -13,8 +13,6 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for ServiceInfo servicesInfo[0xA0] = { 0 }; u32 nbServices = 0; // including "ports" registered with getPort -u32 ndmuServicePid = 3; // use our PID as default. - static Result checkServiceName(const char *name, s32 nameSize) { if(nameSize <= 0 || nameSize > 8) @@ -98,9 +96,6 @@ static Result doRegisterServiceOrPort(u32 pid, Handle *serverPort, Handle client if(!isNamedPort) *serverPort = portServer; - if(R_SUCCEEDED(res) && strcmp(name, "ndm:u") == 0) - ndmuServicePid = pid; - return res; } diff --git a/sysmodules/sm/source/srv.c b/sysmodules/sm/source/srv.c index a27a6fa..5afb505 100644 --- a/sysmodules/sm/source/srv.c +++ b/sysmodules/sm/source/srv.c @@ -167,14 +167,6 @@ Result srvHandleCommands(SessionData *sessionData) break; } - case 0x1000: // Custom command: AddToNdmuWorkaroundCount - { - res = AddToNdmuWorkaroundCount((s32)cmdbuf[1]); - cmdbuf[0] = IPC_MakeHeader(0x1000, 1, 0);; - cmdbuf[1] = (u32)res; - break; - } - default: goto invalid_command; break; From 184f4587fbd8c78c4ca701669527ca8d34697870 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 15 Jul 2020 22:24:08 +0100 Subject: [PATCH 16/23] rosalina: minor menu changes --- sysmodules/rosalina/source/menus.c | 16 ++++++++++------ sysmodules/rosalina/source/menus/miscellaneous.c | 16 +++++++++++++++- sysmodules/rosalina/source/menus/sysconfig.c | 2 +- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/sysmodules/rosalina/source/menus.c b/sysmodules/rosalina/source/menus.c index 901329a..c92da4c 100644 --- a/sysmodules/rosalina/source/menus.c +++ b/sysmodules/rosalina/source/menus.c @@ -63,7 +63,11 @@ Menu rosalinaMenu = { bool rosalinaMenuShouldShowDebugInfo(void) { - return true; + // Don't show on release builds + + s64 out; + svcGetSystemInfo(&out, 0x10000, 0x200); + return out == 0; } void RosalinaMenu_ShowDebugInfo(void) @@ -117,8 +121,8 @@ void RosalinaMenu_ShowCredits(void) Draw_DrawString(10, posY, COLOR_WHITE, ( "Special thanks to:\n" - " Bond697, WinterMute, piepie62, yifanlu\n" - " Luma3DS contributors, ctrulib contributors,\n" + " fincs, WinterMute, mtheall, piepie62,\n" + " Luma3DS contributors, libctru contributors,\n" " other people" )); @@ -138,7 +142,7 @@ void RosalinaMenu_Reboot(void) do { Draw_Lock(); - Draw_DrawString(10, 10, COLOR_TITLE, "Rosalina menu"); + Draw_DrawString(10, 10, COLOR_TITLE, "Reboot"); Draw_DrawString(10, 30, COLOR_WHITE, "Press A to reboot, press B to go back."); Draw_FlushFramebuffer(); Draw_Unlock(); @@ -170,7 +174,7 @@ void RosalinaMenu_ChangeScreenBrightness(void) do { Draw_Lock(); - Draw_DrawString(10, 10, COLOR_TITLE, "Rosalina menu"); + Draw_DrawString(10, 10, COLOR_TITLE, "Screen brightness"); u32 posY = 30; posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Current luminance: %lu\n\n", luminance); posY = Draw_DrawString(10, posY, COLOR_WHITE, "Controls: Up/Down for +-1, Right/Left for +-10.\n"); @@ -254,7 +258,7 @@ void RosalinaMenu_PowerOff(void) // Soft shutdown. do { Draw_Lock(); - Draw_DrawString(10, 10, COLOR_TITLE, "Rosalina menu"); + Draw_DrawString(10, 10, COLOR_TITLE, "Power off"); Draw_DrawString(10, 30, COLOR_WHITE, "Press A to power off, press B to go back."); Draw_FlushFramebuffer(); Draw_Unlock(); diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index 64f9882..4f294eb 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -319,7 +319,21 @@ void MiscellaneousMenu_InputRedirection(void) else { if(res == 0) - Draw_DrawString(10, 30, COLOR_WHITE, "InputRedirection stopped successfully."); + { + u32 posY = 30; + posY = Draw_DrawString(10, posY, COLOR_WHITE, "InputRedirection stopped successfully.\n\n"); + if (isN3DS) + { + posY = Draw_DrawString( + 10, + posY, + COLOR_WHITE, + "This might cause a key press to be repeated in\n" + "Home Menu for no reason.\n\n" + "Just pressing ZL/ZR on the console is enough to fix\nthis.\n" + ); + } + } else Draw_DrawString(10, 30, COLOR_WHITE, buf); } diff --git a/sysmodules/rosalina/source/menus/sysconfig.c b/sysmodules/rosalina/source/menus/sysconfig.c index 4a357dd..babf15b 100644 --- a/sysmodules/rosalina/source/menus/sysconfig.c +++ b/sysmodules/rosalina/source/menus/sysconfig.c @@ -35,10 +35,10 @@ Menu sysconfigMenu = { "System configuration menu", { + { "Control Wireless connection", METHOD, .method = &SysConfigMenu_ControlWifi }, { "Toggle LEDs", METHOD, .method = &SysConfigMenu_ToggleLEDs }, { "Toggle Wireless", METHOD, .method = &SysConfigMenu_ToggleWireless }, { "Toggle Power Button", METHOD, .method=&SysConfigMenu_TogglePowerButton }, - { "Control Wireless connection", METHOD, .method = &SysConfigMenu_ControlWifi }, {}, } }; From 514537a983311d8c729e4de64c9b73b338ad0bfc Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 15 Jul 2020 23:04:35 +0100 Subject: [PATCH 17/23] hbloader: allow homebrew to write to the shared config page --- sysmodules/rosalina/source/hbloader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysmodules/rosalina/source/hbloader.c b/sysmodules/rosalina/source/hbloader.c index 3352089..f645b0c 100644 --- a/sysmodules/rosalina/source/hbloader.c +++ b/sysmodules/rosalina/source/hbloader.c @@ -145,7 +145,7 @@ static const u32 kernelCaps[] = 0xFF81FF78, // RW static mapping: 0x1FF78000 0xFF91F000, // RO static mapping: 0x1F000000 0xFF91F600, // RO static mapping: 0x1F600000 - 0xFF002101, // Exflags: APPLICATION memtype + "Allow debug" + "Access core2" + 0xFF002109, // Exflags: APPLICATION memtype + "Shared page writing" + "Allow debug" + "Access core2" 0xFE000200, // Handle table size: 0x200 }; @@ -344,7 +344,7 @@ void HBLDR_HandleCommands(void *ctx) // See the big comment in sysmodules/pm/source/reslimit.c for technical details. localcaps0->reslimits[0] = BIT(7) | 89; - //localcaps0->storage_info.fs_access_info = 0xFFFFFFFF; // Give access to everything + localcaps0->storage_info.fs_access_info = 0xFFFFFFFF; // Give access to everything localcaps0->storage_info.no_romfs = true; localcaps0->storage_info.use_extended_savedata_access = true; // Whatever From 781cd85b00df1e691ab4ea15d406ed736c791950 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Thu, 16 Jul 2020 00:50:05 +0100 Subject: [PATCH 18/23] rosalina: display min/max luminance --- sysmodules/rosalina/include/luminance.h | 2 ++ sysmodules/rosalina/source/luminance.c | 12 ++++++++++++ sysmodules/rosalina/source/menus.c | 12 +++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/sysmodules/rosalina/include/luminance.h b/sysmodules/rosalina/include/luminance.h index 3590cc3..1b48036 100644 --- a/sysmodules/rosalina/include/luminance.h +++ b/sysmodules/rosalina/include/luminance.h @@ -28,4 +28,6 @@ #include <3ds/types.h> +u32 getMinLuminancePreset(void); +u32 getMaxLuminancePreset(void); u32 getCurrentLuminance(bool top); diff --git a/sysmodules/rosalina/source/luminance.c b/sysmodules/rosalina/source/luminance.c index 3e3ea8c..d26de8c 100644 --- a/sysmodules/rosalina/source/luminance.c +++ b/sysmodules/rosalina/source/luminance.c @@ -96,6 +96,18 @@ static void readCalibration(void) } } +u32 getMinLuminancePreset(void) +{ + readCalibration(); + return s_blPwmData.luminanceLevels[0]; +} + +u32 getMaxLuminancePreset(void) +{ + readCalibration(); + return s_blPwmData.luminanceLevels[s_blPwmData.numLevels - 1]; +} + u32 getCurrentLuminance(bool top) { u32 regbase = top ? 0x10202200 : 0x10202A00; diff --git a/sysmodules/rosalina/source/menus.c b/sysmodules/rosalina/source/menus.c index c92da4c..e7a1908 100644 --- a/sysmodules/rosalina/source/menus.c +++ b/sysmodules/rosalina/source/menus.c @@ -170,13 +170,23 @@ void RosalinaMenu_ChangeScreenBrightness(void) // gsp:LCD GetLuminance is stubbed on O3DS so we have to implement it ourselves... damn it. // Assume top and bottom screen luminances are the same (should be; if not, we'll set them to the same values). u32 luminance = getCurrentLuminance(false); + u32 minLum = getMinLuminancePreset(); + u32 maxLum = getMaxLuminancePreset(); do { Draw_Lock(); Draw_DrawString(10, 10, COLOR_TITLE, "Screen brightness"); u32 posY = 30; - posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Current luminance: %lu\n\n", luminance); + posY = Draw_DrawFormattedString( + 10, + posY, + COLOR_WHITE, + "Current luminance: %lu (min. %lu, max. %lu)\n\n", + luminance, + minLum, + maxLum + ); posY = Draw_DrawString(10, posY, COLOR_WHITE, "Controls: Up/Down for +-1, Right/Left for +-10.\n"); posY = Draw_DrawString(10, posY, COLOR_WHITE, "Press A to start, B to exit.\n\n"); From cf36d21daf4d6e412cc52b77a792b670acd26920 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Thu, 16 Jul 2020 01:24:22 +0100 Subject: [PATCH 19/23] rosalina: forgot float suffix in luminance.c --- sysmodules/rosalina/source/luminance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysmodules/rosalina/source/luminance.c b/sysmodules/rosalina/source/luminance.c index d26de8c..cc12787 100644 --- a/sysmodules/rosalina/source/luminance.c +++ b/sysmodules/rosalina/source/luminance.c @@ -46,7 +46,7 @@ static BlPwmData s_blPwmData = { .coeffs = { { 0.00111639f, 1.41412f, 0.07178809f }, { 0.000418169f, 0.66567f, 0.06098654f }, - { 0.00208543f, 1.55639f, 0.0385939 } + { 0.00208543f, 1.55639f, 0.0385939f } }, .numLevels = 5, .unk = 0, From 70109fed2ccfaf60c2c25e8230b0e7eed58b25c2 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Thu, 16 Jul 2020 16:25:56 +0100 Subject: [PATCH 20/23] Update bug-report.md, etc --- .github/ISSUE_TEMPLATE/bug-report.md | 17 +++++++++-------- sysmodules/pm/README.md | 2 +- sysmodules/pxi/README.md | 2 +- sysmodules/sm/README.md | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 11d093b..fd79937 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -7,13 +7,13 @@ about: Use this to report bugs you encounter with Luma3DS. Make sure you upload -- THIS IS NOT A SUPPORT FORUM! For support go here: -- Nintendo Homebrew: https://discord.gg/MjzatM8 -- --- Rosalina feature requests go here: https://github.com/AuroraWright/Luma3DS/issues/752 +-- Rosalina feature requests go here: https://github.com/LumaTeam/Luma3DS/issues/752 -- --- Also check the Wiki (https://github.com/AuroraWright/Luma3DS/wiki) before making an issue. +-- Also check the Wiki (https://github.com/LumaTeam/Luma3DS/wiki) before making an issue. -- -- For GBA/DSiWare/DS/AGB_FIRM/TWL_FIRM problems: use https://github.com/MechanicalDragon0687/TWLFix-CFW and update your system. -- If you're using an emu/redNAND try installing anything on it to sysNAND. --- Please make sure to read "Enable game patching" https://github.com/AuroraWright/Luma3DS/wiki/Options-and-usage before posting any issues about the "Enable game patching" option(s). +-- Please make sure to read "Enable game patching" https://github.com/LumaTeam/Luma3DS/wiki/Options-and-usage before posting any issues about the "Enable game patching" option(s). -- -- Luma updaters that don't support Boot9Strap/Sighax won't work. -- This is due to support for non-B9S/Sighax entrypoints being dropped. @@ -21,7 +21,7 @@ about: Use this to report bugs you encounter with Luma3DS. Make sure you upload -- Please fill in the placeholders.--> **System model:** -[e.g. 2DS, New 3DS, Old 3DS] +[New 2DS XL, New 3DS XL, New 3DS, Old 2DS, Old 3DS XL, Old 3DS] **SysNAND version (+emu/redNAND version if applicable):** @@ -34,7 +34,7 @@ about: Use this to report bugs you encounter with Luma3DS. Make sure you upload **Luma3DS version:** -[e.g. v10.1.3 stable or if using non-releases specify the commit like this https://github.com/AuroraWright/Luma3DS/commit/0543c208fd154e6326ea5da8cbf66ffcbdef010c] +[e.g. v10.2 stable or if using non-releases specify the commit like this https://github.com/LumaTeam/Luma3DS/commit/0543c208fd154e6326ea5da8cbf66ffcbdef010c] **Luma3DS configuration/options:** @@ -50,7 +50,7 @@ Splash duration: ( ) PIN lock: ( ) New 3DS CPU: ( ) - + -- @@ -70,12 +70,13 @@ Show NAND or user string in System Settings: ( ) Show GBA boot screen in patched AGB_FIRM: ( ) -Patch Arm9 access: ( ) - Set developer UNITINFO: ( ) Disable Arm11 exception handlers: ( ) +Enable Rosalina on SAFE_FIRM: ( ) + + -- diff --git a/sysmodules/pm/README.md b/sysmodules/pm/README.md index 64b7ee4..ecf4f64 100644 --- a/sysmodules/pm/README.md +++ b/sysmodules/pm/README.md @@ -3,7 +3,7 @@ Open source replacement of the Arm11 PM system module. This is licensed under the MIT license. # Usage -To run this system module, use a recent release or commit of [Luma3DS](https://github.com/AuroraWright/Luma3DS/), build this project and copy the generated CXI file to `/luma/sysmodules/pm.cxi`. +To run this system module, use a recent release or commit of [Luma3DS](https://github.com/LumaTeam/Luma3DS/), build this project and copy the generated CXI file to `/luma/sysmodules/pm.cxi`. # Credits @fincs diff --git a/sysmodules/pxi/README.md b/sysmodules/pxi/README.md index 2687003..37a2768 100644 --- a/sysmodules/pxi/README.md +++ b/sysmodules/pxi/README.md @@ -3,7 +3,7 @@ Open source replacement of the Arm11 PXI system module. This is licensed under the MIT license. # Usage -To run this system module, use a recent release or commit of [Luma3DS](https://github.com/AuroraWright/Luma3DS/) and copy pxi.cxi to /luma/sysmodules/. +To run this system module, use a recent release or commit of [Luma3DS](https://github.com/LumaTeam/Luma3DS/) and copy pxi.cxi to /luma/sysmodules/. # Credits This list is not complete at all: diff --git a/sysmodules/sm/README.md b/sysmodules/sm/README.md index b63f514..34a8318 100644 --- a/sysmodules/sm/README.md +++ b/sysmodules/sm/README.md @@ -3,7 +3,7 @@ Open source replacement of the Arm11 SM system module. This is licensed under the MIT license. # Usage -To run this system module, use a recent release or commit of [Luma3DS](https://github.com/AuroraWright/Luma3DS/), build this project and copy sm.cxi to /luma/sysmodules/. +To run this system module, use a recent release or commit of [Luma3DS](https://github.com/LumaTeam/Luma3DS/), build this project and copy sm.cxi to /luma/sysmodules/. # Credits Everyone that helped me fix some of stupid bugs I had been making: @fincs, @Hikari-chin, etc. From d6e72080d97f6f4987105b24bb26a48e94346b23 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Thu, 16 Jul 2020 16:56:59 +0100 Subject: [PATCH 21/23] rosalina: ndm doesn't exist on SAFE_FIRM --- sysmodules/rosalina/source/minisoc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index 50c96bd..624db35 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -87,7 +87,7 @@ Result miniSocInit(void) ret = SOCU_Initialize(miniSocMemHandle, socContextSize); if(ret != 0) goto cleanup; - if (!exclusiveStateEntered) + if (!exclusiveStateEntered && isServiceUsable("ndm:u")) { ndmuInit(); ret = NDMU_EnterExclusiveState(NDM_EXCLUSIVE_STATE_INFRASTRUCTURE); @@ -140,7 +140,7 @@ Result miniSocExitDirect(void) svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE); if(ret == 0) { - if (exclusiveStateEntered) + if (exclusiveStateEntered && isServiceUsable("ndm:u")) { //ndmuInit(); ret = NDMU_UnlockState(); From 748b771618b0bf3ce017a705f6e9f2b3c1875b51 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Thu, 16 Jul 2020 17:55:31 +0100 Subject: [PATCH 22/23] rosalina: ndm + shutdown issue workaround --- sysmodules/rosalina/include/minisoc.h | 4 ++ sysmodules/rosalina/source/main.c | 2 + sysmodules/rosalina/source/minisoc.c | 56 ++++++++++++++++++--------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/sysmodules/rosalina/include/minisoc.h b/sysmodules/rosalina/include/minisoc.h index 6040bc8..c735171 100644 --- a/sysmodules/rosalina/include/minisoc.h +++ b/sysmodules/rosalina/include/minisoc.h @@ -21,6 +21,10 @@ extern bool miniSocEnabled; Result miniSocInit(void); + +void miniSocLockState(void); +void miniSocUnlockState(bool force); + Result miniSocExitDirect(void); Result miniSocExit(void); diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 390f09d..4874161 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -180,6 +180,8 @@ 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); diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index 624db35..252c81d 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -1,3 +1,4 @@ + /* * This file is part of Luma3DS. * Copyright (C) 2016-2020 Aurora Wright, TuxSH @@ -54,6 +55,41 @@ static Result SOCU_Shutdown(void) return cmdbuf[1]; } +// unsafe but what can I do? +void miniSocLockState(void) +{ + Result res = 0; + __dmb(); + if (!exclusiveStateEntered && isServiceUsable("ndm:u")) + { + ndmuInit(); + res = NDMU_EnterExclusiveState(NDM_EXCLUSIVE_STATE_INFRASTRUCTURE); + if (R_SUCCEEDED(res)) + res = NDMU_LockState(); // prevents ndm from switching to StreetPass when the lid is closed + exclusiveStateEntered = R_SUCCEEDED(res); + __dmb(); + } +} + +void miniSocUnlockState(bool force) +{ + Result res = 0; + + __dmb(); + if (exclusiveStateEntered) + { + if (!force) + { + res = NDMU_UnlockState(); + if (R_SUCCEEDED(res)) + res = NDMU_LeaveExclusiveState(); + } + ndmuExit(); + exclusiveStateEntered = R_FAILED(res); + __dmb(); + } +} + Result miniSocInit(void) { if(AtomicPostIncrement(&miniSocRefCount)) @@ -87,15 +123,7 @@ Result miniSocInit(void) ret = SOCU_Initialize(miniSocMemHandle, socContextSize); if(ret != 0) goto cleanup; - if (!exclusiveStateEntered && isServiceUsable("ndm:u")) - { - ndmuInit(); - ret = NDMU_EnterExclusiveState(NDM_EXCLUSIVE_STATE_INFRASTRUCTURE); - if (R_SUCCEEDED(ret)) - ret = NDMU_LockState(); // prevents ndm from switching to StreetPass when the lid is closed - //ndmuExit(); - exclusiveStateEntered = R_SUCCEEDED(ret); - } + miniSocLockState(); svcKernelSetState(0x10000, 0x10); miniSocEnabled = true; @@ -140,15 +168,7 @@ Result miniSocExitDirect(void) svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE); if(ret == 0) { - if (exclusiveStateEntered && isServiceUsable("ndm:u")) - { - //ndmuInit(); - ret = NDMU_UnlockState(); - if (R_SUCCEEDED(ret)) - ret = NDMU_LeaveExclusiveState(); - ndmuExit(); - exclusiveStateEntered = R_FAILED(ret); - } + miniSocUnlockState(false); miniSocEnabled = false; svcKernelSetState(0x10000, 0x10); From bb07a7334f064c9512bd7e387dab1b9ef9e228cd Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Thu, 16 Jul 2020 18:06:14 +0100 Subject: [PATCH 23/23] update gitignore and makefile --- .gitignore | 3 +++ Makefile | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0a21f7f..e5c172f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,8 +13,11 @@ exceptions/arm11/build *.d *.elf *.cxi +*.3dsx .DS_Store *.dmp .project .cproject .settings + +Luma3DS*.zip diff --git a/Makefile b/Makefile index 72cca2e..54c3153 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,8 @@ boot.firm: $(SUBFOLDERS) @echo built... $(notdir $@) boot.3dsx: - @curl -sSL "https://github.com/fincs/new-hbmenu/releases/latest/download/boot.3dsx" -o "boot.3dsx" + @curl -sSL "https://github.com/fincs/new-hbmenu/releases/latest/download/boot.3dsx" -o "$@" + @echo downloaded... $(notdir $@) $(SUBFOLDERS): @$(MAKE) -C $@ all