dsi/exploits/generictwlpayload/arm9stub/source/arm9stub.c
2016-10-29 01:36:20 -04:00

110 lines
2.9 KiB
C

#include "common.h"
#include <nds/system.h>
#include <nds/memory.h>
void memset32(void* addr, int len);
#ifdef BOOTHB
void init_argv(tNDSHeader *hdr)
{
u32 *param = (u32*)(BOOTLDR_NDS-0x1000-8);
char *argv_params = (char*)(BOOTLDR_NDS-0x1000);
char *argv_dest;
int i, pos = 0, argc, argsizetmp, argsize = 0;
if(*param != 0x56475241)return;
argv_dest = (char*)(hdr->arm9destination + hdr->arm9binarySize);
__system_argv->argvMagic = ARGV_MAGIC;
__system_argv->commandLine = argv_dest;
argc = param[1];
memset_arm9((u32*)argv_dest, 0, 1024);
for(i=0; i<argc; i++)
{
strncpy(&argv_dest[pos], &argv_params[pos], 1024-pos);
argsizetmp=strlen(&argv_params[pos])+1;
pos+=argsizetmp;
argsize+=argsizetmp;
}
__system_argv->length = argsize;
}
#endif
int main(void)
{
tNDSHeader *hdr = (tNDSHeader*)BOOTLDR_NDS;
void (*func_ptr)(void);
int DSi_mode = 0;
if(((*((vu32*)0x04004000)) & 3)==1)DSi_mode = 1;
memset32((void*)0x02004000, (BOOTLDR_NDS-0x02004000)-8-0x1000);//clear RAM upto where the .nds is.
DC_FlushAll();
memcpy_arm9((u32*)hdr->arm9destination, (u32*)(BOOTLDR_NDS + hdr->arm9romOffset), hdr->arm9binarySize);
if(DSi_mode && BOOTLDR_TWLNDSHEADER->arm9ibinarySize)memcpy_arm9((u32*)BOOTLDR_TWLNDSHEADER->arm9idestination, (u32*)(BOOTLDR_NDS + BOOTLDR_TWLNDSHEADER->arm9iromOffset), BOOTLDR_TWLNDSHEADER->arm9ibinarySize);//Load the 9i bin when used.
DC_FlushRange((void*)hdr->arm9destination, hdr->arm9binarySize);
if(DSi_mode && BOOTLDR_TWLNDSHEADER->arm9ibinarySize)DC_FlushRange((u32*)BOOTLDR_TWLNDSHEADER->arm9idestination, BOOTLDR_TWLNDSHEADER->arm9ibinarySize);
DC_InvalidateAll();
IC_InvalidateAll();
#ifndef BOOTHB
IPC_SendSync(0x0);
#endif
while(REG_VCOUNT!=192);//Wait for a vblank before copying the header to NDSHEADER to make sure Arm7 is executing our bootstub first.
while(REG_VCOUNT==192);
memcpy_arm9((u32*)NDSHEADER, (u32*)BOOTLDR_NDS, 0x160);
DC_FlushRange((void*)NDSHEADER, 0x160);
if(DSi_mode)
{
#ifdef BOOTHB
memset_arm9((void*)0x02ffe000, 0, 0x1000);
#endif
memcpy((void*)0x02ffe000, (void*)BOOTLDR_NDS, 0x200);
if(BOOTLDR_NDSHEADER->headerSize>=0x1000)memcpy((u32*)0x02ffe200, (u32*)(BOOTLDR_NDS+0x200), 0x1000-0x200);
DC_FlushRange((void*)0x02ffe000, 0x1000);
}
#ifdef BOOTHB
init_argv(hdr);
#endif
memset32((u32*)BOOTLDR_NDS-8-0x1000, 0x1000);
BOOTFLAG = 1;
DC_FlushRange((void*)BOOTFLAG, 4);
while(BOOTFLAG!=2)DC_InvalidateAll();
while(REG_VCOUNT!=192);//Sync with Arm7 before jumping to the bin.
while(REG_VCOUNT==192);
while(BOOTFLAG!=3)DC_InvalidateAll();
func_ptr = (void*)NDSHEADER->arm9executeAddress;
func_ptr();
while(1);//Should never happen.
return 0;
}
void* memcpy_arm9(u32 *a, u32 *b, size_t len)
{
u32 *bufa = a, *bufb = b;
while(len>0)
{
*bufa = *bufb;
bufa++;
bufb++;
len-=4;
}
return a;
}
void* memset_arm9(u32 *buffer, int val, size_t len)
{
u32 *buf = buffer;
while(len>0)
{
*buf = val;
buf++;
len-=4;
}
return buffer;
}