diff --git a/BootLoader/source/clear_cache.arm9.s b/BootLoader/source/clear_cache.arm9.s index 49ec8bb..9d37fe9 100644 --- a/BootLoader/source/clear_cache.arm9.s +++ b/BootLoader/source/clear_cache.arm9.s @@ -41,28 +41,5 @@ BEGIN_ASM_FUNC arm9_clearCache mcr p15, 0, r3, c7, c6, 0 @ Flush DCache mcr p15, 0, r3, c7, c10, 4 @ empty write buffer - mcr p15, 0, r3, c3, c0, 0 @ disable write buffer (def = 0) - - mcr p15, 0, r3, c2, c0, 0 @ disable DTCM and protection unit - - mcr p15, 0, r3, c6, c0, 0 @ disable protection unit 0 (def = 0) - mcr p15, 0, r3, c6, c1, 0 @ disable protection unit 1 (def = 0) - mcr p15, 0, r3, c6, c2, 0 @ disable protection unit 2 (def = 0) - mcr p15, 0, r3, c6, c3, 0 @ disable protection unit 3 (def = 0) - mcr p15, 0, r3, c6, c4, 0 @ disable protection unit 4 (def = ?) - mcr p15, 0, r3, c6, c5, 0 @ disable protection unit 5 (def = ?) - mcr p15, 0, r3, c6, c6, 0 @ disable protection unit 6 (def = ?) - mcr p15, 0, r3, c6, c7, 0 @ disable protection unit 7 (def = ?) - - mcr p15, 0, r3, c5, c0, 3 @ IAccess - mcr p15, 0, r3, c5, c0, 2 @ DAccess - - mov r3, #0x00800000 - add r3, r3, #0x00A - mcr p15, 0, r3, c9, c1, 0 @ DTCM base (def = 0x0080000A) ??? - - mov r3, #0x0000000C - mcr p15, 0, r3, c9, c1, 1 @ ITCM base (def = 0x0000000C) ??? - bx lr diff --git a/BootLoader/source/common.h b/BootLoader/source/common.h index 4d959d1..6ca2e9d 100755 --- a/BootLoader/source/common.h +++ b/BootLoader/source/common.h @@ -20,6 +20,7 @@ #define _COMMON_H #include +#include #include #define resetCpu() \ @@ -32,10 +33,28 @@ enum { ERR_NONE=0x00, ERR_STS_CLR_MEM=0x01, ERR_STS_LOAD_BIN=0x02, ERR_STS_HOOK_ ERR_NOCHEAT=0x21, ERR_HOOK=0x22, } ERROR_CODES; -enum {ARM9_BOOT, ARM9_START, ARM9_MEMCLR, ARM9_READY, ARM9_BOOTBIN, ARM9_DISPERR} ARM9_STATE; -extern volatile int arm9_stateFlag; +// Values fixed so they can be shared with ASM code +enum { + ARM9_BOOT = 0, + ARM9_START = 1, + ARM9_RESET = 2, + ARM9_READY = 3, + ARM9_MEMCLR = 4 + } ARM9_STATE; + +enum { + ARM7_BOOT = 0, + ARM7_START = 1, + ARM7_RESET = 2, + ARM7_READY = 3, + ARM7_MEMCLR = 4, + ARM7_LOADBIN = 5, + ARM7_HOOKBIN = 6, + ARM7_BOOTBIN = 7, + ARM7_ERR = 8 + } ARM7_STATE; + extern volatile u32 arm9_errorCode; -extern volatile bool arm9_errorClearBG; static inline void dmaFill(const void* src, void* dest, uint32 size) { DMA_SRC(3) = (uint32)src; @@ -50,5 +69,13 @@ static inline void copyLoop (u32* dest, const u32* src, size_t size) { } while (size -= 4); } +static inline void ipcSendState(uint8_t state) { + REG_IPC_SYNC = (state & 0x0f) << 8; +} + +static inline uint8_t ipcRecvState(void) { + return (uint8_t)(REG_IPC_SYNC & 0x0f); +} + #endif // _COMMON_H diff --git a/BootLoader/source/main.arm7.c b/BootLoader/source/main.arm7.c index d37911d..5e63f9b 100755 --- a/BootLoader/source/main.arm7.c +++ b/BootLoader/source/main.arm7.c @@ -49,7 +49,11 @@ #include "common.h" #include "read_card.h" -void arm7_clearmem (void* loc, size_t len); +/*------------------------------------------------------------------------- +External functions +--------------------------------------------------------------------------*/ +extern void arm7_clearmem (void* loc, size_t len); +extern void arm7_reset (void); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Important things @@ -60,27 +64,13 @@ tNDSHeader* ndsHeader = (tNDSHeader*)NDS_HEAD; // Used for debugging purposes /* Disabled for now. Re-enable to debug problems static void errorOutput (u32 code) { - // Wait until the ARM9 is ready - while (arm9_stateFlag != ARM9_READY); - // Set the error code, then tell ARM9 to display it +// Set the error code, then set our state to "error" arm9_errorCode = code; - arm9_errorClearBG = true; - arm9_stateFlag = ARM9_DISPERR; + ipcSendState(ARM7_ERR); // Stop while(1); } */ - -static void debugOutput (u32 code) { - // Wait until the ARM9 is ready - while (arm9_stateFlag != ARM9_READY); - // Set the error code, then tell ARM9 to display it - arm9_errorCode = code; - arm9_errorClearBG = false; - arm9_stateFlag = ARM9_DISPERR; - // Wait for completion - while (arm9_stateFlag != ARM9_READY); -} //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Firmware stuff @@ -201,30 +191,6 @@ int arm7_loadBinary (void) { } -/*------------------------------------------------------------------------- -arm7_startBinary -Jumps to the ARM7 NDS binary in sync with the display and ARM9 -Written by Darkain, modified by Chishm. ---------------------------------------------------------------------------*/ -void arm7_startBinary (void) -{ - // Wait until the ARM9 is ready - while (arm9_stateFlag != ARM9_READY); - - while(REG_VCOUNT!=191); - while(REG_VCOUNT==191); - - // Get the ARM9 to boot - arm9_stateFlag = ARM9_BOOTBIN; - - while(REG_VCOUNT!=191); - while(REG_VCOUNT==191); - - // Start ARM7 - ((void (*)())(*(u32*)(0x27FFE34)))(); -} - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Main function @@ -232,26 +198,28 @@ void arm7_main (void) { int errorCode; - // Wait for ARM9 to at least start - while (arm9_stateFlag < ARM9_START); - - debugOutput (ERR_STS_CLR_MEM); + // Synchronise start + while (ipcRecvState() != ARM9_START); + ipcSendState(ARM7_START); + // Wait until ARM9 is ready + while (ipcRecvState() != ARM9_READY); + + ipcSendState(ARM7_MEMCLR); + // Get ARM7 to clear RAM arm7_resetMemory(); - debugOutput (ERR_STS_LOAD_BIN); + ipcSendState(ARM7_LOADBIN); // Load the NDS file - errorCode = arm7_loadBinary(); - if (errorCode) { - debugOutput(errorCode); + errorCode = arm7_loadBinary(); + if (errorCode) { + // errorOutput(errorCode); } - debugOutput (ERR_STS_START); + ipcSendState(ARM7_BOOTBIN); - arm7_startBinary(); - - return; + arm7_reset(); } diff --git a/BootLoader/source/main.arm9.c b/BootLoader/source/main.arm9.c index f62b3cd..62cb6ff 100755 --- a/BootLoader/source/main.arm9.c +++ b/BootLoader/source/main.arm9.c @@ -51,14 +51,19 @@ volatile u32 arm9_BLANK_RAM = 0; External functions --------------------------------------------------------------------------*/ extern void arm9_clearCache(void); +extern void arm9_reset (void); /*------------------------------------------------------------------------- arm9_errorOutput Displays an error code on screen. + +Each box is 2 bits, and left-to-right is most-significant bits to least. +Red = 00, Yellow = 01, Green = 10, Blue = 11 + Written by Chishm --------------------------------------------------------------------------*/ /* Re-enable for debugging. -static void arm9_errorOutput (u32 code, bool clearBG) { +static void arm9_errorOutput (u32 code) { int i, j, k; u16 colour; @@ -66,11 +71,9 @@ static void arm9_errorOutput (u32 code, bool clearBG) { REG_DISPCNT = MODE_FB0; VRAM_A_CR = VRAM_ENABLE; - if (clearBG) { - // Clear display - for (i = 0; i < 256*192; i++) { - VRAM_A[i] = 0x0000; - } + // Clear display + for (i = 0; i < 256*192; i++) { + VRAM_A[i] = 0x0000; } // Draw boxes of colour, signifying error codes @@ -95,51 +98,31 @@ static void arm9_errorOutput (u32 code, bool clearBG) { } } - if ((code >> 8) != 0) { - // Low 16 bits - for (i = 0; i < 8; i++) { // Pair of bits to use - if (((code>>(14-2*i))&3) == 0) { - colour = 0x001F; // Red - } else if (((code>>(14-2*i))&3) == 1) { - colour = 0x03FF; // Yellow - } else if (((code>>(14-2*i))&3) == 2) { - colour = 0x03E0; // Green - } else { - colour = 0x7C00; // Blue - } - for (j = 103; j < 119; j++) { // Row - for (k = 32*i+8; k < 32*i+24; k++) { // Column - VRAM_A[j*256+k] = colour; - } - } + // Low 16 bits + for (i = 0; i < 8; i++) { // Pair of bits to use + if (((code>>(14-2*i))&3) == 0) { + colour = 0x001F; // Red + } else if (((code>>(14-2*i))&3) == 1) { + colour = 0x03FF; // Yellow + } else if (((code>>(14-2*i))&3) == 2) { + colour = 0x03E0; // Green + } else { + colour = 0x7C00; // Blue } - } else { - // Low 8 bits - for (i = 0; i < 4; i++) { // Pair of bits to use - if (((code>>(6-2*i))&3) == 0) { - colour = 0x001F; // Red - } else if (((code>>(6-2*i))&3) == 1) { - colour = 0x03FF; // Yellow - } else if (((code>>(6-2*i))&3) == 2) { - colour = 0x03E0; // Green - } else { - colour = 0x7C00; // Blue - } - for (j = 87; j < 103; j++) { // Row - for (k = 32*i+72; k < 32*i+88; k++) { // Column - VRAM_A[j*256+k] = colour; - } + for (j = 103; j < 119; j++) { // Row + for (k = 32*i+8; k < 32*i+24; k++) { // Column + VRAM_A[j*256+k] = colour; } } } } - */ + /*------------------------------------------------------------------------- arm9_main Clears the ARM9's icahce and dcache Clears the ARM9's DMA channels and resets video memory -Jumps to the ARM9 NDS binary in sync with the display and ARM7 +Jumps to the ARM9 NDS binary in sync with the ARM7 Written by Darkain, modified by Chishm --------------------------------------------------------------------------*/ void arm9_main (void) { @@ -150,12 +133,17 @@ void arm9_main (void) { WRAM_CR = 0x03; REG_EXMEMCNT = 0xE880; - arm9_stateFlag = ARM9_START; - + // Disable interrupts REG_IME = 0; REG_IE = 0; REG_IF = ~0; + // Synchronise start + ipcSendState(ARM9_START); + while (ipcRecvState() != ARM7_START); + + ipcSendState(ARM9_MEMCLR); + arm9_clearCache(); for (i=0; i<16*1024; i+=4) { //first 16KB @@ -167,12 +155,40 @@ void arm9_main (void) { (*(vu32*)(i+0x00000000)) = 0x00000000; //clear ITCM } - arm9_stateFlag = ARM9_MEMCLR; - (*(vu32*)0x00803FFC) = 0; //IRQ_HANDLER ARM9 version (*(vu32*)0x00803FF8) = ~0; //VBLANK_INTR_WAIT_FLAGS ARM9 version - //clear out ARM9 DMA channels + + // Clear out FIFO + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; + REG_IPC_FIFO_CR = 0; + + // Blank out VRAM + VRAM_A_CR = 0x80; + VRAM_B_CR = 0x80; + // Don't mess with the VRAM used for execution + // VRAM_C_CR = 0; + VRAM_D_CR = 0x80; + VRAM_E_CR = 0x80; + VRAM_F_CR = 0x80; + VRAM_G_CR = 0x80; + VRAM_H_CR = 0x80; + VRAM_I_CR = 0x80; + BG_PALETTE[0] = 0xFFFF; + dmaFill((void*)&arm9_BLANK_RAM, BG_PALETTE+1, (2*1024)-2); + dmaFill((void*)&arm9_BLANK_RAM, OAM, 2*1024); + dmaFill((void*)&arm9_BLANK_RAM, VRAM_A, 256*1024); // Banks A, B + dmaFill((void*)&arm9_BLANK_RAM, VRAM_D, 272*1024); // Banks D, E, F, G, H, I + + // Clear out display registers + vu16 *mainregs = (vu16*)0x04000000; + vu16 *subregs = (vu16*)0x04001000; + for (i=0; i<43; i++) { + mainregs[i] = 0; + subregs[i] = 0; + } + + // Clear out ARM9 DMA channels for (i=0; i<4; i++) { DMA_CR(i) = 0; DMA_SRC(i) = 0; @@ -180,29 +196,6 @@ void arm9_main (void) { TIMER_CR(i) = 0; TIMER_DATA(i) = 0; } - - // Clear out FIFO - REG_IPC_SYNC = 0; - REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; - REG_IPC_FIFO_CR = 0; - - VRAM_A_CR = 0x80; - VRAM_B_CR = 0x80; -// Don't mess with the VRAM used for execution -// VRAM_C_CR = 0; - VRAM_D_CR = 0x80; - VRAM_E_CR = 0x80; - VRAM_F_CR = 0x80; - VRAM_G_CR = 0x80; - VRAM_H_CR = 0x80; - VRAM_I_CR = 0x80; - BG_PALETTE[0] = 0xFFFF; - dmaFill((void*)&arm9_BLANK_RAM, BG_PALETTE+1, (2*1024)-2); - dmaFill((void*)&arm9_BLANK_RAM, OAM, 2*1024); - dmaFill((void*)&arm9_BLANK_RAM, (void*)0x04000000, 0x56); //clear main display registers - dmaFill((void*)&arm9_BLANK_RAM, (void*)0x04001000, 0x56); //clear sub display registers - dmaFill((void*)&arm9_BLANK_RAM, VRAM_A, 256*1024); // Banks A, B - dmaFill((void*)&arm9_BLANK_RAM, VRAM_D, 272*1024); // Banks D, E, F, G, H, I REG_DISPSTAT = 0; videoSetMode(0); @@ -219,25 +212,21 @@ void arm9_main (void) { VRAM_I_CR = 0; REG_POWERCNT = 0x820F; - // set ARM9 state to ready and wait for it to change again - arm9_stateFlag = ARM9_READY; - while ( arm9_stateFlag != ARM9_BOOTBIN ) { - if (arm9_stateFlag == ARM9_DISPERR) { + + // set ARM9 state to ready and wait for instructions from ARM7 + ipcSendState(ARM9_READY); + while (ipcRecvState() != ARM7_BOOTBIN) { + if (ipcRecvState() == ARM7_ERR) { // Re-enable for debugging - // arm9_errorOutput (arm9_errorCode, arm9_errorClearBG); - if ( arm9_stateFlag == ARM9_DISPERR) { - arm9_stateFlag = ARM9_READY; - } + // arm9_errorOutput (arm9_errorCode); + // Halt after displaying error code + while(1); } } - // wait for vblank then boot - while(REG_VCOUNT!=191); - while(REG_VCOUNT==191); - // arm9_errorOutput (*(u32*)(first), true); - - ((void (*)())(*(u32*)(0x27FFE24)))(); + // ((void (*)())(*(u32*)(0x27FFE24)))(); + arm9_reset(); } diff --git a/BootLoader/source/reset.arm7.s b/BootLoader/source/reset.arm7.s new file mode 100644 index 0000000..344ee8a --- /dev/null +++ b/BootLoader/source/reset.arm7.s @@ -0,0 +1,81 @@ +/* + Copyright 2015 Dave Murphy (WinterMute) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + .text + .align 4 + + .arm +@--------------------------------------------------------------------------------- + .global arm7_reset + .type arm7_reset STT_FUNC +@--------------------------------------------------------------------------------- +arm7_reset: +@--------------------------------------------------------------------------------- + mrs r0, cpsr @ cpu interrupt disable + orr r0, r0, #0x80 @ (set i flag) + msr cpsr, r0 + + ldr r0, =0x380FFFC @ irq vector + mov r1, #0 + str r1, [r0] + sub r0, r0, #4 @ IRQ1 Check Bits + str r1, [r0] + sub r0, r0, #4 @ IRQ2 Check Bits + str r1, [r0] + + bic r0, r0, #0x7f + + msr cpsr_c, #0xd3 @ svc mode + mov sp, r0 + sub r0, r0, #64 + msr cpsr_c, #0xd2 @ irq mode + mov sp, r0 + sub r0, r0, #512 + msr cpsr_c, #0xdf @ system mode + mov sp, r0 + + mov r12, #0x04000000 + add r12, r12, #0x180 + + @ while (ipcRecvState() != ARM9_RESET); + mov r0, #2 + bl waitsync + @ ipcSendState(ARM7_RESET) + mov r0, #0x200 + strh r0, [r12] + + @ while(ipcRecvState() != ARM9_BOOT); + mov r0, #0 + bl waitsync + @ ipcSendState(ARM7_BOOT) + strh r0, [r12] + + ldr r0,=0x2FFFE34 + + ldr r0,[r0] + bx r0 + + .pool + +@--------------------------------------------------------------------------------- +waitsync: +@--------------------------------------------------------------------------------- + ldrh r1, [r12] + and r1, r1, #0x000f + cmp r0, r1 + bne waitsync + bx lr diff --git a/BootLoader/source/reset.arm9.s b/BootLoader/source/reset.arm9.s new file mode 100644 index 0000000..a0e969d --- /dev/null +++ b/BootLoader/source/reset.arm9.s @@ -0,0 +1,136 @@ +/* + Copyright 2006 - 2015 Dave Murphy (WinterMute) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#include + + .text + .align 4 + + .arm + + .arch armv5te + .cpu arm946e-s + +@--------------------------------------------------------------------------------- + .global arm9_reset + .type arm9_reset STT_FUNC +@--------------------------------------------------------------------------------- +arm9_reset: +@--------------------------------------------------------------------------------- + mrs r0, cpsr @ cpu interrupt disable + orr r0, r0, #0x80 @ (set i flag) + msr cpsr, r0 + + @ Switch off MPU + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #PROTECT_ENABLE + mcr p15, 0, r0, c1, c0, 0 + + + adr r12, mpu_initial_data + ldmia r12, {r0-r10} + + mcr p15, 0, r0, c2, c0, 0 + mcr p15, 0, r0, c2, c0, 1 + mcr p15, 0, r1, c3, c0, 0 + mcr p15, 0, r2, c5, c0, 2 + mcr p15, 0, r3, c5, c0, 3 + mcr p15, 0, r4, c6, c0, 0 + mcr p15, 0, r5, c6, c1, 0 + mcr p15, 0, r6, c6, c3, 0 + mcr p15, 0, r7, c6, c4, 0 + mcr p15, 0, r8, c6, c6, 0 + mcr p15, 0, r9, c6, c7, 0 + mcr p15, 0, r10, c9, c1, 0 + + mov r0, #0 + mcr p15, 0, r0, c6, c2, 0 @ PU Protection Unit Data/Unified Region 2 + mcr p15, 0, r0, c6, c5, 0 @ PU Protection Unit Data/Unified Region 5 + + mrc p15, 0, r0, c9, c1, 0 @ DTCM + mov r0, r0, lsr #12 @ base + mov r0, r0, lsl #12 @ size + add r0, r0, #0x4000 @ dtcm top + + sub r0, r0, #4 @ irq vector + mov r1, #0 + str r1, [r0] + sub r0, r0, #4 @ IRQ1 Check Bits + str r1, [r0] + + bic r0, r0, #0x7f + + msr cpsr_c, #0xd3 @ svc mode + mov sp, r0 + sub r0, r0, #64 + msr cpsr_c, #0xd2 @ irq mode + mov sp, r0 + sub r0, r0, #4096 + msr cpsr_c, #0xdf @ system mode + mov sp, r0 + + mov r12, #0x04000000 + add r12, r12, #0x180 + + @ ipcSendState(ARM9_RESET) + mov r0, #0x200 + strh r0, [r12] + @ while (ipcRecvState() != ARM7_RESET); + mov r0, #2 + bl waitsync + + @ ipcSendState(ARM9_BOOT) + mov r0, #0 + strh r0, [r12] + @ while (ipcRecvState() != ARM7_BOOT); + bl waitsync + + ldr r10, =0x2FFFE24 + ldr r2, [r10] + + @ Switch MPU to startup default + ldr r0, =0x00012078 + mcr p15, 0, r0, c1, c0, 0 + + bx r2 + + .pool + +@--------------------------------------------------------------------------------- +waitsync: +@--------------------------------------------------------------------------------- + ldrh r1, [r12] + and r1, r1, #0x000f + cmp r0, r1 + bne waitsync + bx lr + +mpu_initial_data: + .word 0x00000042 @ p15,0,c2,c0,0..1,r0 ;PU Cachability Bits for Data/Unified+Instruction Protection Region + .word 0x00000002 @ p15,0,c3,c0,0,r1 ;PU Write-Bufferability Bits for Data Protection Regions + .word 0x15111011 @ p15,0,c5,c0,2,r2 ;PU Extended Access Permission Data/Unified Protection Region + .word 0x05100011 @ p15,0,c5,c0,3,r3 ;PU Extended Access Permission Instruction Protection Region + .word 0x04000033 @ p15,0,c6,c0,0,r4 ;PU Protection Unit Data/Unified Region 0 + .word 0x0200002b @ p15,0,c6,c1,0,r5 ;PU Protection Unit Data/Unified Region 1 4MB + .word 0x08000035 @ p15,0,c6,c3,0,r6 ;PU Protection Unit Data/Unified Region 3 + .word 0x0300001b @ p15,0,c6,c4,0,r7 ;PU Protection Unit Data/Unified Region 4 + .word 0xffff001d @ p15,0,c6,c6,0,r8 ;PU Protection Unit Data/Unified Region 6 + .word 0x027ff017 @ p15,0,c6,c7,0,r9 ;PU Protection Unit Data/Unified Region 7 4KB + .word 0x0300000a @ p15,0,c9,c1,0,r10 ;TCM Data TCM Base and Virtual Size +itcm_reset_code_end: + diff --git a/README.md b/README.md index e63e553..0c287c9 100755 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ Launcher side of NitroHax without the cheat engine. Nothing much else to say abo The source to "Launch DS Cart" on FileTrip was never released. I rebuilt it after ahezard ported NitroHax to latest devkitarm. This project is GNU licensed so that original DS Launcher on File Trip should have included source anyways. That has been corrected here. :D -Credits go to Chism for NitroHax which this source is based from. \ No newline at end of file +Credits go to Chism for NitroHax which this source is based from and WinterMute for dslink source/reset code. \ No newline at end of file