atbtest.c 6.69 KB
#include <PR/bcp.h>
#include <PR/bbsim.h>

#include <PR/os.h>
#include <PR/os_bbatb.h>
#include <PR/os_bbfs.h>

#include <aes.h>

#define PRINTF		osSyncPrintf

/*
 * Thread and stack structures
 */

#define IDLE_STACKSIZE (4096*2)
char   idleStack[IDLE_STACKSIZE] __attribute__ ((aligned (8)));

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

static void	idleproc(char *);

extern void *_ftext;

/*
 * FS
 */

static OSBbFs   gFs; /* too big to plop on the stack */

#define BB_ATBAPP_NUM_DIR_ENTRIES 256
static OSBbDirEnt gFsDirs[BB_ATBAPP_NUM_DIR_ENTRIES];

#define BB_ATBAPP_SIZE_BLKLST 1024
static u16 gFsBlkList[BB_ATBAPP_SIZE_BLKLST];

static OSBbStatBuf gFsStat;
static const char gTestFname[] = "tfile_e.bin";

#define BB_ATBAPP_RDBUF_SIZE (16*1024)
static u8 gFsRdBuf[BB_ATBAPP_RDBUF_SIZE];

/*
 * TEST params
 */

/* must match data in TEST script */
BbAesKey gKey = {0xa8190276,0x7e25db17,0x0f3449c5,0xd94b162f};
BbAesIv  gIv  = {0xa438b341,0x0298747b,0x0c089d8f,0x6d2991a8};

#define PHYS_DRAM_DMA_TARGET 0x00100000

static u16 gTestBlkList[BB_ATBAPP_SIZE_BLKLST];
static u16 gMapBlkList[BB_ATBAPP_SIZE_BLKLST];

#if 0	/* this is in libultra now */
/* util string compare function.
 */
int strcmp(const char *s,const char *t)
{
    for(;*s==*t;s++,t++)
        if(*s=='\0')
            return 0;
    return *s - *t;
}
#endif

void aesHwInit(u32 *key,u32 *iv)
{
    int i;
    u32 ekey[44];

    aes_HwKeyExpand((u8 *)key, (u8 *)ekey);

    for(i=0;i<44;i++)
        IO_WRITE(PI_AES_EKEY_REG+i*4,ekey[i]);
    IO_WRITE(PI_AES_INIT_REG,iv[0]);
    IO_WRITE(PI_AES_INIT_REG+4,iv[1]);
    IO_WRITE(PI_AES_INIT_REG+8,iv[2]);
    IO_WRITE(PI_AES_INIT_REG+12,iv[3]);
}

#define _RAND_MAX 0x10000
static int _rand()
{
    static int I=328; /* seed */
    I *= 0x0b9af1;
    I += 0x0ce2e3;
    I &= _RAND_MAX-1;
    return I;
}
#define MYRAND(a)  (((_rand()*(a))/_RAND_MAX))
static void genTestList(u16 *fsBlkList, int numBlks,
                        u16 *testBlkList, u16 *mapBlkList)
{
    int i, indx=0, start, size;

    for(i=0;i<numBlks;i++)
        mapBlkList[i]=fsBlkList[i];

    do{
        start = MYRAND(numBlks-1);
        size = MYRAND(numBlks-start-1)+1;
        if(size==0)size=1;
        for(i=0;i<size;i++)
            testBlkList[indx++]=mapBlkList[start+i];
        for(i=0;i<(numBlks-(start+1)-size);i++)
            mapBlkList[start+i]=mapBlkList[start+size+i];
        numBlks-=size;
    }while(numBlks);
}


static int runAtb(u16 *fsBlkList,int numBlks,u16 *testBlkList)
{
    int i,j;
    u32 expect;

    /* issue dma in each block and insure correct.
     * NOTE: depends on assumed block writing by test, which fills
     *       entire block with u8 numeric logical block index. also, the
     *       comparison skips the first 16B so we do not need to take
     *       into account the correct aes iv. 
     */
    for(i=0;i<numBlks;i++){
        PRINTF("Issuing dma.\n");
        IO_WRITE(PI_STATUS_REG,0);
        IO_WRITE(PI_DRAM_ADDR_REG, PHYS_DRAM_DMA_TARGET);
        IO_WRITE(PI_CART_ADDR_REG, PI_DOM1_ADDR2 + i*16*1024 );
        IO_WRITE(PI_WR_LEN_REG, 512-1);
        while(IO_READ(PI_STATUS_REG) & 
              (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) {
            if (IO_READ(PI_STATUS_REG) & PI_STATUS_ERROR){
                PRINTF("DMA Failed!!!\n");
                return -1;
            }
        }
        
        /* check result */
        for(j=16;j<512;j+=4){
            expect = fsBlkList[testBlkList[i]-fsBlkList[0]] - 
                fsBlkList[0];
            expect |= expect<<8;
            expect |= expect<<16;
            if(j==16)
                PRINTF("%08x\n",*(u32 *)PHYS_TO_K1(PHYS_DRAM_DMA_TARGET+j));
            if(*(u32 *)PHYS_TO_K1(PHYS_DRAM_DMA_TARGET+j) != expect){
                PRINTF("ATB_TEST_FAIL\n");
                return -1;
            }
        }
    }
    return 0;
}

void boot()
{
    osInitialize();
    osCreateThread(&idleThread, 1, (void(*)(void *))idleproc, (void *)0,
                   idleThreadStack+IDLE_STACKSIZE, 8);
    osStartThread(&idleThread);
}

void idleproc(char *argv)
{
    int i, j, numBlks;
    u32 expect;
    s32 fsret,appFd;

    PRINTF("DRAM target address: %08x\n",PHYS_TO_K1(PHYS_DRAM_DMA_TARGET));

    if(osBbFInit(&gFs)<0){
        PRINTF("ERROR osBbFInit()\n");
        goto exit;
    }

    fsret = osBbFReadDir(gFsDirs, BB_ATBAPP_NUM_DIR_ENTRIES);
    if(fsret<0){
        PRINTF("ERROR osBbFReadDir()\n");
        goto exit;
    }

    PRINTF("\nFiles on system:\n");
    for(i=0;i<fsret;i++){
        PRINTF("    %s\n",gFsDirs[i].name);
        if(strcmp(gFsDirs[i].name,gTestFname)==0){
            PRINTF("    --> found test file\n");
        }
    }

    appFd = osBbFOpen(gTestFname,"r");
    fsret = osBbFStat(appFd, &gFsStat, gFsBlkList, BB_ATBAPP_SIZE_BLKLST);
    PRINTF("%s contains %d bytes\n",gTestFname,gFsStat.size);
    PRINTF("  flash blocks (log,phys):\n    ");
    for(i=0;gFsBlkList[i]!=0;i++){
        if(i!=0 && !(i&0x7)){
            PRINTF("(%d,%d)\n    ",i,gFsBlkList[i]);
        }
        else
            PRINTF("(%d,%d),",i,gFsBlkList[i]);
    }
    PRINTF("\n");
    numBlks=i;

    osBbFClose(appFd);

    /* configure aes controller for dma */
    aesHwInit(gKey,gIv);

    /* configure flash for dma */
    /* XXX: assuming fs already has correctly configured
     *      PI_FLASH_CONFIG_REG for the module!!!
     */
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_RDPH  |
                                0xf << PI_FLASH_CTRL_ADPH_SHIFT |
                                0x0 << PI_FLASH_CTRL_CMD_SHIFT |
                                PI_FLASH_CTRL_WRDY |
                                0 << PI_FLASH_CTRL_BUF_SHIFT |
                                0 << PI_FLASH_CTRL_DEV_SHIFT |
                                PI_FLASH_CTRL_ECC |
                                0x3ff);


    /* generate test block lists */
    gTestBlkList[numBlks]=0;

    /* one large mapping */
    for(i=0;i<numBlks;i++)
        gTestBlkList[i]=gFsBlkList[i];
    osBbAtbSetup(PI_DOM1_ADDR2, gTestBlkList, BB_ATBAPP_SIZE_BLKLST);
    if(0>runAtb(gFsBlkList,numBlks,gTestBlkList))
        goto exit;

    /* all 1 blk sized */
    for(i=0;i<numBlks;i++)
        gTestBlkList[i]=gFsBlkList[numBlks-i-1];
    osBbAtbSetup(PI_DOM1_ADDR2, gTestBlkList, BB_ATBAPP_SIZE_BLKLST);
    if(0>runAtb(gFsBlkList,numBlks,gTestBlkList))
        goto exit;


    /* "random" */
    genTestList(gFsBlkList,numBlks,gTestBlkList,gMapBlkList);
    osBbAtbSetup(PI_DOM1_ADDR2, gTestBlkList, BB_ATBAPP_SIZE_BLKLST);
    if(0>runAtb(gFsBlkList,numBlks,gTestBlkList))
        goto exit;

 exit:
    PRINTF("\nAPP FINISHED\n");
    /* power off (cannot do this since not in secure mode) */
    IO_WRITE(PI_GPIO_REG, 0|(1 << PI_GPIO_ENABLE_SHIFT));
    while(1){}
}