diff --git a/.gitignore b/.gitignore index 743e75bed4..2e3d0cea65 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,4 @@ Debug Release ipch *.user -gx/app_booter/app_booter_*.bin +/wii/app_booter/app_booter.bin diff --git a/Makefile.ngc b/Makefile.ngc index 4b49f61c0d..c2fc82a9eb 100644 --- a/Makefile.ngc +++ b/Makefile.ngc @@ -37,9 +37,7 @@ CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map -T gx/ld/ogc.ld LIBS := -lfat -lretro_ngc -logc -APP_BOOTER_DIR = gx/app_booter - -OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter_ngc.binobj +OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -73,23 +71,19 @@ $(ELF_TARGET): $(OBJ) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< -%.bmpobj: %.bmp - $(LD) -r -b binary -o $@ $< - %.binobj: %.bin $(LD) -r -b binary -o $@ $< -$(APP_BOOTER_DIR)/app_booter_ngc.bin: - $(MAKE) -C $(APP_BOOTER_DIR) platform=ngc +%.bmpobj: %.bmp + $(LD) -r -b binary -o $@ $< pkg: all - cp -r $(DOL_TARGET) gx/pkg/CORE.dol + cp -r $(DOL_TARGET) ngc/pkg/CORE.dol clean: rm -f $(DOL_TARGET) rm -f $(ELF_TARGET) rm -f $(OBJ) - $(MAKE) -C $(APP_BOOTER_DIR) platform=ngc clean .PHONY: clean diff --git a/Makefile.ngc.salamander b/Makefile.ngc.salamander index bcb08ce76c..28c7334a48 100644 --- a/Makefile.ngc.salamander +++ b/Makefile.ngc.salamander @@ -37,9 +37,7 @@ CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map LIBS := -lfat -logc -APP_BOOTER_DIR = gx/app_booter - -OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o $(APP_BOOTER_DIR)/app_booter_ngc.binobj +OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o ngc/ssaram.o ngc/sidestep.o ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -73,20 +71,13 @@ $(ELF_TARGET): $(OBJ) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< -%.binobj: %.bin - $(LD) -r -b binary -o $@ $< - -$(APP_BOOTER_DIR)/app_booter_ngc.bin: - $(MAKE) -C $(APP_BOOTER_DIR) platform=ngc - pkg: all - cp -r $(DOL_TARGET) gx/pkg/boot.dol + cp -r $(DOL_TARGET) ngc/pkg/boot.dol clean: rm -f $(DOL_TARGET) rm -f $(ELF_TARGET) rm -f $(OBJ) - $(MAKE) -C $(APP_BOOTER_DIR) platform=ngc clean .PHONY: clean diff --git a/Makefile.wii b/Makefile.wii index c2b6ab354c..dd666d3705 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -37,9 +37,9 @@ CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,strdup,-wrap,strndup,-wrap,malloc_usable_size -T gx/ld/rvl.ld LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte -APP_BOOTER_DIR = gx/app_booter +APP_BOOTER_DIR = wii/app_booter -OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter_wii.binobj +OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter.binobj ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -78,8 +78,8 @@ $(ELF_TARGET): $(OBJ) %.binobj: %.bin $(LD) -r -b binary -o $@ $< -$(APP_BOOTER_DIR)/app_booter_wii.bin: - $(MAKE) -C $(APP_BOOTER_DIR) platform=wii +$(APP_BOOTER_DIR)/app_booter.bin: + $(MAKE) -C $(APP_BOOTER_DIR) pkg: all cp -r $(DOL_TARGET) wii/pkg/CORE.dol @@ -88,7 +88,7 @@ clean: rm -f $(DOL_TARGET) rm -f $(ELF_TARGET) rm -f $(OBJ) - $(MAKE) -C $(APP_BOOTER_DIR) platform=wii clean + $(MAKE) -C $(APP_BOOTER_DIR) clean .PHONY: clean diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander index f746807f78..f74437d552 100644 --- a/Makefile.wii.salamander +++ b/Makefile.wii.salamander @@ -37,9 +37,9 @@ CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map LIBS := -lfat -lwiiuse -logc -lbte -APP_BOOTER_DIR = gx/app_booter +APP_BOOTER_DIR = wii/app_booter -OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o $(APP_BOOTER_DIR)/app_booter_wii.binobj +OBJ = gx/salamander/main.o console/rarch_console_exec.o console/rarch_console_libretro_mgmt.o file_path.o compat/compat.o conf/config_file.o $(APP_BOOTER_DIR)/app_booter.binobj ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER @@ -75,17 +75,17 @@ $(ELF_TARGET): $(OBJ) %.binobj: %.bin $(LD) -r -b binary -o $@ $< -$(APP_BOOTER_DIR)/app_booter_wii.bin: - $(MAKE) -C $(APP_BOOTER_DIR) platform=wii +$(APP_BOOTER_DIR)/app_booter.bin: + $(MAKE) -C $(APP_BOOTER_DIR) pkg: all - cp -r $(DOL_TARGET) gx/pkg/boot.dol + cp -r $(DOL_TARGET) wii/pkg/boot.dol clean: rm -f $(DOL_TARGET) rm -f $(ELF_TARGET) rm -f $(OBJ) - $(MAKE) -C $(APP_BOOTER_DIR) platform=wii clean + $(MAKE) -C $(APP_BOOTER_DIR) clean .PHONY: clean diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 8d33094438..fdd512be03 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -32,6 +32,11 @@ CONSOLE EXTENSIONS #include "../rarch_console_main_wrap.c" #endif +#ifdef HW_DOL +#include "../../ngc/ssaram.c" +#include "../../ngc/sidestep.c" +#endif + #ifdef HAVE_RARCH_EXEC #include "../rarch_console_exec.c" #endif diff --git a/console/rarch_console_exec.c b/console/rarch_console_exec.c index d599c56b86..cbf2003571 100644 --- a/console/rarch_console_exec.c +++ b/console/rarch_console_exec.c @@ -25,52 +25,32 @@ #include #elif defined(_XBOX) #include -#elif defined(GEKKO) +#elif defined(HW_RVL) #include #include #include #include #include #include - -#ifdef HW_RVL #include #include -#else -#include -#endif - -#endif - -#include "rarch_console_exec.h" -#include "../retroarch_logger.h" - -#ifdef GEKKO - -#ifdef HW_RVL #define EXECUTE_ADDR ((uint8_t *) 0x91800000) #define BOOTER_ADDR ((uint8_t *) 0x93000000) #define ARGS_ADDR ((uint8_t *) 0x93200000) -extern uint8_t _binary_gx_app_booter_app_booter_wii_bin_start[]; -extern uint8_t _binary_gx_app_booter_app_booter_wii_bin_end[]; -#define booter_start _binary_gx_app_booter_app_booter_wii_bin_start -#define booter_end _binary_gx_app_booter_app_booter_wii_bin_end - -#else - -#define ARAMSTART 0x8000 -#define BOOTER_ADDR ((uint8_t *) 0x81300000) -extern void __exception_closeall(void); - -extern uint8_t _binary_gx_app_booter_app_booter_ngc_bin_start[]; -extern uint8_t _binary_gx_app_booter_app_booter_ngc_bin_end[]; -#define booter_start _binary_gx_app_booter_app_booter_ngc_bin_start -#define booter_end _binary_gx_app_booter_app_booter_ngc_bin_end +extern uint8_t _binary_wii_app_booter_app_booter_bin_start[]; +extern uint8_t _binary_wii_app_booter_app_booter_bin_end[]; +#define booter_start _binary_wii_app_booter_app_booter_bin_start +#define booter_end _binary_wii_app_booter_app_booter_bin_end +#elif defined(HW_DOL) +#include "../ngc/sidestep.h" #endif +#include "rarch_console_exec.h" +#include "../retroarch_logger.h" + #ifdef HW_RVL // NOTE: this does not update the path to point to the new loading .dol file. // we only need it for keeping the current directory anyway. @@ -89,7 +69,6 @@ void dol_copy_argv_path(void) DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length); } #endif -#endif void rarch_console_exec(const char *path) { @@ -124,7 +103,7 @@ void rarch_console_exec(const char *path) sys_net_finalize_network(); cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); -#elif defined(GEKKO) +#elif defined(HW_RVL) FILE * fp = fopen(path, "rb"); if (fp == NULL) { @@ -132,60 +111,31 @@ void rarch_console_exec(const char *path) return; } -#ifdef HW_RVL fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0, SEEK_SET); fread(EXECUTE_ADDR, 1, size, fp); fclose(fp); DCFlushRange(EXECUTE_ADDR, size); -#else - uint8_t buffer[0x800]; - size_t size; - size_t offset = 0; - AR_Reset(); - AR_Init(NULL, 0); - while ((size = fread(buffer, 1, sizeof(buffer), fp)) != 0) - { - if (size != sizeof(buffer)) - memset(&buffer[size], 0, sizeof(buffer) - size); - - AR_StartDMA(AR_MRAMTOARAM, (u32) buffer, (u32) offset + ARAMSTART, sizeof(buffer)); - while (AR_GetDMAStatus()); - offset += sizeof(buffer); - } -#endif - -#ifdef HW_RVL dol_copy_argv_path(); -#endif fatUnmount("carda:"); fatUnmount("cardb:"); -#ifdef HW_RVL fatUnmount("sd:"); fatUnmount("usb:"); __io_wiisd.shutdown(); __io_usbstorage.shutdown(); -#endif size_t booter_size = booter_end - booter_start; memcpy(BOOTER_ADDR, booter_start, booter_size); DCFlushRange(BOOTER_ADDR, booter_size); RARCH_LOG("jumping to %08x\n", (unsigned) BOOTER_ADDR); -#ifdef HW_RVL SYS_ResetSystem(SYS_SHUTDOWN,0,0); -#else // we need to keep the ARAM alive for the booter app. - int level; - _CPU_ISR_Disable(level); - __exception_closeall(); -#endif __lwp_thread_stopmultitasking((void (*)(void)) BOOTER_ADDR); -#ifdef HW_DOL - _CPU_ISR_Restore(level); -#endif +#elif defined(HW_DOL) + DOLtoARAM(path); #else RARCH_WARN("External loading of executables is not supported for this platform.\n"); #endif diff --git a/gx/app_booter/string.c b/gx/app_booter/string.c deleted file mode 100644 index 30109578ef..0000000000 --- a/gx/app_booter/string.c +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2008-2009 Segher Boessenkool -// This code is licensed to you under the terms of the GNU GPL, version 2; -// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt - -#include - -#ifdef HW_DOL -#include -#include - -#define DSPCR_DSPDMA 0x0200 // ARAM dma in progress, if set -#define DSPCR_DSPINT 0x0080 // * interrupt active (RWC) -#define DSPCR_ARINT 0x0020 -#define DSPCR_AIINT 0x0008 - -#define ARAMSTART 0x8000 - -#define _SHIFTR(v, s, w) \ - ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) - -static uint8_t buffer[0x800]; - -static vu16* const _dspReg = (u16*) 0xCC005000; -static __inline__ void __ARClearInterrupt() -{ - u16 cause; - - cause = _dspReg[5]&~(DSPCR_DSPINT|DSPCR_AIINT); - _dspReg[5] = (cause|DSPCR_ARINT); -} - -static __inline__ void __ARWaitDma() -{ - while(_dspReg[5]&DSPCR_DSPDMA); -} - -static void __ARReadDMA(u32 memaddr,u32 aramaddr,u32 len) -{ - int level; - _CPU_ISR_Disable(level); - // set main memory address - _dspReg[16] = (_dspReg[16]&~0x03ff)|_SHIFTR(memaddr,16,16); - _dspReg[17] = (_dspReg[17]&~0xffe0)|_SHIFTR(memaddr, 0,16); - - // set aram address - _dspReg[18] = (_dspReg[18]&~0x03ff)|_SHIFTR(aramaddr,16,16); - _dspReg[19] = (_dspReg[19]&~0xffe0)|_SHIFTR(aramaddr, 0,16); - - // set cntrl bits - _dspReg[20] = (_dspReg[20]&~0x8000)|0x8000; - _dspReg[20] = (_dspReg[20]&~0x03ff)|_SHIFTR(len,16,16); - _dspReg[21] = (_dspReg[21]&~0xffe0)|_SHIFTR(len, 0,16); - - __ARWaitDma(); - __ARClearInterrupt(); - _CPU_ISR_Restore(level); -} -#endif - -void *memset(void *b, int c, size_t len) -{ - size_t i; - - for (i = 0; i < len; i++) - ((unsigned char *)b)[i] = c; - - return b; -} - -void *memcpy(void *dst, const void *src, size_t len) -{ -#ifdef HW_DOL - if (((unsigned) src & 0x80000000) == 0) - { - size_t i; - u32 _dst = (u32) dst, _src = (u32) src; - - if ((_src & 0x1F) != 0) - { - unsigned templen = 32 - (_src & 0x1F); - unsigned offset = 32 - templen; - __ARReadDMA((u32) buffer, (u32) (_src & ~0x1F) + ARAMSTART, 32); - memcpy((void *) _dst, &buffer[offset], templen > len ? len : templen); - _src += templen; - _dst += templen; - if (templen >= len) - return (void *) _dst; - len -= templen; - } - - size_t blocks = len >> 11; - for (i = 0; i < blocks; i++) - { - __ARReadDMA(_dst, _src + ARAMSTART, sizeof(buffer)); - _src += sizeof(buffer); - _dst += sizeof(buffer); - len -= sizeof(buffer); - } - - if (len) - { - __ARReadDMA((u32) buffer, _src + ARAMSTART, sizeof(buffer)); - memcpy((void *) _dst, buffer, len); - } - - return (void *) _dst; - } - else -#endif - { - size_t i; - - for (i = 0; i < len; i++) - ((unsigned char *)dst)[i] = ((unsigned char *)src)[i]; - - return dst; - } -} diff --git a/gx/pkg/icon.png b/gx/pkg/icon.png deleted file mode 100644 index 23d1a0762e..0000000000 Binary files a/gx/pkg/icon.png and /dev/null differ diff --git a/gx/pkg/meta.xml b/gx/pkg/meta.xml deleted file mode 100644 index 0d4b53ce65..0000000000 --- a/gx/pkg/meta.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - RetroArch GX - Maister, Squarepusher, ToadKing - 0.9.7.1 - 2012 - Multi-system emulator - A port of RetroArch to the GameCube/Wii. - - diff --git a/ngc/pkg/.empty b/ngc/pkg/.empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ngc/sidestep.c b/ngc/sidestep.c new file mode 100644 index 0000000000..cd13f58afa --- /dev/null +++ b/ngc/sidestep.c @@ -0,0 +1,319 @@ +/** This code is licensed to you under the terms of the GNU GPL, version 2; + see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ + +/**************************************************************************** +* SideStep DOL Loading +* +* This module runs a DOL file from Auxilliary RAM. This removes any memory +* issues which might occur - and also means you can easily overwrite yourself! +* +* softdev March 2007 +***************************************************************************/ +#ifndef HW_RVL +#include +#include +#include +#include +#include +#include +#include + +#include "sidestep.h" +#include "ssaram.h" + +#define ARAMSTART 0x8000 + +/*** A global or two ***/ +static DOLHEADER *dolhdr; +static u32 minaddress = 0; +static u32 maxaddress = 0; +static char dol_readbuf[2048]; + +typedef int (*BOOTSTUB) (u32 entrypoint, u32 dst, u32 src, int len, u32 invlen, u32 invaddress); + +/*--- Auxilliary RAM Support ----------------------------------------------*/ +/**************************************************************************** +* ARAMStub +* +* This is an assembly routine and should only be called through ARAMRun +* *DO NOT CALL DIRECTLY!* +****************************************************************************/ +static void ARAMStub(void) +{ + /*** The routine expects to receive + R3 = entrypoint + R4 = Destination in main RAM + R5 = Source from ARAM + R6 = Data length + R7 = Invalidate Length / 32 + R8 = Invalidate Start Address + ***/ + + asm("mtctr 7"); + asm("Invalidate:"); + asm("dcbi 0,8"); + asm("addi 8,8,32"); + asm("bdnz Invalidate"); + + asm("lis 8,0xcc00"); + asm("ori 8,8,0x3004"); + asm("lis 7,0"); + asm("stw 7,0(8)"); + + asm("mfmsr 8"); + asm("ori 8,8,2"); + asm("rlwinm 8,8,0,17,15"); + asm("mtmsr 8"); + + asm("lis 7,0xcc00"); + asm("ori 7,7,0x5020"); + asm("stw 4,0(7)"); /*** Store Memory Address ***/ + asm("stw 5,4(7)"); /*** Store ARAM Address ***/ + asm("stw 6,8(7)"); /*** Store Length ***/ + + asm("lis 7,0xcc00"); + asm("ori 7,7,0x500a"); + asm("WaitDMA:"); + asm("lhz 5,0(7)"); + asm("andi. 5,5,0x200"); + asm("cmpwi 5,5,0"); + asm("bne WaitDMA"); /*** Wait DMA Complete ***/ + + /*** Update exceptions ***/ + asm("lis 8,0x8000"); + asm("lis 5,0x4c00"); + asm("ori 5,5,0x64"); + asm("stw 5,0x100(8)"); + asm("stw 5,0x200(8)"); + asm("stw 5,0x300(8)"); + asm("stw 5,0x400(8)"); + asm("stw 5,0x500(8)"); + asm("stw 5,0x600(8)"); + asm("stw 5,0x700(8)"); + asm("stw 5,0x800(8)"); + asm("stw 5,0x900(8)"); + asm("stw 5,0xC00(8)"); + asm("stw 5,0xD00(8)"); + asm("stw 5,0xF00(8)"); + asm("stw 5,0x1300(8)"); + asm("stw 5,0x1400(8)"); + asm("stw 5,0x1700(8)"); + + /*** Flush it all again ***/ + asm("lis 7,0x30"); + asm("lis 8,0x8000"); + asm("mtctr 7"); + asm("flush:"); + asm("dcbst 0,8"); + asm("sync"); + asm("icbi 0,8"); + asm("addi 8,8,8"); + asm("bdnz flush"); + asm("isync"); + + /*** Fix ints ***/ + asm("mfmsr 8"); + asm("rlwinm 8,8,0,17,15"); + asm("mtmsr 8"); + + asm("mfmsr 8"); + asm("ori 8,8,8194"); + asm("mtmsr 8"); + + /*** Party! ***/ + asm("mtlr 3"); + asm("blr"); /*** Boot DOL ***/ + +} + +/**************************************************************************** +* ARAMRun +* +* This actually runs the new DOL ... eventually ;) +****************************************************************************/ +void ARAMRun(u32 entrypoint, u32 dst, u32 src, u32 len) +{ + char *p; + char *s = (char *) ARAMStub; + BOOTSTUB stub; + + /*** Shutdown libOGC ***/ + SYS_ResetSystem(SYS_SHUTDOWN, 0, 0); + + /*** Copy ARAMStub to 81300000 ***/ + if (dst + len < 0x81300000) p = (void *) 0x81300000; + else p = (void *) 0x80003100; + memcpy(p, s, 256); /*** Way too much - but who cares ***/ + + /*** Round length to 32 bytes ***/ + if (len & 0x1f) len = (len & ~0x1f) + 0x20; + + /*** Flush everything! ***/ + DCFlushRange((void *) 0x80000000, 0x1800000); + + /*** Boot the bugger :D ***/ + stub = (BOOTSTUB) p; + stub((u32) entrypoint, dst, src, len | 0x80000000, len >> 5, dst); +} + +/**************************************************************************** +* ARAMClear +* +* To make life easy, just clear out the Auxilliary RAM completely. +****************************************************************************/ +static void ARAMClear(void) +{ + int i; + char *buffer = memalign(32, 2048); /*** A little 2k buffer ***/ + + memset(buffer, 0, 2048); + DCFlushRange(buffer, 2048); + + for (i = ARAMSTART; i < 0x1000000; i += 2048) + { + ARAMPut(buffer, (char *) i, 2048); + while (AR_GetDMAStatus()); + } + + free(buffer); +} + +/*--- DOL Decoding functions -----------------------------------------------*/ +/**************************************************************************** +* DOLMinMax +* +* Calculate the DOL minimum and maximum memory addresses +****************************************************************************/ +static void DOLMinMax(DOLHEADER * dol) +{ + int i; + + maxaddress = 0; + minaddress = 0x87100000; + + /*** Go through DOL sections ***/ + /*** Text sections ***/ + for (i = 0; i < MAXTEXTSECTION; i++) + { + if (dol->textAddress[i] && dol->textLength[i]) + { + if (dol->textAddress[i] < minaddress) + minaddress = dol->textAddress[i]; + if ((dol->textAddress[i] + dol->textLength[i]) > maxaddress) + maxaddress = dol->textAddress[i] + dol->textLength[i]; + } + } + + /*** Data sections ***/ + for (i = 0; i < MAXDATASECTION; i++) + { + if (dol->dataAddress[i] && dol->dataLength[i]) + { + if (dol->dataAddress[i] < minaddress) + minaddress = dol->dataAddress[i]; + if ((dol->dataAddress[i] + dol->dataLength[i]) > maxaddress) + maxaddress = dol->dataAddress[i] + dol->dataLength[i]; + } + } + + /*** And of course, any BSS section ***/ + if (dol->bssAddress) + { + if ((dol->bssAddress + dol->bssLength) > maxaddress) + maxaddress = dol->bssAddress + dol->bssLength; + } + + /*** Some OLD dols, Xrick in particular, require ~128k clear memory ***/ + maxaddress += 0x20000; +} + +/**************************************************************************** +* DOLtoARAM +* +* Moves the DOL from main memory to ARAM, positioning as it goes +* +* Pass in a memory pointer to a previously loaded DOL +****************************************************************************/ +int DOLtoARAM(const char *dol_name) +{ + u32 sizeinbytes; + int i, j; + static DOLHEADER dolhead; + FILE *f = fopen(dol_name, "rb"); + + if (!f) + return 1; + + fread(&dolhead, 1, sizeof(DOLHEADER), f); + /*** Make sure ARAM subsystem is alive! ***/ + AR_Init(NULL, 0); /*** No stack - we need it all ***/ + ARAMClear(); + + /*** Get DOL header ***/ + dolhdr = (DOLHEADER *) &dolhead; + + /*** First, does this look like a DOL? ***/ + if (dolhdr->textOffset[0] != DOLHDRLENGTH) + return 0; + + /*** Get DOL stats ***/ + DOLMinMax(dolhdr); + sizeinbytes = maxaddress - minaddress; + + /*** Move all DOL sections into ARAM ***/ + /*** Move text sections ***/ + for (i = 0; i < MAXTEXTSECTION; i++) + { + /*** This may seem strange, but in developing d0lLZ we found some with section addresses with zero length ***/ + if (dolhdr->textAddress[i] && dolhdr->textLength[i]) + { + fseek(f, dolhdr->textOffset[i], SEEK_SET); + unsigned count = dolhdr->textLength[i] / sizeof(dol_readbuf); + for (j = 0; j < count; j++) + { + fread(dol_readbuf, 1, sizeof(dol_readbuf), f); + ARAMPut(dol_readbuf, (char *) ((dolhdr->textAddress[i] - minaddress) + (sizeof(dol_readbuf) * i) + ARAMSTART), + sizeof(dol_readbuf)); + } + unsigned remaining = dolhdr->textLength[i] % sizeof(dol_readbuf); + if (remaining) + { + fread(dol_readbuf, 1, remaining, f); + ARAMPut(dol_readbuf, (char *) ((dolhdr->textAddress[i] - minaddress) + (count * i) + ARAMSTART), + remaining); + } + } + } + + /*** Move data sections ***/ + for (i = 0; i < MAXDATASECTION; i++) + { + if (dolhdr->dataAddress[i] && dolhdr->dataLength[i]) + { + fseek(f, dolhdr->dataOffset[i], SEEK_SET); + unsigned count = dolhdr->dataLength[i] / sizeof(dol_readbuf); + for (j = 0; j < count; j++) + { + fread(dol_readbuf, 1, sizeof(dol_readbuf), f); + ARAMPut(dol_readbuf, (char *) ((dolhdr->dataAddress[i] - minaddress) + (sizeof(dol_readbuf) * i) + ARAMSTART), + sizeof(dol_readbuf)); + } + unsigned remaining = dolhdr->dataLength[i] % sizeof(dol_readbuf); + if (remaining) + { + fread(dol_readbuf, 1, remaining, f); + ARAMPut(dol_readbuf, (char *) ((dolhdr->dataAddress[i] - minaddress) + (count * i) + ARAMSTART), + remaining); + } + } + } + + fclose(f); + + /*** Now go run it ***/ + ARAMRun(dolhdr->entryPoint, minaddress, ARAMSTART, sizeinbytes); + + /*** Will never return ***/ + return 1; +} +#endif diff --git a/ngc/sidestep.h b/ngc/sidestep.h new file mode 100644 index 0000000000..faeaafc76f --- /dev/null +++ b/ngc/sidestep.h @@ -0,0 +1,39 @@ +/**************************************************************************** +* SideStep DOL Loading +* +* This module runs a DOL file from Auxilliary RAM. This removes any memory +* issues which might occur - and also means you can easily overwrite yourself! +* +* softdev March 2007 +***************************************************************************/ +#ifndef HW_RVL +#ifndef __SIDESTEP__ +#define __SIDESTEP__ + +/*** A standard DOL header ***/ +#define DOLHDRLENGTH 256 /*** All DOLS must have a 256 byte header ***/ +#define MAXTEXTSECTION 7 +#define MAXDATASECTION 11 + +/*** A handy DOL structure ***/ +typedef struct { + unsigned int textOffset[MAXTEXTSECTION]; + unsigned int dataOffset[MAXDATASECTION]; + + unsigned int textAddress[MAXTEXTSECTION]; + unsigned int dataAddress[MAXDATASECTION]; + + unsigned int textLength[MAXTEXTSECTION]; + unsigned int dataLength[MAXDATASECTION]; + + unsigned int bssAddress; + unsigned int bssLength; + + unsigned int entryPoint; + unsigned int unused[MAXTEXTSECTION]; +} DOLHEADER; + +int DOLtoARAM(const char *dol_name); + +#endif +#endif diff --git a/ngc/ssaram.c b/ngc/ssaram.c new file mode 100644 index 0000000000..2b59f5af9b --- /dev/null +++ b/ngc/ssaram.c @@ -0,0 +1,106 @@ +/** This code is licensed to you under the terms of the GNU GPL, version 2; + see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ + +/**************************************************************************** +* SSARAM +***************************************************************************/ +#ifndef HW_RVL +#include +#include +#include +#include +#include "ssaram.h" + +static char aramfix[2048] ATTRIBUTE_ALIGN(32); + +#define ARAMSTART 0x8000 +#define ARAM_READ 1 +#define ARAM_WRITE 0 + +/**************************************************************************** +* ARAMPut +* +* This version of ARAMPut fixes up those segments which are misaligned. +* The IPL rules for DOLs is that they must contain 32byte aligned sections with +* 32byte aligned lengths. +* +* The reality is that most homebrew DOLs don't adhere to this. +****************************************************************************/ +void ARAMPut(char *src, char *dst, int len) +{ + u32 misalignaddress; + u32 misalignedbytes; + u32 misalignedbytestodo; + + int i, block; + int offset = 0; + + /*** Check destination alignment ***/ + if ((u32) dst & 0x1f) + { + /*** Retrieve previous 32 byte section ***/ + misalignaddress = ((u32) dst & ~0x1f); + misalignedbytestodo = 32 - ((u32) dst & 0x1f); + misalignedbytes = ((u32) dst & 0x1f); + ARAMFetch(aramfix, (char *) misalignaddress, 32); + + /*** Update from source ***/ + memcpy(aramfix + misalignedbytes, src, misalignedbytestodo); + + /*** Put it back ***/ + DCFlushRange(aramfix, 32); + AR_StartDMA(ARAM_WRITE, (u32) aramfix, (u32) dst & ~0x1f, 32); + while (AR_GetDMAStatus()); + + /*** Update pointers ***/ + src += misalignedbytestodo; + len -= misalignedbytestodo; + dst = (char *) (((u32) dst & ~0x1f) + 32); + } + + /*** Move 2k blocks - saves aligning source buffer ***/ + block = (len >> 11); + for (i = 0; i < block; i++) + { + memcpy(aramfix, src + offset, 2048); + DCFlushRange(aramfix, 2048); + AR_StartDMA(ARAM_WRITE, (u32) aramfix, (u32) dst + offset, 2048); + while (AR_GetDMAStatus()); + offset += 2048; + } + + /*** Clean up remainder ***/ + len &= 0x7ff; + if (len) + { + block = len & 0x1f; /*** Is length aligned ? ***/ + memcpy(aramfix, src + offset, len & ~0x1f); + DCFlushRange(aramfix, len & ~0x1f); + AR_StartDMA(ARAM_WRITE, (u32) aramfix, (u32) dst + offset, len & ~0x1f); + while (AR_GetDMAStatus()); + + if (block) + { + offset += len & ~0x1f; + misalignedbytes = len & 0x1f; + + /*** Do same shuffle as destination alignment ***/ + ARAMFetch(aramfix, dst + offset, 32); + memcpy(aramfix, src + offset, misalignedbytes); + DCFlushRange(aramfix, 32); + AR_StartDMA(ARAM_WRITE, (u32) aramfix, (u32) dst + offset, 32); + while (AR_GetDMAStatus()); + } + } +} + +/**************************************************************************** +* ARAMFetch +****************************************************************************/ +void ARAMFetch(char *dst, char *src, int len) +{ + DCInvalidateRange(dst, len); + AR_StartDMA(ARAM_READ, (u32) dst, (u32) src, len); + while (AR_GetDMAStatus()); +} +#endif diff --git a/ngc/ssaram.h b/ngc/ssaram.h new file mode 100644 index 0000000000..db3f1eeb74 --- /dev/null +++ b/ngc/ssaram.h @@ -0,0 +1,12 @@ +/**************************************************************************** +* SSARAM +***************************************************************************/ +#ifndef HW_RVL +#ifndef __SSARAM__ +#define __SSARAM__ + +void ARAMPut(char *src, char *dst, int len); +void ARAMFetch(char *dst, char *src, int len); + +#endif +#endif diff --git a/gx/app_booter/Makefile b/wii/app_booter/Makefile similarity index 77% rename from gx/app_booter/Makefile rename to wii/app_booter/Makefile index a5dd8129a9..ea13bfa32a 100644 --- a/gx/app_booter/Makefile +++ b/wii/app_booter/Makefile @@ -18,27 +18,16 @@ CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT) OBJCOPY = $(DEVKITPPC)/bin/powerpc-eabi-objcopy$(EXE_EXT) -ifeq ($(platform),wii) - BIN_TARGET := app_booter_wii.bin - ELF_TARGET := app_booter_wii.elf -else - BIN_TARGET := app_booter_ngc.bin - ELF_TARGET := app_booter_ngc.elf -endif +BIN_TARGET := app_booter.bin +ELF_TARGET := app_booter.elf INCLUDE := -I. -I$(DEVKITPRO)/libogc/include LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -MACHDEP := -mno-eabi -mno-sdata -mcpu=750 +MACHDEP := -DHW_RVL -DGEKKO -mno-eabi -mno-sdata -mcpu=750 # todo: find out why -Os spits out linker errors CFLAGS += -Wall -O2 -ffreestanding -std=gnu99 $(MACHDEP) $(INCLUDE) -ifeq ($(platform),wii) - CFLAGS += -DHW_RVL -else - CFLAGS += -DHW_DOL -endif - LDFLAGS := -T link.ld OBJ = crt0.o dolloader.o elfloader.o main.o string.o sync.o diff --git a/gx/app_booter/crt0.s b/wii/app_booter/crt0.s similarity index 100% rename from gx/app_booter/crt0.s rename to wii/app_booter/crt0.s diff --git a/gx/app_booter/dolloader.c b/wii/app_booter/dolloader.c similarity index 100% rename from gx/app_booter/dolloader.c rename to wii/app_booter/dolloader.c diff --git a/gx/app_booter/dolloader.h b/wii/app_booter/dolloader.h similarity index 100% rename from gx/app_booter/dolloader.h rename to wii/app_booter/dolloader.h diff --git a/gx/app_booter/elf_abi.h b/wii/app_booter/elf_abi.h similarity index 100% rename from gx/app_booter/elf_abi.h rename to wii/app_booter/elf_abi.h diff --git a/gx/app_booter/elfloader.c b/wii/app_booter/elfloader.c similarity index 100% rename from gx/app_booter/elfloader.c rename to wii/app_booter/elfloader.c diff --git a/gx/app_booter/elfloader.h b/wii/app_booter/elfloader.h similarity index 100% rename from gx/app_booter/elfloader.h rename to wii/app_booter/elfloader.h diff --git a/gx/app_booter/link.ld b/wii/app_booter/link.ld similarity index 100% rename from gx/app_booter/link.ld rename to wii/app_booter/link.ld diff --git a/gx/app_booter/main.c b/wii/app_booter/main.c similarity index 81% rename from gx/app_booter/main.c rename to wii/app_booter/main.c index b84a5dc8b8..5a03b02315 100644 --- a/gx/app_booter/main.c +++ b/wii/app_booter/main.c @@ -10,22 +10,14 @@ #include "elfloader.h" #include "sync.h" -#if HW_RVL #define EXECUTABLE_MEM_ADDR 0x91800000 #define SYSTEM_ARGV ((struct __argv *) 0x93200000) -#endif // if we name this main, GCC inserts the __eabi symbol, even when we specify -mno-eabi // what a lovely "feature" void app_booter_main(void) { -#if HW_RVL void *exeBuffer = (void *) EXECUTABLE_MEM_ADDR; -#else - uint8_t _exeBuffer[0x200]; // should be enough for most elf headers, and more than enough for dol headers - memcpy(_exeBuffer, 0, sizeof(_exeBuffer)); - void *exeBuffer = _exeBuffer; -#endif u32 exeEntryPointAddress = 0; entrypoint exeEntryPoint; @@ -38,14 +30,12 @@ void app_booter_main(void) if (!exeEntryPoint) return; -#ifdef HW_RVL if (SYSTEM_ARGV->argvMagic == ARGV_MAGIC) { void *new_argv = (void *) (exeEntryPointAddress + 8); memcpy(new_argv, SYSTEM_ARGV, sizeof(struct __argv)); sync_before_exec(new_argv, sizeof(struct __argv)); } -#endif exeEntryPoint (); } diff --git a/wii/app_booter/string.c b/wii/app_booter/string.c new file mode 100644 index 0000000000..0e6b31a1e6 --- /dev/null +++ b/wii/app_booter/string.c @@ -0,0 +1,25 @@ +// Copyright 2008-2009 Segher Boessenkool +// This code is licensed to you under the terms of the GNU GPL, version 2; +// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + +#include + +void *memset(void *b, int c, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + ((unsigned char *)b)[i] = c; + + return b; +} + +void *memcpy(void *dst, const void *src, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + ((unsigned char *)dst)[i] = ((unsigned char *)src)[i]; + + return dst; +} diff --git a/gx/app_booter/string.h b/wii/app_booter/string.h similarity index 100% rename from gx/app_booter/string.h rename to wii/app_booter/string.h diff --git a/gx/app_booter/sync.c b/wii/app_booter/sync.c similarity index 100% rename from gx/app_booter/sync.c rename to wii/app_booter/sync.c diff --git a/gx/app_booter/sync.h b/wii/app_booter/sync.h similarity index 100% rename from gx/app_booter/sync.h rename to wii/app_booter/sync.h