1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-03 00:38:44 +00:00

(NGC) new dol booter, move app_booter to wii folder

move package folders to wii and ngc respectively
This commit is contained in:
Toad King 2012-09-03 18:05:23 -04:00
parent 41359681c3
commit 20db83cd93
28 changed files with 540 additions and 248 deletions

2
.gitignore vendored
View File

@ -21,4 +21,4 @@ Debug
Release
ipch
*.user
gx/app_booter/app_booter_*.bin
/wii/app_booter/app_booter.bin

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,52 +25,32 @@
#include <np/drm.h>
#elif defined(_XBOX)
#include <xtl.h>
#elif defined(GEKKO)
#elif defined(HW_RVL)
#include <string.h>
#include <fat.h>
#include <gctypes.h>
#include <ogc/cache.h>
#include <ogc/lwp_threads.h>
#include <ogc/system.h>
#ifdef HW_RVL
#include <ogc/usbstorage.h>
#include <sdcard/wiisd_io.h>
#else
#include <ogc/aram.h>
#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

View File

@ -1,118 +0,0 @@
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
// 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 <stdio.h>
#ifdef HW_DOL
#include <gctypes.h>
#include <ogc/machine/processor.h>
#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;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="1">
<name>RetroArch GX</name>
<coder>Maister, Squarepusher, ToadKing</coder>
<version>0.9.7.1</version>
<release_date>2012</release_date>
<short_description>Multi-system emulator</short_description>
<long_description>A port of RetroArch to the GameCube/Wii.</long_description>
<no_ios_reload/>
</app>

0
ngc/pkg/.empty Normal file
View File

319
ngc/sidestep.c Normal file
View File

@ -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 <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <network.h>
#include <smb.h>
#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

39
ngc/sidestep.h Normal file
View File

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

106
ngc/ssaram.c Normal file
View File

@ -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 <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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

12
ngc/ssaram.h Normal file
View File

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

View File

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

View File

@ -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 ();
}

25
wii/app_booter/string.c Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
// 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 <stdio.h>
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;
}