atb.c 3.13 KB
#include <PR/bcp.h>

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

#undef ATB_DEBUG
#ifdef ATB_DEBUG
#define PRINTF		osSyncPrintf
#else
#define PRINTF(x, args...)
#endif

u32 osBbAtbGetVAddr()
{
    u32 addr;

    addr = IO_READ(PI_ATB_BUFFER_LO_REG+4);
    addr &= PI_ATBL_VADDR_MASK;
    addr = addr >> PI_ATBL_VADDR_SHIFT;
    addr = addr << 14;
    return addr;
}

/* for now, atb uses an entry for each 16KB block. 
 *  assume device 0.
 */
s32 osBbAtbSetup(u32 vAddrBase, u16 *fsBlockList, u32 maxListLen) 
{
    int atbIndx, maxPow2, lenRun, numBlks, indx, entryBlksPow2, runStart = 0;
    u32 vAddr, atbLower;

    if((vAddrBase&(~((1<<14)-1)))==0)
        return BB_ATB_FAIL;

    /* the dummy entry for init */
    IO_WRITE(PI_ATBU_REG, PI_ATBU_IV |                          /* IV */
                          (0<<PI_ATBU_DEV_SHIFT) |              /* device */
                          PI_ATBU_PERM_PIO | PI_ATBU_PERM_DMA | /* perm */
                          (0<<PI_ATBU_SIZE_SHIFT));             /* size */
    IO_WRITE(PI_ATB_BUFFER_LO_REG,
             0 | (((vAddrBase>>14)-1) << PI_ATBL_VADDR_SHIFT) );
    atbIndx=1;
    vAddr=vAddrBase;

    for(numBlks=0; fsBlockList[numBlks]!=0; numBlks++){
        if(numBlks == (maxListLen-1))
            return BB_ATB_FAIL;
    }

    do{

        for(maxPow2=0; ((vAddr>>(14+maxPow2))&1)==0; maxPow2++){}
        PRINTF("vAddr = %08x, maxPow2 = %d\n",vAddr,maxPow2);

        /* determine lenRun */
        for(indx=runStart, lenRun=1,entryBlksPow2=0;
            (fsBlockList[indx]+1)==fsBlockList[indx+1] && 
                entryBlksPow2<maxPow2; 
            indx++){
            
            if( (++lenRun & ((1<<(entryBlksPow2+1))-1) ) == 0 )
                entryBlksPow2++;
        }

        /* 
         * setup atb entry using entryBlksPow2, runStart 
         */

        PRINTF("Run start = %d, length = %d\n",runStart,(1<<entryBlksPow2));
        /* setup atb entry upper bits */
        IO_WRITE(PI_ATBU_REG, (0<<PI_ATBU_DEV_SHIFT) | /* device */
                 PI_ATBU_PERM_PIO | PI_ATBU_PERM_DMA | /* perm */
                 (entryBlksPow2<<PI_ATBU_SIZE_SHIFT)); /* size */
        atbLower=(((u32)fsBlockList[runStart]) << PI_ATBL_PADDR_SHIFT) |
                 ((vAddr>>14) << PI_ATBL_VADDR_SHIFT);
        PRINTF("atbLower = %08x\n",atbLower);
        IO_WRITE(PI_ATB_BUFFER_LO_REG+atbIndx*4,atbLower);
        atbIndx++;
        vAddr+=(1<<entryBlksPow2)*16*1024;

        runStart+=(1<<entryBlksPow2);

    } while(runStart<numBlks);

    /* map rest of entries with same last entry */

    IO_WRITE(PI_ATBU_REG, (0<<PI_ATBU_DEV_SHIFT) | /* device */
             PI_ATBU_PERM_PIO | PI_ATBU_PERM_DMA | /* perm */
             (0<<PI_ATBU_SIZE_SHIFT)); /* size */
    atbLower=(((u32)fsBlockList[0]) << PI_ATBL_PADDR_SHIFT) |
             ((vAddr>>14) << PI_ATBL_VADDR_SHIFT);
    PRINTF("vAddr = %08x, maxPow2 = %d\n",vAddr,maxPow2);
    PRINTF("Run start = %d, length = %d\n",0,1);
    PRINTF("atbLower = %08x\n",atbLower);
    PRINTF("%d atb entries\n", atbIndx);
    while(atbIndx < PI_ATB_NUM_ENTRIES){
        IO_WRITE(PI_ATB_BUFFER_LO_REG+atbIndx*4,atbLower);
        atbIndx++;
    }

    return BB_ATB_SUCCESS;
}