Fix bootloader

This commit is contained in:
RocketRobz 2018-10-05 21:59:31 -06:00
parent c311120c0c
commit 2a0f5e7c38
8 changed files with 108 additions and 112 deletions

View File

@ -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;

3
bootloader/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*build
load.bin
load.elf

View File

@ -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)

View File

@ -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

View File

@ -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 <nds/arm7/audio.h>
#include <nds/arm7/sdmmc.h>
#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();

View File

@ -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)

View File

@ -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

View File

@ -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;