External .code section loading for titles and some refactoring

This commit is contained in:
TuxSH 2016-06-05 20:43:49 +02:00
parent ae1033d975
commit f78dd5365c
5 changed files with 77 additions and 45 deletions

View File

@ -125,21 +125,50 @@ static u32 loadConfig(void)
return config; return config;
} }
static void progIdToStr(char *strEnd, u64 progId)
{
while(progId)
{
static const char hexDigits[] = "0123456789ABCDEF";
*strEnd-- = hexDigits[(u32)(progId & 0xF)];
progId >>= 4;
}
}
static int loadTitleCodeSection(u64 progId, u8 *code, u32 size)
{
/* Here we look for "/luma/code_sections/[u64 titleID in hex, uppercase].bin"
If it exists it should be a decompressed binary code file */
char path[] = "/luma/code_sections/0000000000000000.bin";
progIdToStr(path + 35, progId);
IFile file;
Result ret = fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ);
if(R_SUCCEEDED(ret))
{
u64 fileSize, total;
ret = IFile_GetSize(&file, &fileSize);
if(!R_SUCCEEDED(ret) || fileSize > size) return -1;
ret = IFile_Read(&file, &total, code, fileSize);
IFile_Close(&file);
if(!R_SUCCEEDED(ret)) return -1;
else if(total < fileSize) return -2; //Shouldn't happen
}
return ret;
}
static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId) static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
{ {
/* Here we look for "/luma/locales/[u64 titleID in hex, uppercase].txt" /* Here we look for "/luma/locales/[u64 titleID in hex, uppercase].txt"
If it exists it should contain, for example, "EUR IT" */ If it exists it should contain, for example, "EUR IT" */
char path[] = "/luma/locales/0000000000000000.txt"; char path[] = "/luma/locales/0000000000000000.txt";
progIdToStr(path + 29, progId);
u32 i = 29;
while(progId)
{
static const char hexDigits[] = "0123456789ABCDEF";
path[i--] = hexDigits[(u32)(progId & 0xF)];
progId >>= 4;
}
IFile file; IFile file;
Result ret = fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ); Result ret = fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ);
@ -522,6 +551,9 @@ void patchCode(u64 progId, u8 *code, u32 size)
if(tidHigh == 0x0004000) if(tidHigh == 0x0004000)
{ {
//External .code section loading
if(loadTitleCodeSection(progId, code, size) == -2) svcBreak(USERBREAK_ASSERT);
//Language emulation //Language emulation
u8 regionId = 0xFF, u8 regionId = 0xFF,
languageId = 0xFF; languageId = 0xFF;

View File

@ -24,7 +24,7 @@ void configureCFW(const char *configPath)
"( ) SysNAND is updated (A9LH-only)", "( ) SysNAND is updated (A9LH-only)",
"( ) Force A9LH detection", "( ) Force A9LH detection",
"( ) Use second EmuNAND as default", "( ) Use second EmuNAND as default",
"( ) Enable region/language emulation", "( ) Enable region/language emu. and external .code loading",
"( ) Show current NAND in System Settings", "( ) Show current NAND in System Settings",
"( ) Show GBA boot screen in patched AGB_FIRM", "( ) Show GBA boot screen in patched AGB_FIRM",
"( ) Enable splash screen with no screen-init" }; "( ) Enable splash screen with no screen-init" };

View File

@ -11,16 +11,16 @@ start:
mov sp, #0x27000000 mov sp, #0x27000000
@ Disable caches / mpu @ Disable caches / mpu
mrc p15, 0, r4, c1, c0, 0 @ read control register mrc p15, 0, r0, c1, c0, 0 @ read control register
bic r4, #(1<<12) @ - instruction cache disable bic r0, #(1<<12) @ - instruction cache disable
bic r4, #(1<<2) @ - data cache disable bic r0, #(1<<2) @ - data cache disable
bic r4, #(1<<0) @ - mpu disable bic r0, #(1<<0) @ - mpu disable
mcr p15, 0, r4, c1, c0, 0 @ write control register mcr p15, 0, r0, c1, c0, 0 @ write control register
@ Give read/write access to all the memory regions @ Give read/write access to all the memory regions
ldr r5, =0x33333333 ldr r0, =0x33333333
mcr p15, 0, r5, c5, c0, 2 @ write data access mcr p15, 0, r0, c5, c0, 2 @ write data access
mcr p15, 0, r5, c5, c0, 3 @ write instruction access mcr p15, 0, r0, c5, c0, 3 @ write instruction access
@ Sets MPU permissions and cache settings @ Sets MPU permissions and cache settings
ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part) ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part)
@ -31,9 +31,7 @@ start:
ldr r5, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS) ldr r5, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS)
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)
mov r10, #0x25 mov r8, #0x25
mov r11, #0x25
mov r12, #0x25
mcr p15, 0, r0, c6, c0, 0 mcr p15, 0, r0, c6, c0, 0
mcr p15, 0, r1, c6, c1, 0 mcr p15, 0, r1, c6, c1, 0
mcr p15, 0, r2, c6, c2, 0 mcr p15, 0, r2, c6, c2, 0
@ -42,28 +40,28 @@ start:
mcr p15, 0, r5, c6, c5, 0 mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0 mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0 mcr p15, 0, r7, c6, c7, 0
mcr p15, 0, r10, c3, c0, 0 @ Write bufferable 0, 2, 5 mcr p15, 0, r8, c3, c0, 0 @ Write bufferable 0, 2, 5
mcr p15, 0, r11, c2, c0, 0 @ Data cacheable 0, 2, 5 mcr p15, 0, r8, c2, c0, 0 @ Data cacheable 0, 2, 5
mcr p15, 0, r12, c2, c0, 1 @ Inst cacheable 0, 2, 5 mcr p15, 0, r8, c2, c0, 1 @ Inst cacheable 0, 2, 5
@ Enable dctm @ Enable dctm
ldr r1, =0x3000800A @ set dtcm ldr r0, =0x3000800A @ set dtcm
mcr p15, 0, r1, c9, c1, 0 @ set the dtcm Region Register mcr p15, 0, r0, c9, c1, 0 @ set the dtcm Region Register
@ Enable caches @ Enable caches
mrc p15, 0, r4, c1, c0, 0 @ read control register mrc p15, 0, r0, c1, c0, 0 @ read control register
orr r4, r4, #(1<<18) @ - itcm enable orr r0, r0, #(1<<18) @ - itcm enable
orr r4, r4, #(1<<16) @ - dtcm enable orr r0, r0, #(1<<16) @ - dtcm enable
orr r4, r4, #(1<<12) @ - instruction cache enable orr r0, r0, #(1<<12) @ - instruction cache enable
orr r4, r4, #(1<<2) @ - data cache enable orr r0, r0, #(1<<2) @ - data cache enable
orr r4, r4, #(1<<0) @ - mpu enable orr r0, r0, #(1<<0) @ - mpu enable
mcr p15, 0, r4, c1, c0, 0 @ write control register mcr p15, 0, r0, c1, c0, 0 @ write control register
@ Flush caches @ Flush caches
mov r5, #0 mov r0, #0
mcr p15, 0, r5, c7, c5, 0 @ flush I-cache mcr p15, 0, r0, c7, c5, 0 @ flush I-cache
mcr p15, 0, r5, c7, c6, 0 @ flush D-cache mcr p15, 0, r0, c7, c6, 0 @ flush D-cache
mcr p15, 0, r5, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
@ Fixes mounting of SDMC @ Fixes mounting of SDMC
ldr r0, =0x10000020 ldr r0, =0x10000020

View File

@ -44,13 +44,13 @@ static inline void startChrono(u64 initialTicks)
{ {
//Based on a NATIVE_FIRM disassembly //Based on a NATIVE_FIRM disassembly
*(vu16 *)0x10003002 = 0; //67MHz REG_TIMER_CNT(0) = 0; //67MHz
for(u32 i = 1; i < 4; i++) *(vu16 *)(0x10003002 + 4 * i) = 4; //Count-up for(u32 i = 1; i < 4; i++) REG_TIMER_CNT(i) = 4; //Count-up
for(u32 i = 0; i < 4; i++) *(vu16 *)(0x10003000 + 4 * i) = (u16)(initialTicks >> (16 * i)); for(u32 i = 0; i < 4; i++) REG_TIMER_VAL(i) = (u16)(initialTicks >> (16 * i));
*(vu16 *)0x10003002 = 0x80; //67MHz; enabled REG_TIMER_CNT(0) = 0x80; //67MHz; enabled
for(u32 i = 1; i < 4; i++) *(vu16 *)(0x10003002 + 4 * i) = 0x84; //Count-up; enabled for(u32 i = 1; i < 4; i++) REG_TIMER_CNT(i) = 0x84; //Count-up; enabled
} }
void chrono(u32 seconds) void chrono(u32 seconds)
@ -64,7 +64,7 @@ void chrono(u32 seconds)
do do
{ {
res = 0; res = 0;
for(u32 i = 0; i < 4; i++) res |= *(vu16 *)(0x10003000 + 4 * i) << (16 * i); for(u32 i = 0; i < 4; i++) res |= REG_TIMER_VAL(i) << (16 * i);
} }
while(res - startingTicks < seconds * TICKS_PER_SEC); while(res - startingTicks < seconds * TICKS_PER_SEC);
@ -73,5 +73,5 @@ void chrono(u32 seconds)
void stopChrono(void) void stopChrono(void)
{ {
for(u32 i = 1; i < 4; i++) *(vu16 *)(0x10003002 + 4 * i) &= ~0x80; for(u32 i = 0; i < 4; i++) REG_TIMER_CNT(i) &= ~0x80;
} }

View File

@ -10,6 +10,8 @@ u32 waitInput(void);
void mcuReboot(void); void mcuReboot(void);
#define TICKS_PER_SEC 67027964ULL #define TICKS_PER_SEC 67027964ULL
#define REG_TIMER_CNT(i) *(vu16 *)(0x10003002 + 4 * i)
#define REG_TIMER_VAL(i) *(vu16 *)(0x10003000 + 4 * i)
void chrono(u32 seconds); void chrono(u32 seconds);
void stopChrono(void); void stopChrono(void);