From 136e0d897433af8516800edb52ee851800037300 Mon Sep 17 00:00:00 2001 From: Aurora Date: Fri, 1 Jul 2016 20:27:28 +0200 Subject: [PATCH 1/4] Cleanup --- injector/source/patcher.c | 30 ++++++++-------- loader/source/cache.h | 5 +++ loader/source/cache.s | 39 ++++++++++++++++++++ loader/source/main.c | 4 +-- loader/source/start.s | 11 +----- patches/reboot.s | 75 ++++++++++++--------------------------- source/cache.s | 4 +-- source/config.c | 8 ++--- source/draw.h | 2 ++ source/firm.c | 6 ++-- source/screen.c | 61 +++++++++++++++---------------- source/screen.h | 8 +++-- source/start.s | 52 ++++++++++++--------------- source/utils.c | 2 +- 14 files changed, 151 insertions(+), 156 deletions(-) create mode 100644 loader/source/cache.h create mode 100644 loader/source/cache.s diff --git a/injector/source/patcher.c b/injector/source/patcher.c index 3b3d4a5..286724e 100644 --- a/injector/source/patcher.c +++ b/injector/source/patcher.c @@ -135,31 +135,29 @@ static void progIdToStr(char *strEnd, u64 progId) } } -static int loadTitleCodeSection(u64 progId, u8 *code, u32 size) +static void 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 + + if(R_SUCCEEDED(ret) && fileSize <= size) + { + ret = IFile_Read(&file, &total, code, fileSize); + IFile_Close(&file); + } } - - return ret; } static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId) @@ -366,7 +364,7 @@ void patchCode(u64 progId, u8 *code, u32 size) ); //Apply only if the updated NAND hasn't been booted - if((BOOTCONFIG(0, 3) != 0) == (BOOTCONFIG(3, 1) && CONFIG(1))) + if((BOOTCONFIG(0, 3) != 0) == (BOOTCONFIG(2, 1) && CONFIG(1))) { static const u8 skipEshopUpdateCheckPattern[] = { 0x30, 0xB5, 0xF1, 0xB0 @@ -552,8 +550,8 @@ void patchCode(u64 progId, u8 *code, u32 size) if(tidHigh == 0x0004000) { //External .code section loading - if(loadTitleCodeSection(progId, code, size) == -2) svcBreak(USERBREAK_ASSERT); - + loadTitleCodeSection(progId, code, size); + //Language emulation u8 regionId = 0xFF, languageId = 0xFF; @@ -575,4 +573,4 @@ void patchCode(u64 progId, u8 *code, u32 size) break; } -} +} \ No newline at end of file diff --git a/loader/source/cache.h b/loader/source/cache.h new file mode 100644 index 0000000..565f51e --- /dev/null +++ b/loader/source/cache.h @@ -0,0 +1,5 @@ +#pragma once + +#include "types.h" + +void flushCaches(void); \ No newline at end of file diff --git a/loader/source/cache.s b/loader/source/cache.s new file mode 100644 index 0000000..75da741 --- /dev/null +++ b/loader/source/cache.s @@ -0,0 +1,39 @@ +@ +@ cache.s +@ by TuxSH +@ +@ This is part of Luma3DS, see LICENSE.txt for details +@ + +.arm +.global flushCaches +.type flushCaches STT_FUNC + +flushCaches: + @ Clean and flush data cache + @ Adpated 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 + @ Note: ARM's example is actually for a 8KB DCache (which is what the 3DS has) + @ Implemented in bootROM at address 0xffff0830 + + mov r1, #0 @ segment counter + outer_loop: + mov r0, #0 @ line counter + + inner_loop: + orr r2, r1, r0 @ generate segment and line address + mcr p15, 0, r2, c7, c14, 2 @ clean and flush the line + add r0, #0x20 @ increment to next line + cmp r0, #0x400 + bne inner_loop + + add r1, #0x40000000 + cmp r1, #0 + bne outer_loop + + mcr p15, 0, r1, c7, c10, 4 @ drain write buffer + + @ Flush instruction cache + mcr p15, 0, r1, c7, c5, 0 + + bx lr diff --git a/loader/source/main.c b/loader/source/main.c index 633eee2..9c20fe8 100644 --- a/loader/source/main.c +++ b/loader/source/main.c @@ -1,4 +1,5 @@ #include "memory.h" +#include "cache.h" void main(void) { @@ -6,8 +7,7 @@ void main(void) memcpy(payloadAddress, (void*)0x24F00000, *(u32 *)0x24FFFF04); - ((void (*)(void))0xFFFF0830)(); //Clean and flush the entire DCache, then drain the write buffer - ((void (*)(void))0xFFFF0AB4)(); //Flush the entire ICache + flushCaches(); ((void (*)())payloadAddress)(); } \ No newline at end of file diff --git a/loader/source/start.s b/loader/source/start.s index 4e1920b..0d411d9 100644 --- a/loader/source/start.s +++ b/loader/source/start.s @@ -2,15 +2,6 @@ .align 4 .global _start _start: - b start + b main .word 0 - -start: - @ Flush caches - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ flush I-cache - mcr p15, 0, r0, c7, c6, 0 @ flush D-cache - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - - b main diff --git a/patches/reboot.s b/patches/reboot.s index e662db5..1a7a91c 100644 --- a/patches/reboot.s +++ b/patches/reboot.s @@ -1,7 +1,7 @@ .arm.little payload_addr equ 0x23F00000 ; Brahma payload address. -payload_maxsize equ 0x20000 ; Maximum size for the payload (200 KB will do). +payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeBrah supports). .create "build/reboot.bin", 0 .arm @@ -88,60 +88,31 @@ dat_fname: .dcw "sdmc:/Luma3DS.dat" .align 4 kernelcode_start: - ; Set MPU settings - mrc p15, 0, r0, c2, c0, 0 ; dcacheable - mrc p15, 0, r12, c2, c0, 1 ; icacheable - mrc p15, 0, r1, c3, c0, 0 ; write bufferable - mrc p15, 0, r2, c5, c0, 2 ; daccess - mrc p15, 0, r3, c5, c0, 3 ; iaccess - ldr r4, =0x18000035 ; 0x18000000 128M - bic r2, r2, #0xF0000 ; unprotect region 4 - bic r3, r3, #0xF0000 ; unprotect region 4 - orr r0, r0, #0x10 ; dcacheable region 4 - orr r2, r2, #0x30000 ; region 4 r/w - orr r3, r3, #0x30000 ; region 4 r/w - orr r12, r12, #0x10 ; icacheable region 4 - orr r1, r1, #0x10 ; write bufferable region 4 - mcr p15, 0, r0, c2, c0, 0 - mcr p15, 0, r12, c2, c0, 1 - mcr p15, 0, r1, c3, c0, 0 ; write bufferable - mcr p15, 0, r2, c5, c0, 2 ; daccess - mcr p15, 0, r3, c5, c0, 3 ; iaccess - mcr p15, 0, r4, c6, c4, 0 ; region 4 (hmmm) - mrc p15, 0, r0, c2, c0, 0 ; dcacheable - mrc p15, 0, r1, c2, c0, 1 ; icacheable - mrc p15, 0, r2, c3, c0, 0 ; write bufferable - orr r0, r0, #0x20 ; dcacheable region 5 - orr r1, r1, #0x20 ; icacheable region 5 - orr r2, r2, #0x20 ; write bufferable region 5 - mcr p15, 0, r0, c2, c0, 0 ; dcacheable - mcr p15, 0, r1, c2, c0, 1 ; icacheable - mcr p15, 0, r2, c3, c0, 0 ; write bufferable - - ; Flush cache - mov r2, #0 - mov r1, r2 - flush_cache: - mov r0, #0 - mov r3, r2, lsl #30 - flush_cache_inner_loop: - orr r12, r3, r0, lsl#5 - mcr p15, 0, r1, c7, c10, 4 ; drain write buffer - mcr p15, 0, r12, c7, c14, 2 ; clean and flush dcache entry (index and segment) - add r0, #1 - cmp r0, #0x20 - bcc flush_cache_inner_loop - add r2, #1 - cmp r2, #4 - bcc flush_cache - - ; Enable MPU + ; Disable MPU ldr r0, =0x42078 ; alt vector select, enable itcm mcr p15, 0, r0, c1, c0, 0 - mcr p15, 0, r1, c7, c5, 0 ; flush dcache - mcr p15, 0, r1, c7, c6, 0 ; flush icache - mcr p15, 0, r1, c7, c10, 4 ; drain write buffer + + ; Clean and flush data cache + mov r1, #0 ; segment counter + outer_loop: + mov r0, #0 ; line counter + + inner_loop: + orr r2, r1, r0 ; generate segment and line address + mcr p15, 0, r2, c7, c14, 2 ; clean and flush the line + add r0, #0x20 ; increment to next line + cmp r0, #0x400 + bne inner_loop + + add r1, #0x40000000 + cmp r1, #0 + bne outer_loop + + mcr p15, 0, r1, c7, c10, 4 ; drain write buffer + + ; Flush instruction cache + mcr p15, 0, r1, c7, c5, 0 ; Jump to payload ldr r0, =payload_addr diff --git a/source/cache.s b/source/cache.s index d9fdad1..d241726 100644 --- a/source/cache.s +++ b/source/cache.s @@ -47,7 +47,7 @@ flushDCacheRange: mcr p15, 0, r0, c7, c14, 1 @ clean and flush the line corresponding to the address r0 is holding add r0, #0x20 cmp r0, r1 - blt flush_dcache_range_loop + blo flush_dcache_range_loop mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer @@ -74,7 +74,7 @@ flushICacheRange: mcr p15, 0, r0, c7, c5, 1 @ flush the line corresponding to the address r0 is holding add r0, #0x20 cmp r0, r1 - blt flush_icache_range_loop + blo flush_icache_range_loop bx lr \ No newline at end of file diff --git a/source/config.c b/source/config.c index 538b3d7..8df501e 100644 --- a/source/config.c +++ b/source/config.c @@ -145,6 +145,9 @@ void configureCFW(const char *configPath) u32 oldEnabled = multiOptions[selectedOption].enabled; drawCharacter(selected, 10 + multiOptions[selectedOption].posXs[oldEnabled] * SPACING_X, multiOptions[selectedOption].posY, COLOR_BLACK); multiOptions[selectedOption].enabled = oldEnabled == 3 ? 0 : oldEnabled + 1; + + if(!selectedOption) + updateBrightness(multiOptions[selectedOption].enabled); } else { @@ -156,12 +159,7 @@ void configureCFW(const char *configPath) //In any case, if the current option is enabled (or a multiple choice option is selected) we must display a red 'x' if(selectedOption < multiOptionsAmount) - { - if(selectedOption == 0) - updateBrightness(multiOptions[selectedOption].enabled); - drawCharacter(selected, 10 + multiOptions[selectedOption].posXs[multiOptions[selectedOption].enabled] * SPACING_X, multiOptions[selectedOption].posY, COLOR_RED); - } else { u32 singleSelected = selectedOption - multiOptionsAmount; diff --git a/source/draw.h b/source/draw.h index e21b0d5..401d2c7 100644 --- a/source/draw.h +++ b/source/draw.h @@ -19,6 +19,8 @@ #define COLOR_RED 0x0000FF #define COLOR_BLACK 0x000000 +extern volatile struct fb *const fb; + u32 loadSplash(void); void drawCharacter(char character, int posX, int posY, u32 color); int drawString(const char *string, int posX, int posY, u32 color); \ No newline at end of file diff --git a/source/firm.c b/source/firm.c index dba2364..89d4f22 100755 --- a/source/firm.c +++ b/source/firm.c @@ -22,7 +22,7 @@ static const firmSectionHeader *section; u32 config, isN3DS, emuOffset; - + FirmwareSource firmSource; void main(void) @@ -37,7 +37,7 @@ void main(void) FirmwareSource nandType; ConfigurationStatus needConfig; A9LHMode a9lhMode; - + //Detect the console being used isN3DS = PDN_MPCORE_CFG == 7; @@ -381,7 +381,7 @@ static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch) flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed flushEntireICache(); - + //Set ARM11 kernel entrypoint *arm11 = (u32)firm->arm11Entry; diff --git a/source/screen.c b/source/screen.c index 8c21ee2..4b50e18 100644 --- a/source/screen.c +++ b/source/screen.c @@ -12,18 +12,17 @@ #include "draw.h" #include "i2c.h" -#define ARM11_STUB_ADDRESS (0x25000000 - 0x40) //It's currently only 0x28 bytes large. We're putting 0x40 just to be sure here -#define WAIT_FOR_ARM9() *arm11Entry = 0; while(!*arm11Entry); ((void (*)())*arm11Entry)(); vu32 *arm11Entry = (vu32 *)0x1FFFFFF8; +volatile struct fb *const fb = (volatile struct fb *)0x23FFFE00; void __attribute__((naked)) arm11Stub(void) { //Disable interrupts __asm(".word 0xF10C01C0"); - + //Wait for the entry to be set while(*arm11Entry == ARM11_STUB_ADDRESS); - + //Jump to it ((void (*)())*arm11Entry)(); } @@ -31,12 +30,14 @@ void __attribute__((naked)) arm11Stub(void) static inline void invokeArm11Function(void (*func)()) { static u32 hasCopiedStub = 0; - if(!hasCopiedStub++) + + if(!hasCopiedStub) { memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x40); flushDCacheRange((void *)ARM11_STUB_ADDRESS, 0x40); + hasCopiedStub = 1; } - + *arm11Entry = (u32)func; while(*arm11Entry); *arm11Entry = ARM11_STUB_ADDRESS; @@ -62,25 +63,23 @@ void deinitScreens(void) if(PDN_GPU_CNT != 1) invokeArm11Function(ARM11); } -void updateBrightness(u32 brightnessLevel) +void updateBrightness(u32 brightnessIndex) { - static int brightnessValue; - - brightnessValue = brightness[brightnessLevel]; - + u32 brightnessLevel = brightness[brightnessIndex]; + void __attribute__((naked)) ARM11(void) { //Disable interrupts - __asm(".word 0xF10C01C0"); - + __asm(".word 0xF10C01C0"); + //Change brightness - *(vu32 *)0x10202240 = brightnessValue; - *(vu32 *)0x10202A40 = brightnessValue; + *(vu32 *)0x10202240 = brightnessLevel; + *(vu32 *)0x10202A40 = brightnessLevel; WAIT_FOR_ARM9(); } - flushDCacheRange(&brightnessValue, 4); + flushDCacheRange(&brightnessLevel, 4); invokeArm11Function(ARM11); } @@ -90,21 +89,20 @@ void clearScreens(void) { //Disable interrupts __asm(".word 0xF10C01C0"); - + //Setting up two simultaneous memory fills using the GPU - vu32 *REGs_PSC0 = (vu32 *)0x10400010; REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address REGs_PSC0[1] = (u32)(fb->top_left + 0x46500) >> 3; //End address REGs_PSC0[2] = 0; //Fill value - REGs_PSC0[3] = (2 << 8) | 1; //32-bit patter; start + REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start vu32 *REGs_PSC1 = (vu32 *)0x10400020; REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address REGs_PSC1[1] = (u32)(fb->bottom + 0x38400) >> 3; //End address REGs_PSC1[2] = 0; //Fill value - REGs_PSC1[3] = (2 << 8) | 1; //32-bit patter; start - + REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start + while(!((REGs_PSC0[3] & 2) && (REGs_PSC1[3] & 2))); if(fb->top_right != fb->top_left) @@ -112,14 +110,14 @@ void clearScreens(void) REGs_PSC0[0] = (u32)fb->top_right >> 3; //Start address REGs_PSC0[1] = (u32)(fb->top_right + 0x46500) >> 3; //End address REGs_PSC0[2] = 0; //Fill value - REGs_PSC0[3] = (2 << 8) | 1; //32-bit patter; start - + REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start + while(!(REGs_PSC0[3] & 2)); } - + WAIT_FOR_ARM9(); } - + flushDCacheRange((void *)fb, sizeof(struct fb)); invokeArm11Function(ARM11); } @@ -133,13 +131,13 @@ u32 initScreens(void) //Disable interrupts __asm(".word 0xF10C01C0"); - u32 brightnessLevel = MULTICONFIG(0); + u32 brightnessLevel = brightness[MULTICONFIG(0)]; *(vu32 *)0x10141200 = 0x1007F; *(vu32 *)0x10202014 = 0x00000001; *(vu32 *)0x1020200C &= 0xFFFEFFFE; - *(vu32 *)0x10202240 = brightness[brightnessLevel]; - *(vu32 *)0x10202A40 = brightness[brightnessLevel]; + *(vu32 *)0x10202240 = brightnessLevel; + *(vu32 *)0x10202A40 = brightnessLevel; *(vu32 *)0x10202244 = 0x1023E; *(vu32 *)0x10202A44 = 0x1023E; @@ -225,7 +223,7 @@ u32 initScreens(void) WAIT_FOR_ARM9(); } - + if(needToInit) { flushDCacheRange(&config, 4); @@ -235,9 +233,8 @@ u32 initScreens(void) //Turn on backlight i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); } - else - updateBrightness(MULTICONFIG(0)); - + else updateBrightness(MULTICONFIG(0)); + clearScreens(); return needToInit; diff --git a/source/screen.h b/source/screen.h index 5f2bf1d..31866e0 100644 --- a/source/screen.h +++ b/source/screen.h @@ -10,14 +10,16 @@ #include "types.h" #define PDN_GPU_CNT (*(vu8 *)0x10141200) +#define ARM11_STUB_ADDRESS (0x25000000 - 0x40) //It's currently only 0x28 bytes large. We're putting 0x40 just to be sure here +#define WAIT_FOR_ARM9() *arm11Entry = 0; while(!*arm11Entry); ((void (*)())*arm11Entry)(); -static volatile struct fb { +struct fb { u8 *top_left; u8 *top_right; u8 *bottom; -} *const fb = (volatile struct fb *)0x23FFFE00; +}; void deinitScreens(void); -void updateBrightness(u32 brightnessLevel); +void updateBrightness(u32 brightnessIndex); void clearScreens(void); u32 initScreens(void); \ No newline at end of file diff --git a/source/start.s b/source/start.s index 1171c49..9fecc38 100644 --- a/source/start.s +++ b/source/start.s @@ -10,28 +10,32 @@ start: @ Change the stack pointer mov sp, #0x27000000 - @ Disable caches / mpu + @ Disable caches / MPU mrc p15, 0, r0, c1, c0, 0 @ read control register bic r0, #(1<<12) @ - instruction cache disable bic r0, #(1<<2) @ - data cache disable bic r0, #(1<<0) @ - mpu disable mcr p15, 0, r0, c1, c0, 0 @ write control register - + + @ Flush caches + bl flushEntireDCache + bl flushEntireICache + @ Give read/write access to all the memory regions - ldr r0, =0x33333333 + ldr r0, =0x3333333 mcr p15, 0, r0, c5, c0, 2 @ write data access mcr p15, 0, r0, c5, c0, 3 @ write instruction access - @ Sets MPU permissions and cache settings - ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part) - ldr r1, =0x3000801B @ fff00000 16k | dtcm - ldr r2, =0x01FF801D @ 01ff8000 32k | itcm - ldr r3, =0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS) - ldr r4, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB) - ldr r5, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS) - ldr r6, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram - ldr r7, =0x1800002D @ 18000000 8M | vram (+ 2MB) - mov r8, #0x29 + @ Set MPU permissions and cache settings + ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part) + ldr r1, =0x01FF801D @ 01ff8000 32k | itcm + ldr r2, =0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS) + ldr r3, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB) + ldr r4, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS) + ldr r5, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram + ldr r6, =0x1800002D @ 18000000 8M | vram (+ 2MB) + mov r7, #0 + mov r8, #0x15 mcr p15, 0, r0, c6, c0, 0 mcr p15, 0, r1, c6, c1, 0 mcr p15, 0, r2, c6, c2, 0 @@ -40,30 +44,18 @@ start: mcr p15, 0, r5, c6, c5, 0 mcr p15, 0, r6, c6, c6, 0 mcr p15, 0, r7, c6, c7, 0 - mcr p15, 0, r8, c3, c0, 0 @ Write bufferable 0, 3, 5 - mcr p15, 0, r8, c2, c0, 0 @ Data cacheable 0, 3, 5 - mcr p15, 0, r8, c2, c0, 1 @ Inst cacheable 0, 3, 5 + mcr p15, 0, r8, c3, c0, 0 @ Write bufferable 0, 2, 4 + mcr p15, 0, r8, c2, c0, 0 @ Data cacheable 0, 2, 4 + mcr p15, 0, r8, c2, c0, 1 @ Inst cacheable 0, 2, 4 - @ Enable dctm - ldr r0, =0x3000800A @ set dtcm - mcr p15, 0, r0, c9, c1, 0 @ set the dtcm Region Register - - @ Enable caches + @ Enable caches / MPU mrc p15, 0, r0, c1, c0, 0 @ read control register - orr r0, r0, #(1<<18) @ - itcm enable - orr r0, r0, #(1<<16) @ - dtcm enable orr r0, r0, #(1<<12) @ - instruction cache enable orr r0, r0, #(1<<2) @ - data cache enable orr r0, r0, #(1<<0) @ - mpu enable mcr p15, 0, r0, c1, c0, 0 @ write control register - @ Flush caches - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ flush I-cache - mcr p15, 0, r0, c7, c6, 0 @ flush D-cache - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - - @ Fixes mounting of SDMC + @ Fix mounting of SDMC ldr r0, =0x10000020 mov r1, #0x340 str r1, [r0] diff --git a/source/utils.c b/source/utils.c index 9a56a31..812ea7c 100644 --- a/source/utils.c +++ b/source/utils.c @@ -38,7 +38,7 @@ u32 waitInput(void) void mcuReboot(void) { flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed - + i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while(1); } From 29d8e637d8ced79d8630d52b9d8b7644d49f0f13 Mon Sep 17 00:00:00 2001 From: Aurora Date: Fri, 1 Jul 2016 20:36:43 +0200 Subject: [PATCH 2/4] One-liners ftw --- source/cache.h | 2 +- source/cache.s | 28 ++++++++++++---------------- source/config.c | 2 +- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/source/cache.h b/source/cache.h index 0176c94..4ba7615 100644 --- a/source/cache.h +++ b/source/cache.h @@ -4,6 +4,7 @@ */ #pragma once + #include "types.h" /*** @@ -17,6 +18,5 @@ void flushEntireDCache(void); //actually: "clean and flush" void flushDCacheRange(void *startAddress, u32 size); - void flushEntireICache(void); void flushICacheRange(void *startAddress, u32 size); \ No newline at end of file diff --git a/source/cache.s b/source/cache.s index d241726..45a0773 100644 --- a/source/cache.s +++ b/source/cache.s @@ -12,69 +12,65 @@ .global flushEntireDCache .type flushEntireDCache, %function flushEntireDCache: - @ Adpated 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 @ Note: ARM's example is actually for a 8KB DCache (which is what the 3DS has) + @ Implemented in bootROM at address 0xffff0830 - mov r1, #0 @ segment counter outer_loop: mov r0, #0 @ line counter - + inner_loop: orr r2, r1, r0 @ generate segment and line address mcr p15, 0, r2, c7, c14, 2 @ clean and flush the line add r0, #0x20 @ increment to next line cmp r0, #0x400 bne inner_loop - + add r1, #0x40000000 cmp r1, #0 bne outer_loop - + mcr p15, 0, r1, c7, c10, 4 @ drain write buffer bx lr - + .global flushDCacheRange .type flushDCacheRange, %function flushDCacheRange: @ Implemented in bootROM at address 0xffff08a0 - add r1, r0, r1 @ end address bic r0, #0x1f @ align source address to cache line size (32 bytes) - + flush_dcache_range_loop: mcr p15, 0, r0, c7, c14, 1 @ clean and flush the line corresponding to the address r0 is holding add r0, #0x20 cmp r0, r1 blo flush_dcache_range_loop - + mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer bx lr - + .global flushEntireICache .type flushEntireICache, %function flushEntireICache: @ Implemented in bootROM at address 0xffff0ab4 - mov r0, #0 mcr p15, 0, r0, c7, c5, 0 bx lr - + .global flushICacheRange .type flushICacheRange, %function flushICacheRange: @ Implemented in bootROM at address 0xffff0ac0 - add r1, r0, r1 @ end address bic r0, #0x1f @ align source address to cache line size (32 bytes) - + flush_icache_range_loop: mcr p15, 0, r0, c7, c5, 1 @ flush the line corresponding to the address r0 is holding add r0, #0x20 cmp r0, r1 blo flush_icache_range_loop - + bx lr - \ No newline at end of file diff --git a/source/config.c b/source/config.c index 8df501e..a11bcb8 100644 --- a/source/config.c +++ b/source/config.c @@ -24,7 +24,7 @@ void configureCFW(const char *configPath) "( ) SysNAND is updated (A9LH-only)", "( ) Force A9LH detection", "( ) Use second EmuNAND as default", - "( ) Enable region/language emu. and external .code loading", + "( ) Enable region/language emu. and ext. .code", "( ) Show current NAND in System Settings", "( ) Show GBA boot screen in patched AGB_FIRM", "( ) Enable splash screen with no screen-init" }; From 2238293c0f47ce6d0dc4084d79ccc4332d81cfc2 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sat, 2 Jul 2016 10:59:21 +0200 Subject: [PATCH 3/4] Fix indentation --- source/start.s | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/start.s b/source/start.s index 9fecc38..90f9f1d 100644 --- a/source/start.s +++ b/source/start.s @@ -27,13 +27,13 @@ start: mcr p15, 0, r0, c5, c0, 3 @ write instruction access @ Set MPU permissions and cache settings - ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part) - ldr r1, =0x01FF801D @ 01ff8000 32k | itcm - ldr r2, =0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS) - ldr r3, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB) - ldr r4, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS) - ldr r5, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram - ldr r6, =0x1800002D @ 18000000 8M | vram (+ 2MB) + ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part) + ldr r1, =0x01FF801D @ 01ff8000 32k | itcm + ldr r2, =0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS) + ldr r3, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB) + ldr r4, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS) + ldr r5, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram + ldr r6, =0x1800002D @ 18000000 8M | vram (+ 2MB) mov r7, #0 mov r8, #0x15 mcr p15, 0, r0, c6, c0, 0 @@ -44,9 +44,9 @@ start: mcr p15, 0, r5, c6, c5, 0 mcr p15, 0, r6, c6, c6, 0 mcr p15, 0, r7, c6, c7, 0 - mcr p15, 0, r8, c3, c0, 0 @ Write bufferable 0, 2, 4 - mcr p15, 0, r8, c2, c0, 0 @ Data cacheable 0, 2, 4 - mcr p15, 0, r8, c2, c0, 1 @ Inst cacheable 0, 2, 4 + mcr p15, 0, r8, c3, c0, 0 @ Write bufferable 0, 2, 4 + mcr p15, 0, r8, c2, c0, 0 @ Data cacheable 0, 2, 4 + mcr p15, 0, r8, c2, c0, 1 @ Inst cacheable 0, 2, 4 @ Enable caches / MPU mrc p15, 0, r0, c1, c0, 0 @ read control register From 730e716f0f822ab43060214578fc35545f3b0255 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sat, 2 Jul 2016 12:32:39 +0200 Subject: [PATCH 4/4] Update CakeBrah --- CakeBrah | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CakeBrah b/CakeBrah index 42ebe0d..bead2ce 160000 --- a/CakeBrah +++ b/CakeBrah @@ -1 +1 @@ -Subproject commit 42ebe0d0bc075ba98fa631441590de9bd2733d2b +Subproject commit bead2ce337cc31da6b7ca1c1ce30672d78a7fe00