diff options
Diffstat (limited to 'src/DSi.cpp')
-rw-r--r-- | src/DSi.cpp | 383 |
1 files changed, 249 insertions, 134 deletions
diff --git a/src/DSi.cpp b/src/DSi.cpp index ebfbae6..c6df5df 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -82,6 +82,14 @@ DSi_SDHost* SDIO; u64 ConsoleID; u8 eMMC_CID[16]; +// FIXME: these currently have no effect (and aren't stored in a savestate) +// ... not that they matter all that much +u8 GPIO_Data; +u8 GPIO_Dir; +u8 GPIO_IEdgeSel; +u8 GPIO_IE; +u8 GPIO_WiFi; + void Set_SCFG_Clock9(u16 val); void Set_SCFG_MC(u32 val); @@ -159,7 +167,14 @@ void Reset() DSi_AES::Reset(); - SCFG_BIOS = 0x0101; // TODO: should be zero when booting from BIOS + if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot)) + { + SCFG_BIOS = 0x0000; + } + else + { + SCFG_BIOS = 0x0101; + } SCFG_Clock9 = 0x0187; // CHECKME SCFG_Clock7 = 0x0187; SCFG_EXT[0] = 0x8307F100; @@ -169,6 +184,12 @@ void Reset() DSi_DSP::SetRstLine(false); + GPIO_Data = 0xff; // these actually initialize to high after reset + GPIO_Dir = 0x80; // enable sound out, all others input + GPIO_IEdgeSel = 0; + GPIO_IE = 0; + GPIO_WiFi = 0; + // LCD init flag GPU::DispStat[0] |= (1<<6); GPU::DispStat[1] |= (1<<6); @@ -673,7 +694,14 @@ void SoftReset() DSi_AES::Reset(); - SCFG_BIOS = 0x0101; // TODO: should be zero when booting from BIOS + if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot)) + { + SCFG_BIOS = 0x0000; + } + else + { + SCFG_BIOS = 0x0101; + } SCFG_Clock9 = 0x0187; // CHECKME SCFG_Clock7 = 0x0187; SCFG_EXT[0] = 0x8307F100; @@ -733,12 +761,16 @@ bool LoadBIOS() fclose(f); } - // herp - *(u32*)&ARM9iBIOS[0] = 0xEAFFFFFE; - *(u32*)&ARM7iBIOS[0] = 0xEAFFFFFE; + if (!Platform::GetConfigBool(Platform::DSi_FullBIOSBoot)) + { + // herp + *(u32*)&ARM9iBIOS[0] = 0xEAFFFFFE; + *(u32*)&ARM7iBIOS[0] = 0xEAFFFFFE; - // TODO!!!! - // hax the upper 32K out of the goddamn DSi + // TODO!!!! + // hax the upper 32K out of the goddamn DSi + // done that :) -pcy + } return true; } @@ -775,115 +807,138 @@ bool LoadNAND() memset(NWRAMMask, 0, sizeof(NWRAMMask)); u32 bootparams[8]; - fseek(nand, 0x220, SEEK_SET); - fread(bootparams, 4, 8, nand); - - Log(LogLevel::Debug, "ARM9: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n", - bootparams[0], bootparams[1], bootparams[2], bootparams[3]); - Log(LogLevel::Debug, "ARM7: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n", - bootparams[4], bootparams[5], bootparams[6], bootparams[7]); - - // read and apply new-WRAM settings - - MBK[0][8] = 0; - MBK[1][8] = 0; - - u32 mbk[12]; - fseek(nand, 0x380, SEEK_SET); - fread(mbk, 4, 12, nand); - - MapNWRAM_A(0, mbk[0] & 0xFF); - MapNWRAM_A(1, (mbk[0] >> 8) & 0xFF); - MapNWRAM_A(2, (mbk[0] >> 16) & 0xFF); - MapNWRAM_A(3, mbk[0] >> 24); - - MapNWRAM_B(0, mbk[1] & 0xFF); - MapNWRAM_B(1, (mbk[1] >> 8) & 0xFF); - MapNWRAM_B(2, (mbk[1] >> 16) & 0xFF); - MapNWRAM_B(3, mbk[1] >> 24); - MapNWRAM_B(4, mbk[2] & 0xFF); - MapNWRAM_B(5, (mbk[2] >> 8) & 0xFF); - MapNWRAM_B(6, (mbk[2] >> 16) & 0xFF); - MapNWRAM_B(7, mbk[2] >> 24); - - MapNWRAM_C(0, mbk[3] & 0xFF); - MapNWRAM_C(1, (mbk[3] >> 8) & 0xFF); - MapNWRAM_C(2, (mbk[3] >> 16) & 0xFF); - MapNWRAM_C(3, mbk[3] >> 24); - MapNWRAM_C(4, mbk[4] & 0xFF); - MapNWRAM_C(5, (mbk[4] >> 8) & 0xFF); - MapNWRAM_C(6, (mbk[4] >> 16) & 0xFF); - MapNWRAM_C(7, mbk[4] >> 24); - - MapNWRAMRange(0, 0, mbk[5]); - MapNWRAMRange(0, 1, mbk[6]); - MapNWRAMRange(0, 2, mbk[7]); - - MapNWRAMRange(1, 0, mbk[8]); - MapNWRAMRange(1, 1, mbk[9]); - MapNWRAMRange(1, 2, mbk[10]); - - // TODO: find out why it is 0xFF000000 - mbk[11] &= 0x00FFFF0F; - MBK[0][8] = mbk[11]; - MBK[1][8] = mbk[11]; - - // load boot2 binaries + if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot)) + { + // TODO: figure out default MBK mapping + // MBK1..5: disable mappings + for (int i = 0; i < 8; ++i) + { + if (i < 4) + MapNWRAM_A(i, 0); + MapNWRAM_B(i, 0); + MapNWRAM_C(i, 0); + } + // MBK6..8: address mappings: nothing mapped + for (int i = 0; i < 6; ++i) + { + MapNWRAMRange(i & 1, i >> 1, 0); + } + // MBK9: ARM9 allowed to write + MBK[0][8] = 0; + MBK[1][8] = 0; + } + else + { + fseek(nand, 0x220, SEEK_SET); + fread(bootparams, 4, 8, nand); - AES_ctx ctx; - const u8 boot2key[16] = {0xAD, 0x34, 0xEC, 0xF9, 0x62, 0x6E, 0xC2, 0x3A, 0xF6, 0xB4, 0x6C, 0x00, 0x80, 0x80, 0xEE, 0x98}; - u8 boot2iv[16]; - u8 tmp[16]; - u32 dstaddr; + Log(LogLevel::Debug, "ARM9: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n", + bootparams[0], bootparams[1], bootparams[2], bootparams[3]); + Log(LogLevel::Debug, "ARM7: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n", + bootparams[4], bootparams[5], bootparams[6], bootparams[7]); - *(u32*)&tmp[0] = bootparams[3]; - *(u32*)&tmp[4] = -bootparams[3]; - *(u32*)&tmp[8] = ~bootparams[3]; - *(u32*)&tmp[12] = 0; - for (int i = 0; i < 16; i++) boot2iv[i] = tmp[15-i]; + // read and apply new-WRAM settings - AES_init_ctx_iv(&ctx, boot2key, boot2iv); + MBK[0][8] = 0; + MBK[1][8] = 0; - fseek(nand, bootparams[0], SEEK_SET); - dstaddr = bootparams[2]; - for (u32 i = 0; i < bootparams[3]; i += 16) - { - u8 data[16]; - fread(data, 16, 1, nand); + u32 mbk[12]; + fseek(nand, 0x380, SEEK_SET); + fread(mbk, 4, 12, nand); - for (int j = 0; j < 16; j++) tmp[j] = data[15-j]; - AES_CTR_xcrypt_buffer(&ctx, tmp, 16); - for (int j = 0; j < 16; j++) data[j] = tmp[15-j]; + MapNWRAM_A(0, mbk[0] & 0xFF); + MapNWRAM_A(1, (mbk[0] >> 8) & 0xFF); + MapNWRAM_A(2, (mbk[0] >> 16) & 0xFF); + MapNWRAM_A(3, mbk[0] >> 24); - ARM9Write32(dstaddr, *(u32*)&data[0]); dstaddr += 4; - ARM9Write32(dstaddr, *(u32*)&data[4]); dstaddr += 4; - ARM9Write32(dstaddr, *(u32*)&data[8]); dstaddr += 4; - ARM9Write32(dstaddr, *(u32*)&data[12]); dstaddr += 4; - } + MapNWRAM_B(0, mbk[1] & 0xFF); + MapNWRAM_B(1, (mbk[1] >> 8) & 0xFF); + MapNWRAM_B(2, (mbk[1] >> 16) & 0xFF); + MapNWRAM_B(3, mbk[1] >> 24); + MapNWRAM_B(4, mbk[2] & 0xFF); + MapNWRAM_B(5, (mbk[2] >> 8) & 0xFF); + MapNWRAM_B(6, (mbk[2] >> 16) & 0xFF); + MapNWRAM_B(7, mbk[2] >> 24); - *(u32*)&tmp[0] = bootparams[7]; - *(u32*)&tmp[4] = -bootparams[7]; - *(u32*)&tmp[8] = ~bootparams[7]; - *(u32*)&tmp[12] = 0; - for (int i = 0; i < 16; i++) boot2iv[i] = tmp[15-i]; + MapNWRAM_C(0, mbk[3] & 0xFF); + MapNWRAM_C(1, (mbk[3] >> 8) & 0xFF); + MapNWRAM_C(2, (mbk[3] >> 16) & 0xFF); + MapNWRAM_C(3, mbk[3] >> 24); + MapNWRAM_C(4, mbk[4] & 0xFF); + MapNWRAM_C(5, (mbk[4] >> 8) & 0xFF); + MapNWRAM_C(6, (mbk[4] >> 16) & 0xFF); + MapNWRAM_C(7, mbk[4] >> 24); - AES_init_ctx_iv(&ctx, boot2key, boot2iv); + MapNWRAMRange(0, 0, mbk[5]); + MapNWRAMRange(0, 1, mbk[6]); + MapNWRAMRange(0, 2, mbk[7]); - fseek(nand, bootparams[4], SEEK_SET); - dstaddr = bootparams[6]; - for (u32 i = 0; i < bootparams[7]; i += 16) - { - u8 data[16]; - fread(data, 16, 1, nand); + MapNWRAMRange(1, 0, mbk[8]); + MapNWRAMRange(1, 1, mbk[9]); + MapNWRAMRange(1, 2, mbk[10]); - for (int j = 0; j < 16; j++) tmp[j] = data[15-j]; - AES_CTR_xcrypt_buffer(&ctx, tmp, 16); - for (int j = 0; j < 16; j++) data[j] = tmp[15-j]; + // TODO: find out why it is 0xFF000000 + mbk[11] &= 0x00FFFF0F; + MBK[0][8] = mbk[11]; + MBK[1][8] = mbk[11]; + + // load boot2 binaries + + AES_ctx ctx; + const u8 boot2key[16] = {0xAD, 0x34, 0xEC, 0xF9, 0x62, 0x6E, 0xC2, 0x3A, 0xF6, 0xB4, 0x6C, 0x00, 0x80, 0x80, 0xEE, 0x98}; + u8 boot2iv[16]; + u8 tmp[16]; + u32 dstaddr; + + *(u32*)&tmp[0] = bootparams[3]; + *(u32*)&tmp[4] = -bootparams[3]; + *(u32*)&tmp[8] = ~bootparams[3]; + *(u32*)&tmp[12] = 0; + for (int i = 0; i < 16; i++) boot2iv[i] = tmp[15-i]; + + AES_init_ctx_iv(&ctx, boot2key, boot2iv); + + fseek(nand, bootparams[0], SEEK_SET); + dstaddr = bootparams[2]; + for (u32 i = 0; i < bootparams[3]; i += 16) + { + u8 data[16]; + fread(data, 16, 1, nand); + + for (int j = 0; j < 16; j++) tmp[j] = data[15-j]; + AES_CTR_xcrypt_buffer(&ctx, tmp, 16); + for (int j = 0; j < 16; j++) data[j] = tmp[15-j]; + + ARM9Write32(dstaddr, *(u32*)&data[0]); dstaddr += 4; + ARM9Write32(dstaddr, *(u32*)&data[4]); dstaddr += 4; + ARM9Write32(dstaddr, *(u32*)&data[8]); dstaddr += 4; + ARM9Write32(dstaddr, *(u32*)&data[12]); dstaddr += 4; + } + + *(u32*)&tmp[0] = bootparams[7]; + *(u32*)&tmp[4] = -bootparams[7]; + *(u32*)&tmp[8] = ~bootparams[7]; + *(u32*)&tmp[12] = 0; + for (int i = 0; i < 16; i++) boot2iv[i] = tmp[15-i]; - ARM7Write32(dstaddr, *(u32*)&data[0]); dstaddr += 4; - ARM7Write32(dstaddr, *(u32*)&data[4]); dstaddr += 4; - ARM7Write32(dstaddr, *(u32*)&data[8]); dstaddr += 4; - ARM7Write32(dstaddr, *(u32*)&data[12]); dstaddr += 4; + AES_init_ctx_iv(&ctx, boot2key, boot2iv); + + fseek(nand, bootparams[4], SEEK_SET); + dstaddr = bootparams[6]; + for (u32 i = 0; i < bootparams[7]; i += 16) + { + u8 data[16]; + fread(data, 16, 1, nand); + + for (int j = 0; j < 16; j++) tmp[j] = data[15-j]; + AES_CTR_xcrypt_buffer(&ctx, tmp, 16); + for (int j = 0; j < 16; j++) data[j] = tmp[15-j]; + + ARM7Write32(dstaddr, *(u32*)&data[0]); dstaddr += 4; + ARM7Write32(dstaddr, *(u32*)&data[4]); dstaddr += 4; + ARM7Write32(dstaddr, *(u32*)&data[8]); dstaddr += 4; + ARM7Write32(dstaddr, *(u32*)&data[12]); dstaddr += 4; + } } #define printhex(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[z]); printf("\n"); } @@ -894,35 +949,44 @@ bool LoadNAND() Log(LogLevel::Debug, "eMMC CID: "); printhex(eMMC_CID, 16); Log(LogLevel::Debug, "Console ID: %" PRIx64 "\n", ConsoleID); - u32 eaddr = 0x03FFE6E4; - ARM7Write32(eaddr+0x00, *(u32*)&eMMC_CID[0]); - ARM7Write32(eaddr+0x04, *(u32*)&eMMC_CID[4]); - ARM7Write32(eaddr+0x08, *(u32*)&eMMC_CID[8]); - ARM7Write32(eaddr+0x0C, *(u32*)&eMMC_CID[12]); - ARM7Write16(eaddr+0x2C, 0x0001); - ARM7Write16(eaddr+0x2E, 0x0001); - ARM7Write16(eaddr+0x3C, 0x0100); - ARM7Write16(eaddr+0x3E, 0x40E0); - ARM7Write16(eaddr+0x42, 0x0001); - - memcpy(&NDS::ARM9->ITCM[0x4400], &ARM9iBIOS[0x87F4], 0x400); - memcpy(&NDS::ARM9->ITCM[0x4800], &ARM9iBIOS[0x9920], 0x80); - memcpy(&NDS::ARM9->ITCM[0x4894], &ARM9iBIOS[0x99A0], 0x1048); - memcpy(&NDS::ARM9->ITCM[0x58DC], &ARM9iBIOS[0xA9E8], 0x1048); - - u8 ARM7Init[0x3C00]; - memset(ARM7Init, 0, 0x3C00); - memcpy(&ARM7Init[0x0000], &ARM7iBIOS[0x8188], 0x200); - memcpy(&ARM7Init[0x0200], &ARM7iBIOS[0xB5D8], 0x40); - memcpy(&ARM7Init[0x0254], &ARM7iBIOS[0xC6D0], 0x1048); - memcpy(&ARM7Init[0x129C], &ARM7iBIOS[0xD718], 0x1048); - - for (u32 i = 0; i < 0x3C00; i+=4) - ARM7Write32(0x03FFC400+i, *(u32*)&ARM7Init[i]); - - // repoint the CPUs to the boot2 binaries - NDS::ARM9->JumpTo(bootparams[2]); - NDS::ARM7->JumpTo(bootparams[6]); + if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot)) + { + // point CPUs to boot ROM reset vectors + NDS::ARM9->JumpTo(0xFFFF0000); + NDS::ARM7->JumpTo(0x00000000); + } + else + { + u32 eaddr = 0x03FFE6E4; + ARM7Write32(eaddr+0x00, *(u32*)&eMMC_CID[0]); + ARM7Write32(eaddr+0x04, *(u32*)&eMMC_CID[4]); + ARM7Write32(eaddr+0x08, *(u32*)&eMMC_CID[8]); + ARM7Write32(eaddr+0x0C, *(u32*)&eMMC_CID[12]); + ARM7Write16(eaddr+0x2C, 0x0001); + ARM7Write16(eaddr+0x2E, 0x0001); + ARM7Write16(eaddr+0x3C, 0x0100); + ARM7Write16(eaddr+0x3E, 0x40E0); + ARM7Write16(eaddr+0x42, 0x0001); + + memcpy(&NDS::ARM9->ITCM[0x4400], &ARM9iBIOS[0x87F4], 0x400); + memcpy(&NDS::ARM9->ITCM[0x4800], &ARM9iBIOS[0x9920], 0x80); + memcpy(&NDS::ARM9->ITCM[0x4894], &ARM9iBIOS[0x99A0], 0x1048); + memcpy(&NDS::ARM9->ITCM[0x58DC], &ARM9iBIOS[0xA9E8], 0x1048); + + u8 ARM7Init[0x3C00]; + memset(ARM7Init, 0, 0x3C00); + memcpy(&ARM7Init[0x0000], &ARM7iBIOS[0x8188], 0x200); + memcpy(&ARM7Init[0x0200], &ARM7iBIOS[0xB5D8], 0x40); + memcpy(&ARM7Init[0x0254], &ARM7iBIOS[0xC6D0], 0x1048); + memcpy(&ARM7Init[0x129C], &ARM7iBIOS[0xD718], 0x1048); + + for (u32 i = 0; i < 0x3C00; i+=4) + ARM7Write32(0x03FFC400+i, *(u32*)&ARM7Init[i]); + + // repoint the CPUs to the boot2 binaries + NDS::ARM9->JumpTo(bootparams[2]); + NDS::ARM7->JumpTo(bootparams[6]); + } DSi_NAND::PatchUserData(); @@ -2680,6 +2744,7 @@ u8 ARM7IORead8(u32 addr) case 0x04004000: return SCFG_BIOS & 0xFF; case 0x04004001: return SCFG_BIOS >> 8; + case 0x04004002: return 0; // SCFG_ROMWE, always 0 CASE_READ8_32BIT(0x04004040, MBK[1][0]) CASE_READ8_32BIT(0x04004044, MBK[1][1]) @@ -2706,6 +2771,13 @@ u8 ARM7IORead8(u32 addr) case 0x4004700: return DSi_DSP::SNDExCnt; case 0x4004701: return DSi_DSP::SNDExCnt >> 8; + + case 0x04004C00: return GPIO_Data; + case 0x04004C01: return GPIO_Dir; + case 0x04004C02: return GPIO_IEdgeSel; + case 0x04004C03: return GPIO_IE; + case 0x04004C04: return GPIO_WiFi & 0xff; + case 0x04004C05: return GPIO_WiFi >> 8; } return NDS::ARM7IORead8(addr); @@ -2719,6 +2791,7 @@ u16 ARM7IORead16(u32 addr) case 0x0400021C: return NDS::IF2; case 0x04004000: return SCFG_BIOS; + case 0x04004002: return 0; // SCFG_ROMWE, always 0 case 0x04004004: return SCFG_Clock7; case 0x04004006: return 0; // JTAG register case 0x04004010: return SCFG_MC & 0xFFFF; @@ -2740,6 +2813,10 @@ u16 ARM7IORead16(u32 addr) case 0x04004D08: return 0; case 0x4004700: return DSi_DSP::SNDExCnt; + + case 0x04004C00: return GPIO_Data | ((u16)GPIO_Dir << 8); + case 0x04004C02: return GPIO_IEdgeSel | ((u16)GPIO_IE << 8); + case 0x04004C04: return GPIO_WiFi; } if (addr >= 0x04004800 && addr < 0x04004A00) @@ -2845,6 +2922,9 @@ void ARM7IOWrite8(u32 addr, u8 val) return; SCFG_BIOS |= ((val & 0x07) << 8); return; + case 0x04004002: + // SCFG_ROMWE. ignored, as it always reads as 0 + return; case 0x04004060: case 0x04004061: case 0x04004062: @@ -2869,6 +2949,22 @@ void ARM7IOWrite8(u32 addr, u8 val) case 0x4004701: DSi_DSP::WriteSNDExCnt(((u16)val << 8) | (DSi_DSP::SNDExCnt & 0x00FF)); return; + + case 0x04004C00: + GPIO_Data = val; + return; + case 0x04004C01: + GPIO_Dir = val; + return; + case 0x04004C02: + GPIO_IEdgeSel = val; + return; + case 0x04004C03: + GPIO_IE = val; + return; + case 0x04004C04: + GPIO_WiFi = val | (GPIO_WiFi & 0xff00); + return; } if (addr >= 0x04004420 && addr < 0x04004430) @@ -2919,6 +3015,9 @@ void ARM7IOWrite16(u32 addr, u16 val) return; SCFG_BIOS |= (val & 0x0703); return; + case 0x04004002: + // SCFG_ROMWE. ignored, as it always reads as 0 + return; case 0x04004004: if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/ return; @@ -2942,9 +3041,25 @@ void ARM7IOWrite16(u32 addr, u16 val) } return; + case 0x04004406: + DSi_AES::WriteBlkCnt(val<<16); + return; + case 0x4004700: DSi_DSP::WriteSNDExCnt(val); return; + + case 0x04004C00: + GPIO_Data = val & 0xff; + GPIO_Dir = val >> 8; + return; + case 0x04004C02: + GPIO_IEdgeSel = val & 0xff; + GPIO_IE = val >> 8; + return; + case 0x04004C04: + GPIO_WiFi = val; + return; } if (addr >= 0x04004420 && addr < 0x04004430) |