diff --git a/source/crypto.c b/source/crypto.c index a7bce98..885bbc1 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -350,8 +350,8 @@ u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf) //Sets the 7.x NCCH KeyX and the 6.x gamecard save data KeyY void setRSAMod0DerivedKeys(void) { - const u8 keyX0x25[0x10] = {0xCE, 0xE7, 0xD8, 0xAB, 0x30, 0xC0, 0x0D, 0xAE, 0x85, 0x0E, 0xF5, 0xE3, 0x82, 0xAC, 0x5A, 0xF3}; - const u8 keyY0x2F[0x10] = {0xC3, 0x69, 0xBA, 0xA2, 0x1E, 0x18, 0x8A, 0x88, 0xA9, 0xAA, 0x94, 0xE5, 0x50, 0x6A, 0x9F, 0x16}; + const u8 keyX0x25[0x10] = {0xCE, 0xE7, 0xD8, 0xAB, 0x30, 0xC0, 0x0D, 0xAE, 0x85, 0x0E, 0xF5, 0xE3, 0x82, 0xAC, 0x5A, 0xF3}, + keyY0x2F[0x10] = {0xC3, 0x69, 0xBA, 0xA2, 0x1E, 0x18, 0x8A, 0x88, 0xA9, 0xAA, 0x94, 0xE5, 0x50, 0x6A, 0x9F, 0x16}; aes_setkey(0x25, keyX0x25, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); aes_setkey(0x2F, keyY0x2F, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL); diff --git a/source/firm.c b/source/firm.c index 2ce3d55..b6274a0 100755 --- a/source/firm.c +++ b/source/firm.c @@ -89,22 +89,6 @@ void main(void) //Get pressed buttons u32 pressed = HID_PAD; - //If no configuration file exists or SELECT is held, load configuration menu - if(needConfig == CREATE_CONFIGURATION || ((pressed & BUTTON_SELECT) && !(pressed & BUTTON_L1))) - { - configureCFW(configPath); - - //Zero the last booted FIRM flag - CFG_BOOTENV = 0; - - nbChronoStarted = 1; - chrono(0); - chrono(2); - - //Update pressed buttons - pressed = HID_PAD; - } - isFirmlaunch = false; firmType = NATIVE_FIRM; @@ -125,42 +109,54 @@ void main(void) newConfig = (u32)a9lhMode << 3; - if(a9lhBoot) + //If it's a MCU reboot, try to force boot options + if(a9lhBoot && CFG_BOOTENV) { - //If it's a MCU reboot, try to force boot options - if(CFG_BOOTENV) + //Always force a sysNAND boot when quitting AGB_FIRM + if(CFG_BOOTENV == 7) { - //Always force a sysNAND boot when quitting AGB_FIRM - if(CFG_BOOTENV == 7) - { - nandType = FIRMWARE_SYSNAND; - firmSource = updatedSys ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCONFIG(2, 1); - needConfig = DONT_CONFIGURE; + nandType = FIRMWARE_SYSNAND; + firmSource = updatedSys ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCONFIG(2, 1); + needConfig = DONT_CONFIGURE; - //Flag to prevent multiple boot options-forcing - newConfig |= 1 << 4; - } - - /* Else, force the last used boot options unless a button is pressed - or the no-forcing flag is set */ - else if(!pressed && !BOOTCONFIG(4, 1)) - { - nandType = (FirmwareSource)BOOTCONFIG(0, 3); - firmSource = (FirmwareSource)BOOTCONFIG(2, 1); - needConfig = DONT_CONFIGURE; - } + //Flag to prevent multiple boot options-forcing + newConfig |= 1 << 4; } - //If the SAFE MODE combo is held, force a sysNAND boot - else if(pressed == SAFE_MODE) + /* Else, force the last used boot options unless a button is pressed + or the no-forcing flag is set */ + else if(!pressed && !BOOTCONFIG(4, 1)) { - a9lhMode = A9LH_WITH_SFIRM_FIRMPROT; - nandType = FIRMWARE_SYSNAND; - firmSource = FIRMWARE_SYSNAND; + nandType = (FirmwareSource)BOOTCONFIG(0, 3); + firmSource = (FirmwareSource)BOOTCONFIG(2, 1); needConfig = DONT_CONFIGURE; } } + //If no configuration file exists or SELECT is held, load configuration menu + if(needConfig == CREATE_CONFIGURATION || ((pressed & BUTTON_SELECT) && !(pressed & BUTTON_L1))) + { + configureCFW(configPath); + + //Zero the last booted FIRM flag + CFG_BOOTENV = 0; + + nbChronoStarted = 1; + chrono(0); + chrono(2); + + //Update pressed buttons + pressed = HID_PAD; + } + + if(needConfig != DONT_CONFIGURE && pressed == SAFE_MODE) + { + a9lhMode = A9LH_WITH_SFIRM_FIRMPROT; + nandType = FIRMWARE_SYSNAND; + firmSource = FIRMWARE_SYSNAND; + needConfig = DONT_CONFIGURE; + } + //Boot options aren't being forced if(needConfig != DONT_CONFIGURE) { @@ -308,7 +304,7 @@ static inline void patchNativeFirm(FirmwareSource nandType, u32 emuHeader, A9LHM //Sets the 7.x NCCH KeyX and the 6.x gamecard save data KeyY if(a9lhMode == NO_A9LH) setRSAMod0DerivedKeys(); - + //Find the Process9 .code location, size and memory address u32 process9Size, process9MemAddr; diff --git a/source/screen.c b/source/screen.c index 523500c..ef73a4d 100644 --- a/source/screen.c +++ b/source/screen.c @@ -32,32 +32,31 @@ #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; 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)(); } static inline void invokeArm11Function(void (*func)()) { - static bool hasCopiedStub = false; + static u32 hasCopiedStub = 0; + if(!hasCopiedStub) { memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x40); flushDCacheRange((void *)ARM11_STUB_ADDRESS, 0x40); - hasCopiedStub = true; + hasCopiedStub = 1; } - + *arm11Entry = (u32)func; while(*arm11Entry); *arm11Entry = ARM11_STUB_ADDRESS; @@ -83,25 +82,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); } @@ -111,9 +108,8 @@ 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 @@ -125,7 +121,7 @@ void clearScreens(void) REGs_PSC1[1] = (u32)(fb->bottom + 0x38400) >> 3; //End address REGs_PSC1[2] = 0; //Fill value 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) @@ -134,13 +130,13 @@ void clearScreens(void) 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 pattern; start - + while(!(REGs_PSC0[3] & 2)); } - + WAIT_FOR_ARM9(); } - + flushDCacheRange((void *)fb, sizeof(struct fb)); invokeArm11Function(ARM11); } @@ -154,13 +150,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; @@ -246,7 +242,7 @@ u32 initScreens(void) WAIT_FOR_ARM9(); } - + if(needToInit) { flushDCacheRange(&config, 4); @@ -256,9 +252,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 09b120e..4954f63 100644 --- a/source/screen.h +++ b/source/screen.h @@ -30,14 +30,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 { - u8 *top_left; - u8 *top_right; - u8 *bottom; + 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