fsmunge.c 4.36 KB
#include "ultra64.h"
#include <PR/bcp.h>
#include "os_bb.h"
#include "bbskapi.h"
#include <aes.h>
#include <sha1.h>
//#define VIDEO_PRINT
#ifdef VIDEO_PRINT
#include "libfb.h"
#endif

#include "fsmunge.h"


#define DMA_QUEUE_SIZE	200
#define MSG_FAULT	0x10

#ifdef VIDEO_PRINT
static int ypos = 2, xpos = 2;
#define PRINTF(args...)		fbPrintf(fbWhite, xpos, ypos++, args);osWritebackDCacheAll()
static u16 cfb[640*480] __attribute__((aligned(64)));
#else
#define PRINTF			osSyncPrintf
#endif


/*
 * 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)));

/*
 * Message queues and message buffers used by this app 
 */
static OSMesg           PiMessages[DMA_QUEUE_SIZE];
static OSMesgQueue      PiMessageQ;

static OSMesg           SiMessages[DMA_QUEUE_SIZE];
static OSMesgQueue      SiMessageQ;

/*
 * Local variables and routines
 */

static void		idleproc(char *);
static void		mainproc(char *);

void
boot(void)
{
    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);
    osViSetMode(&osViModeTable[OS_VI_NTSC_LPN1]);

    /*
     * 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/8, (OSPri)7);
    osStartThread(&mainThread);

    osSetThreadPri(0, OS_PRIORITY_IDLE);
    for(;;);                                    /* idle thread */
}

static OSMesgQueue	retraceMessageQ;
static OSMesg		dummyMessage, retraceMessageBuf;
static OSBbFs fs;
#define NDIR 100
#define NBLOCKS 	64
static u8 blocks[NBLOCKS*BB_FL_BLOCK_SIZE] __attribute__((aligned(16)));
static u16 blist[4096];

static void 
mainproc(char *argv) {
    s32 fd, rv;
    extern u8 __osBbCardNoEcc;
    extern u32 __osBbCardSbErr;
    u8 spare[BB_FL_SPARE_SIZE], save;
    OSBbStatBuf sb;
    osCreateMesgQueue(&retraceMessageQ, &retraceMessageBuf, 1);
    osViSetEvent(&retraceMessageQ, dummyMessage, 1);
#ifdef VIDEO_PRINT
    osViBlack(1);
    osViSwapBuffer(cfb);
    fbInit(FB_LOW_RES);
    osViBlack(0);
    osWritebackDCacheAll();
    osViSwapBuffer(cfb);
#endif

#define FILE_NAME	"00001001.rec" /* super mario */
    PRINTF("\n=> mainproc...\n");
    PRINTF("init\n");
    if ((rv = osBbFInit(&fs)) < 0) {
	PRINTF("osBbFInit failed %d\n", rv);
	goto out;
    }
//#define TEST_ECC
#define ERR_TYPE	PI_ERROR_SYS_INTR
//#define ERR_TYPE	PI_ERROR_KERNEL_INTR
    IO_WRITE(PI_ERROR_REG, ERR_TYPE);
    if ((fd = osBbFOpen(FILE_NAME, "w")) < 0) {
	PRINTF("osBbFOpen %s failed %d\n", FILE_NAME, fd);
	goto out;
    }

    PRINTF ("test single bit error\n");
    bzero(blist, sizeof blist);
    osBbFStat(fd, &sb, blist, sizeof blist);
    osBbCardReadBlock(0, blist[20], blocks, spare);
#define LOC	(BB_FL_BLOCK_SIZE-100)
    save = blocks[LOC];
    blocks[LOC] ^= 1;
    __osBbCardNoEcc = 1;
    if ((rv = osBbCardWriteBlock(0, blist[20], blocks, spare)) < 0) {
	PRINTF("osBbCardWriteBlock %d failed %d\n", blist[0], rv);
	goto out;
    }
    if ((rv = osBbCardReadBlock(0, blist[20], blocks, 0)) < 0) {
	PRINTF("osBbCardReadBlock %d failed %d\n", blist[0], rv);
	goto out;
    }
    if (save != blocks[LOC]) {
	PRINTF("single bit error not corrected %x %x\n", save, blocks[LOC]);
	goto out;
    }
    if ((IO_READ(PI_FLASH_CTRL_REG) & PI_FLASH_CTRL_SBERR) == 0) {
	PRINTF("single bit error not detected, ctrl reg %x\n", IO_READ(PI_FLASH_CTRL_REG));
	goto out;
    }

out:
    PRINTF("done\n");
    IO_WRITE(PI_GPIO_REG, 0|(1 << PI_GPIO_ENABLE_SHIFT));
#ifndef VIDEO_PRINT
    IO_READ(MI_SEC_MODE_REG);
    skExit();
#endif
    for(;;) ;
}