Skip to content

Commit

Permalink
fix emunand patches on certain old TWL_FIRM versions
Browse files Browse the repository at this point in the history
- port the emunand patch to thumb and remove unnecessary register restores so it fits in the kernel9 free space of 3.x TWL_FIRMs
- account for possibly unaligned code in patchNandRw
  • Loading branch information
aspargas2 committed Dec 4, 2021
1 parent ff3f3c8 commit e5fb94d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 21 deletions.
6 changes: 3 additions & 3 deletions arm9/source/emunand.c
Expand Up @@ -169,13 +169,13 @@ static inline u32 patchNandRw(u8 *pos, u32 size, u32 branchOffset)
//Look for read/write code
static const u8 pattern[] = {0x1E, 0x00, 0xC8, 0x05};

u16 *readOffset = (u16 *)memsearch(pos, pattern, size, sizeof(pattern));
u16 *readOffset = (u16 *)((u32)memsearch(pos, pattern, size, sizeof(pattern)) | 2);

if(readOffset == NULL) return 1;

readOffset -= 3;

u16 *writeOffset = (u16 *)memsearch((u8 *)(readOffset + 5), pattern, 0x100, sizeof(pattern));
u16 *writeOffset = (u16 *)((u32)memsearch((u8 *)(readOffset + 5), pattern, 0x100, sizeof(pattern)) | 2);

if(writeOffset == NULL) return 1;

Expand Down Expand Up @@ -223,7 +223,7 @@ u32 patchEmuNand(u8 *arm9Section, u32 kernel9Size, u8 *process9Offset, u32 proce
memcpy(freeK9Space, emunandPatch, emunandPatchSize);

//Add EmuNAND hooks
u32 branchOffset = (u32)(freeK9Space - arm9Section + kernel9Address);
u32 branchOffset = (u32)(freeK9Space - arm9Section + kernel9Address) | 1;
ret += patchNandRw(process9Offset, process9Size, branchOffset);

//Set MPU
Expand Down
39 changes: 21 additions & 18 deletions arm9/source/large_patches.s
@@ -1,5 +1,5 @@
.section .large_patch.emunand, "aw", %progbits
.arm
.thumb
.align 4

@ Code originally by Normmatt
Expand All @@ -14,40 +14,43 @@ emunandPatch:
@ End

@ If we're already trying to access the SD, return
ldr r2, [r0, #4]
ldr r1, emunandPatchSdmmcStructPtr
cmp r2, r1
ldr r2, [r4, #4]
ldr r0, emunandPatchSdmmcStructPtr
cmp r2, r0
beq out

str r1, [r0, #4] @ Set object to be SD
ldr r2, [r0, #8] @ Get sector to read
cmp r2, #0 @ For GW compatibility, see if we're trying to read the ncsd header (sector 0)
ldr r2, [r4, #8] @ Get sector to read
str r0, [r4, #4] @ Set object to be SD

ldr r3, emunandPatchNandOffset
add r2, r3 @ Add the offset to the NAND in the SD

ldreq r3, emunandPatchNcsdHeaderOffset
addeq r2, r3 @ If we're reading the ncsd header, add the offset of that sector
cmp r2, r3 @ For GW compatibility, see if we're trying to read the ncsd header (sector 0)
bne skip_add

str r2, [r0, #8] @ Store sector to read
ldr r3, emunandPatchNcsdHeaderOffset
add r2, r3 @ If we're reading the ncsd header, add the offset of that sector

out:
@ Restore registers.
mov r1, r5
mov r2, r7
mov r3, r6
skip_add:
str r2, [r4, #8] @ Store sector to read

out:
@ Return 4 bytes behind where we got called,
@ due to the offset of this function being stored there
mov r0, lr
add r0, #4
bx r0
mov r2, lr
add r2, #4

@ More original code that might have been skipped depending on alignment;
@ needs to be done at the end so CSPR is preserved
lsl r0, r1, #0x17
bx r2

.pool

.global emunandPatchSdmmcStructPtr
.global emunandPatchNandOffset
.global emunandPatchNcsdHeaderOffset
.balign 4

emunandPatchSdmmcStructPtr: .word 0 @ Pointer to sdmmc struct
emunandPatchNandOffset: .word 0 @ For rednand this should be 1
Expand Down

0 comments on commit e5fb94d

Please sign in to comment.