Skip to content

Commit

Permalink
move to using direct ARAM access and preloaded IPL image
Browse files Browse the repository at this point in the history
  • Loading branch information
trevor403 committed Jan 9, 2025
1 parent 705fe0e commit 0c4e864
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 49 deletions.
31 changes: 4 additions & 27 deletions cubeboot/source/boot/sidestep.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* softdev March 2007
***************************************************************************/
#include <string.h>
#include <malloc.h>
#include <ogc/aram.h>
#include <ogc/cache.h>
#include <ogc/gx.h>
Expand All @@ -17,7 +16,8 @@
#include "sidestep.h"
#include "ssaram.h"

#define ARAMSTART 0x8000
#define ARAMSTART 0
#define ARAMSIZE (10 * 1024 * 1024)

/*** A global or two ***/
static DOLHEADER *dolhdr;
Expand Down Expand Up @@ -168,28 +168,6 @@ void ARAMRun(u32 entrypoint, u32 dst, u32 src, u32 len)
__lwp_thread_stopmultitasking((void(*)())ARAMRunStub());
}

/****************************************************************************
* ARAMClear
*
* To make life easy, just clear out the Auxilliary RAM completely.
****************************************************************************/
static void ARAMClear(void)
{
int i;
unsigned 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
Expand Down Expand Up @@ -252,9 +230,8 @@ int DOLtoARAM(unsigned char *dol, int argc, char *argv[])
int i;
struct __argv dolargs;

/*** Make sure ARAM subsystem is alive! ***/
AR_Init(NULL, 0); /*** No stack - we need it all ***/
ARAMClear();
// clear the part of ARAM we will use
ARAMClear(ARAMSTART, ARAMSIZE);

/*** Get DOL header ***/
dolhdr = (DOLHEADER *) dol;
Expand Down
108 changes: 99 additions & 9 deletions cubeboot/source/boot/ssaram.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
***************************************************************************/
#ifndef HW_RVL
#include <string.h>
#include <malloc.h>
#include <gctypes.h>
#include <gcutil.h>
#include <ogc/aram.h>
Expand All @@ -15,6 +16,99 @@ static u8 aramfix[2048] ATTRIBUTE_ALIGN(32);
#define ARAM_READ 1
#define ARAM_WRITE 0

// DSPCR bits
#define DSPCR_DSPRESET 0x0800 // Reset DSP
#define DSPCR_DSPDMA 0x0200 // ARAM dma in progress, if set
#define DSPCR_DSPINTMSK 0x0100 // * interrupt mask (RW)
#define DSPCR_DSPINT 0x0080 // * interrupt active (RWC)
#define DSPCR_ARINTMSK 0x0040
#define DSPCR_ARINT 0x0020
#define DSPCR_AIINTMSK 0x0010
#define DSPCR_AIINT 0x0008
#define DSPCR_HALT 0x0004 // halt DSP
#define DSPCR_PIINT 0x0002 // assert DSP PI interrupt
#define DSPCR_RES 0x0001 // reset DSP

#define _SHIFTL(v, s, w) \
((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
#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)
{
// 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();
}

static void __ARWriteDMA(u32 memaddr,u32 aramaddr,u32 len)
{
// 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);
_dspReg[20] = (_dspReg[20]&~0x03ff)|_SHIFTR(len,16,16);
_dspReg[21] = (_dspReg[21]&~0xffe0)|_SHIFTR(len, 0,16);

__ARWaitDma();
__ARClearInterrupt();
}

/****************************************************************************
* ARAMClear
*
* To make life easy, just clear out the Auxilliary RAM completely.
****************************************************************************/
void ARAMClear(u32 start, u32 length)
{
int i;
unsigned char *buffer = memalign(32, 2048); /*** A little 2k buffer ***/

memset(buffer, 0, 2048);
DCFlushRange(buffer, 2048);

for (i = start; i < 0x1000000 - length; i += 2048)
{
ARAMPut(buffer, (char *) i, 2048);
while (AR_GetDMAStatus());
}

free(buffer);
}

/****************************************************************************
* ARAMPut
*
Expand Down Expand Up @@ -47,8 +141,7 @@ void ARAMPut(unsigned char *src, char *dst, int len)

/*** Put it back ***/
DCFlushRange(aramfix, 32);
AR_StartDMA(ARAM_WRITE, (u32) aramfix, (u32) dst & ~0x1f, 32);
while (AR_GetDMAStatus());
__ARWriteDMA((u32) aramfix, (u32) dst & ~0x1f, 32);

/*** Update pointers ***/
src += misalignedbytestodo;
Expand All @@ -62,7 +155,7 @@ void ARAMPut(unsigned char *src, char *dst, int len)
{
memcpy(aramfix, src + offset, 2048);
DCFlushRange(aramfix, 2048);
AR_StartDMA(ARAM_WRITE, (u32) aramfix, (u32) dst + offset, 2048);
__ARWriteDMA((u32) aramfix, (u32) dst + offset, 2048);
while (AR_GetDMAStatus());
offset += 2048;
}
Expand All @@ -74,8 +167,7 @@ void ARAMPut(unsigned char *src, char *dst, int 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());
__ARWriteDMA((u32) aramfix, (u32) dst + offset, len & ~0x1f);

if (block)
{
Expand All @@ -86,8 +178,7 @@ void ARAMPut(unsigned char *src, char *dst, int len)
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());
__ARWriteDMA((u32) aramfix, (u32) dst + offset, 32);
}
}
}
Expand All @@ -98,7 +189,6 @@ void ARAMPut(unsigned char *src, char *dst, int len)
void ARAMFetch(unsigned char *dst, char *src, int len)
{
DCInvalidateRange(dst, len);
AR_StartDMA(ARAM_READ, (u32) dst, (u32) src, len);
while (AR_GetDMAStatus());
__ARReadDMA((u32) dst, (u32) src, len);
}
#endif
1 change: 1 addition & 0 deletions cubeboot/source/boot/ssaram.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef __SSARAM__
#define __SSARAM__

void ARAMClear(u32 start, u32 length);
void ARAMPut(unsigned char *src, char *dst, int len);
void ARAMFetch(unsigned char *dst, char *src, int len);

Expand Down
2 changes: 1 addition & 1 deletion cubeboot/source/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#define VIDEO_ENABLE
// #define CONSOLE_ENABLE

// #define GECKO_PRINT_ENABLE
#define GECKO_PRINT_ENABLE
// #define DOLPHIN_PRINT_ENABLE

// #define PRINT_PATCHES
Expand Down
41 changes: 34 additions & 7 deletions cubeboot/source/ipl.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
#include "print.h"
#include "halt.h"

#include "tinf_crc32.h"
#include "descrambler.h"
#include "crc32.h"
#include "ipl.h"

#include "flippy_sync.h"
#include "boot/ssaram.h"

extern GXRModeObj *rmode;
extern void *xfb;
Expand Down Expand Up @@ -65,13 +67,13 @@ char *bios_path = "/ipl.bin";
// NOTE: these are not ipl.bin CRCs, but decoded ipl[0x100:] hashes
// FIXME: this is over-reading by a lot (not fixed to code size)
bios_item bios_table[] = {
{IPL_NTSC_10, IPL_NTSC, "gc-ntsc-10", "ntsc10", "VER_NTSC_10", CRC(0xa8325e47), SDA(0x81465320)},
{IPL_NTSC_11, IPL_NTSC, "gc-ntsc-11", "ntsc11", "VER_NTSC_11", CRC(0xf1ebeb95), SDA(0x81489120)},
{IPL_NTSC_12_001, IPL_NTSC, "gc-ntsc-12_001", "ntsc12_001", "VER_NTSC_12_001", CRC(0xc4c5a12a), SDA(0x8148b1c0)},
{IPL_NTSC_12_101, IPL_NTSC, "gc-ntsc-12_101", "ntsc12_101", "VER_NTSC_12_101", CRC(0xbf225e4d), SDA(0x8148b640)},
{IPL_PAL_10, IPL_PAL, "gc-pal-10", "pal10", "VER_PAL_10", CRC(0x5c3445d0), SDA(0x814b4fc0)},
{IPL_PAL_11, IPL_PAL, "gc-pal-11", "pal11", "VER_PAL_11", CRC(0x05196b74), SDA(0x81483de0)}, // MPAL
{IPL_PAL_12, IPL_PAL, "gc-pal-12", "pal12", "VER_PAL_12", CRC(0x1082fbc9), SDA(0x814b7280)},
{IPL_NTSC_10, IPL_NTSC, "gc-ntsc-10", "ntsc10", "VER_NTSC_10", CRC(0x2487919c), SDA(0x81465320)},
{IPL_NTSC_11, IPL_NTSC, "gc-ntsc-11", "ntsc11", "VER_NTSC_11", CRC(0x53faeffc), SDA(0x81489120)},
{IPL_NTSC_12_001, IPL_NTSC, "gc-ntsc-12_001", "ntsc12_001", "VER_NTSC_12_001", CRC(0xdc527533), SDA(0x8148b1c0)},
{IPL_NTSC_12_101, IPL_NTSC, "gc-ntsc-12_101", "ntsc12_101", "VER_NTSC_12_101", CRC(0x84075b6d), SDA(0x8148b640)},
{IPL_PAL_10, IPL_PAL, "gc-pal-10", "pal10", "VER_PAL_10", CRC(0xeadf6ce5), SDA(0x814b4fc0)},
{IPL_PAL_11, IPL_PAL, "gc-pal-11", "pal11", "VER_PAL_11", CRC(0x76b301de), SDA(0x81483de0)}, // MPAL
{IPL_PAL_12, IPL_PAL, "gc-pal-12", "pal12", "VER_PAL_12", CRC(0x89f5a81a), SDA(0x814b7280)},
};

extern void __SYS_ReadROM(void *buf,u32 len,u32 offset);
Expand All @@ -81,7 +83,27 @@ extern u32 diff_msec(s64 start,s64 end);

static bool valid = false;

typedef struct {
u16 magic;
u8 revision;
u8 padding;
u32 blob_checksum;
u32 code_size;
u32 code_checksum;
} ipl_metadata_t;

void load_ipl(bool is_running_dolphin) {
ARAMFetch((void*)BS2_BASE_ADDR, (void*)0xe00000, 0x200000);
ipl_metadata_t *blob_metadata = (void*)0x81500000 - sizeof(ipl_metadata_t);

ipl_metadata_t metadata = {};
memcpy(&metadata, blob_metadata, sizeof(ipl_metadata_t));
memset(blob_metadata, 0, sizeof(ipl_metadata_t));

if (metadata.magic != 0xC0DE) {
prog_halt("Invalid IPL metadata\n");
}
#if 0
if (is_running_dolphin) {
__SYS_ReadROM(bs2, bs2_size, BS2_CODE_OFFSET); // IPL is not encrypted on Dolphin
iprintf("TEST IPL D, %08x\n", *(u32*)bs2);
Expand Down Expand Up @@ -114,8 +136,13 @@ void load_ipl(bool is_running_dolphin) {
iprintf("TEST IPL D, %08x\n", *(u32*)bs2);
#endif


u32 crc = csp_crc32_memory(bs2, bs2_size);
iprintf("Read BS2 crc=%08x\n", crc);
#endif

u32 crc = tinf_crc32((void*)BS2_BASE_ADDR, metadata.code_size);
iprintf("Read BS2 crc=%08x\n", crc);

u32 sda = get_sda_address();
iprintf("Read BS2 sda=%08x\n", sda);
Expand Down
5 changes: 5 additions & 0 deletions cubeboot/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "bnr.h"

#include "flippy_sync.h"
#include "sram.h"

#define DEFAULT_FIFO_SIZE (256 * 1024)

Expand Down Expand Up @@ -186,6 +187,10 @@ int main(int argc, char **argv) {
iprintf("Loading settings\n");
load_settings();

// fix sram
set_sram_swiss(true);
create_swiss_config();

//// fun stuff

// load ipl
Expand Down
11 changes: 7 additions & 4 deletions entry/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,16 @@ void _main() {
for (int i = 0; i < MAXDATASECTION; i++) {
if (hdr->dataAddress[i] && hdr->dataLength[i]) {
_memcpy((void*)hdr->dataAddress[i], ((unsigned char*)dol_buf) + hdr->dataOffset[i], hdr->dataLength[i]);
// u32 _max = hdr->dataAddress[i] + hdr->dataLength[i];
// if (_max > max) max = _max;
u32 _max = hdr->dataAddress[i] + hdr->dataLength[i];
if (_max > max) max = _max;
}
}

gprintf("ddd %08x\n", max);

u32 code_length = max - hdr->entryPoint;
gprintf("DDD %08x %08x %08x\n", hdr->entryPoint, max, code_length);

// Clear BSS
_memset((void*)hdr->bssAddress, 0, hdr->bssLength);

Expand All @@ -99,8 +102,8 @@ void _main() {
void (*entrypoint)();
entrypoint = (void(*)())hdr->entryPoint;

DCFlushRangeNoSync((void*)hdr->entryPoint, max);
ICInvalidateRange((void*)hdr->entryPoint, max);
DCFlushRangeNoSync((void*)hdr->entryPoint, code_length);
ICInvalidateRange((void*)hdr->entryPoint, code_length);
gprintf("boot\n");
entrypoint();
__builtin_unreachable();
Expand Down
2 changes: 1 addition & 1 deletion entry/source/usbgecko.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,4 @@ void usb_OSReport(const char *fmt, ...) {
WriteUARTN(buf, length);

va_end(args);
}
}

0 comments on commit 0c4e864

Please sign in to comment.