From 2a0f5e7c38f3f21cc6ffbb2e20bffbde03ab6c8a Mon Sep 17 00:00:00 2001 From: RocketRobz Date: Fri, 5 Oct 2018 21:59:31 -0600 Subject: [PATCH] Fix bootloader --- arm9/source/nds_loader_arm9.c | 10 ++- bootloader/.gitignore | 3 + bootloader/Makefile | 4 +- bootloader/source/arm9clear.arm.c | 18 ----- bootloader/source/boot.c | 121 ++++++++++++++++++++++-------- bootloader/source/boot.h | 2 - bootloader/source/load_crt0.s | 3 + bootloader/source/sdmmc.c | 59 --------------- 8 files changed, 108 insertions(+), 112 deletions(-) create mode 100644 bootloader/.gitignore diff --git a/arm9/source/nds_loader_arm9.c b/arm9/source/nds_loader_arm9.c index c5dc700..f457366 100644 --- a/arm9/source/nds_loader_arm9.c +++ b/arm9/source/nds_loader_arm9.c @@ -31,6 +31,7 @@ #ifndef _NO_BOOTSTUB_ #include "bootstub_bin.h" +#include "exceptionstub_bin.h" #endif #include "nds_loader_arm9.h" @@ -403,6 +404,9 @@ dldiOffset: dsiSD: .word 0 */ + +void(*exceptionstub)(void) = (void(*)(void))0x2ffa000; + bool installBootStub(bool havedsiSD) { #ifndef _NO_BOOTSTUB_ extern char *fake_heap_end; @@ -424,7 +428,11 @@ bool installBootStub(bool havedsiSD) { bootstub->arm9reboot = (VoidFn)(((u32)bootstub->arm9reboot)+fake_heap_end); bootstub->arm7reboot = (VoidFn)(((u32)bootstub->arm7reboot)+fake_heap_end); bootstub->bootsize = load_bin_size; - + + memcpy(exceptionstub,exceptionstub_bin,exceptionstub_bin_size); + + exceptionstub(); + DC_FlushAll(); return ret; diff --git a/bootloader/.gitignore b/bootloader/.gitignore new file mode 100644 index 0000000..c6c6a5c --- /dev/null +++ b/bootloader/.gitignore @@ -0,0 +1,3 @@ +*build +load.bin +load.elf diff --git a/bootloader/Makefile b/bootloader/Makefile index 437ac39..cf3bf9e 100644 --- a/bootloader/Makefile +++ b/bootloader/Makefile @@ -33,7 +33,7 @@ CFLAGS += $(INCLUDE) $(EXTRA_CFLAGS) -DARM7 ASFLAGS := -g $(ARCH) $(EXTRA_CFLAGS) $(INCLUDE) LDFLAGS = -nostartfiles -T $(TOPDIR)/load.ld -g $(ARCH) -Wl,-Map,$(TARGET).map -LIBS := -lnds7 +LIBS := #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -50,7 +50,7 @@ ifneq ($(BUILD),$(notdir $(CURDIR))) #--------------------------------------------------------------------------------- export TOPDIR := $(CURDIR) -export LOADBIN := $(CURDIR)/../data/$(TARGET).bin +export LOADBIN ?= $(CURDIR)/$(TARGET).bin export LOADELF := $(CURDIR)/$(TARGET).elf export DEPSDIR := $(CURDIR)/$(BUILD) diff --git a/bootloader/source/arm9clear.arm.c b/bootloader/source/arm9clear.arm.c index b212da3..c08809e 100644 --- a/bootloader/source/arm9clear.arm.c +++ b/bootloader/source/arm9clear.arm.c @@ -71,24 +71,6 @@ void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn) while(1); } -void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)) clearMasterBright_ARM9 (void) -{ - u16 mode = 1 << 14; - - *(u16*)(0x0400006C + (0x1000 * 0)) = 0 + mode; - *(u16*)(0x0400006C + (0x1000 * 1)) = 0 + mode; - - // Return to passme loop - *((vu32*)0x02FFFE04) = (u32)0xE59FF018; // ldr pc, 0x02FFFE24 - *((vu32*)0x02FFFE24) = (u32)0x02FFFE04; // Set ARM9 Loop address - - asm volatile( - "\tbx %0\n" - : : "r" (0x02FFFE04) - ); - while(1); -} - /*------------------------------------------------------------------------- startBinary_ARM9 Jumps to the ARM9 NDS binary in sync with the display and ARM7 diff --git a/bootloader/source/boot.c b/bootloader/source/boot.c index 93c69a5..34e8ff9 100644 --- a/bootloader/source/boot.c +++ b/bootloader/source/boot.c @@ -1,10 +1,10 @@ /*----------------------------------------------------------------- boot.c - + BootLoader Loads a file into memory and runs it - All resetMemory and startBinary functions are based + All resetMemory and startBinary functions are based on the MultiNDS loader by Darkain. Original source available at: http://cvs.sourceforge.net/viewcvs.py/ndslib/ndslib/examples/loader/boot/main.cpp @@ -28,7 +28,7 @@ License: If you use this code, please give due credit and email me about your project at chishm@hotmail.com - + Helpful information: This code runs from VRAM bank C on ARM7 ------------------------------------------------------------------*/ @@ -46,20 +46,18 @@ Helpful information: #undef ARM9 #define ARM7 #include - +#include #include "fat.h" #include "dldi_patcher.h" #include "card.h" #include "boot.h" void arm7clearRAM(); -int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, void *out); -int sdmmc_sdcard_init(); -void sdmmc_controller_init(); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Important things -#define TEMP_MEM 0x02FFE000 +#define TEMP_MEM 0x02FFD000 +#define TWL_HEAD 0x02FFE000 #define NDS_HEAD 0x02FFFE00 #define TEMP_ARM9_START_ADDRESS (*(vu32*)0x02FFFFF4) @@ -73,6 +71,7 @@ extern unsigned long wantToPatchDLDI; extern unsigned long argStart; extern unsigned long argSize; extern unsigned long dsiSD; +extern unsigned long dsiMode; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Firmware stuff @@ -116,7 +115,7 @@ static inline void copyLoop (u32* dest, const u32* src, u32 size) { /*------------------------------------------------------------------------- passArgs_ARM7 -Copies the command line arguments to the end of the ARM9 binary, +Copies the command line arguments to the end of the ARM9 binary, then sets a flag in memory for the loaded NDS to use --------------------------------------------------------------------------*/ void passArgs_ARM7 (void) { @@ -124,15 +123,32 @@ void passArgs_ARM7 (void) { u32 ARM9_LEN = *((u32*)(NDS_HEAD + 0x02C)); u32* argSrc; u32* argDst; - + if (!argStart || !argSize) return; - + + if ( ARM9_DST == 0 && ARM9_LEN == 0) { + ARM9_DST = *((u32*)(NDS_HEAD + 0x038)); + ARM9_LEN = *((u32*)(NDS_HEAD + 0x03C)); + } + argSrc = (u32*)(argStart + (int)&_start); - - argDst = (u32*)((ARM9_DST + ARM9_LEN + 3) & ~3); // Word aligned - + + argDst = (u32*)((ARM9_DST + ARM9_LEN + 3) & ~3); // Word aligned + + if (dsiMode && (*(u8*)(NDS_HEAD + 0x012) & BIT(1))) + { + u32 ARM9i_DST = *((u32*)(TWL_HEAD + 0x1C8)); + u32 ARM9i_LEN = *((u32*)(TWL_HEAD + 0x1CC)); + if (ARM9i_LEN) + { + u32* argDst2 = (u32*)((ARM9i_DST + ARM9i_LEN + 3) & ~3); // Word aligned + if (argDst2 > argDst) + argDst = argDst2; + } + } + copyLoop(argDst, argSrc, argSize); - + __system_argv->argvMagic = ARGV_MAGIC; __system_argv->commandLine = (char*)argDst; __system_argv->length = argSize; @@ -153,7 +169,7 @@ void resetMemory_ARM7 (void) int i; u8 settings1, settings2; u32 settingsOffset = 0; - + REG_IME = 0; for (i=0; i<16; i++) { @@ -173,7 +189,7 @@ void resetMemory_ARM7 (void) TIMER_CR(i) = 0; TIMER_DATA(i) = 0; } - + arm7clearRAM(); REG_IE = 0; @@ -181,20 +197,25 @@ void resetMemory_ARM7 (void) (*(vu32*)(0x04000000-4)) = 0; //IRQ_HANDLER ARM7 version (*(vu32*)(0x04000000-8)) = ~0; //VBLANK_INTR_WAIT_FLAGS, ARM7 version REG_POWERCNT = 1; //turn off power to stuff - + // Get settings location boot_readFirmware((u32)0x00020, (u8*)&settingsOffset, 0x2); settingsOffset *= 8; - + // Reload DS Firmware settings boot_readFirmware(settingsOffset + 0x070, &settings1, 0x1); boot_readFirmware(settingsOffset + 0x170, &settings2, 0x1); - + if ((settings1 & 0x7F) == ((settings2+1) & 0x7F)) { boot_readFirmware(settingsOffset + 0x000, (u8*)0x02FFFC80, 0x70); } else { boot_readFirmware(settingsOffset + 0x100, (u8*)0x02FFFC80, 0x70); } + + ((vu32*)0x040044f0)[2] = 0x202DDD1D; + ((vu32*)0x040044f0)[3] = 0xE1A00005; + while((*(vu32*)0x04004400) & 0x2000000); + } @@ -212,7 +233,7 @@ void loadBinary_ARM7 (u32 fileCluster) u32 ARM7_SRC = ndsHeader[0x030>>2]; char* ARM7_DST = (char*)ndsHeader[0x038>>2]; u32 ARM7_LEN = ndsHeader[0x03C>>2]; - + // Load binaries into memory fileRead(ARM9_DST, fileCluster, ARM9_SRC, ARM9_LEN); fileRead(ARM7_DST, fileCluster, ARM7_SRC, ARM7_LEN); @@ -222,6 +243,24 @@ void loadBinary_ARM7 (u32 fileCluster) TEMP_ARM9_START_ADDRESS = ndsHeader[0x024>>2]; // Store for later ndsHeader[0x024>>2] = 0; dmaCopyWords(3, (void*)ndsHeader, (void*)NDS_HEAD, 0x170); + + if (dsiMode && (ndsHeader[0x10>>2]&BIT(16+1))) + { + // Read full TWL header + fileRead((char*)TWL_HEAD, fileCluster, 0, 0x1000); + + u32 ARM9i_SRC = *(u32*)(TWL_HEAD+0x1C0); + char* ARM9i_DST = (char*)*(u32*)(TWL_HEAD+0x1C8); + u32 ARM9i_LEN = *(u32*)(TWL_HEAD+0x1CC); + u32 ARM7i_SRC = *(u32*)(TWL_HEAD+0x1D0); + char* ARM7i_DST = (char*)*(u32*)(TWL_HEAD+0x1D8); + u32 ARM7i_LEN = *(u32*)(TWL_HEAD+0x1DC); + + if (ARM9i_LEN) + fileRead(ARM9i_DST, fileCluster, ARM9i_SRC, ARM9i_LEN); + if (ARM7i_LEN) + fileRead(ARM7i_DST, fileCluster, ARM7i_SRC, ARM7i_LEN); + } } /*------------------------------------------------------------------------- @@ -231,7 +270,7 @@ Written by Darkain. Modified by Chishm: * Removed MultiNDS specific stuff --------------------------------------------------------------------------*/ -void startBinary_ARM7 (void) { +void startBinary_ARM7 (void) { REG_IME=0; while(REG_VCOUNT!=191); while(REG_VCOUNT==191); @@ -242,7 +281,7 @@ void startBinary_ARM7 (void) { VoidFn arm7code = *(VoidFn*)(0x2FFFE34); arm7code(); } - +#ifndef NO_SDMMC int sdmmc_sd_readsectors(u32 sector_no, u32 numsectors, void *out); //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Main function @@ -251,21 +290,29 @@ bool sdmmc_inserted() { } bool sdmmc_startup() { - sdmmc_controller_init(); + sdmmc_controller_init(true); return sdmmc_sdcard_init() == 0; } bool sdmmc_readsectors(u32 sector_no, u32 numsectors, void *out) { return sdmmc_sdcard_readsectors(sector_no, numsectors, out) == 0; } +#endif +void mpu_reset(); +void mpu_reset_end(); int main (void) { - if (dsiSD) { +#ifdef NO_DLDI + dsiSD = true; + dsiMode = true; +#endif +#ifndef NO_SDMMC + if (dsiSD && dsiMode) { _io_dldi.fn_readSectors = sdmmc_readsectors; _io_dldi.fn_isInserted = sdmmc_inserted; _io_dldi.fn_startup = sdmmc_startup; } - +#endif u32 fileCluster = storedFileCluster; // Init card if(!FAT_InitFiles(initDisc)) @@ -280,7 +327,7 @@ int main (void) { { return -1; } - + // ARM9 clears its memory part 2 // copy ARM9 function to RAM, and make the ARM9 jump to it copyLoop((void*)TEMP_MEM, (void*)resetMemory2_ARM9, resetMemory2_ARM9_size); @@ -288,9 +335,16 @@ int main (void) { // Wait until the ARM9 has completed its task while ((*(vu32*)0x02FFFE24) == (u32)TEMP_MEM); + // ARM9 sets up mpu + // copy ARM9 function to RAM, and make the ARM9 jump to it + copyLoop((void*)TEMP_MEM, (void*)mpu_reset, mpu_reset_end - mpu_reset); + (*(vu32*)0x02FFFE24) = (u32)TEMP_MEM; // Make ARM9 jump to the function + // Wait until the ARM9 has completed its task + while ((*(vu32*)0x02FFFE24) == (u32)TEMP_MEM); + // Get ARM7 to clear RAM - resetMemory_ARM7(); - + resetMemory_ARM7(); + // ARM9 enters a wait loop // copy ARM9 function to RAM, and make the ARM9 jump to it copyLoop((void*)TEMP_MEM, (void*)startBinary_ARM9, startBinary_ARM9_size); @@ -298,12 +352,19 @@ int main (void) { // Load the NDS file loadBinary_ARM7(fileCluster); - + +#ifndef NO_DLDI // Patch with DLDI if desired if (wantToPatchDLDI) { dldiPatchBinary ((u8*)((u32*)NDS_HEAD)[0x0A], ((u32*)NDS_HEAD)[0x0B]); } +#endif +#ifndef NO_SDMMC + if (dsiSD && dsiMode) { + sdmmc_controller_init(true); + } +#endif // Pass command line arguments to loaded program passArgs_ARM7(); diff --git a/bootloader/source/boot.h b/bootloader/source/boot.h index 3bb312e..e71d9ff 100644 --- a/bootloader/source/boot.h +++ b/bootloader/source/boot.h @@ -3,8 +3,6 @@ #define resetMemory2_ARM9_size 0x400 void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)) resetMemory2_ARM9(); -#define clearMasterBright_ARM9_size 0x200 -void __attribute__ ((long_call)) __attribute__((naked)) __attribute__((noreturn)) clearMasterBright_ARM9(); #define startBinary_ARM9_size 0x100 void __attribute__ ((long_call)) __attribute__((noreturn)) __attribute__((naked)) startBinary_ARM9 (); #define ARM9_START_FLAG (*(vu8*)0x02FFFDFB) diff --git a/bootloader/source/load_crt0.s b/bootloader/source/load_crt0.s index ea7949b..6c57e6d 100644 --- a/bootloader/source/load_crt0.s +++ b/bootloader/source/load_crt0.s @@ -29,6 +29,7 @@ .global argStart .global argSize .global dsiSD + .global dsiMode @--------------------------------------------------------------------------------- .align 4 .arm @@ -52,6 +53,8 @@ dldiOffset: .word _dldi_start - _start dsiSD: .word 0 +dsiMode: + .word 0 startUp: mov r0, #0x04000000 diff --git a/bootloader/source/sdmmc.c b/bootloader/source/sdmmc.c index 13ff139..c7c8f83 100644 --- a/bootloader/source/sdmmc.c +++ b/bootloader/source/sdmmc.c @@ -48,13 +48,6 @@ void sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) { sdmmc_write16(REG_SDIRMASK1,0); sdmmc_write16(REG_SDSTATUS0,0); sdmmc_write16(REG_SDSTATUS1,0); -#ifdef DATA32_SUPPORT -// if(readdata)sdmmc_mask16(REG_DATACTL32, 0x1000, 0x800); -// if(writedata)sdmmc_mask16(REG_DATACTL32, 0x800, 0x1000); -// sdmmc_mask16(REG_DATACTL32,0x1800,2); -#else - sdmmc_mask16(REG_DATACTL32,0x1800,0); -#endif sdmmc_write16(REG_SDCMDARG0,args &0xFFFF); sdmmc_write16(REG_SDCMDARG1,args >> 16); sdmmc_write16(REG_SDCMD,cmd &0xFFFF); @@ -70,30 +63,22 @@ void sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) { while(1) { volatile uint16_t status1 = sdmmc_read16(REG_SDSTATUS1); -#ifdef DATA32_SUPPORT volatile uint16_t ctl32 = sdmmc_read16(REG_SDDATACTL32); if((ctl32 & 0x100)) -#else - if((status1 & TMIO_STAT1_RXRDY)) -#endif { if(readdata) { if(useBuf) { sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0); if(size > 0x1FF) { -#ifdef DATA32_SUPPORT if(useBuf32) { for(i = 0; i<0x200; i+=4) { *dataPtr32++ = sdmmc_read32(REG_SDFIFO32); } } else { -#endif for(i = 0; i<0x200; i+=2) { *dataPtr++ = sdmmc_read16(REG_SDFIFO); } -#ifdef DATA32_SUPPORT } -#endif size -= 0x200; } } @@ -101,33 +86,7 @@ void sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) { sdmmc_mask16(REG_SDDATACTL32, 0x800, 0); } } -#ifdef DATA32_SUPPORT - if(!(ctl32 & 0x200)) -#else - if((status1 & TMIO_STAT1_TXRQ)) -#endif - { - if(writedata) { - if(useBuf) { - sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0); - //sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_TXRQ); - if(size > 0x1FF) { -#ifdef DATA32_SUPPORT - for(i = 0; i<0x200; i+=4) { - sdmmc_write32(REG_SDFIFO32,*dataPtr32++); - } -#else - for(i = 0; i<0x200; i+=2) { - sdmmc_write16(REG_SDFIFO,*dataPtr++); - } -#endif - size -= 0x200; - } - } - sdmmc_mask16(REG_SDDATACTL32, 0x1000, 0); - } - } if(status1 & TMIO_MASK_GW) { ctx->error |= 4; break; @@ -178,21 +137,11 @@ void sdmmc_controller_init(bool force) { *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xF7FFu; *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xEFFFu; -#ifdef DATA32_SUPPORT *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u; -#else - *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u; -#endif *(vu16*)(SDMMC_BASE + REG_SDDATACTL) = (*(vu16*)(SDMMC_BASE + REG_SDDATACTL) & 0xFFDD) | 2; -#ifdef DATA32_SUPPORT *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFFu; *(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDFu; *(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 512; -#else - *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFDu; - *(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDDu; - *(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 0; -#endif *(vu16*)(SDMMC_BASE + REG_SDBLKCOUNT32) = 1; *(vu16*)(SDMMC_BASE + REG_SDRESET) &= 0xFFFEu; *(vu16*)(SDMMC_BASE + REG_SDRESET) |= 1u; @@ -201,18 +150,12 @@ void sdmmc_controller_init(bool force) { *(vu16*)(SDMMC_BASE + 0x0fc) |= 0xDBu; //SDCTL_RESERVED7 *(vu16*)(SDMMC_BASE + 0x0fe) |= 0xDBu; //SDCTL_RESERVED8 *(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu; -#ifdef DATA32_SUPPORT *(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x20; *(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EE; -#else - *(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x40; //Nintendo sets this to 0x20 - *(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EB; //Nintendo sets this to 0x40EE -#endif *(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu; *(vu16*)(SDMMC_BASE + REG_SDBLKLEN) = 512; *(vu16*)(SDMMC_BASE + REG_SDSTOP) = 0; - setTarget(&deviceSD); } //--------------------------------------------------------------------------------- @@ -287,10 +230,8 @@ int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, void *out) { setTarget(&deviceSD); sdmmc_write16(REG_SDSTOP,0x100); -#ifdef DATA32_SUPPORT sdmmc_write16(REG_SDBLKCOUNT32,numsectors); sdmmc_write16(REG_SDBLKLEN32,0x200); -#endif sdmmc_write16(REG_SDBLKCOUNT,numsectors); deviceSD.data = out;