Added Rosalina, see details
- see release notes - ( ͡° ͜ʖ ͡°)( ͡° ͜ʖ ͡°)( ͡° ͜ʖ ͡°) - (∩ ͡° ͜ʖ ͡°)⊃━☆゚ - ( ͡ᵔ ͜ʖ ͡ᵔ) ♫┌( ͡° ͜ʖ ͡°)┘♪ ♫└( ͡° ͜ʖ ͡°)┐♪
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.macro TEST_IF_MODE_AND_ARM_INST_OR_JUMP lbl, mode
|
||||
cpsid aif
|
||||
mrs sp, spsr
|
||||
tst sp, #0x20
|
||||
bne \lbl
|
||||
and sp, #0x1f @ get previous processor mode
|
||||
cmp sp, #\mode
|
||||
bne \lbl
|
||||
|
||||
sub sp, lr, #4
|
||||
mcr p15, 0, sp, c7, c8, 0 @ VA to PA translation with privileged read permission check
|
||||
mrc p15, 0, sp, c7, c4, 0 @ read PA register
|
||||
tst sp, #1 @ failure bit
|
||||
bne \lbl
|
||||
.endm
|
||||
|
||||
|
||||
.macro GEN_USUAL_HANDLER name, index, pos
|
||||
\name\()Handler:
|
||||
ldr sp, =exceptionStackTop
|
||||
ldr sp, [sp]
|
||||
sub sp, #0x100
|
||||
|
||||
push {r0-r12, lr}
|
||||
mrs r0, spsr
|
||||
bl isExceptionFatal
|
||||
cmp r0, #0
|
||||
pop {r0-r12, lr}
|
||||
bne _exc_is_fatal_\name
|
||||
|
||||
ldr sp, =originalHandlers
|
||||
ldr sp, [sp, #\pos]
|
||||
bx sp
|
||||
|
||||
_exc_is_fatal_\name:
|
||||
push {r8, r9}
|
||||
mov r8, #\index
|
||||
b _commonHandler
|
||||
.endm
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
_die:
|
||||
cpsid aif
|
||||
_die_loop:
|
||||
wfi
|
||||
b _die_loop
|
||||
|
||||
_commonHandler:
|
||||
cpsid aif
|
||||
|
||||
push {r0}
|
||||
ldr r0, =_fatalExceptionOccured
|
||||
ldr r0, [r0]
|
||||
cmp r0, #0
|
||||
bne _die_loop
|
||||
pop {r0}
|
||||
|
||||
ldr r9, =_regs
|
||||
stmia r9, {r0-r7}
|
||||
mov r1, r8
|
||||
pop {r8,r9}
|
||||
|
||||
ldr r0, =_fatalExceptionOccured
|
||||
mov r4, #1
|
||||
|
||||
_try_lock:
|
||||
ldrex r2, [r0]
|
||||
strex r3, r4, [r0]
|
||||
cmp r3, #0
|
||||
bne _try_lock
|
||||
|
||||
push {r1, r12, lr} @ attempt to hang the other cores
|
||||
adr r0, _die
|
||||
mov r1, #0xf
|
||||
mov r2, #1
|
||||
mov r3, #0
|
||||
bl executeFunctionOnCores
|
||||
pop {r1, r12, lr}
|
||||
|
||||
mrs r2, spsr
|
||||
mrs r3, cpsr
|
||||
ldr r6, =_regs
|
||||
add r6, #0x20
|
||||
|
||||
ands r4, r2, #0xf @ get the mode that triggered the exception
|
||||
moveq r4, #0xf @ usr => sys
|
||||
bic r5, r3, #0xf
|
||||
orr r5, r4
|
||||
msr cpsr_c, r5 @ change processor mode
|
||||
stmia r6!, {r8-lr}
|
||||
msr cpsr_c, r3 @ restore processor mode
|
||||
|
||||
str lr, [r6], #4
|
||||
str r2, [r6], #4
|
||||
|
||||
mov r0, r6
|
||||
|
||||
mrc p15, 0, r4, c5, c0, 0 @ dfsr
|
||||
mrc p15, 0, r5, c5, c0, 1 @ ifsr
|
||||
mrc p15, 0, r6, c6, c0, 0 @ far
|
||||
fmrx r7, fpexc
|
||||
fmrx r8, fpinst
|
||||
fmrx r9, fpinst2
|
||||
bic r3, #(1<<31)
|
||||
fmxr fpexc, r3 @ clear the VFP11 exception flag (if it's set)
|
||||
|
||||
stmia r0!, {r4-r9}
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c14, 0 @ Clean and Invalidate Entire Data Cache
|
||||
mcr p15, 0, r0, c7, c10, 4 @ Drain Synchronization Barrier
|
||||
|
||||
ldr r0, =isN3DS
|
||||
ldr r0, [r0]
|
||||
cmp r0, #0
|
||||
beq _no_L2C
|
||||
ldr r0, =(0x17e10100 | 1 << 31)
|
||||
ldr r0, [r0]
|
||||
tst r0, #1 @ is the L2C enabled?
|
||||
beq _no_L2C
|
||||
|
||||
ldr r0, =0xffff
|
||||
ldr r2, =(0x17e10730 | 1 << 31)
|
||||
str r0, [r2, #0x4c] @ invalidate by way
|
||||
|
||||
_L2C_sync:
|
||||
ldr r0, [r2] @ L2C cache sync register
|
||||
tst r0, #1
|
||||
bne _L2C_sync
|
||||
|
||||
_no_L2C:
|
||||
|
||||
cps #0x1F
|
||||
ldr sp, =exceptionStackTop
|
||||
ldr sp, [sp]
|
||||
sub sp, #0x100
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 5 @ Drain Memory Barrier
|
||||
ldr r0, =_regs
|
||||
mrc p15, 0, r2, c0, c0, 5 @ CPU ID register
|
||||
bl fatalExceptionHandlersMain
|
||||
|
||||
ldr r12, =mcuReboot
|
||||
ldr r12, [r12]
|
||||
bx r12
|
||||
|
||||
.global FIQHandler
|
||||
.type FIQHandler, %function
|
||||
GEN_USUAL_HANDLER FIQ, 0, 28
|
||||
|
||||
.global undefinedInstructionHandler
|
||||
.type undefinedInstructionHandler, %function
|
||||
undefinedInstructionHandler:
|
||||
TEST_IF_MODE_AND_ARM_INST_OR_JUMP _undefinedInstructionNormalHandler, 0x10
|
||||
|
||||
ldr sp, [lr, #-4] @ test if it's an VFP instruction that was aborted
|
||||
lsl sp, #4
|
||||
sub sp, #0xc0000000
|
||||
cmp sp, #0x30000000
|
||||
bcs _undefinedInstructionNormalHandler
|
||||
fmrx sp, fpexc
|
||||
tst sp, #0x40000000
|
||||
bne _undefinedInstructionNormalHandler
|
||||
|
||||
@ FPU init
|
||||
sub lr, #4
|
||||
srsfd sp!, #0x13
|
||||
cps #0x13
|
||||
stmfd sp, {r0-r3, r11-lr}^
|
||||
sub sp, #0x20
|
||||
ldr r12, =initFPU
|
||||
ldr r12, [r12]
|
||||
blx r12
|
||||
ldmfd sp, {r0-r3, r11-lr}^
|
||||
add sp, #0x20
|
||||
rfefd sp! @ retry aborted instruction
|
||||
|
||||
GEN_USUAL_HANDLER _undefinedInstructionNormal, 1, 4
|
||||
|
||||
.global prefetchAbortHandler
|
||||
.type prefetchAbortHandler, %function
|
||||
prefetchAbortHandler:
|
||||
TEST_IF_MODE_AND_ARM_INST_OR_JUMP _prefetchAbortNormalHandler, 0x13
|
||||
|
||||
ldr sp, =(Break + 3*4 + 4)
|
||||
cmp lr, sp
|
||||
bne _prefetchAbortNormalHandler
|
||||
|
||||
sub sp, r0, #0x110
|
||||
pop {r0-r7, r12, lr}
|
||||
pop {r8-r11}
|
||||
ldr lr, [sp, #8]!
|
||||
ldr sp, [sp, #4]
|
||||
msr spsr, sp
|
||||
addne lr, #2 @ adjust address for later
|
||||
|
||||
GEN_USUAL_HANDLER _prefetchAbortNormal, 2, 12
|
||||
|
||||
.global dataAbortHandler
|
||||
.type dataAbortHandler, %function
|
||||
dataAbortHandler:
|
||||
ldr sp, =exceptionStackTop
|
||||
ldr sp, [sp]
|
||||
push {r0-r12, lr}
|
||||
mrs r0, spsr
|
||||
sub r1, lr, #8
|
||||
bl isDataAbortExceptionRangeControlled
|
||||
cmp r0, #0
|
||||
pop {r0-r12, lr}
|
||||
beq _dataAbortNormalHandler
|
||||
|
||||
msr spsr_f, #(1 << 30)
|
||||
mov r12, #0
|
||||
subs pc, lr, #4
|
||||
|
||||
GEN_USUAL_HANDLER _dataAbortNormal, 3, 16
|
||||
|
||||
.bss
|
||||
.balign 4
|
||||
_regs: .skip (4 * 23)
|
||||
_fatalExceptionOccured: .word 0
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "fatalExceptionHandlers.h"
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "memory.h"
|
||||
#include "globals.h"
|
||||
|
||||
#define REG_DUMP_SIZE 4 * 23
|
||||
#define CODE_DUMP_SIZE 48
|
||||
|
||||
bool isExceptionFatal(u32 spsr)
|
||||
{
|
||||
if((spsr & 0x1f) != 0x10) return true;
|
||||
|
||||
KThread *thread = currentCoreContext->objectContext.currentThread;
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
if(thread != NULL && thread->threadLocalStorage != NULL && *((vu32 *)thread->threadLocalStorage + 0x10) != 0)
|
||||
return false;
|
||||
|
||||
if(currentProcess != NULL)
|
||||
{
|
||||
if(debugOfProcess(currentProcess) != NULL)
|
||||
return false;
|
||||
|
||||
thread = KPROCESS_GET_RVALUE(currentProcess, mainThread);
|
||||
if(thread != NULL && thread->threadLocalStorage != NULL && *((vu32 *)thread->threadLocalStorage + 0x10) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern u32 safecpy_sz;
|
||||
bool isDataAbortExceptionRangeControlled(u32 spsr, u32 addr)
|
||||
{
|
||||
return ((spsr & 0x1F) != 0x10) && (
|
||||
((u32)kernelUsrCopyFuncsStart <= addr && addr < (u32)kernelUsrCopyFuncsEnd) ||
|
||||
((u32)safecpy <= addr && addr < (u32)safecpy + safecpy_sz)
|
||||
);
|
||||
}
|
||||
void fatalExceptionHandlersMain(u32 *registerDump, u32 type, u32 cpuId)
|
||||
{
|
||||
ExceptionDumpHeader dumpHeader;
|
||||
|
||||
u8 codeDump[CODE_DUMP_SIZE];
|
||||
u8 *finalBuffer = (u8 *)PA_PTR(0x25000000);
|
||||
u8 *final = finalBuffer;
|
||||
|
||||
dumpHeader.magic[0] = 0xDEADC0DE;
|
||||
dumpHeader.magic[1] = 0xDEADCAFE;
|
||||
dumpHeader.versionMajor = 1;
|
||||
dumpHeader.versionMinor = 2;
|
||||
|
||||
dumpHeader.processor = 11;
|
||||
dumpHeader.core = cpuId & 0xF;
|
||||
dumpHeader.type = type;
|
||||
|
||||
dumpHeader.registerDumpSize = REG_DUMP_SIZE;
|
||||
dumpHeader.codeDumpSize = CODE_DUMP_SIZE;
|
||||
|
||||
u32 cpsr = registerDump[16];
|
||||
u32 pc = registerDump[15] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
|
||||
|
||||
registerDump[15] = pc;
|
||||
|
||||
//Dump code
|
||||
u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //Doesn't work well on 32-bit Thumb instructions, but it isn't much of a problem
|
||||
dumpHeader.codeDumpSize = ((u32)instr & (((cpsr & 0x20) != 0) ? 1 : 3)) != 0 ? 0 : safecpy(codeDump, instr, dumpHeader.codeDumpSize);
|
||||
|
||||
//Copy register dump and code dump
|
||||
final = (u8 *)(finalBuffer + sizeof(ExceptionDumpHeader));
|
||||
memcpy(final, registerDump, dumpHeader.registerDumpSize);
|
||||
final += dumpHeader.registerDumpSize;
|
||||
memcpy(final, codeDump, dumpHeader.codeDumpSize);
|
||||
final += dumpHeader.codeDumpSize;
|
||||
|
||||
//Dump stack in place
|
||||
dumpHeader.stackDumpSize = safecpy(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF));
|
||||
final += dumpHeader.stackDumpSize;
|
||||
|
||||
if(currentCoreContext->objectContext.currentProcess)
|
||||
{
|
||||
vu64 *additionalData = (vu64 *)final;
|
||||
KCodeSet *currentCodeSet = codeSetOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
if(currentCodeSet != NULL)
|
||||
{
|
||||
dumpHeader.additionalDataSize = 16;
|
||||
memcpy((void *)additionalData, currentCodeSet->processName, 8);
|
||||
additionalData[1] = currentCodeSet->titleId;
|
||||
}
|
||||
else dumpHeader.additionalDataSize = 0;
|
||||
}
|
||||
else dumpHeader.additionalDataSize = 0;
|
||||
|
||||
dumpHeader.totalSize = sizeof(ExceptionDumpHeader) + dumpHeader.registerDumpSize + dumpHeader.codeDumpSize + dumpHeader.stackDumpSize + dumpHeader.additionalDataSize;
|
||||
|
||||
//Copy header (actually optimized by the compiler)
|
||||
*(ExceptionDumpHeader *)finalBuffer = dumpHeader;
|
||||
}
|
||||
104
sysmodules/rosalina/kernel_extension/source/globals.c
Normal file
104
sysmodules/rosalina/kernel_extension/source/globals.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
KRecursiveLock *criticalSectionLock;
|
||||
KObjectList *threadList;
|
||||
KObjectMutex *synchronizationMutex;
|
||||
|
||||
void (*KRecursiveLock__Lock)(KRecursiveLock *this);
|
||||
void (*KRecursiveLock__Unlock)(KRecursiveLock *this);
|
||||
|
||||
void (*KAutoObject__AddReference)(KAutoObject *this);
|
||||
KProcess * (*KProcessHandleTable__ToKProcess)(KProcessHandleTable *this, Handle processHandle);
|
||||
KThread * (*KProcessHandleTable__ToKThread)(KProcessHandleTable *this, Handle threadHandle);
|
||||
KAutoObject * (*KProcessHandleTable__ToKAutoObject)(KProcessHandleTable *this, Handle handle);
|
||||
void (*KSynchronizationObject__Signal)(KSynchronizationObject *this, bool isPulse);
|
||||
Result (*WaitSynchronization1)(void *this_unused, KThread *thread, KSynchronizationObject *syncObject, s64 timeout);
|
||||
Result (*KProcessHandleTable__CreateHandle)(KProcessHandleTable *this, Handle *out, KAutoObject *obj, u8 token);
|
||||
Result (*KProcessHwInfo__MapProcessMemory)(KProcessHwInfo *this, KProcessHwInfo *other, void *dst, void *src, u32 nbPages);
|
||||
Result (*KProcessHwInfo__UnmapProcessMemory)(KProcessHwInfo *this, void *addr, u32 nbPages);
|
||||
Result (*KEvent__Clear)(KEvent *this);
|
||||
void (*KObjectMutex__WaitAndAcquire)(KObjectMutex *this);
|
||||
void (*KObjectMutex__ErrorOccured)(void);
|
||||
|
||||
void (*KScheduler__AdjustThread)(KScheduler *this, KThread *thread, u32 oldSchedulingMask);
|
||||
void (*KScheduler__AttemptSwitchingThreadContext)(KScheduler *this);
|
||||
|
||||
Result (*ControlMemory)(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm, bool isLoader);
|
||||
void (*SleepThread)(s64 ns);
|
||||
Result (*CloseHandle)(Handle handle);
|
||||
Result (*GetSystemInfo)(s64 *out, s32 type, s32 param);
|
||||
Result (*GetProcessInfo)(s64 *out, Handle processHandle, u32 type);
|
||||
Result (*GetThreadInfo)(s64 *out, Handle threadHandle, u32 type);
|
||||
Result (*ConnectToPort)(Handle *out, const char *name);
|
||||
Result (*SendSyncRequest)(Handle handle);
|
||||
Result (*OpenProcess)(Handle *out, u32 processId);
|
||||
Result (*GetProcessId)(u32 *out, Handle process);
|
||||
Result (*DebugActiveProcess)(Handle *out, u32 processId);
|
||||
Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3);
|
||||
|
||||
void (*flushDataCacheRange)(void *addr, u32 len);
|
||||
void (*invalidateInstructionCacheRange)(void *addr, u32 len);
|
||||
|
||||
bool (*usrToKernelMemcpy8)(void *dst, const void *src, u32 len);
|
||||
bool (*usrToKernelMemcpy32)(u32 *dst, const u32 *src, u32 len);
|
||||
s32 (*usrToKernelStrncpy)(char *dst, const char *src, u32 len);
|
||||
bool (*kernelToUsrMemcpy8)(void *dst, const void *src, u32 len);
|
||||
bool (*kernelToUsrMemcpy32)(u32 *dst, const u32 *src, u32 len);
|
||||
s32 (*kernelToUsrStrncpy)(char *dst, const char *src, u32 len);
|
||||
|
||||
Result (*CustomBackdoor)(void *function, ...);
|
||||
|
||||
void (*svcFallbackHandler)(u8 svcId);
|
||||
void (*kernelpanic)(void);
|
||||
void (*PostprocessSvc)(void);
|
||||
|
||||
Result (*SignalDebugEvent)(DebugEventType type, u32 info, ...);
|
||||
|
||||
bool isN3DS;
|
||||
u32 *exceptionStackTop;
|
||||
|
||||
u32 TTBCR;
|
||||
u32 L1MMUTableAddrs[4];
|
||||
|
||||
u32 kernelVersion;
|
||||
void *kernelUsrCopyFuncsStart, *kernelUsrCopyFuncsEnd;
|
||||
|
||||
bool *isDevUnit;
|
||||
|
||||
InterruptManager *interruptManager;
|
||||
KBaseInterruptEvent *customInterruptEvent;
|
||||
|
||||
void (*initFPU)(void);
|
||||
void (*mcuReboot)(void);
|
||||
void (*coreBarrier)(void);
|
||||
|
||||
CfwInfo cfwInfo;
|
||||
|
||||
u32 rosalinaState;
|
||||
bool hasStartedRosalinaNetworkFuncsOnce;
|
||||
321
sysmodules/rosalina/kernel_extension/source/ipc.c
Normal file
321
sysmodules/rosalina/kernel_extension/source/ipc.c
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "ipc.h"
|
||||
#include "memory.h"
|
||||
|
||||
static SessionInfo sessionInfos[MAX_SESSION] = { {NULL} };
|
||||
static u32 nbActiveSessions = 0;
|
||||
static KRecursiveLock sessionInfosLock = { NULL };
|
||||
|
||||
KRecursiveLock processLangemuLock;
|
||||
LangemuAttributes processLangemuAttributes[0x40];
|
||||
|
||||
static void *customSessionVtable[0x10] = { NULL }; // should be enough
|
||||
|
||||
static u32 SessionInfo_FindClosestSlot(KSession *session)
|
||||
{
|
||||
if(nbActiveSessions == 0 || session <= sessionInfos[0].session)
|
||||
return 0;
|
||||
else if(session > sessionInfos[nbActiveSessions - 1].session)
|
||||
return nbActiveSessions;
|
||||
|
||||
u32 a = 0, b = nbActiveSessions - 1, m;
|
||||
|
||||
do
|
||||
{
|
||||
m = (a + b) / 2;
|
||||
if(sessionInfos[m].session < session)
|
||||
a = m;
|
||||
else if(sessionInfos[m].session > session)
|
||||
b = m;
|
||||
else
|
||||
return m;
|
||||
}
|
||||
while(b - a > 1);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
SessionInfo *SessionInfo_Lookup(KSession *session)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
SessionInfo *ret;
|
||||
u32 id = SessionInfo_FindClosestSlot(session);
|
||||
if(id == nbActiveSessions)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = (void **)(sessionInfos[id].session->autoObject.vtable) == customSessionVtable ? &sessionInfos[id] : NULL;
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SessionInfo *SessionInfo_FindFirst(const char *name)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
SessionInfo *ret;
|
||||
u32 id;
|
||||
for(id = 0; id < nbActiveSessions && strncmp(sessionInfos[id].name, name, 12) != 0; id++);
|
||||
if(id == nbActiveSessions)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = (void **)(sessionInfos[id].session->autoObject.vtable) == customSessionVtable ? &sessionInfos[id] : NULL;
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SessionInfo_Add(KSession *session, const char *name)
|
||||
{
|
||||
KAutoObject__AddReference(&session->autoObject);
|
||||
SessionInfo_ChangeVtable(session);
|
||||
session->autoObject.vtable->DecrementReferenceCount(&session->autoObject);
|
||||
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
if(nbActiveSessions == MAX_SESSION)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 id = SessionInfo_FindClosestSlot(session);
|
||||
|
||||
if(id != nbActiveSessions && sessionInfos[id].session == session)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
for(u32 i = nbActiveSessions; i > id && i != 0; i--)
|
||||
sessionInfos[i] = sessionInfos[i - 1];
|
||||
|
||||
nbActiveSessions++;
|
||||
|
||||
sessionInfos[id].session = session;
|
||||
strncpy(sessionInfos[id].name, name, 12);
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
}
|
||||
|
||||
void SessionInfo_Remove(KSession *session)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
if(nbActiveSessions == MAX_SESSION)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 id = SessionInfo_FindClosestSlot(session);
|
||||
|
||||
if(id == nbActiveSessions)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
for(u32 i = id; i < nbActiveSessions - 1; i++)
|
||||
sessionInfos[i] = sessionInfos[i + 1];
|
||||
|
||||
memset(&sessionInfos[--nbActiveSessions], 0, sizeof(SessionInfo));
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
}
|
||||
|
||||
static void (*KSession__dtor_orig)(KAutoObject *this);
|
||||
static void KSession__dtor_hook(KAutoObject *this)
|
||||
{
|
||||
KSession__dtor_orig(this);
|
||||
SessionInfo_Remove((KSession *)this);
|
||||
}
|
||||
|
||||
void SessionInfo_ChangeVtable(KSession *session)
|
||||
{
|
||||
if(customSessionVtable[2] == NULL)
|
||||
{
|
||||
memcpy(customSessionVtable, session->autoObject.vtable, 0x40);
|
||||
KSession__dtor_orig = session->autoObject.vtable->dtor;
|
||||
customSessionVtable[2] = (void *)KSession__dtor_hook;
|
||||
}
|
||||
session->autoObject.vtable = (Vtable__KAutoObject *)customSessionVtable;
|
||||
}
|
||||
|
||||
bool doLangEmu(Result *res, Handle handle, u32 *cmdbuf)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&processLangemuLock);
|
||||
|
||||
u64 titleId = codeSetOfProcess(currentCoreContext->objectContext.currentProcess)->titleId;
|
||||
LangemuAttributes *attribs = NULL;
|
||||
bool skip = true;
|
||||
|
||||
*res = 0;
|
||||
for(u32 i = 0; i < 0x40; i++)
|
||||
{
|
||||
if(processLangemuAttributes[i].titleId == titleId)
|
||||
attribs = &processLangemuAttributes[i];
|
||||
}
|
||||
|
||||
if(attribs == NULL)
|
||||
{
|
||||
KRecursiveLock__Unlock(&processLangemuLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
if((cmdbuf[0] == 0x20000 || cmdbuf[0] == 0x4060000 || cmdbuf[0] == 0x8160000) && (attribs->mask & 1)) // SecureInfoGetRegion
|
||||
{
|
||||
cmdbuf[0] = (cmdbuf[0] & 0xFFFF0000) | 0x80;
|
||||
cmdbuf[1] = 0;
|
||||
cmdbuf[2] = attribs->region;
|
||||
}
|
||||
else if(cmdbuf[1] == 1 && cmdbuf[2] == 0xA0002 && cmdbuf[3] == 0x1C && (attribs->mask & 2))
|
||||
{
|
||||
cmdbuf[0] = (cmdbuf[0] & 0xFFFF0000) | 0x40;
|
||||
cmdbuf[1] = 0;
|
||||
*(u8 *)cmdbuf[4] = attribs->language;
|
||||
}
|
||||
else if(cmdbuf[1] == 4 && cmdbuf[2] == 0xB0000 && cmdbuf[3] == 0x4C && (attribs->mask & 0xC))
|
||||
{
|
||||
u8 *ptr = (u8 *)cmdbuf[4];
|
||||
*res = SendSyncRequest(handle);
|
||||
flushEntireDataCache(); // looks like it's needed. WTF?!
|
||||
if(*res == 0)
|
||||
{
|
||||
if(attribs->mask & 4)
|
||||
ptr[3] = attribs->country;
|
||||
if(attribs->mask & 8)
|
||||
ptr[2] = attribs->state;
|
||||
}
|
||||
}
|
||||
else
|
||||
skip = false;
|
||||
|
||||
KRecursiveLock__Unlock(&processLangemuLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return skip;
|
||||
}
|
||||
|
||||
Result doPublishToProcessHook(Handle handle, u32 *cmdbuf)
|
||||
{
|
||||
Result res = 0;
|
||||
u32 pid;
|
||||
bool terminateRosalina = cmdbuf[1] == 0x100 && cmdbuf[2] == 0; // cmdbuf[2] to check for well-formed requests
|
||||
u32 savedCmdbuf[4];
|
||||
memcpy(savedCmdbuf, cmdbuf, 16);
|
||||
|
||||
if(!terminateRosalina || GetProcessId(&pid, cmdbuf[3]) != 0)
|
||||
terminateRosalina = false;
|
||||
else
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcess *process = KProcessHandleTable__ToKProcess(handleTable, cmdbuf[3]);
|
||||
if((strcmp(codeSetOfProcess(process)->processName, "socket") == 0 && (rosalinaState & 2)) ||
|
||||
strcmp(codeSetOfProcess(process)->processName, "pxi") == 0)
|
||||
terminateRosalina = true;
|
||||
else
|
||||
terminateRosalina = false;
|
||||
((KAutoObject *)process)->vtable->DecrementReferenceCount((KAutoObject *)process);
|
||||
}
|
||||
|
||||
if(terminateRosalina)
|
||||
{
|
||||
Handle rosalinaProcessHandle;
|
||||
res = OpenProcess(&rosalinaProcessHandle, 5);
|
||||
if(res == 0)
|
||||
{
|
||||
cmdbuf[0] = cmdbuf[0];
|
||||
cmdbuf[1] = 0x100;
|
||||
cmdbuf[2] = 0;
|
||||
cmdbuf[3] = rosalinaProcessHandle;
|
||||
|
||||
res = SendSyncRequest(handle);
|
||||
CloseHandle(rosalinaProcessHandle);
|
||||
memcpy(cmdbuf, savedCmdbuf, 16);
|
||||
}
|
||||
}
|
||||
|
||||
return SendSyncRequest(handle);
|
||||
}
|
||||
|
||||
bool doErrfThrowHook(u32 *cmdbuf)
|
||||
{
|
||||
// If fatalErrorInfo->type is "card removed" or "logged", returning from ERRF:Throw is a no-op
|
||||
// for the SDK function
|
||||
|
||||
// r6 (arm) or r4 (thumb) is copied into cmdbuf[1..31]
|
||||
u32 *r0_to_r7_r12_usr = (u32 *)((u8 *)currentCoreContext->objectContext.currentThread->endOfThreadContext - 0x110);
|
||||
u32 spsr = *(u32 *)((u8 *)currentCoreContext->objectContext.currentThread->endOfThreadContext - 0xCC);
|
||||
u8 *srcerrbuf = (u8 *)r0_to_r7_r12_usr[(spsr & 0x20) ? 4 : 6];
|
||||
const char *pname = codeSetOfProcess(currentCoreContext->objectContext.currentProcess)->processName;
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
Result errCode;
|
||||
} errorCodesToIgnore[] =
|
||||
{
|
||||
/*
|
||||
If you're getting this error, you have broken your head-tracking hardware,
|
||||
and should uncomment the following line:
|
||||
*/
|
||||
//{ "qtm", (Result)0xF96183FE },
|
||||
|
||||
{ "", 0 }, // impossible case to ensure the array has at least 1 element
|
||||
};
|
||||
|
||||
for(u32 i = 0; i < sizeof(errorCodesToIgnore) / sizeof(errorCodesToIgnore[0]); i++)
|
||||
{
|
||||
if(strcmp(pname, errorCodesToIgnore[i].name) == 0 && (Result)cmdbuf[2] == errorCodesToIgnore[i].errCode)
|
||||
{
|
||||
srcerrbuf[0] = 5;
|
||||
cmdbuf[0] = 0x10040;
|
||||
cmdbuf[1] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
310
sysmodules/rosalina/kernel_extension/source/main.c
Normal file
310
sysmodules/rosalina/kernel_extension/source/main.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "globals.h"
|
||||
#include "synchronization.h"
|
||||
#include "fatalExceptionHandlers.h"
|
||||
#include "svc.h"
|
||||
#include "svc/ConnectToPort.h"
|
||||
#include "svcHandler.h"
|
||||
#include "memory.h"
|
||||
|
||||
static const u32 *const exceptionsPage = (const u32 *)0xFFFF0000;
|
||||
void *originalHandlers[8] = {NULL};
|
||||
|
||||
enum VECTORS { RESET = 0, UNDEFINED_INSTRUCTION, SVC, PREFETCH_ABORT, DATA_ABORT, RESERVED, IRQ, FIQ };
|
||||
|
||||
static void setupSGI0Handler(void)
|
||||
{
|
||||
for(u32 i = 0; i < getNumberOfCores(); i++)
|
||||
interruptManager->N3DS.privateInterrupts[i][0].interruptEvent = customInterruptEvent;
|
||||
}
|
||||
|
||||
static inline void **getHandlerDestination(enum VECTORS vector)
|
||||
{
|
||||
u32 *branch_dst = (u32 *)decodeARMBranch((u32 *)exceptionsPage + (u32)vector);
|
||||
return (void **)(branch_dst + 2);
|
||||
}
|
||||
|
||||
static inline void swapHandlerInVeneer(enum VECTORS vector, void *handler)
|
||||
{
|
||||
void **dst = getHandlerDestination(vector);
|
||||
originalHandlers[(u32)vector] = *dst;
|
||||
if(handler != NULL)
|
||||
*(void**)PA_FROM_VA_PTR(dst) = handler;
|
||||
}
|
||||
|
||||
static u32 *trampo_;
|
||||
static bool **enableUserExceptionHandlersForCPUExcLoc;
|
||||
static bool enableUserExceptionHandlersForCPUExc = true;
|
||||
|
||||
static void setupSvcHandler(void)
|
||||
{
|
||||
swapHandlerInVeneer(SVC, svcHandler);
|
||||
|
||||
void **arm11SvcTable = (void**)originalHandlers[(u32)SVC];
|
||||
while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL)
|
||||
memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E);
|
||||
|
||||
u32 *off;
|
||||
for(off = (u32 *)officialSVCs[0x2D]; *off != 0x65736162; off++);
|
||||
*(void **)PA_FROM_VA_PTR(arm11SvcTable + 0x2D) = officialSVCs[0x2D] = (void *)off[1];
|
||||
trampo_ = (u32 *)PA_FROM_VA_PTR(off + 3);
|
||||
|
||||
CustomBackdoor = (Result (*)(void *, ...))((u32 *)officialSVCs[0x2F] + 2);
|
||||
*(void **)PA_FROM_VA_PTR(arm11SvcTable + 0x2F) = officialSVCs[0x2F] = (void *)*((u32 *)officialSVCs[0x2F] + 1);
|
||||
|
||||
off = (u32 *)originalHandlers[(u32) SVC];
|
||||
while(*off++ != 0xE1A00009);
|
||||
svcFallbackHandler = (void (*)(u8))decodeARMBranch(off);
|
||||
for(; *off != 0xE92D000F; off++);
|
||||
PostprocessSvc = (void (*)(void))decodeARMBranch(off + 1);
|
||||
}
|
||||
|
||||
static void setupExceptionHandlers(void)
|
||||
{
|
||||
swapHandlerInVeneer(FIQ, FIQHandler);
|
||||
swapHandlerInVeneer(UNDEFINED_INSTRUCTION, undefinedInstructionHandler);
|
||||
swapHandlerInVeneer(PREFETCH_ABORT, prefetchAbortHandler);
|
||||
swapHandlerInVeneer(DATA_ABORT, dataAbortHandler);
|
||||
|
||||
setupSvcHandler();
|
||||
}
|
||||
|
||||
static void findUsefulSymbols(void)
|
||||
{
|
||||
u32 *off;
|
||||
|
||||
KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]);
|
||||
|
||||
for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE28DD014; off++);
|
||||
KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off - 1);
|
||||
|
||||
for(; *off != 0xE8BD80F0; off++);
|
||||
KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 2);
|
||||
|
||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++);
|
||||
off -= 2;
|
||||
criticalSectionLock = (KRecursiveLock *)off[2 + (off[0] & 0xFF) / 4];
|
||||
KRecursiveLock__Lock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1);
|
||||
off += 4;
|
||||
|
||||
for(; (*off >> 16) != 0xE59F; off++);
|
||||
KRecursiveLock__Unlock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1);
|
||||
|
||||
for(; *off != 0xE5C4007D; off++);
|
||||
KSynchronizationObject__Signal = (void (*)(KSynchronizationObject *, bool))decodeARMBranch(off + 3);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x19]; *off != 0xE1A04005; off++);
|
||||
KEvent__Clear = (Result (*)(KEvent *))decodeARMBranch(off + 1);
|
||||
for(off = (u32 *)KEvent__Clear; *off != 0xE8BD8070; off++)
|
||||
synchronizationMutex = *(KObjectMutex **)(off + 1);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++);
|
||||
WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeARMBranch(off + 6);
|
||||
|
||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE20030FF; off++);
|
||||
KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off + 2);
|
||||
|
||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++);
|
||||
threadList = *(KObjectList **)(off + 1);
|
||||
|
||||
KProcessHandleTable__ToKThread = (KThread * (*)(KProcessHandleTable *, Handle))decodeARMBranch((u32 *)decodeARMBranch((u32 *)officialSVCs[0x37] + 3) /* GetThreadId */ + 5);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x54]; *off != 0xE8BD8008; off++);
|
||||
flushDataCacheRange = (void (*)(void *, u32))(*(u32 **)(off[1]) + 3);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++);
|
||||
KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++);
|
||||
KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x7C]; *off != 0x03530000; off++);
|
||||
KObjectMutex__WaitAndAcquire = (void (*)(KObjectMutex *))decodeARMBranch(++off);
|
||||
for(; *off != 0xE320F000; off++);
|
||||
KObjectMutex__ErrorOccured = (void (*)(void))decodeARMBranch(off + 1);
|
||||
|
||||
for(off = (u32 *)originalHandlers[(u32) DATA_ABORT]; *off != (u32)exceptionStackTop; off++);
|
||||
kernelUsrCopyFuncsStart = (void *)off[1];
|
||||
kernelUsrCopyFuncsEnd = (void *)off[2];
|
||||
|
||||
u32 n_cmp_0;
|
||||
for(off = (u32 *)kernelUsrCopyFuncsStart, n_cmp_0 = 1; n_cmp_0 <= 6; off++)
|
||||
{
|
||||
if(*off == 0xE3520000)
|
||||
{
|
||||
// We're missing some funcs
|
||||
switch(n_cmp_0)
|
||||
{
|
||||
case 1:
|
||||
usrToKernelMemcpy8 = (bool (*)(void *, const void *, u32))off;
|
||||
break;
|
||||
case 2:
|
||||
usrToKernelMemcpy32 = (bool (*)(u32 *, const u32 *, u32))off;
|
||||
break;
|
||||
case 3:
|
||||
usrToKernelStrncpy = (s32 (*)(char *, const char *, u32))off;
|
||||
break;
|
||||
case 4:
|
||||
kernelToUsrMemcpy8 = (bool (*)(void *, const void *, u32))off;
|
||||
break;
|
||||
case 5:
|
||||
kernelToUsrMemcpy32 = (bool (*)(u32 *, const u32 *, u32))off;
|
||||
break;
|
||||
case 6:
|
||||
kernelToUsrStrncpy = (s32 (*)(char *, const char *, u32))off;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
n_cmp_0++;
|
||||
}
|
||||
}
|
||||
|
||||
// The official prototype of ControlMemory doesn't have that extra param'
|
||||
ControlMemory = (Result (*)(u32 *, u32, u32, u32, MemOp, MemPerm, bool))
|
||||
decodeARMBranch((u32 *)officialSVCs[0x01] + 5);
|
||||
SleepThread = (void (*)(s64))officialSVCs[0x0A];
|
||||
CloseHandle = (Result (*)(Handle))officialSVCs[0x23];
|
||||
GetSystemInfo = (Result (*)(s64 *, s32, s32))decodeARMBranch((u32 *)officialSVCs[0x2A] + 3);
|
||||
GetProcessInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2B] + 3);
|
||||
GetThreadInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2C] + 3);
|
||||
ConnectToPort = (Result (*)(Handle *, const char*))decodeARMBranch((u32 *)officialSVCs[0x2D] + 3);
|
||||
SendSyncRequest = (Result (*)(Handle))officialSVCs[0x32];
|
||||
OpenProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x33] + 3);
|
||||
GetProcessId = (Result (*)(u32 *, Handle))decodeARMBranch((u32 *)officialSVCs[0x35] + 3);
|
||||
DebugActiveProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x60] + 3);
|
||||
KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1);
|
||||
|
||||
for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++);
|
||||
kernelpanic = (void (*)(void))off;
|
||||
|
||||
for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++);
|
||||
SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeARMBranch(off + 2);
|
||||
|
||||
for(; *off != 0x96007F9; off++);
|
||||
isDevUnit = *(bool **)(off - 1);
|
||||
enableUserExceptionHandlersForCPUExcLoc = (bool **)(off + 1);
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
// Shitty/lazy heuristic but it works on even 4.5, so...
|
||||
u32 textStart = ((u32)originalHandlers[(u32) SVC]) & ~0xFFFF;
|
||||
u32 rodataStart = (u32)(interruptManager->N3DS.privateInterrupts[0][6].interruptEvent->vtable) & ~0xFFF;
|
||||
|
||||
u32 textSize = rodataStart - textStart;
|
||||
for(off = (u32 *)textStart; off < (u32 *)(textStart + textSize) - 3; off++)
|
||||
{
|
||||
if(off[0] == 0xE5D13034 && off[1] == 0xE1530002)
|
||||
KScheduler__AdjustThread = (void (*)(KScheduler *, KThread *, u32))off;
|
||||
else if(off[0] == (u32)interruptManager && off[1] == (u32)¤tCoreContext->objectContext)
|
||||
KScheduler__AttemptSwitchingThreadContext = (void (*)(KScheduler *))(off - 2);
|
||||
else if(off[0] == 0xE3510B1A && off[1] == 0xE3A06000)
|
||||
{
|
||||
u32 *off2;
|
||||
for(off2 = off; *off2 != 0xE92D40F8; off2--);
|
||||
invalidateInstructionCacheRange = (void (*)(void *, u32))off2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Parameters
|
||||
{
|
||||
void (*SGI0HandlerCallback)(struct Parameters *, u32 *);
|
||||
InterruptManager *interruptManager;
|
||||
u32 *L2MMUTable; // bit31 mapping
|
||||
|
||||
void (*initFPU)(void);
|
||||
void (*mcuReboot)(void);
|
||||
void (*coreBarrier)(void);
|
||||
|
||||
u32 TTBCR;
|
||||
u32 L1MMUTableAddrs[4];
|
||||
|
||||
u32 kernelVersion;
|
||||
|
||||
CfwInfo cfwInfo;
|
||||
};
|
||||
|
||||
static void enableDebugFeatures(void)
|
||||
{
|
||||
*isDevUnit = true; // for debug SVCs and user exc. handlers, etc.
|
||||
*(bool **)PA_FROM_VA_PTR(enableUserExceptionHandlersForCPUExcLoc) = &enableUserExceptionHandlersForCPUExc;
|
||||
|
||||
u32 *off;
|
||||
for(off = (u32 *)officialSVCs[0x7C]; off[0] != 0xE5D00001 || off[1] != 0xE3500000; off++);
|
||||
*(u32 *)PA_FROM_VA_PTR(off + 2) = 0xE1A00000; // in case 6: beq -> nop
|
||||
|
||||
for(off = (u32 *)DebugActiveProcess; *off != 0xE3110001; off++);
|
||||
*(u32 *)PA_FROM_VA_PTR(off) = 0xE3B01001; // tst r1, #1 -> movs r1, #1
|
||||
}
|
||||
|
||||
static void doOtherPatches(void)
|
||||
{
|
||||
u32 *kpanic = (u32 *)kernelpanic;
|
||||
*(u32 *)PA_FROM_VA_PTR(kpanic) = 0xE12FFF7E; // bkpt 0xFFFE
|
||||
|
||||
u32 *off;
|
||||
for(off = (u32 *)ControlMemory; (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++);
|
||||
off -= 2;
|
||||
|
||||
/*
|
||||
Here we replace currentProcess->processID == 1 by additionnalParameter == 1.
|
||||
This patch should be generic enough to work even on firmware version 5.0.
|
||||
|
||||
It effectively changes the prototype of the ControlMemory function which
|
||||
only caller is the svc 0x01 handler on OFW.
|
||||
*/
|
||||
*(u32 *)PA_FROM_VA_PTR(off) = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeARMFrameSize((u32 *)ControlMemory)); // ldr r0, [sp, #(frameSize + 8)]
|
||||
|
||||
}
|
||||
|
||||
void main(volatile struct Parameters *p)
|
||||
{
|
||||
isN3DS = getNumberOfCores() == 4;
|
||||
interruptManager = p->interruptManager;
|
||||
|
||||
initFPU = p->initFPU;
|
||||
mcuReboot = p->mcuReboot;
|
||||
coreBarrier = p->coreBarrier;
|
||||
|
||||
TTBCR = p->TTBCR;
|
||||
memcpy(L1MMUTableAddrs, (const void *)p->L1MMUTableAddrs, 16);
|
||||
exceptionStackTop = (u32 *)0xFFFF2000 + (1 << (32 - TTBCR - 20));
|
||||
kernelVersion = p->kernelVersion;
|
||||
cfwInfo = p->cfwInfo;
|
||||
|
||||
setupSGI0Handler();
|
||||
setupExceptionHandlers();
|
||||
findUsefulSymbols();
|
||||
enableDebugFeatures();
|
||||
doOtherPatches();
|
||||
|
||||
rosalinaState = 0;
|
||||
hasStartedRosalinaNetworkFuncsOnce = false;
|
||||
*trampo_ = (u32)ConnectToPortHookWrapper;
|
||||
}
|
||||
176
sysmodules/rosalina/kernel_extension/source/memory.c
Normal file
176
sysmodules/rosalina/kernel_extension/source/memory.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "memory.h"
|
||||
#include "utils.h"
|
||||
|
||||
void *memcpy(void *dest, const void *src, u32 size)
|
||||
{
|
||||
u8 *destc = (u8 *)dest;
|
||||
const u8 *srcc = (const u8 *)src;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
destc[i] = srcc[i];
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *buf1, const void *buf2, u32 size)
|
||||
{
|
||||
const u8 *buf1c = (const u8 *)buf1;
|
||||
const u8 *buf2c = (const u8 *)buf2;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
{
|
||||
int cmp = buf1c[i] - buf2c[i];
|
||||
if(cmp)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memset(void *dest, u32 value, u32 size)
|
||||
{
|
||||
u8 *destc = (u8 *)dest;
|
||||
|
||||
for(u32 i = 0; i < size; i++) destc[i] = (u8)value;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset32(void *dest, u32 value, u32 size)
|
||||
{
|
||||
u32 *dest32 = (u32 *)dest;
|
||||
|
||||
for(u32 i = 0; i < size/4; i++) dest32[i] = value;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
//Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
|
||||
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
|
||||
{
|
||||
const u8 *patternc = (const u8 *)pattern;
|
||||
u32 table[256];
|
||||
|
||||
//Preprocessing
|
||||
for(u32 i = 0; i < 256; i++)
|
||||
table[i] = patternSize;
|
||||
for(u32 i = 0; i < patternSize - 1; i++)
|
||||
table[patternc[i]] = patternSize - i - 1;
|
||||
|
||||
//Searching
|
||||
u32 j = 0;
|
||||
while(j <= size - patternSize)
|
||||
{
|
||||
u8 c = startPos[j + patternSize - 1];
|
||||
if(patternc[patternSize - 1] == c && memcmp(pattern, startPos + j, patternSize - 1) == 0)
|
||||
return startPos + j;
|
||||
j += table[c];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strcpy(char *dest, const char *src)
|
||||
{
|
||||
u32 i;
|
||||
for(i = 0; src[i] != 0; i++)
|
||||
dest[i] = src[i];
|
||||
|
||||
dest[i] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
char *strncpy(char *dest, const char *src, u32 size)
|
||||
{
|
||||
u32 i;
|
||||
for(i = 0; i < size && src[i] != 0; i++)
|
||||
dest[i] = src[i];
|
||||
|
||||
for(; i < size; i++)
|
||||
dest[i] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
s32 strnlen(const char *string, s32 maxlen)
|
||||
{
|
||||
s32 size;
|
||||
for(size = 0; *string && size < maxlen; string++, size++);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
s32 strlen(const char *string)
|
||||
{
|
||||
char *stringEnd = (char *)string;
|
||||
while(*stringEnd) stringEnd++;
|
||||
|
||||
return stringEnd - string;
|
||||
}
|
||||
|
||||
s32 strcmp(const char *str1, const char *str2)
|
||||
{
|
||||
while(*str1 && (*str1 == *str2))
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
|
||||
return *str1 - *str2;
|
||||
}
|
||||
|
||||
s32 strncmp(const char *str1, const char *str2, u32 size)
|
||||
{
|
||||
while(size && *str1 && (*str1 == *str2))
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
size--;
|
||||
}
|
||||
if (!size)
|
||||
return 0;
|
||||
else
|
||||
return *str1 - *str2;
|
||||
}
|
||||
|
||||
void hexItoa(u64 number, char *out, u32 digits, bool uppercase)
|
||||
{
|
||||
const char hexDigits[] = "0123456789ABCDEF";
|
||||
const char hexDigitsLowercase[] = "0123456789abcdef";
|
||||
u32 i = 0;
|
||||
|
||||
while(number > 0)
|
||||
{
|
||||
out[digits - 1 - i++] = uppercase ? hexDigits[number & 0xF] : hexDigitsLowercase[number & 0xF];
|
||||
number >>= 4;
|
||||
}
|
||||
|
||||
while(i < digits) out[digits - 1 - i++] = '0';
|
||||
}
|
||||
55
sysmodules/rosalina/kernel_extension/source/start.s
Normal file
55
sysmodules/rosalina/kernel_extension/source/start.s
Normal file
@@ -0,0 +1,55 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.section .text.start
|
||||
.balign 4
|
||||
.global _start
|
||||
_start:
|
||||
push {r4, lr}
|
||||
|
||||
mrc p15, 0, r4, c0, c0, 5 @ CPUID register
|
||||
and r4, #3
|
||||
cmp r4, #1
|
||||
beq _core1_only
|
||||
|
||||
_waitLoop:
|
||||
wfe
|
||||
ldr r0, =_setupFinished
|
||||
ldr r0, [r0]
|
||||
cmp r0, #0
|
||||
beq _waitLoop
|
||||
b end
|
||||
|
||||
_core1_only:
|
||||
bl main
|
||||
ldr r0, =_setupFinished
|
||||
str r4, [r0]
|
||||
sev
|
||||
|
||||
end:
|
||||
pop {r4, pc}
|
||||
|
||||
.bss
|
||||
.balign 4
|
||||
_setupFinished: .word 0
|
||||
155
sysmodules/rosalina/kernel_extension/source/svc.c
Normal file
155
sysmodules/rosalina/kernel_extension/source/svc.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc.h"
|
||||
#include "svc/ControlMemory.h"
|
||||
#include "svc/GetProcessInfo.h"
|
||||
#include "svc/GetThreadInfo.h"
|
||||
#include "svc/GetSystemInfo.h"
|
||||
#include "svc/GetCFWInfo.h"
|
||||
#include "svc/ConnectToPort.h"
|
||||
#include "svc/SendSyncRequest.h"
|
||||
#include "svc/Break.h"
|
||||
#include "svc/SetGpuProt.h"
|
||||
#include "svc/SetWifiEnabled.h"
|
||||
#include "svc/Backdoor.h"
|
||||
#include "svc/KernelSetState.h"
|
||||
#include "svc/MapProcessMemoryEx.h"
|
||||
#include "svc/UnmapProcessMemoryEx.h"
|
||||
#include "svc/ControlService.h"
|
||||
#include "svc/CopyHandle.h"
|
||||
#include "svc/TranslateHandle.h"
|
||||
|
||||
void *officialSVCs[0x7E] = {NULL};
|
||||
|
||||
static inline void yieldDuringRosalinaMenu(void)
|
||||
{
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
u64 titleId = codeSetOfProcess(currentProcess)->titleId;
|
||||
u32 highTitleId = (u32)(titleId >> 32), lowTitleId = (u32)titleId;
|
||||
while((rosalinaState & 1) && idOfProcess(currentProcess) >= 6 &&
|
||||
(highTitleId != 0x00040130 || (highTitleId == 0x00040130 && (lowTitleId == 0x1A02 || lowTitleId == 0x1C02))))
|
||||
SleepThread(25 * 1000 * 1000LL);
|
||||
}
|
||||
|
||||
void signalSvcEntry(u8 *pageEnd)
|
||||
{
|
||||
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
yieldDuringRosalinaMenu();
|
||||
|
||||
if(svcId == 0xFE)
|
||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
||||
|
||||
// Since DBGEVENT_SYSCALL_ENTRY is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
||||
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
||||
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFE, svcId);
|
||||
}
|
||||
|
||||
void signalSvcReturn(u8 *pageEnd)
|
||||
{
|
||||
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
yieldDuringRosalinaMenu();
|
||||
|
||||
if(svcId == 0xFE)
|
||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x1FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
||||
|
||||
// Since DBGEVENT_SYSCALL_RETURN is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
||||
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
||||
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFF, svcId);
|
||||
}
|
||||
|
||||
void *svcHook(u8 *pageEnd)
|
||||
{
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
u32 svcId = *(u8 *)(pageEnd - 0xB5);
|
||||
if(svcId == 0xFE)
|
||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
||||
switch(svcId)
|
||||
{
|
||||
case 0x01:
|
||||
return ControlMemoryHookWrapper;
|
||||
case 0x2A:
|
||||
return GetSystemInfoHookWrapper;
|
||||
case 0x2B:
|
||||
return GetProcessInfoHookWrapper;
|
||||
case 0x2C:
|
||||
return GetThreadInfoHookWrapper;
|
||||
case 0x2D:
|
||||
return ConnectToPortHookWrapper;
|
||||
case 0x2E:
|
||||
return GetCFWInfo; // DEPRECATED
|
||||
case 0x32:
|
||||
return SendSyncRequestHook;
|
||||
case 0x3C:
|
||||
return (debugOfProcess(currentProcess) != NULL) ? officialSVCs[0x3C] : (void *)Break;
|
||||
case 0x59:
|
||||
return SetGpuProt;
|
||||
case 0x5A:
|
||||
return SetWifiEnabled;
|
||||
case 0x7B:
|
||||
return Backdoor;
|
||||
case 0x7C:
|
||||
return KernelSetStateHook;
|
||||
|
||||
|
||||
case 0x80:
|
||||
return CustomBackdoor;
|
||||
|
||||
case 0x90:
|
||||
return convertVAToPA;
|
||||
case 0x91:
|
||||
return flushDataCacheRange;
|
||||
case 0x92:
|
||||
return flushEntireDataCache;
|
||||
case 0x93:
|
||||
return invalidateInstructionCacheRange;
|
||||
case 0x94:
|
||||
return invalidateEntireInstructionCache;
|
||||
|
||||
case 0xA0:
|
||||
return MapProcessMemoryEx;
|
||||
case 0xA1:
|
||||
return UnmapProcessMemoryEx;
|
||||
case 0xA2:
|
||||
return ControlMemoryEx;
|
||||
|
||||
case 0xB0:
|
||||
return ControlService;
|
||||
case 0xB1:
|
||||
return CopyHandleWrapper;
|
||||
case 0xB2:
|
||||
return TranslateHandleWrapper;
|
||||
|
||||
default:
|
||||
return (svcId <= 0x7D) ? officialSVCs[svcId] : NULL;
|
||||
}
|
||||
}
|
||||
43
sysmodules/rosalina/kernel_extension/source/svc/Backdoor.s
Normal file
43
sysmodules/rosalina/kernel_extension/source/svc/Backdoor.s
Normal file
@@ -0,0 +1,43 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
.global Backdoor
|
||||
.type Backdoor, %function
|
||||
Backdoor:
|
||||
@ Nintendo's code
|
||||
bic r1, sp, #0xff
|
||||
orr r1, r1, #0xf00
|
||||
add r1, r1, #0x28 @ get user stack.
|
||||
|
||||
ldr r2, [r1]
|
||||
stmdb r2!, {sp, lr}
|
||||
mov sp, r2 @ sp_svc = sp_usr. You'll get nice crashes if an interrupt or context switch occurs during svcBackdoor
|
||||
blx r0
|
||||
pop {r0, r1}
|
||||
mov sp, r0
|
||||
bx r1
|
||||
35
sysmodules/rosalina/kernel_extension/source/svc/Break.s
Normal file
35
sysmodules/rosalina/kernel_extension/source/svc/Break.s
Normal file
@@ -0,0 +1,35 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
.global Break
|
||||
.type Break, %function
|
||||
Break:
|
||||
bic r0, sp, #0xf00
|
||||
bic r0, #0xff
|
||||
add r0, #0x1000 @ get page context top
|
||||
bkpt 0xffff
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/ConnectToPort.h"
|
||||
#include "memory.h"
|
||||
#include "ipc.h"
|
||||
|
||||
Result ConnectToPortHook(Handle *out, const char *name)
|
||||
{
|
||||
char portName[12] = {0};
|
||||
Result res = 0;
|
||||
if(name != NULL)
|
||||
{
|
||||
s32 nb = usrToKernelStrncpy(portName, name, 12);
|
||||
if(nb < 0)
|
||||
return 0xD9001814;
|
||||
else if(nb == 12 && portName[11] != 0)
|
||||
return 0xE0E0181E;
|
||||
}
|
||||
res = ConnectToPort(out, name);
|
||||
if(res != 0)
|
||||
return res;
|
||||
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KClientSession *clientSession = (KClientSession *)KProcessHandleTable__ToKAutoObject(handleTable, *out);
|
||||
if(clientSession != NULL)
|
||||
{
|
||||
SessionInfo_Add(clientSession->parentSession, portName);
|
||||
clientSession->syncObject.autoObject.vtable->DecrementReferenceCount(&clientSession->syncObject.autoObject);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/ControlMemory.h"
|
||||
|
||||
Result ControlMemoryHook(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm)
|
||||
{
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
return ControlMemory(addrOut, addr0, addr1, size, op, perm, idOfProcess(currentProcess) == 1);
|
||||
}
|
||||
|
||||
108
sysmodules/rosalina/kernel_extension/source/svc/ControlService.c
Normal file
108
sysmodules/rosalina/kernel_extension/source/svc/ControlService.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/ControlService.h"
|
||||
#include "memory.h"
|
||||
#include "ipc.h"
|
||||
|
||||
Result ControlService(ServiceOp op, u32 varg1, u32 varg2)
|
||||
{
|
||||
Result res = 0;
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
|
||||
switch(op)
|
||||
{
|
||||
case SERVICEOP_GET_NAME:
|
||||
{
|
||||
KSession *session = NULL;
|
||||
SessionInfo *info = NULL;
|
||||
KAutoObject *obj = KProcessHandleTable__ToKAutoObject(handleTable, (Handle)varg2);
|
||||
if(obj == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
else if(kernelVersion >= SYSTEM_VERSION(2, 46, 0))
|
||||
{
|
||||
KClassToken tok;
|
||||
obj->vtable->GetClassToken(&tok, obj);
|
||||
if(tok.flags == 0x95)
|
||||
session = ((KServerSession *)obj)->parentSession;
|
||||
else if(tok.flags == 0xA5)
|
||||
session = ((KClientSession *)obj)->parentSession;
|
||||
}
|
||||
else
|
||||
{ // not the exact same tests but it should work
|
||||
if(strcmp(obj->vtable->GetClassName(obj), "KServerSession") == 0)
|
||||
session = ((KServerSession *)obj)->parentSession;
|
||||
else if(strcmp(obj->vtable->GetClassName(obj), "KClientSession") == 0)
|
||||
session = ((KClientSession *)obj)->parentSession;
|
||||
}
|
||||
|
||||
if(session != NULL)
|
||||
info = SessionInfo_Lookup(session);
|
||||
|
||||
if(info == NULL)
|
||||
res = 0xD8E007F7;
|
||||
else
|
||||
{
|
||||
// names are limited to 11 characters (for ports)
|
||||
// kernelToUsrStrncpy doesn't clear trailing bytes
|
||||
char name[12] = { 0 };
|
||||
strncpy(name, info->name, 12);
|
||||
res = kernelToUsrMemcpy8((void *)varg1, name, strlen(name) + 1) ? 0 : 0xE0E01BF5;
|
||||
}
|
||||
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
return res;
|
||||
}
|
||||
|
||||
case SERVICEOP_STEAL_CLIENT_SESSION:
|
||||
{
|
||||
char name[12] = { 0 };
|
||||
SessionInfo *info = NULL;
|
||||
if(name != NULL)
|
||||
{
|
||||
s32 nb = usrToKernelStrncpy(name, (const char *)varg2, 12);
|
||||
if(nb < 0)
|
||||
return 0xD9001814;
|
||||
else if(nb == 12 && name[11] != 0)
|
||||
return 0xE0E0181E;
|
||||
}
|
||||
|
||||
info = SessionInfo_FindFirst(name);
|
||||
|
||||
if(info == NULL)
|
||||
return 0x9401BFE; // timeout (the wanted service is likely not initalized)
|
||||
else
|
||||
{
|
||||
Handle out;
|
||||
res = createHandleForThisProcess(&out, &info->session->clientSession.syncObject.autoObject);
|
||||
return (res != 0) ? res : (kernelToUsrMemcpy32((u32 *)varg1, (u32 *)&out, 4) ? 0 : (Result)0xE0E01BF5);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return 0xF8C007F4;
|
||||
}
|
||||
}
|
||||
76
sysmodules/rosalina/kernel_extension/source/svc/CopyHandle.c
Normal file
76
sysmodules/rosalina/kernel_extension/source/svc/CopyHandle.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/CopyHandle.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result CopyHandle(Handle *outHandle, Handle outProcessHandle, Handle inHandle, Handle inProcessHandle)
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcess *inProcess, *outProcess;
|
||||
Result res;
|
||||
|
||||
if(inProcessHandle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
inProcess = currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference((KAutoObject *)inProcess);
|
||||
}
|
||||
else
|
||||
inProcess = KProcessHandleTable__ToKProcess(handleTable, inProcessHandle);
|
||||
|
||||
if(inProcess == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
|
||||
if(outProcessHandle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
outProcess = currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference((KAutoObject *)outProcess);
|
||||
}
|
||||
else
|
||||
outProcess = KProcessHandleTable__ToKProcess(handleTable, outProcessHandle);
|
||||
|
||||
if(outProcess == NULL)
|
||||
{
|
||||
((KAutoObject *)inProcess)->vtable->DecrementReferenceCount((KAutoObject *)inProcess);
|
||||
return 0xD8E007F7; // invalid handle
|
||||
}
|
||||
|
||||
KAutoObject *obj = KProcessHandleTable__ToKAutoObject(handleTableOfProcess(inProcess), inHandle);
|
||||
if(obj == NULL)
|
||||
{
|
||||
((KAutoObject *)inProcess)->vtable->DecrementReferenceCount((KAutoObject *)inProcess);
|
||||
((KAutoObject *)outProcess)->vtable->DecrementReferenceCount((KAutoObject *)outProcess);
|
||||
return 0xD8E007F7; // invalid handle
|
||||
}
|
||||
|
||||
res = createHandleForProcess(outHandle, outProcess, obj);
|
||||
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
((KAutoObject *)inProcess)->vtable->DecrementReferenceCount((KAutoObject *)inProcess);
|
||||
((KAutoObject *)outProcess)->vtable->DecrementReferenceCount((KAutoObject *)outProcess);
|
||||
|
||||
return res;
|
||||
}
|
||||
33
sysmodules/rosalina/kernel_extension/source/svc/GetCFWInfo.c
Normal file
33
sysmodules/rosalina/kernel_extension/source/svc/GetCFWInfo.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetCFWInfo.h"
|
||||
|
||||
// DEPRECATED
|
||||
Result GetCFWInfo(CfwInfo *out)
|
||||
{
|
||||
return kernelToUsrMemcpy8(out, &cfwInfo, 16) ? 0 : 0xE0E01BF5;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetProcessInfo.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result GetProcessInfoHook(s64 *out, Handle processHandle, u32 type)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
if(type >= 0x10000)
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcess *process;
|
||||
if(processHandle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
process = currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference((KAutoObject *)process);
|
||||
}
|
||||
else
|
||||
process = KProcessHandleTable__ToKProcess(handleTable, processHandle);
|
||||
|
||||
if(process == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0x10000:
|
||||
memcpy(out, codeSetOfProcess(process)->processName, 8);
|
||||
break;
|
||||
case 0x10001:
|
||||
*(u64 *)out = codeSetOfProcess(process)->titleId;
|
||||
break;
|
||||
case 0x10002:
|
||||
*out = codeSetOfProcess(process)->nbTextPages << 12;
|
||||
break;
|
||||
case 0x10003:
|
||||
*out = codeSetOfProcess(process)->nbRodataPages << 12;
|
||||
break;
|
||||
case 0x10004:
|
||||
*out = codeSetOfProcess(process)->nbRwPages << 12;
|
||||
break;
|
||||
case 0x10005:
|
||||
*out = (s64)(u64)(u32)codeSetOfProcess(process)->textSection.section.loadAddress;
|
||||
break;
|
||||
case 0x10006:
|
||||
*out = (s64)(u64)(u32)codeSetOfProcess(process)->rodataSection.section.loadAddress;
|
||||
break;
|
||||
case 0x10007:
|
||||
*out = (s64)(u64)(u32)codeSetOfProcess(process)->dataSection.section.loadAddress;
|
||||
break;
|
||||
case 0x10008:
|
||||
*out = (isN3DS ? hwInfoOfProcess(process)->N3DS.translationTableBase :
|
||||
(kernelVersion >= SYSTEM_VERSION(2, 44, 6)
|
||||
? hwInfoOfProcess(process)->O3DS8x.translationTableBase
|
||||
: hwInfoOfProcess(process)->O3DSPre8x.translationTableBase)
|
||||
) & ~((1 << (14 - TTBCR)) - 1);
|
||||
break;
|
||||
default:
|
||||
res = 0xD8E007ED; // invalid enum value
|
||||
break;
|
||||
}
|
||||
|
||||
((KAutoObject *)process)->vtable->DecrementReferenceCount((KAutoObject *)process);
|
||||
}
|
||||
|
||||
else
|
||||
res = GetProcessInfo(out, processHandle, type);
|
||||
|
||||
return res;
|
||||
}
|
||||
123
sysmodules/rosalina/kernel_extension/source/svc/GetSystemInfo.c
Normal file
123
sysmodules/rosalina/kernel_extension/source/svc/GetSystemInfo.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetSystemInfo.h"
|
||||
#include "utils.h"
|
||||
#include "ipc.h"
|
||||
#include "synchronization.h"
|
||||
|
||||
Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0x10000:
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case 0:
|
||||
*out = SYSTEM_VERSION(cfwInfo.versionMajor, cfwInfo.versionMinor, cfwInfo.versionBuild);
|
||||
break;
|
||||
case 1:
|
||||
*out = cfwInfo.commitHash;
|
||||
break;
|
||||
case 2:
|
||||
*out = cfwInfo.config;
|
||||
break;
|
||||
case 3: // isRelease
|
||||
*out = cfwInfo.flags & 1;
|
||||
break;
|
||||
case 4: // isN3DS
|
||||
*out = (cfwInfo.flags >> 4) & 1;
|
||||
break;
|
||||
case 5: // isSafeMode
|
||||
*out = (cfwInfo.flags >> 5) & 1;
|
||||
break;
|
||||
case 6: // isSdMode
|
||||
*out = (cfwInfo.flags >> 6) & 1;
|
||||
break;
|
||||
default:
|
||||
res = 0xF8C007F4; // not implemented
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10001: // N3DS-related info
|
||||
{
|
||||
if(isN3DS)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case 0: // current clock rate
|
||||
*out = (((CFG11_MPCORE_CLKCNT >> 1) & 3) + 1) * 268;
|
||||
break;
|
||||
case 1: // higher clock rate
|
||||
*out = (((CFG11_MPCORE_CFG >> 2) & 1) + 2) * 268;
|
||||
break;
|
||||
case 2: // L2C enabled status
|
||||
*out = L2C_CTRL & 1;
|
||||
break;
|
||||
default:
|
||||
res = 0xF8C007F4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
res = 0xF8C007F4;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10002: // MMU config (cached values from booting)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case 0:
|
||||
*out = TTBCR;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if((u32)param <= getNumberOfCores())
|
||||
*out = L1MMUTableAddrs[param - 1];
|
||||
else
|
||||
res = 0xF8C007F4;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GetSystemInfo(out, type, param);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetThreadInfo.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result GetThreadInfoHook(s64 *out, Handle threadHandle, u32 type)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
if(type == 0x10000) // Get TLS
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KThread *thread;
|
||||
|
||||
if(threadHandle == CUR_THREAD_HANDLE)
|
||||
{
|
||||
thread = currentCoreContext->objectContext.currentThread;
|
||||
KAutoObject__AddReference(&thread->syncObject.autoObject);
|
||||
}
|
||||
else
|
||||
thread = KProcessHandleTable__ToKThread(handleTable, threadHandle);
|
||||
|
||||
if(thread == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
|
||||
*out = (s64)(u64)(u32)thread->threadLocalStorage;
|
||||
|
||||
KAutoObject *obj = (KAutoObject *)thread;
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
}
|
||||
|
||||
else
|
||||
res = GetThreadInfo(out, threadHandle, type);
|
||||
|
||||
return res;
|
||||
}
|
||||
149
sysmodules/rosalina/kernel_extension/source/svc/KernelSetState.c
Normal file
149
sysmodules/rosalina/kernel_extension/source/svc/KernelSetState.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/KernelSetState.h"
|
||||
#include "synchronization.h"
|
||||
#include "ipc.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define MAX_DEBUG 3
|
||||
|
||||
static u32 nbEnabled = 0;
|
||||
static u32 maskedPids[MAX_DEBUG];
|
||||
static u32 masks[MAX_DEBUG][8] = {0};
|
||||
|
||||
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId)
|
||||
{
|
||||
u32 pid = idOfProcess(process);
|
||||
u32 id;
|
||||
for(id = 0; id < nbEnabled && maskedPids[id] != pid; id++);
|
||||
if(id == MAX_DEBUG)
|
||||
return false;
|
||||
else
|
||||
return ((masks[id][svcId / 32] >> (31 - (svcId % 32))) & 1) != 0;
|
||||
}
|
||||
|
||||
Result SetSyscallDebugEventMask(u32 pid, bool enable, const u32 *mask)
|
||||
{
|
||||
static KRecursiveLock syscallDebugEventMaskLock = { NULL };
|
||||
|
||||
u32 tmpMask[8];
|
||||
if(enable && nbEnabled == MAX_DEBUG)
|
||||
return 0xC86018FF; // Out of resource (255)
|
||||
|
||||
if(enable && !usrToKernelMemcpy8(&tmpMask, mask, 32))
|
||||
return 0xE0E01BF5;
|
||||
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&syscallDebugEventMaskLock);
|
||||
|
||||
if(enable)
|
||||
{
|
||||
maskedPids[nbEnabled] = pid;
|
||||
memcpy(&masks[nbEnabled++], tmpMask, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 id;
|
||||
for(id = 0; id < nbEnabled && maskedPids[id] != pid; id++);
|
||||
if(id == nbEnabled)
|
||||
{
|
||||
KRecursiveLock__Unlock(&syscallDebugEventMaskLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return 0xE0E01BFD; // out of range (it's not fully technically correct but meh)
|
||||
}
|
||||
|
||||
for(u32 i = id; i < nbEnabled - 1; i++)
|
||||
{
|
||||
maskedPids[i] = maskedPids[i + 1];
|
||||
memcpy(&masks[i], &masks[i + 1], 32);
|
||||
}
|
||||
maskedPids[--nbEnabled] = 0;
|
||||
memset(&masks[nbEnabled], 0, 32);
|
||||
}
|
||||
|
||||
KRecursiveLock__Unlock(&syscallDebugEventMaskLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0x10000:
|
||||
{
|
||||
do
|
||||
{
|
||||
__ldrex((s32 *)&rosalinaState);
|
||||
}
|
||||
while(__strex((s32 *)&rosalinaState, (s32)(rosalinaState ^ varg1)));
|
||||
|
||||
if(rosalinaState & 2)
|
||||
hasStartedRosalinaNetworkFuncsOnce = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x10001:
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&processLangemuLock);
|
||||
|
||||
u32 i;
|
||||
for(i = 0; i < 0x40 && processLangemuAttributes[i].titleId != 0ULL; i++);
|
||||
if(i < 0x40)
|
||||
{
|
||||
processLangemuAttributes[i].titleId = ((u64)varg3 << 32) | (u32)varg2;
|
||||
processLangemuAttributes[i].state = (u8)(varg1 >> 24);
|
||||
processLangemuAttributes[i].country = (u8)(varg1 >> 16);
|
||||
processLangemuAttributes[i].language = (u8)(varg1 >> 8);
|
||||
processLangemuAttributes[i].region = (u8)(varg1 >> 4);
|
||||
processLangemuAttributes[i].mask = (u8)(varg1 & 0xf);
|
||||
}
|
||||
else
|
||||
res = 0xD8609013;
|
||||
|
||||
KRecursiveLock__Unlock(&processLangemuLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
break;
|
||||
}
|
||||
case 0x10002:
|
||||
{
|
||||
res = SetSyscallDebugEventMask(varg1, (bool)varg2, (const u32 *)varg3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
res = KernelSetState(type, varg1, varg2, varg3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/MapProcessMemoryEx.h"
|
||||
|
||||
Result MapProcessMemoryEx(Handle processHandle, void *dst, void *src, u32 size)
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcessHwInfo *currentHwInfo = hwInfoOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcess *process = KProcessHandleTable__ToKProcess(handleTable, processHandle);
|
||||
|
||||
if(process == NULL)
|
||||
return 0xD8E007F7;
|
||||
|
||||
Result res = KProcessHwInfo__MapProcessMemory(currentHwInfo, hwInfoOfProcess(process), dst, src, size >> 12);
|
||||
|
||||
KAutoObject *obj = (KAutoObject *)process;
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/SendSyncRequest.h"
|
||||
#include "memory.h"
|
||||
#include "ipc.h"
|
||||
|
||||
Result SendSyncRequestHook(Handle handle)
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KClientSession *clientSession = (KClientSession *)KProcessHandleTable__ToKAutoObject(handleTable, handle);
|
||||
|
||||
u32 *cmdbuf = (u32 *)((u8 *)currentCoreContext->objectContext.currentThread->threadLocalStorage + 0x80);
|
||||
bool skip = false;
|
||||
Result res = 0;
|
||||
|
||||
bool isValidClientSession = false;
|
||||
if(clientSession != NULL && kernelVersion >= SYSTEM_VERSION(2, 46, 0))
|
||||
{
|
||||
KClassToken tok;
|
||||
clientSession->syncObject.autoObject.vtable->GetClassToken(&tok, &clientSession->syncObject.autoObject);
|
||||
isValidClientSession = tok.flags == 0xA5;
|
||||
}
|
||||
else if(clientSession != NULL) // not the exact same test but it should work
|
||||
isValidClientSession = strcmp(clientSession->syncObject.autoObject.vtable->GetClassName(&clientSession->syncObject.autoObject), "KClientSession");
|
||||
|
||||
if(isValidClientSession)
|
||||
{
|
||||
switch (cmdbuf[0])
|
||||
{
|
||||
case 0x10042:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && strcmp(info->name, "srv:pm") == 0)
|
||||
{
|
||||
res = doPublishToProcessHook(handle, cmdbuf);
|
||||
skip = true;
|
||||
}
|
||||
else if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce)
|
||||
{
|
||||
cmdbuf[0] = 0x10040;
|
||||
cmdbuf[1] = 0;
|
||||
skip = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10082:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && (strcmp(info->name, "cfg:u") == 0 || strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk2
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10800:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && strcmp(info->name, "err:f") == 0) // Throw
|
||||
skip = doErrfThrowHook(cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x20000:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && (strcmp(info->name, "cfg:u") == 0 || strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // SecureInfoGetRegion
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x20002:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && strcmp(info->name, "ndm:u") == 0 && hasStartedRosalinaNetworkFuncsOnce)
|
||||
{
|
||||
cmdbuf[0] = 0x20040;
|
||||
cmdbuf[1] = 0;
|
||||
skip = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x50100:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && strcmp(info->name, "srv:") == 0)
|
||||
{
|
||||
char name[9] = { 0 };
|
||||
memcpy(name, cmdbuf + 1, 8);
|
||||
|
||||
skip = true;
|
||||
res = SendSyncRequest(handle);
|
||||
if(res == 0)
|
||||
{
|
||||
KClientSession *outClientSession;
|
||||
|
||||
outClientSession = (KClientSession *)KProcessHandleTable__ToKAutoObject(handleTable, (Handle)cmdbuf[3]);
|
||||
if(outClientSession != NULL)
|
||||
{
|
||||
SessionInfo_Add(outClientSession->parentSession, name);
|
||||
outClientSession->syncObject.autoObject.vtable->DecrementReferenceCount(&outClientSession->syncObject.autoObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x80040:
|
||||
{
|
||||
if(!hasStartedRosalinaNetworkFuncsOnce)
|
||||
break;
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
skip = info != NULL && strcmp(info->name, "ndm:u") == 0; // SuspendScheduler
|
||||
if(skip)
|
||||
cmdbuf[1] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x90000:
|
||||
{
|
||||
if(!hasStartedRosalinaNetworkFuncsOnce)
|
||||
break;
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && strcmp(info->name, "ndm:u") == 0) // ResumeScheduler
|
||||
{
|
||||
cmdbuf[0] = 0x90040;
|
||||
cmdbuf[1] = 0;
|
||||
skip = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4010042:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && strcmp(info->name, "srv:pm") == 0)
|
||||
{
|
||||
res = doPublishToProcessHook(handle, cmdbuf);
|
||||
skip = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4010082:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk4
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4020082:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk8
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x8010082:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0)) // GetConfigInfoBlk4
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x8020082:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession);
|
||||
if(info != NULL && strcmp(info->name, "cfg:i") == 0) // GetConfigInfoBlk8
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x4060000:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion
|
||||
if(info != NULL && (strcmp(info->name, "cfg:s") == 0 || strcmp(info->name, "cfg:i") == 0))
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x8160000:
|
||||
{
|
||||
SessionInfo *info = SessionInfo_Lookup(clientSession->parentSession); // SecureInfoGetRegion
|
||||
if(info != NULL && strcmp(info->name, "cfg:i") == 0)
|
||||
skip = doLangEmu(&res, handle, cmdbuf);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(clientSession != NULL)
|
||||
clientSession->syncObject.autoObject.vtable->DecrementReferenceCount(&clientSession->syncObject.autoObject);
|
||||
|
||||
res = skip ? res : SendSyncRequest(handle);
|
||||
|
||||
return res;
|
||||
}
|
||||
32
sysmodules/rosalina/kernel_extension/source/svc/SetGpuProt.c
Normal file
32
sysmodules/rosalina/kernel_extension/source/svc/SetGpuProt.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/SetGpuProt.h"
|
||||
|
||||
Result SetGpuProt(bool prot UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/SetWifiEnabled.h"
|
||||
|
||||
void SetWifiEnabled(bool enable)
|
||||
{
|
||||
if(enable)
|
||||
CFG11_WIFICNT |= 1;
|
||||
else
|
||||
CFG11_WIFICNT &= ~1;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/TranslateHandle.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result TranslateHandle(u32 *outKAddr, char *outClassName, Handle handle)
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KAutoObject *obj;
|
||||
Result res;
|
||||
const char *name;
|
||||
|
||||
if(handle == CUR_THREAD_HANDLE)
|
||||
{
|
||||
obj = (KAutoObject *)currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference(obj);
|
||||
}
|
||||
else if(handle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
obj = (KAutoObject *)currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference(obj);
|
||||
}
|
||||
else
|
||||
obj = KProcessHandleTable__ToKAutoObject(handleTable, handle);
|
||||
|
||||
if(obj == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
|
||||
if(kernelVersion >= SYSTEM_VERSION(2, 46, 0))
|
||||
{
|
||||
KClassToken tok;
|
||||
obj->vtable->GetClassToken(&tok, obj);
|
||||
name = tok.name;
|
||||
}
|
||||
else
|
||||
name = obj->vtable->GetClassName(obj);
|
||||
|
||||
if(name == NULL) // shouldn't happen
|
||||
name = "KAutoObject";
|
||||
|
||||
*outKAddr = (u32)obj;
|
||||
res = kernelToUsrMemcpy8(outClassName, name, strlen(name) + 1) ? 0 : 0xE0E01BF5;
|
||||
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/MapProcessMemoryEx.h"
|
||||
|
||||
Result UnmapProcessMemoryEx(Handle processHandle UNUSED, void *dst, u32 size)
|
||||
{
|
||||
KProcessHwInfo *currentHwInfo = hwInfoOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
|
||||
Result res = KProcessHwInfo__UnmapProcessMemory(currentHwInfo, dst, size >> 12);
|
||||
|
||||
invalidateEntireInstructionCache();
|
||||
flushEntireDataCache();
|
||||
|
||||
return res;
|
||||
}
|
||||
85
sysmodules/rosalina/kernel_extension/source/svc/wrappers.s
Normal file
85
sysmodules/rosalina/kernel_extension/source/svc/wrappers.s
Normal file
@@ -0,0 +1,85 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
.macro GEN_GETINFO_WRAPPER, name
|
||||
.global Get\name\()InfoHookWrapper
|
||||
.type Get\name\()InfoHookWrapper, %function
|
||||
Get\name\()InfoHookWrapper:
|
||||
push {r12, lr}
|
||||
sub sp, #8
|
||||
mov r0, sp
|
||||
bl Get\name\()InfoHook
|
||||
pop {r1, r2, r12, pc}
|
||||
.endm
|
||||
|
||||
GEN_GETINFO_WRAPPER System
|
||||
GEN_GETINFO_WRAPPER Process
|
||||
GEN_GETINFO_WRAPPER Thread
|
||||
|
||||
.macro GEN_OUT1_WRAPPER, name
|
||||
.global \name\()Wrapper
|
||||
.type \name\()Wrapper, %function
|
||||
\name\()Wrapper:
|
||||
push {lr}
|
||||
sub sp, #4
|
||||
mov r0, sp
|
||||
bl \name
|
||||
pop {r1, pc}
|
||||
.endm
|
||||
|
||||
GEN_OUT1_WRAPPER ConnectToPortHook
|
||||
GEN_OUT1_WRAPPER CopyHandle
|
||||
GEN_OUT1_WRAPPER TranslateHandle
|
||||
|
||||
.global ControlMemoryHookWrapper
|
||||
.type ControlMemoryHookWrapper, %function
|
||||
ControlMemoryHookWrapper:
|
||||
push {lr}
|
||||
sub sp, #12
|
||||
stmia sp, {r0, r4}
|
||||
add r0, sp, #8
|
||||
bl ControlMemoryHook
|
||||
ldr r1, [sp, #8]
|
||||
add sp, #12
|
||||
pop {pc}
|
||||
|
||||
.global ControlMemoryEx
|
||||
.type ControlMemoryEx, %function
|
||||
ControlMemoryEx:
|
||||
push {lr}
|
||||
sub sp, #8
|
||||
cmp r5, #0
|
||||
movne r5, #1
|
||||
push {r0, r4, r5}
|
||||
add r0, sp, #12
|
||||
ldr r12, =ControlMemory
|
||||
ldr r12, [r12]
|
||||
blx r12
|
||||
ldr r1, [sp, #12]
|
||||
add sp, #20
|
||||
pop {pc}
|
||||
127
sysmodules/rosalina/kernel_extension/source/svcHandler.s
Normal file
127
sysmodules/rosalina/kernel_extension/source/svcHandler.s
Normal file
@@ -0,0 +1,127 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
.global svcHandler
|
||||
.type svcHandler, %function
|
||||
svcHandler:
|
||||
srsdb sp!, #0x13
|
||||
stmfd sp, {r8-r11, sp, lr}^
|
||||
sub sp, #0x18
|
||||
mrs r9, spsr
|
||||
ands r9, #0x20
|
||||
ldrneb r9, [lr, #-2]
|
||||
ldreqb r9, [lr, #-4]
|
||||
|
||||
mov lr, #0 @ do stuff as if the "allow debug" flag is always set
|
||||
push {r0-r7, r12, lr}
|
||||
mov r10, #1
|
||||
strb r9, [sp, #0x58+3] @ page end - 0xb8 + 3: svc being handled
|
||||
strb r10, [sp, #0x58+1] @ page end - 0xb8 + 1: "allow debug" flag
|
||||
|
||||
@ sp = page end - 0x110
|
||||
add r0, sp, #0x110 @ page end
|
||||
bl svcHook
|
||||
cpsid i
|
||||
mov r8, r0
|
||||
ldmfd sp, {r0-r7, r12, lr}
|
||||
cmp r8, #0
|
||||
beq _fallback @ invalid svc, or svc 0xff (stop point)
|
||||
|
||||
_handled_svc: @ unused label, just here for formatting
|
||||
push {r0-r12, lr}
|
||||
add r0, sp, #0x148
|
||||
cpsie i
|
||||
bl signalSvcEntry
|
||||
cpsid i
|
||||
pop {r0-r12, lr}
|
||||
|
||||
cpsie i
|
||||
blx r8
|
||||
cpsid i
|
||||
|
||||
ldrb lr, [sp, #0x58+0] @ page end - 0xb8 + 0: scheduling flags
|
||||
b _fallback_end
|
||||
|
||||
_fallback:
|
||||
mov r0, r9
|
||||
ldr r8, =svcFallbackHandler
|
||||
ldr r8, [r8]
|
||||
blx r8
|
||||
mov lr, #0
|
||||
|
||||
_fallback_end:
|
||||
|
||||
ldr r8, [sp, #0x24] @ page_end - 0xec: saved lr (see above) : should reload regs
|
||||
cmp r8, #0
|
||||
addeq sp, #0x24
|
||||
popne {r0-r7, r12}
|
||||
add sp, #4
|
||||
|
||||
cmp r9, #0xff
|
||||
beq _no_signal_return
|
||||
|
||||
push {r0-r7, r12, lr}
|
||||
add r0, sp, #0x110 @ page end
|
||||
cpsie i
|
||||
bl signalSvcReturn
|
||||
cpsid i
|
||||
pop {r0-r7, r12}
|
||||
add sp, #4
|
||||
|
||||
_no_signal_return:
|
||||
|
||||
mov r8, #0
|
||||
strb r8, [sp, #0x30+3] @ page_end - 0xb8 + 3: svc being handled
|
||||
|
||||
_svc_finished:
|
||||
|
||||
ldmfd sp, {r8-r11, sp, lr}^
|
||||
cmp lr, #0
|
||||
bne _postprocess_svc
|
||||
|
||||
_svc_return:
|
||||
add sp, #0x18
|
||||
rfefd sp! @ return to user mode
|
||||
|
||||
_postprocess_svc:
|
||||
mov lr, #0
|
||||
push {r0-r7, r12, lr}
|
||||
|
||||
push {r0-r3}
|
||||
ldr r0, =PostprocessSvc
|
||||
ldr r0, [r0]
|
||||
blx r0
|
||||
pop {r0-r3}
|
||||
|
||||
ldrb lr, [sp, #0x58+0] @ page end - 0xb8 + 0: scheduling flags
|
||||
ldr r8, [sp, #0x24] @ page_end - 0xec: saved lr (see above) : should reload regs
|
||||
cmp r8, #0
|
||||
addeq sp, #0x24
|
||||
popne {r0-r7, r12}
|
||||
add sp, #4
|
||||
b _svc_finished
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "synchronization.h"
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
|
||||
extern SGI0Handler_t SGI0Handler;
|
||||
|
||||
void executeFunctionOnCores(SGI0Handler_t handler, u8 targetList, u8 targetListFilter)
|
||||
{
|
||||
u32 coreID = getCurrentCoreID();
|
||||
SGI0Handler = handler;
|
||||
|
||||
if(targetListFilter == 0 && (targetListFilter & (1 << coreID)) != 0)
|
||||
__asm__ volatile("cpsie i"); // make sure interrupts aren't masked
|
||||
MPCORE_GID_SGI = (targetListFilter << 24) | (targetList << 16) | 0;
|
||||
}
|
||||
139
sysmodules/rosalina/kernel_extension/source/utils.s
Normal file
139
sysmodules/rosalina/kernel_extension/source/utils.s
Normal file
@@ -0,0 +1,139 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
.global convertVAToPA
|
||||
.type convertVAToPA, %function
|
||||
convertVAToPA:
|
||||
mov r3, r1
|
||||
mov r1, #0xf00
|
||||
orr r1, #0xff
|
||||
and r2, r0, r1
|
||||
bic r0, r1
|
||||
cmp r3, #1
|
||||
beq _convertVAToPA_write_check
|
||||
_convertVAToPA_read_check:
|
||||
mcr p15, 0, r0, c7, c8, 0 @ VA to PA translation with privileged read permission check
|
||||
b _convertVAToPA_end_check
|
||||
_convertVAToPA_write_check:
|
||||
mcr p15, 0, r0, c7, c8, 1 @ VA to PA translation with privileged write permission check
|
||||
_convertVAToPA_end_check:
|
||||
mrc p15, 0, r0, c7, c4, 0 @ read PA register
|
||||
tst r0, #1 @ failure bit
|
||||
bic r0, r1
|
||||
addeq r0, r2
|
||||
movne r0, #0
|
||||
bx lr
|
||||
|
||||
.global flushEntireDataCache
|
||||
.type flushEntireDataCache, %function
|
||||
flushEntireDataCache:
|
||||
mvn r1, #0 @ this is translated to a full cache flush
|
||||
ldr r12, =flushDataCacheRange
|
||||
ldr r12, [r12]
|
||||
bx r12
|
||||
|
||||
.global invalidateEntireInstructionCache
|
||||
.type invalidateEntireInstructionCache, %function
|
||||
invalidateEntireInstructionCache:
|
||||
mvn r1, #0 @ this is translated to a full cache flush
|
||||
ldr r12, =invalidateInstructionCacheRange
|
||||
ldr r12, [r12]
|
||||
bx r12
|
||||
|
||||
.global KObjectMutex__Acquire
|
||||
.type KObjectMutex__Acquire, %function
|
||||
KObjectMutex__Acquire:
|
||||
ldr r1, =0xFFFF9000 @ current thread addr
|
||||
|
||||
ldr r1, [r1]
|
||||
ldrex r2, [r0]
|
||||
cmp r2, #0
|
||||
strexeq r3, r1, [r0] @ store current thread
|
||||
strexne r3, r2, [r0] @ stored thread != NULL, no change
|
||||
cmpeq r3, #0
|
||||
bxeq lr
|
||||
|
||||
ldr r12, =KObjectMutex__WaitAndAcquire
|
||||
ldr r12, [r12]
|
||||
bx r12
|
||||
|
||||
.global KObjectMutex__Release
|
||||
.type KObjectMutex__Release, %function
|
||||
KObjectMutex__Release:
|
||||
mov r1, #0
|
||||
str r1, [r0]
|
||||
ldrh r1, [r0, #4]
|
||||
cmp r1, #0
|
||||
bxle lr
|
||||
|
||||
ldr r12, =KObjectMutex__ErrorOccured
|
||||
ldr r12, [r12]
|
||||
blx r12
|
||||
bx lr
|
||||
|
||||
.global safecpy
|
||||
.type safecpy, %function
|
||||
safecpy:
|
||||
push {r4, lr}
|
||||
mov r3, #0
|
||||
movs r12, #1
|
||||
|
||||
_safecpy_loop:
|
||||
ldrb r4, [r1, r3]
|
||||
cmp r12, #0
|
||||
beq _safecpy_loop_end
|
||||
strb r4, [r0, r3]
|
||||
add r3, #1
|
||||
cmp r3, r2
|
||||
blo _safecpy_loop
|
||||
|
||||
_safecpy_loop_end:
|
||||
mov r0, r3
|
||||
pop {r4, pc}
|
||||
|
||||
_safecpy_end:
|
||||
|
||||
.section .rodata
|
||||
|
||||
.global safecpy_sz
|
||||
safecpy_sz: .word _safecpy_end - safecpy
|
||||
|
||||
.bss
|
||||
.balign 4
|
||||
|
||||
.global SGI0Handler
|
||||
SGI0Handler: .word 0 @ see synchronization.c
|
||||
|
||||
.balign 4
|
||||
|
||||
.section .data
|
||||
.balign 4
|
||||
|
||||
_customInterruptEventObj: .word SGI0Handler
|
||||
.global customInterruptEvent
|
||||
customInterruptEvent: .word _customInterruptEventObj
|
||||
Reference in New Issue
Block a user