(GX) initial work on gamecube app_booter

This commit is contained in:
Toad King 2012-08-31 19:38:12 -04:00
parent 297723b836
commit 616af5e5ec
11 changed files with 268 additions and 28 deletions

2
.gitignore vendored
View File

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

View File

@ -37,7 +37,9 @@ CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE)
LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map -T gx/ld/ogc.ld
LIBS := -lfat -lretro_wii -logc
OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o
APP_BOOTER_DIR = gx/app_booter
OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter_gc.binobj
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
@ -76,6 +78,9 @@ $(ELF_TARGET): $(OBJ)
%.binobj: %.bin
$(LD) -r -b binary -o $@ $<
$(APP_BOOTER_DIR)/app_booter_gc.bin:
$(MAKE) -C $(APP_BOOTER_DIR) platform=gc
pkg: all
# cp -r $(DOL_TARGET) gx/pkg/CORE.dol
@ -83,6 +88,7 @@ clean:
rm -f $(DOL_TARGET)
rm -f $(ELF_TARGET)
rm -f $(OBJ)
$(MAKE) -C $(APP_BOOTER_DIR) platform=gc clean
.PHONY: clean

91
Makefile.gc.salamander Normal file
View File

@ -0,0 +1,91 @@
###
##
# Makefile for RetroArch GameCube.
##
DEBUG = 0
HAVE_LOGGER = 0
HAVE_FILE_LOGGER = 0
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
PC_DEVELOPMENT_UDP_PORT = 3490
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT)
ELF2DOL = $(DEVKITPPC)/bin/elf2dol$(EXE_EXT)
DOL_TARGET := retroarch-salamander_gx_gc.dol
ELF_TARGET := retroarch-salamander_gx_gc.elf
INCLUDE := -I. -I$(DEVKITPRO)/libogc/include
LIBDIRS := -L$(DEVKITPRO)/libogc/lib/cube -L.
MACHDEP := -DGEKKO -DHW_DOL -mogc -mcpu=750 -meabi -mhard-float
CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE)
LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map
LIBS := -lfat -lretro_wii -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_gc.binobj
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
CFLAGS += -Iconsole/logger
OBJ += console/logger/logger.o
endif
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
CFLAGS += -Iconsole/logger
endif
CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DPACKAGE_VERSION=\"0.9.7\" -Wno-char-subscripts
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
else
CFLAGS += -O3
endif
all: $(DOL_TARGET)
%.dol: %.elf
$(ELF2DOL) $< $@
$(ELF_TARGET): $(OBJ)
$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.binobj: %.bin
$(LD) -r -b binary -o $@ $<
$(APP_BOOTER_DIR)/app_booter_gc.bin:
$(MAKE) -C $(APP_BOOTER_DIR) platform=gc
pkg: all
#cp -r $(DOL_TARGET) gx/pkg/boot.dol
clean:
rm -f $(DOL_TARGET)
rm -f $(ELF_TARGET)
rm -f $(OBJ)
$(MAKE) -C $(APP_BOOTER_DIR) platform=gc clean
.PHONY: clean

View File

@ -39,7 +39,7 @@ LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte
APP_BOOTER_DIR = gx/app_booter
OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter.binobj
OBJ = console/griffin/griffin.o console/font.binobj console/rzlib/rzlib.o $(APP_BOOTER_DIR)/app_booter_wii.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.bin:
$(MAKE) -C $(APP_BOOTER_DIR)
$(APP_BOOTER_DIR)/app_booter_wii.bin:
$(MAKE) -C $(APP_BOOTER_DIR) platform=wii
pkg: all
cp -r $(DOL_TARGET) gx/pkg/CORE.dol
@ -88,7 +88,7 @@ clean:
rm -f $(DOL_TARGET)
rm -f $(ELF_TARGET)
rm -f $(OBJ)
$(MAKE) -C $(APP_BOOTER_DIR) clean
$(MAKE) -C $(APP_BOOTER_DIR) platform=wii clean
.PHONY: clean

View File

@ -39,7 +39,7 @@ LIBS := -lfat -lretro_wii -lwiiuse -logc -lbte
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.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_wii.binobj
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
@ -53,7 +53,7 @@ CFLAGS += -DHAVE_FILE_LOGGER
CFLAGS += -Iconsole/logger
endif
CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DPACKAGE_VERSION=\"0.9.7\" -Wno-char-subscripts
CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DHAVE_CONFIGFILE=1 -DGEKKO -DPACKAGE_VERSION=\"0.9.7\" -Wno-char-subscripts
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
@ -75,8 +75,8 @@ $(ELF_TARGET): $(OBJ)
%.binobj: %.bin
$(LD) -r -b binary -o $@ $<
$(APP_BOOTER_DIR)/app_booter.bin:
$(MAKE) -C $(APP_BOOTER_DIR)
$(APP_BOOTER_DIR)/app_booter_wii.bin:
$(MAKE) -C $(APP_BOOTER_DIR) platform=wii
pkg: all
cp -r $(DOL_TARGET) gx/pkg/boot.dol
@ -85,7 +85,7 @@ clean:
rm -f $(DOL_TARGET)
rm -f $(ELF_TARGET)
rm -f $(OBJ)
$(MAKE) -C $(APP_BOOTER_DIR) clean
$(MAKE) -C $(APP_BOOTER_DIR) platform=wii clean
.PHONY: clean

View File

@ -25,29 +25,53 @@
#include <np/drm.h>
#elif defined(_XBOX)
#include <xtl.h>
#elif defined(HW_RVL)
#elif defined(GEKKO)
#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_bin_start[];
extern uint8_t _binary_gx_app_booter_app_booter_bin_end[];
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_gc_bin_start[];
extern uint8_t _binary_gx_app_booter_app_booter_gc_bin_end[];
#define booter_start _binary_gx_app_booter_app_booter_gc_bin_start
#define booter_end _binary_gx_app_booter_app_booter_gc_bin_end
#endif
#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.
void dol_copy_argv_path(void)
@ -65,6 +89,7 @@ void dol_copy_argv_path(void)
DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length);
}
#endif
#endif
void rarch_console_exec(const char *path)
{
@ -99,36 +124,67 @@ void rarch_console_exec(const char *path)
sys_net_finalize_network();
cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP);
cellSysmoduleUnloadModule(CELL_SYSMODULE_NET);
#elif defined(HW_RVL)
#elif defined(GEKKO)
FILE * fp = fopen(path, "rb");
if (fp == NULL)
{
RARCH_ERR("Could not execute DOL file.\n");
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_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 = _binary_gx_app_booter_app_booter_bin_end - _binary_gx_app_booter_app_booter_bin_start;
memcpy(BOOTER_ADDR, _binary_gx_app_booter_app_booter_bin_start, booter_size);
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", BOOTER_ADDR);
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
#else
RARCH_WARN("External loading of executables is not supported for this platform.\n");
#endif

View File

@ -18,8 +18,13 @@ CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT)
OBJCOPY = $(DEVKITPPC)/bin/powerpc-eabi-objcopy$(EXE_EXT)
BIN_TARGET := app_booter.bin
ELF_TARGET := app_booter.elf
ifeq ($(platform),wii)
BIN_TARGET := app_booter_wii.bin
ELF_TARGET := app_booter_wii.elf
else
BIN_TARGET := app_booter_gc.bin
ELF_TARGET := app_booter_gc.elf
endif
INCLUDE := -I. -I$(DEVKITPRO)/libogc/include
LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii
@ -27,6 +32,13 @@ LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii
MACHDEP := -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,14 +10,22 @@
#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;
@ -30,12 +38,14 @@ 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 ();
}

View File

@ -4,22 +4,81 @@
#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 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;
size_t i;
for (i = 0; i < len; i++)
((unsigned char *)b)[i] = c;
for (i = 0; i < len; i++)
((unsigned char *)b)[i] = c;
return b;
return b;
}
void *memcpy(void *dst, const void *src, size_t len)
{
size_t i;
#ifdef HW_DOL
if (((unsigned) src & ~0x00FFFFFF) == 0)
{
__ARReadDMA((u32) dst, (u32) src + ARAMSTART, len);
for (i = 0; i < len; i++)
((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
return dst;
}
#endif
size_t i;
return dst;
for (i = 0; i < len; i++)
((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
return dst;
}

View File

@ -410,6 +410,9 @@ int rarch_main(int argc, char **argv);
static void get_environment_settings(void)
{
#ifdef HW_DOL
chdir("carda:/retroarch/cores");
#endif
getcwd(default_paths.core_dir, MAXPATHLEN);
char *last_slash = strrchr(default_paths.core_dir, '/');
if (last_slash)

View File

@ -122,6 +122,9 @@ static void init_settings(void)
static void get_environment_settings(void)
{
#ifdef HW_DOL
chdir("carda:/retroarch/cores");
#endif
getcwd(default_paths.core_dir, MAXPATHLEN);
char *last_slash = strrchr(default_paths.core_dir, '/');
if (last_slash)