ARM => Arm

This commit is contained in:
TuxSH 2020-04-25 13:17:23 +01:00
parent 4a655384e2
commit 58f3edda12
20 changed files with 76 additions and 76 deletions

View File

@ -70,11 +70,11 @@ Show NAND or user string in System Settings: ( )
Show GBA boot screen in patched AGB_FIRM: ( ) Show GBA boot screen in patched AGB_FIRM: ( )
Patch ARM9 access: ( ) Patch Arm9 access: ( )
Set developer UNITINFO: ( ) Set developer UNITINFO: ( )
Disable ARM11 exception handlers: ( ) Disable Arm11 exception handlers: ( )
-- --
@ -94,6 +94,6 @@ Disable ARM11 exception handlers: ( )
**Dump file:** **Dump file:**
<!--If the issue leads to a crash you must uncheck the "Disable ARM11 exception handlers" option. <!--If the issue leads to a crash you must uncheck the "Disable Arm11 exception handlers" option.
-- The error message will tell you where the dump is. -- The error message will tell you where the dump is.
-- Zip the dmp file and drag & drop it below.--> -- Zip the dmp file and drag & drop it below.-->

View File

@ -71,7 +71,7 @@ start:
.global prepareForFirmlaunch .global prepareForFirmlaunch
.type prepareForFirmlaunch, %function .type prepareForFirmlaunch, %function
prepareForFirmlaunch: prepareForFirmlaunch:
str r0, [r1] @ tell ARM9 we're done str r0, [r1] @ tell Arm9 we're done
mov r0, #0x20000000 mov r0, #0x20000000
_wait_for_core0_entrypoint_loop: _wait_for_core0_entrypoint_loop:

View File

@ -33,7 +33,7 @@
The data cache and/or the instruction cache MUST be flushed before doing one of the following: The data cache and/or the instruction cache MUST be flushed before doing one of the following:
- rebooting - rebooting
- powering down - powering down
- setting the ARM11 entrypoint to execute a function - setting the Arm11 entrypoint to execute a function
- jumping to a payload - jumping to a payload
***/ ***/

View File

@ -31,7 +31,7 @@
flushEntireDCache: flushEntireDCache:
@ Adapted from http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0155a/ch03s03s05.html, @ Adapted from http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0155a/ch03s03s05.html,
@ and https://github.com/gemarcano/libctr9_io/blob/master/src/ctr_system_ARM.c#L39 as well @ and https://github.com/gemarcano/libctr9_io/blob/master/src/ctr_system_ARM.c#L39 as well
@ Note: ARM's example is actually for a 8KB DCache (which is what the 3DS has) @ Note: Arm's example is actually for a 8KB DCache (which is what the 3DS has)
@ Implemented in bootROM at address 0xffff0830 @ Implemented in bootROM at address 0xffff0830
mov r1, #0 @ segment counter mov r1, #0 @ segment counter

View File

@ -94,7 +94,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
"( ) Show NAND or user string in System Settings", "( ) Show NAND or user string in System Settings",
"( ) Show GBA boot screen in patched AGB_FIRM", "( ) Show GBA boot screen in patched AGB_FIRM",
"( ) Set developer UNITINFO", "( ) Set developer UNITINFO",
"( ) Disable ARM11 exception handlers", "( ) Disable Arm11 exception handlers",
}; };
static const char *optionsDescription[] = { "Select the default EmuNAND.\n\n" static const char *optionsDescription[] = { "Select the default EmuNAND.\n\n"
@ -189,7 +189,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
"are doing!", "are doing!",
"Disables the fatal error exception\n" "Disables the fatal error exception\n"
"handlers for the ARM11 CPU.\n\n" "handlers for the Arm11 CPU.\n\n"
"Note: Disabling the exception handlers\n" "Note: Disabling the exception handlers\n"
"will disqualify you from submitting\n" "will disqualify you from submitting\n"
"issues or bug reports to the Luma3DS\n" "issues or bug reports to the Luma3DS\n"

View File

@ -599,11 +599,11 @@ void kernel9Loader(Arm9Bin *arm9Section)
__attribute__((aligned(4))) u8 arm9BinCtr[AES_BLOCK_SIZE]; __attribute__((aligned(4))) u8 arm9BinCtr[AES_BLOCK_SIZE];
memcpy(arm9BinCtr, arm9Section->ctr, sizeof(arm9BinCtr)); memcpy(arm9BinCtr, arm9Section->ctr, sizeof(arm9BinCtr));
//Decrypt ARM9 binary //Decrypt Arm9 binary
aes_use_keyslot(arm9BinSlot); aes_use_keyslot(arm9BinSlot);
aes(startOfArm9Bin, startOfArm9Bin, arm9SectionSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); aes(startOfArm9Bin, startOfArm9Bin, arm9SectionSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary."); if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the Arm9 binary.");
} }
void computePinHash(u8 *outbuf, const u8 *inbuf) void computePinHash(u8 *outbuf, const u8 *inbuf)
@ -612,7 +612,7 @@ void computePinHash(u8 *outbuf, const u8 *inbuf)
cipherText[AES_BLOCK_SIZE]; cipherText[AES_BLOCK_SIZE];
sdmmc_get_cid(1, (u32 *)cid); sdmmc_get_cid(1, (u32 *)cid);
aes_use_keyslot(0x04); //Console-unique keyslot whose keys are set by the ARM9 bootROM aes_use_keyslot(0x04); //Console-unique keyslot whose keys are set by the Arm9 bootROM
aes(cipherText, inbuf, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); aes(cipherText, inbuf, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
sha(outbuf, cipherText, sizeof(cipherText), SHA_256_MODE); sha(outbuf, cipherText, sizeof(cipherText), SHA_256_MODE);
} }

View File

@ -85,8 +85,8 @@ void detectAndProcessExceptionDumps(void)
drawString(true, 10, 10, COLOR_RED, "An exception occurred"); drawString(true, 10, 10, COLOR_RED, "An exception occurred");
u32 posY; u32 posY;
if(dumpHeader->processor == 11) posY = drawFormattedString(true, 10, 30, COLOR_WHITE, "Processor: ARM11 (core %u)", dumpHeader->core); if(dumpHeader->processor == 11) posY = drawFormattedString(true, 10, 30, COLOR_WHITE, "Processor: Arm11 (core %u)", dumpHeader->core);
else posY = drawString(true, 10, 30, COLOR_WHITE, "Processor: ARM9"); else posY = drawString(true, 10, 30, COLOR_WHITE, "Processor: Arm9");
if(dumpHeader->type == 2) if(dumpHeader->type == 2)
{ {

View File

@ -58,7 +58,7 @@ static __attribute__((noinline)) bool inRange(u32 as, u32 ae, u32 bs, u32 be)
static bool checkFirm(u32 firmSize) static bool checkFirm(u32 firmSize)
{ {
if(memcmp(firm->magic, "FIRM", 4) != 0 || firm->arm9Entry == NULL) //Allow for the ARM11 entrypoint to be zero in which case nothing is done on the ARM11 side if(memcmp(firm->magic, "FIRM", 4) != 0 || firm->arm9Entry == NULL) //Allow for the Arm11 entrypoint to be zero in which case nothing is done on the Arm11 side
return false; return false;
bool arm9EpFound = false, bool arm9EpFound = false,
@ -184,7 +184,7 @@ u32 loadNintendoFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadF
else if(ctrNandError) error("Unable to mount CTRNAND or load the CTRNAND FIRM.\nPlease use an external one."); else if(ctrNandError) error("Unable to mount CTRNAND or load the CTRNAND FIRM.\nPlease use an external one.");
} }
//Check that the FIRM is right for the console from the ARM9 section address //Check that the FIRM is right for the console from the Arm9 section address
if((firm->section[3].offset != 0 ? firm->section[3].address : firm->section[2].address) != (ISN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800)) if((firm->section[3].offset != 0 ? firm->section[3].address : firm->section[2].address) != (ISN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))
error("The %s FIRM is not for this console.", loadedFromStorage ? "external" : "CTRNAND"); error("The %s FIRM is not for this console.", loadedFromStorage ? "external" : "CTRNAND");
@ -350,7 +350,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora
if(ISN3DS) if(ISN3DS)
{ {
//Decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader //Decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
kernel9Loader((Arm9Bin *)arm9Section); kernel9Loader((Arm9Bin *)arm9Section);
firm->arm9Entry = (u8 *)0x801B01C; firm->arm9Entry = (u8 *)0x801B01C;
} }
@ -409,7 +409,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora
if(!ISDEVUNIT) ret += patchCheckForDevCommonKey(process9Offset, process9Size); if(!ISDEVUNIT) ret += patchCheckForDevCommonKey(process9Offset, process9Size);
} }
//ARM9 exception handlers //Arm9 exception handlers
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size); ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address); ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
ret += patchKernel9Panic(arm9Section, kernel9Size); ret += patchKernel9Panic(arm9Section, kernel9Size);
@ -426,7 +426,7 @@ u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch)
{ {
u8 *arm9Section = (u8 *)firm + firm->section[3].offset; u8 *arm9Section = (u8 *)firm + firm->section[3].offset;
//On N3DS, decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader //On N3DS, decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
if(ISN3DS) if(ISN3DS)
{ {
kernel9Loader((Arm9Bin *)arm9Section); kernel9Loader((Arm9Bin *)arm9Section);
@ -465,7 +465,7 @@ u32 patchAgbFirm(bool loadFromStorage, bool doUnitinfoPatch)
{ {
u8 *arm9Section = (u8 *)firm + firm->section[3].offset; u8 *arm9Section = (u8 *)firm + firm->section[3].offset;
//On N3DS, decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader //On N3DS, decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
if(ISN3DS) if(ISN3DS)
{ {
kernel9Loader((Arm9Bin *)arm9Section); kernel9Loader((Arm9Bin *)arm9Section);
@ -501,7 +501,7 @@ u32 patch1x2xNativeAndSafeFirm(void)
if(ISN3DS) if(ISN3DS)
{ {
//Decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader //Decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
kernel9Loader((Arm9Bin *)arm9Section); kernel9Loader((Arm9Bin *)arm9Section);
firm->arm9Entry = (u8 *)0x801B01C; firm->arm9Entry = (u8 *)0x801B01C;
} }
@ -518,7 +518,7 @@ u32 patch1x2xNativeAndSafeFirm(void)
ret += ISN3DS ? patchSignatureChecks(process9Offset, process9Size) : patchOldSignatureChecks(process9Offset, process9Size); ret += ISN3DS ? patchSignatureChecks(process9Offset, process9Size) : patchOldSignatureChecks(process9Offset, process9Size);
//ARM9 exception handlers //Arm9 exception handlers
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size); ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address); ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);

View File

@ -79,8 +79,8 @@ u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 *
return arm11SvcTable; return arm11SvcTable;
} }
// For ARM prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases) // For Arm prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases)
static inline u32 computeARMFrameSize(const u32 *prolog) static inline u32 computeArmFrameSize(const u32 *prolog)
{ {
const u32 *off; const u32 *off;
@ -230,7 +230,7 @@ u32 patchKernel11(u8 *pos, u32 size, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm
*/ */
for(off = (u32 *)ControlMemoryPos; (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++); for(off = (u32 *)ControlMemoryPos; (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++);
off -= 2; off -= 2;
*off = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeARMFrameSize((u32 *)ControlMemoryPos)); // ldr r0, [sp, #(frameSize + 8)] *off = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeArmFrameSize((u32 *)ControlMemoryPos)); // ldr r0, [sp, #(frameSize + 8)]
//Patch DebugActiveProcess //Patch DebugActiveProcess
for(off = (u32 *)(pos + (arm11SvcTable[0x60] - baseK11VA)); *off != 0xE3110001; off++); for(off = (u32 *)(pos + (arm11SvcTable[0x60] - baseK11VA)); *off != 0xE3110001; off++);
@ -312,7 +312,7 @@ u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
off -= 0x13; off -= 0x13;
//Firmlaunch function offset - offset in BLX opcode (A4-16 - ARM DDI 0100E) + 1 //Firmlaunch function offset - offset in BLX opcode (A4-16 - Arm DDI 0100E) + 1
u32 fOpenOffset = (u32)(off + 9 - (-((*(u32 *)off & 0x00FFFFFF) << 2) & (0xFFFFFF << 2)) - pos + process9MemAddr); u32 fOpenOffset = (u32)(off + 9 - (-((*(u32 *)off & 0x00FFFFFF) << 2) & (0xFFFFFF << 2)) - pos + process9MemAddr);
//Put the fOpen offset in the right location //Put the fOpen offset in the right location

View File

@ -77,7 +77,7 @@ _start:
ldr r1, =0xFFF0001B @ fff00000 16k | dtcm ldr r1, =0xFFF0001B @ fff00000 16k | dtcm
ldr r2, =0x01FF801D @ 01ff8000 32k | itcm ldr r2, =0x01FF801D @ 01ff8000 32k | itcm
ldr r3, =0x08000027 @ 08000000 1M | arm9 mem ldr r3, =0x08000027 @ 08000000 1M | arm9 mem
ldr r4, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB) ldr r4, =0x10000029 @ 10000000 2M | io mem (Arm9 / first 2MB)
ldr r5, =0x20000035 @ 20000000 128M | fcram ldr r5, =0x20000035 @ 20000000 128M | fcram
ldr r6, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram ldr r6, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram
ldr r7, =0x1800002D @ 18000000 8M | vram (+ 2MB) ldr r7, =0x1800002D @ 18000000 8M | vram (+ 2MB)
@ -153,11 +153,11 @@ disableMpuAndJumpToEntrypoints:
bic r0, #(1<<0) @ - MPU disable bic r0, #(1<<0) @ - MPU disable
mcr p15, 0, r0, c1, c0, 0 @ write control register mcr p15, 0, r0, c1, c0, 0 @ write control register
@ Set the ARM11 entrypoint @ Set the Arm11 entrypoint
mov r0, #0x20000000 mov r0, #0x20000000
str r7, [r0, #-4] str r7, [r0, #-4]
@ Jump to the ARM9 entrypoint @ Jump to the Arm9 entrypoint
mov r0, r4 mov r0, r4
mov r1, r5 mov r1, r5
ldr r2, =0x3BEEF ldr r2, =0x3BEEF

View File

@ -121,8 +121,8 @@ def main(args=None):
addtionalDataOffset = stackOffset + stackDumpSize addtionalDataOffset = stackOffset + stackDumpSize
additionalData = data[addtionalDataOffset : addtionalDataOffset + additionalDataSize] additionalData = data[addtionalDataOffset : addtionalDataOffset + additionalDataSize]
if processor == 9: print("Processor: ARM9") if processor == 9: print("Processor: Arm9")
else: print("Processor: ARM11 (core {0})".format(processor >> 16)) else: print("Processor: Arm11 (core {0})".format(processor >> 16))
typeDetailsStr = "" typeDetailsStr = ""
if exceptionType == 2: if exceptionType == 2:

View File

@ -33,7 +33,7 @@
#define PA_PTR(addr) (void *)((u32)(addr) | 1u << 31) #define PA_PTR(addr) (void *)((u32)(addr) | 1u << 31)
#define PA_FROM_VA_PTR(addr) PA_PTR(convertVAToPA(addr, false)) #define PA_FROM_VA_PTR(addr) PA_PTR(convertVAToPA(addr, false))
static inline u32 makeARMBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy static inline u32 makeArmBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
{ {
u32 instrBase = link ? 0xEB000000 : 0xEA000000; u32 instrBase = link ? 0xEB000000 : 0xEA000000;
u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed
@ -41,7 +41,7 @@ static inline u32 makeARMBranch(const void *src, const void *dst, bool link) //
return instrBase | ((off >> 2) & 0xFFFFFF); return instrBase | ((off >> 2) & 0xFFFFFF);
} }
static inline void *decodeARMBranch(const void *src) static inline void *decodeArmBranch(const void *src)
{ {
u32 instr = *(const u32 *)src; u32 instr = *(const u32 *)src;
s32 off = (instr & 0xFFFFFF) << 2; s32 off = (instr & 0xFFFFFF) << 2;
@ -50,8 +50,8 @@ static inline void *decodeARMBranch(const void *src)
return (void *)((const u8 *)src + 8 + off); return (void *)((const u8 *)src + 8 + off);
} }
// For ARM prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases) // For Arm prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases)
static inline u32 computeARMFrameSize(const u32 *prolog) static inline u32 computeArmFrameSize(const u32 *prolog)
{ {
const u32 *off; const u32 *off;

View File

@ -108,67 +108,67 @@ static void findUsefulSymbols(void)
for(; *off != 0xE3A0A0C2; off++); for(; *off != 0xE3A0A0C2; off++);
mcuReboot = (void (*) (void))--off; mcuReboot = (void (*) (void))--off;
coreBarrier = (void (*) (void))decodeARMBranch(off - 4); coreBarrier = (void (*) (void))decodeArmBranch(off - 4);
for(off = (u32 *)originalHandlers[2]; *off != 0xE1A00009; off++); for(off = (u32 *)originalHandlers[2]; *off != 0xE1A00009; off++);
svcFallbackHandler = (void (*)(u8))decodeARMBranch(off + 1); svcFallbackHandler = (void (*)(u8))decodeArmBranch(off + 1);
for(; *off != 0xE92D000F; off++); for(; *off != 0xE92D000F; off++);
officialPostProcessSvc = (void (*)(void))decodeARMBranch(off + 1); officialPostProcessSvc = (void (*)(void))decodeArmBranch(off + 1);
KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]); KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeArmBranch(5 + (u32 *)officialSVCs[0x76]);
for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE1A00004; off++); for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE1A00004; off++);
KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off + 1); KAutoObject__AddReference = (void (*)(KAutoObject *))decodeArmBranch(off + 1);
for(; *off != 0xE320F000; off++); for(; *off != 0xE320F000; off++);
KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 1); KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeArmBranch(off + 1);
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++); for(off = (u32 *)decodeArmBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++);
off -= 2; off -= 2;
criticalSectionLock = (KRecursiveLock *)off[2 + (off[0] & 0xFF) / 4]; criticalSectionLock = (KRecursiveLock *)off[2 + (off[0] & 0xFF) / 4];
KRecursiveLock__Lock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1); KRecursiveLock__Lock = (void (*)(KRecursiveLock *))decodeArmBranch(off + 1);
off += 4; off += 4;
for(; (*off >> 16) != 0xE59F; off++); for(; (*off >> 16) != 0xE59F; off++);
KRecursiveLock__Unlock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1); KRecursiveLock__Unlock = (void (*)(KRecursiveLock *))decodeArmBranch(off + 1);
for(; *off != 0xE5C4007D; off++); for(; *off != 0xE5C4007D; off++);
KSynchronizationObject__Signal = (void (*)(KSynchronizationObject *, bool))decodeARMBranch(off + 3); KSynchronizationObject__Signal = (void (*)(KSynchronizationObject *, bool))decodeArmBranch(off + 3);
for(off = (u32 *)officialSVCs[0x19]; *off != 0xE1A04005; off++); for(off = (u32 *)officialSVCs[0x19]; *off != 0xE1A04005; off++);
KEvent__Clear = (Result (*)(KEvent *))decodeARMBranch(off + 1); KEvent__Clear = (Result (*)(KEvent *))decodeArmBranch(off + 1);
for(off = (u32 *)KEvent__Clear; *off != 0xE8BD8070; off++); for(off = (u32 *)KEvent__Clear; *off != 0xE8BD8070; off++);
synchronizationMutex = *(KObjectMutex **)(off + 1); synchronizationMutex = *(KObjectMutex **)(off + 1);
for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++); for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++);
WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeARMBranch(off + 6); WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeArmBranch(off + 6);
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE1A05000; off++); for(off = (u32 *)decodeArmBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE1A05000; off++);
KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off - 1); KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeArmBranch(off - 1);
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++); for(off = (u32 *)decodeArmBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++);
threadList = *(KObjectList **)(off + 1); threadList = *(KObjectList **)(off + 1);
off = (u32 *)decodeARMBranch((u32 *)officialSVCs[0x37] + 3) + 5; /* GetThreadId */ off = (u32 *)decodeArmBranch((u32 *)officialSVCs[0x37] + 3) + 5; /* GetThreadId */
KProcessHandleTable__ToKThread = (KThread * (*)(KProcessHandleTable *, Handle))decodeARMBranch((*off >> 16) == 0xEB00 ? off : off + 2); KProcessHandleTable__ToKThread = (KThread * (*)(KProcessHandleTable *, Handle))decodeArmBranch((*off >> 16) == 0xEB00 ? off : off + 2);
for(off = (u32 *)officialSVCs[0x50]; off[0] != 0xE1A05000 || off[1] != 0xE2100102 || off[2] != 0x5A00000B; off++); for(off = (u32 *)officialSVCs[0x50]; off[0] != 0xE1A05000 || off[1] != 0xE2100102 || off[2] != 0x5A00000B; off++);
InterruptManager__MapInterrupt = (Result (*)(InterruptManager *, KBaseInterruptEvent *, u32, u32, u32, bool, bool))decodeARMBranch(--off); InterruptManager__MapInterrupt = (Result (*)(InterruptManager *, KBaseInterruptEvent *, u32, u32, u32, bool, bool))decodeArmBranch(--off);
interruptManager = *(InterruptManager **)(off - 4 + (off[-6] & 0xFFF) / 4); interruptManager = *(InterruptManager **)(off - 4 + (off[-6] & 0xFFF) / 4);
for(off = (u32 *)officialSVCs[0x54]; *off != 0xE8BD8008; off++); for(off = (u32 *)officialSVCs[0x54]; *off != 0xE8BD8008; off++);
flushDataCacheRange = (void (*)(void *, u32))(*(u32 **)(off[1]) + 3); flushDataCacheRange = (void (*)(void *, u32))(*(u32 **)(off[1]) + 3);
for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++); for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++);
KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1); KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeArmBranch(off - 1);
// From 4.x to 6.x the pattern will match but the result will be wrong // From 4.x to 6.x the pattern will match but the result will be wrong
for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++); for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++);
KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1); KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeArmBranch(off - 1);
for(off = (u32 *)officialSVCs[0x7C]; *off != 0x03530000; off++); for(off = (u32 *)officialSVCs[0x7C]; *off != 0x03530000; off++);
KObjectMutex__WaitAndAcquire = (void (*)(KObjectMutex *))decodeARMBranch(++off); KObjectMutex__WaitAndAcquire = (void (*)(KObjectMutex *))decodeArmBranch(++off);
for(; *off != 0xE320F000; off++); for(; *off != 0xE320F000; off++);
KObjectMutex__ErrorOccured = (void (*)(void))decodeARMBranch(off + 1); KObjectMutex__ErrorOccured = (void (*)(void))decodeArmBranch(off + 1);
for(off = (u32 *)originalHandlers[4]; *off != (u32)exceptionStackTop; off++); for(off = (u32 *)originalHandlers[4]; *off != (u32)exceptionStackTop; off++);
kernelUsrCopyFuncsStart = (void *)off[1]; kernelUsrCopyFuncsStart = (void *)off[1];
@ -208,26 +208,26 @@ static void findUsefulSymbols(void)
// The official prototype of ControlMemory doesn't have that extra param' // The official prototype of ControlMemory doesn't have that extra param'
ControlMemory = (Result (*)(u32 *, u32, u32, u32, MemOp, MemPerm, bool)) ControlMemory = (Result (*)(u32 *, u32, u32, u32, MemOp, MemPerm, bool))
decodeARMBranch((u32 *)officialSVCs[0x01] + 5); decodeArmBranch((u32 *)officialSVCs[0x01] + 5);
SleepThread = (void (*)(s64))officialSVCs[0x0A]; SleepThread = (void (*)(s64))officialSVCs[0x0A];
CloseHandle = (Result (*)(Handle))officialSVCs[0x23]; CloseHandle = (Result (*)(Handle))officialSVCs[0x23];
GetHandleInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x29] + 3); GetHandleInfo = (Result (*)(s64 *, Handle, u32))decodeArmBranch((u32 *)officialSVCs[0x29] + 3);
GetSystemInfo = (Result (*)(s64 *, s32, s32))decodeARMBranch((u32 *)officialSVCs[0x2A] + 3); GetSystemInfo = (Result (*)(s64 *, s32, s32))decodeArmBranch((u32 *)officialSVCs[0x2A] + 3);
GetProcessInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2B] + 3); GetProcessInfo = (Result (*)(s64 *, Handle, u32))decodeArmBranch((u32 *)officialSVCs[0x2B] + 3);
GetThreadInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2C] + 3); GetThreadInfo = (Result (*)(s64 *, Handle, u32))decodeArmBranch((u32 *)officialSVCs[0x2C] + 3);
ConnectToPort = (Result (*)(Handle *, const char*))decodeARMBranch((u32 *)officialSVCs[0x2D] + 3); ConnectToPort = (Result (*)(Handle *, const char*))decodeArmBranch((u32 *)officialSVCs[0x2D] + 3);
SendSyncRequest = (Result (*)(Handle))officialSVCs[0x32]; SendSyncRequest = (Result (*)(Handle))officialSVCs[0x32];
OpenProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x33] + 3); OpenProcess = (Result (*)(Handle *, u32))decodeArmBranch((u32 *)officialSVCs[0x33] + 3);
GetProcessId = (Result (*)(u32 *, Handle))decodeARMBranch((u32 *)officialSVCs[0x35] + 3); GetProcessId = (Result (*)(u32 *, Handle))decodeArmBranch((u32 *)officialSVCs[0x35] + 3);
DebugActiveProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x60] + 3); DebugActiveProcess = (Result (*)(Handle *, u32))decodeArmBranch((u32 *)officialSVCs[0x60] + 3);
UnmapProcessMemory = (Result (*)(Handle, void *, u32))officialSVCs[0x72]; UnmapProcessMemory = (Result (*)(Handle, void *, u32))officialSVCs[0x72];
KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1); KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1);
for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++); for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++);
kernelpanic = (void (*)(void))decodeARMBranch(off + 1); kernelpanic = (void (*)(void))decodeArmBranch(off + 1);
for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++); for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++);
SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeARMBranch(off + 2); SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeArmBranch(off + 2);
for(; *off != 0x96007F9; off++); for(; *off != 0x96007F9; off++);
isDevUnit = *(bool **)(off - 1); isDevUnit = *(bool **)(off - 1);

View File

@ -1,5 +1,5 @@
# 3ds_pm # 3ds_pm
Open source replacement of the ARM11 PM system module. Open source replacement of the Arm11 PM system module.
This is licensed under the MIT license. This is licensed under the MIT license.
# Usage # Usage

View File

@ -1,5 +1,5 @@
# 3ds_pxi # 3ds_pxi
Open source replacement of the ARM11 PXI system module. Open source replacement of the Arm11 PXI system module.
This is licensed under the MIT license. This is licensed under the MIT license.
# Usage # Usage

View File

@ -39,7 +39,7 @@
#define REG32(addr) (*(vu32 *)(PA_PTR(addr))) #define REG32(addr) (*(vu32 *)(PA_PTR(addr)))
static inline u32 makeARMBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy static inline u32 makeArmBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
{ {
u32 instrBase = link ? 0xEB000000 : 0xEA000000; u32 instrBase = link ? 0xEB000000 : 0xEA000000;
u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed
@ -47,7 +47,7 @@ static inline u32 makeARMBranch(const void *src, const void *dst, bool link) //
return instrBase | ((off >> 2) & 0xFFFFFF); return instrBase | ((off >> 2) & 0xFFFFFF);
} }
static inline void *decodeARMBranch(const void *src) static inline void *decodeArmBranch(const void *src)
{ {
u32 instr = *(const u32 *)src; u32 instr = *(const u32 *)src;
s32 off = (instr & 0xFFFFFF) << 2; s32 off = (instr & 0xFFFFFF) << 2;

View File

@ -12,7 +12,7 @@
#include <errno.h> #include <errno.h>
/* /*
There are only 2 Watchpoint Register Pairs on MPCORE ARM11 CPUs, There are only 2 Watchpoint Register Pairs on MPCORE Arm11 CPUs,
and only 2 Breakpoint Register Pairs with context ID capabilities (BRP4-5) as well. and only 2 Breakpoint Register Pairs with context ID capabilities (BRP4-5) as well.
We'll reserve and use all 4 of them We'll reserve and use all 4 of them

View File

@ -26,7 +26,7 @@
#include <3ds.h> #include <3ds.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "utils.h" // for makeARMBranch #include "utils.h" // for makeArmBranch
#include "minisoc.h" #include "minisoc.h"
#include "input_redirection.h" #include "input_redirection.h"
#include "menus.h" #include "menus.h"
@ -315,7 +315,7 @@ Result InputRedirection_DoOrUndoPatches(void)
return -6; return -6;
} }
*(void **)(irCodePhys + 8) = decodeARMBranch(off + 4); *(void **)(irCodePhys + 8) = decodeArmBranch(off + 4);
*(void **)(irCodePhys + 12) = (void*)irDataPhys; *(void **)(irCodePhys + 12) = (void*)irDataPhys;
irHookLoc = off; irHookLoc = off;

View File

@ -32,7 +32,7 @@
#include "draw.h" #include "draw.h"
#include "hbloader.h" #include "hbloader.h"
#include "fmt.h" #include "fmt.h"
#include "utils.h" // for makeARMBranch #include "utils.h" // for makeArmBranch
#include "minisoc.h" #include "minisoc.h"
#include "ifile.h" #include "ifile.h"
#include "pmdbgext.h" #include "pmdbgext.h"

View File

@ -1,5 +1,5 @@
# 3ds_sm # 3ds_sm
Open source replacement of the ARM11 SM system module. Open source replacement of the Arm11 SM system module.
This is licensed under the MIT license. This is licensed under the MIT license.
# Usage # Usage