Patch legacy k11 to allow exception dispatching

This commit is contained in:
TuxSH 2023-09-16 19:45:06 +02:00
parent c0e0f02443
commit 6a2e1d4aa3
3 changed files with 22 additions and 3 deletions

View File

@ -597,6 +597,8 @@ u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch)
{ {
u8 *section1 = (u8 *)firm + firm->section[1].offset; u8 *section1 = (u8 *)firm + firm->section[1].offset;
u32 section1Size = firm->section[1].size; u32 section1Size = firm->section[1].size;
u8 *section2 = (u8 *)firm + firm->section[2].offset;
u32 section2Size = firm->section[2].size;
u8 *arm9Section = (u8 *)firm + firm->section[3].offset; u8 *arm9Section = (u8 *)firm + firm->section[3].offset;
@ -630,7 +632,7 @@ u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch)
//Apply UNITINFO patch //Apply UNITINFO patch
if(doUnitinfoPatch) ret += patchUnitInfoValueSet(arm9Section, kernel9Size); if(doUnitinfoPatch) ret += patchUnitInfoValueSet(arm9Section, kernel9Size);
ret += patchLgyK11(section1, section1Size); ret += patchLgyK11(section1, section1Size, section2, section2Size);
// Also patch TwlBg here // Also patch TwlBg here
mergeSection0(TWL_FIRM, 0, loadFromStorage); mergeSection0(TWL_FIRM, 0, loadFromStorage);

View File

@ -810,7 +810,7 @@ void patchTwlBg(u8 *pos, u32 size)
} }
} }
u32 patchLgyK11(u8 *section1, u32 section1Size) u32 patchLgyK11(u8 *section1, u32 section1Size, u8 *section2, u32 section2Size)
{ {
u32 *off; u32 *off;
@ -826,5 +826,22 @@ u32 patchLgyK11(u8 *section1, u32 section1Size)
*off &= ~0x231; // clear APX mask and XN *off &= ~0x231; // clear APX mask and XN
*off |= 0x030; // re-set APX (to user/kernel RW) *off |= 0x030; // re-set APX (to user/kernel RW)
// Patch two pointer-to-bool to point to a non-zero byte, enabling user exception handling.
// It is impossible to enable it by normal means, otherwise
for (off = (u32 *)section2; (u8 *)off <= section2 + section2Size && *off != 0x100021F; off++);
if ((u8 *)off >= section2 + section2Size)
return 1;
off[1] = 0xFFFF0F00;
off[2] = 0xFFFF0F04;
// Dispatch-to-user code checks for memory block type and permissions (etc.), but
// LGY K11 doesn't do any memory management, so these checks will always fail.
// Patch with b +0x38 to skip all those checks
u16 *off2;
for (off2 = (u16 *)section2; (u8 *)off2 <= section2 + section2Size && (off2[0] != 0xDB1F || off2[1] != 0x4915); off2++);
if ((u8 *)off2 >= section2 + section2Size)
return 1;
*off2 = 0xE01A;
return 0; return 0;
} }

View File

@ -67,4 +67,4 @@ u32 patchOldTwlFlashcartChecks(u8 *pos, u32 size);
u32 patchTwlShaHashChecks(u8 *pos, u32 size); u32 patchTwlShaHashChecks(u8 *pos, u32 size);
u32 patchAgbBootSplash(u8 *pos, u32 size); u32 patchAgbBootSplash(u8 *pos, u32 size);
void patchTwlBg(u8 *pos, u32 size); // silently fails void patchTwlBg(u8 *pos, u32 size); // silently fails
u32 patchLgyK11(u8 *section1, u32 section1Size); u32 patchLgyK11(u8 *section1, u32 section1Size, u8 *section2, u32 section2Size);