reenc_stress.c 9.42 KB
#include <PR/bcp.h>
#include <PR/R4300.h>
#include <PR/bbsim.h>
#include <PR/bbskapi.h>

#include <PR/os.h>
#include <PR/os_bb.h>
#include <PR/os_bbfs.h>
#include <PR/os_bbatb.h>
#include <PR/os_bbexec.h>
#include <PR/ramrom.h>

#include <PR/os_bbsa.h>
#include <libfb.h>
#include "reenc_stress.h"

#define ALIGN_DCACHE __attribute__((aligned(DCACHE_LINESIZE)))
#define printstr fbPrintf

static u32 gMiSecModeRegEntryVal;
static char gDispStr[1024];
static int gTicketIndex;
OSBbSaTickets      gTickets __attribute__((aligned(16)));
OSBbSaGameMetaData gGameMeta[32];
extern u32  __osBbHackFlags;


/*
 * debug print support
 */

#undef PRINTF

#ifdef DEBUG
#define	PRINTF	osSyncPrintf
#else
#define	PRINTF(format, args...)
#endif

#define fbhBlue         GPACK_RGBA5551(0,0,80,1)
#define fbhGreen        GPACK_RGBA5551(0,80,0,1)
#define fbhRed          GPACK_RGBA5551(80,0,0,1)
#define fbhYellow       GPACK_RGBA5551(80,80,0,1)
#define fbhMagenta      GPACK_RGBA5551(80,0,80,1)
#define fbhCyan         GPACK_RGBA5551(0,80,80,1)

#define fbLemonChiffon          GPACK_RGBA5551(255,250,205,1)
#define fbLightSlateBlue        GPACK_RGBA5551(132,112,255,1)
#define fbLightPink1            GPACK_RGBA5551(255,174,185,1)
#define fbThistle2              GPACK_RGBA5551(238,210,238,1)
#define fbSeaGreen4             GPACK_RGBA5551(105,139,105,1)
#define fbTomato1               GPACK_RGBA5551(255,99,71,1)
#define fbTurquoise2            GPACK_RGBA5551(0,229,238,1)
#define fbSienna4               GPACK_RGBA5551(139,71,38,1)


/*
 * Thread and stack structures
 */

char   bootStack[STACKSIZE] __attribute__ ((aligned (8)));

static OSThread idleThread;
static char     idleThreadStack[STACKSIZE] __attribute__ ((aligned (8)));

static OSThread mainThread;
static char     mainThreadStack[STACKSIZE] __attribute__ ((aligned (8)));

/* 
 * FS specific definitions
 */

static void	idleproc(char *);
static void	mainproc(char *);
static OSBbFs   gFs; /* too big to plop on the stack */

/* XXX: hard-coded size requires more consideration */
#define BB_SYSAPP_NUM_DIR_ENTRIES 256
static OSBbDirEnt gFsDirs[BB_SYSAPP_NUM_DIR_ENTRIES];

static const char gTicketFname[] = "ticket.sys";

static u8 gShuffleHeap[RECRYPT_CHUNK_SIZE] ALIGN_DCACHE;

#define DMA_QUEUE_SIZE	200

static OSMesg           PiMessages[DMA_QUEUE_SIZE];
static OSMesgQueue      PiMessageQ;

static OSMesg           SiMessages[DMA_QUEUE_SIZE];
static OSMesgQueue      SiMessageQ;


/*
 * simple graphics
 */

static OSMesgQueue      retraceMessageQ;
static OSMesg           dummyMessage, retraceMessageBuf;
static u16 cfb[320*240] __attribute__((aligned(64)));

/*
 * controller
 */
static OSMesgQueue      contMessageQ;
OSContStatus statusData[MAXCONTROLLERS];
OSContPad controllerData[MAXCONTROLLERS];
static int no_controller = 1;
static int gParental = 1;


#define EXTERN_LIMIT 1
static void
initController(void)
{
    int i, c = 0;
    u8 pattern;

    if (__osBbIsBb<2)
        __osBbHackFlags = 1;
    else
        __osBbHackFlags = 0;

    osCreateMesgQueue(&contMessageQ, &dummyMessage, 1);
    osSetEventMesg(OS_EVENT_SI, &contMessageQ, (OSMesg) 0);

    osContInit(&contMessageQ, &pattern, &statusData[0]);

    for (i = 0; i < MAXCONTROLLERS; i++) {
        if ((pattern & (1 << i)) &&
            !(statusData[i].errno & CONT_NO_RESPONSE_ERROR)) {
            ++c;
            no_controller = 0;
        }
    }
}


void outputCid()
{
    sprintf(gDispStr,"CID: %08x",
            (unsigned int)(gTickets.ticket[gTicketIndex].cmd.head.id));
    printstr(fbWhite, 3, 6, gDispStr);
    osWritebackDCacheAll();
}


static void
delay(void) {
    int k;
    for(k = 0; k < 1000000; k++)
	;
}

void  __osBbVideoPllInit(u32);
void boot(u32 miSecModeRegVal)
{
    gMiSecModeRegEntryVal = miSecModeRegVal;

    /* Init the video PLL */
    __osBbVideoPllInit(OS_TV_NTSC);

    osInitialize();

    osCreateThread(&idleThread, 1, (void(*)(void *))idleproc, (void *)0,
                   idleThreadStack+STACKSIZE, 8);
    osStartThread(&idleThread);
}


static void
idleproc(char *argv)		/* priority 8 */
{
    osCreateViManager(OS_PRIORITY_VIMGR);
    fbInit(FB_LOW_RES);

#ifdef DEBUG
    /* should allow usb printing */
    osBbUsbInit();
#endif

    /*
     * Start PI Mgr for access to cartridge - start before the debugger
     */
    osCreatePiManager((OSPri) OS_PRIORITY_PIMGR, &PiMessageQ, PiMessages,
            DMA_QUEUE_SIZE);

    osCreateMesgQueue(&SiMessageQ, SiMessages, DMA_QUEUE_SIZE);
    osSetEventMesg(OS_EVENT_SI, &SiMessageQ, (OSMesg)DMA_QUEUE_SIZE);

    /*
     * The main thread's priority must be the same or lower than the original
     * idle's thread priority. This allows the idle thread to change its
     * priority to 0 before the main thread starts execution.
     */
    osCreateThread(&mainThread, 3, (void(*)(void *))mainproc, argv,
           mainThreadStack+STACKSIZE, (OSPri)7);
    osStartThread(&mainThread);

    osSetThreadPri(0, OS_PRIORITY_IDLE);

    for(;;){}
}


static u8 buf[BB_FL_BLOCK_SIZE] ALIGN_DCACHE;
static int
copyFile(const char* src, const char* dst) {
  s32 sfd, dfd, rv;
  u32 l;
  OSBbStatBuf sb;

  osBbFDelete(dst);
  if ((sfd = osBbFOpen(src, "r")) < 0) return sfd;
  if ((rv = osBbFStat(sfd, &sb, 0, 0)) < 0) {
    goto fail;
  }
  if ((dfd = osBbFCreate(dst, 1, sb.size)) < 0) {
    rv = dfd;
    goto fail;
  }
  for(l = 0; l < sb.size; l += BB_FL_BLOCK_SIZE) {
    if ((rv = osBbFRead(sfd, l, buf, BB_FL_BLOCK_SIZE)) < 0) goto fail;
    if ((rv = osBbFWrite(dfd, l, buf, BB_FL_BLOCK_SIZE)) < 0) goto fail;
  }
  osBbFClose(sfd);
  osBbFClose(dfd);
  return 0;
fail:
  osBbFDelete(dst);
  osBbFClose(sfd);
  return rv;
}

static int
checkFile(void) {
    char app_name[11];
    char rec_name[11];
    char cpy_name[11];
    s32 fd;
    u32 count;
    count = 0;

    /* update launch.cnt */
    if ((fd = osBbFOpen("launch.cnt", "w")) >= 0) {
      osBbFRead(fd, 0, buf, sizeof buf);
      count = *(u32*)buf;
    }
    osBbFClose(fd);
    count++;
    
    *(u32*)buf = count;
    osBbFDelete("tmp.tmp");
    fd = osBbFCreate("tmp.tmp", 1, sizeof buf);
    osBbFWrite(fd, 0, buf, sizeof buf);
    osBbFClose(fd);
    osBbFRename("tmp.tmp", "launch.cnt");

    /* remove re-encrypted file, re-copy saved to app */
    sprintf(app_name, "%08lx.app", gTickets.ticket[gTicketIndex].cmd.head.id);
    sprintf(rec_name, "%08lx.rec", gTickets.ticket[gTicketIndex].cmd.head.id);
    sprintf(cpy_name, "%08lx.cpy", gTickets.ticket[gTicketIndex].cmd.head.id);
    osBbFDelete(rec_name);
    copyFile(cpy_name, app_name);
    return count;
}


void mainproc(char *argv)
{
    int ret,i;
    s32 fsret;
    char tmp[16];
    int count;
    char text[256];
    
    /* setup text output to screen */
    osCreateMesgQueue(&retraceMessageQ, &retraceMessageBuf, 1);
    osViSetEvent(&retraceMessageQ, dummyMessage, 1);
    osViBlack(1);
    osViSwapBuffer(cfb);
    fbSetBg(fbBlack);
    fbClear();
    osViBlack(0);
    osWritebackDCacheAll();
    osViSwapBuffer(cfb);
    fbClear();
    initController();

    printstr(fbWhite, 3, 2, "ReEncryption Stress Test");
    osWritebackDCacheAll();

    
    if(osBbFInit(&gFs)<0){
        goto exit;
    }

    /* power-down */
    /* check for rev 1.1 version of BCP */
    if (IO_READ(PI_GPIO_REG) & PI_ID_BOARD_REV_MASK){
        if( gMiSecModeRegEntryVal & MI_SEC_MODE_BUT_TRAP){
            osBbSaveState(tmp);
            printstr(fbWhite, 3, 12, "POWER DOWN");
            osWritebackDCacheAll();
            delay();
            osBbPowerOff();
            return;
        }
    }else{
        osBbSaveState(tmp);
    }
    
    fsret = osBbFReadDir(gFsDirs, BB_SYSAPP_NUM_DIR_ENTRIES);
    if(fsret<0){
        goto exit;
    }

    osBbSaMetaGetTickets(&gTickets);

    gTicketIndex = 0;
    outputCid();

    osBbSaMetaGetData(&gTickets,gGameMeta);

    count = checkFile();
    
    sprintf(text, "Iteration %d\n", count);
    printstr(fbWhite, 3, 4, text);
    osWritebackDCacheAll();
    delay();

    printstr(fbWhite, 3, 12, "Launching...");
    osWritebackDCacheAll();

    /* ticket of interest. 
     */
    
    ret = osBbSaGamePrelaunch(&(gTickets.ticket[gTicketIndex]));
    if(ret==SALAUNCH_PERSONALIZE){
        printstr(fbWhite, 3, 12, "Personalizing...");
        osWritebackDCacheAll();
        for(i=0;
            (ret=osBbSaGamePersonalize(gShuffleHeap)) == SALAUNCH_PERSONALIZE;
            i++){
            switch(i%4){
            case 0: printstr(fbWhite,22,12,".   ");osWritebackDCacheAll();break;
            case 1: printstr(fbWhite,22,12,"..  ");osWritebackDCacheAll();break;
            case 2: printstr(fbWhite,22,12,"... ");osWritebackDCacheAll();break;
            default: printstr(fbWhite,22,12,"....");osWritebackDCacheAll();
            }
        }
    }

    /* use this to make app return to sysapp */
    gParental = 1;

    if (skSetLimit(EXTERN_LIMIT + count , 0) < 0){
      printstr(fbWhite, 3, 11, "Setting external limit failed  \n");
      osWritebackDCacheAll();
    }    
    else{
      printstr(fbWhite, 3, 11, "Setting external limit...  \n");
      osWritebackDCacheAll();
    }
    
	
    if(ret==SALAUNCH_OK){
        printstr(fbWhite, 3, 13, "Launching...                 \n");
        osWritebackDCacheAll();
        osBbSaGameLaunch(&gGameMeta[gTicketIndex].launch);
        /* should not return on success */
        goto exit;
    }

    
    printstr(fbWhite, 3, 13, "Launch Failed \n");
    osWritebackDCacheAll();
 exit:
    
    /* power off (cannot do this since not in secure mode) */
    printstr(fbWhite, 3, 12, "Launch Failed");
    osWritebackDCacheAll();
    delay();
    osBbPowerOff();
    return;
}