execfile.c 6.77 KB
#include "os.h"
#include "os_bb.h"
#include "os_internal.h"
#include "bcp.h"
#include "bbint.h"


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

u32
osBbLoadApp(OSBbLaunchMetaData *md, u16 *blockList, s32 listSize, s32 loadAll)
{
    u32 addr;
    s32 rv = 0;
    OSMesgQueue dmaMessageQ;
    OSMesg dmaMessageBuf;
    OSIoMesg dmaMesg;
    OSPiHandle* handler;
    s32 fileSize = listSize * BB_FL_BLOCK_SIZE;

    osCreateMesgQueue(&dmaMessageQ, &dmaMessageBuf, 1);

    if (listSize >= 0) {
        /* set up atb mapping */
        blockList[listSize] = 0;
        if ((rv = osBbAtbSetup(K1_TO_PHYS(md->romBase), blockList, listSize+1)) < 0)
            return 0;
    }
    handler = osCartRomInit();
    IO_WRITE(PI_ERROR_REG, 0);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_RDPH |
                                (0xf << PI_FLASH_CTRL_ADPH_SHIFT) |
                                PI_FLASH_CTRL_WRDY |
                                PI_FLASH_CTRL_ECC |
                                0x3ff);
    osEPiReadIo(handler, 0x8, &addr);
    dmaMesg.hdr.pri      = OS_MESG_PRI_NORMAL;
    dmaMesg.hdr.retQueue = &dmaMessageQ;
    if(loadAll){
        dmaMesg.dramAddr     = ((char*)addr)-4096;
        dmaMesg.devAddr      = 0;
        dmaMesg.size         = fileSize;
    }
    else{
        dmaMesg.dramAddr     = (char*)addr;
        dmaMesg.devAddr      = 4096;
        dmaMesg.size         = (fileSize-4096) < 1024*1024 ? (fileSize-4096) : 1024*1024;
    }

    osEPiStartDma(handler, &dmaMesg, OS_READ);
    (void)osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);

    if (md->errataSize && fileSize > md->errataSize) {
        dmaMesg.hdr.pri      = OS_MESG_PRI_NORMAL;
        dmaMesg.hdr.retQueue = &dmaMessageQ;
        dmaMesg.dramAddr     = (char *)md->errataAddress;
        dmaMesg.devAddr      = fileSize-md->errataSize;
        dmaMesg.size         = md->errataSize;
        PRINTF("Errata!\n");
        PRINTF("Addr 0x%x\n", dmaMesg.dramAddr);
        PRINTF("Size: %d\n", dmaMesg.size);
        PRINTF("Device addr: 0x%x\n", dmaMesg.devAddr);
        osEPiStartDma(handler, &dmaMesg, OS_READ);
        (void)osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);
    }

    osWritebackDCacheAll();
    osInvalICache((void*)K0BASE, 64*1024);
    osRomBase = (void*)md->romBase;
    osMemSize = md->memSize;
    osTvType = md->tvType;
    osBbAuxDataSetLimit(BB_AUXDATA_COUNT(md));
    return addr;
}


s32
osBbExecApp(u32 addr)
{
    int (*f)();
    f = (void*)addr;
    /* grant access to everything */
    IO_WRITE(PI_ACCESS_REG, PI_ACCESS_ALL);
    // Don't have PI errors cause a secure-kernel trap
    //IO_WRITE(PI_ERROR_REG, PI_ERROR_KERNEL_INTR);
    IO_WRITE(USB0_SECURE_MODE_REG, USB_SECURE_MODE_OFF);
    IO_WRITE(USB1_SECURE_MODE_REG, USB_SECURE_MODE_OFF);
//    IO_WRITE(MI_CTRL_REG, MI_CTRL_SK_TRAP_PIF|MI_CTRL_BUS_ERROR_PIF|MI_CTRL_SK_TRAP_BNM|MI_CTRL_BUS_ERROR_BNM);
    /* Leave secure mode */
    /* clear and re-enable button interrupt to arm secure button trap  */
    if (__osBbIsBb > 1) {
        IO_WRITE(MI_INTR_EMASK_REG, MI_INTR_MASK_CLR_BUT);
        IO_WRITE(MI_INTR_EMASK_REG, MI_INTR_MASK_SET_BUT);
        IO_WRITE(MI_SEC_MODE_REG, MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BUT_TRAP_EN/*|MI_SEC_MODE_MD_TRAP_EN*/);
    } else {
        IO_WRITE(MI_SEC_MODE_REG, MI_SEC_MODE_IRAM_ACCESS/*|MI_SEC_MODE_MD_TRAP_EN*/);
    }
    __osDisableInt();
    return (*f)();
}

s32
osBbExecFile(s32 fd, const char *name, OSBbLaunchMetaData *md, u8* buffer)
{
    u32 addr;
    int (*f)();
    s32 rv = 0, i, off;
    u8* block = buffer;
    u16* blockList = (u16*)buffer;

    i = strlen(name);
    if (i > 3 && name[i-4] == '.' && name[i-3] == 'a' && 
                 name[i-2] == 'e' && name[i-1] == 's') {
        s32 listSize;
        OSBbStatBuf sb;
	OSMesgQueue dmaMessageQ;
	OSMesg dmaMessageBuf;
	OSIoMesg dmaMesg;
	OSPiHandle* handler;

	osCreateMesgQueue(&dmaMessageQ, &dmaMessageBuf, 1);

        if ((rv = osBbFStat(fd, &sb, blockList, 4096)) < 0)
	    return rv;
        listSize = sb.size / BB_FL_BLOCK_SIZE;
        if (listSize >= 0) {
            /* set up atb mapping */
            blockList[listSize] = 0;
            if ((rv = osBbAtbSetup(md->romBase, blockList, listSize+1)) < 0)
		return rv;
        }
        handler = osCartRomInit();
        IO_WRITE(PI_AES_CTRL_REG, 0);
        IO_WRITE(PI_ERROR_REG, 0);
        IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_RDPH |
                                    (0xf << PI_FLASH_CTRL_ADPH_SHIFT) |
                                    PI_FLASH_CTRL_WRDY |
                                    PI_FLASH_CTRL_ECC |
                                    0x3ff);
	osEPiReadIo(handler, 0x8, &addr);
        f = (void*)addr;
        dmaMesg.hdr.pri      = OS_MESG_PRI_NORMAL;
        dmaMesg.hdr.retQueue = &dmaMessageQ;
        dmaMesg.dramAddr     = (char*)addr;
        dmaMesg.devAddr      = 4096;
        dmaMesg.size         = (sb.size-4096) < 1024*1024 ? (sb.size-4096) : 1024*1024;

        osEPiStartDma(handler, &dmaMesg, OS_READ);
        (void)osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);

        if (md->errataSize && sb.size > md->errataSize) {
            dmaMesg.hdr.pri      = OS_MESG_PRI_NORMAL;
            dmaMesg.hdr.retQueue = &dmaMessageQ;
            dmaMesg.dramAddr     = (char *)md->errataAddress;
            dmaMesg.devAddr      = sb.size-md->errataSize;
            dmaMesg.size         = md->errataSize;
            osEPiStartDma(handler, &dmaMesg, OS_READ);
            (void)osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);
        }
    } else {
        OSBbStatBuf sb;
        if ((rv = osBbFStat(fd, &sb, 0, 0)) < 0)
	    return rv;
        rv = osBbFRead(fd, 0, block, BB_FL_BLOCK_SIZE);
        addr = *(unsigned int*)(block+8);
        f = (void*)addr;
        bcopy(block+4096, (void*)addr, BB_FL_BLOCK_SIZE - 4096);
        addr += BB_FL_BLOCK_SIZE - 4096;
	off = BB_FL_BLOCK_SIZE;
        while (rv >= 0 && off < sb.size) {
            rv = osBbFRead(fd, off, (void*)addr, BB_FL_BLOCK_SIZE);
            if (rv <= 0) break;
            addr += BB_FL_BLOCK_SIZE;
            off += BB_FL_BLOCK_SIZE;
        }
	if (rv < 0) return rv;
    }
    osRomBase = (void*)md->romBase;
    osMemSize = md->memSize;
    osTvType = md->tvType;
    osWritebackDCacheAll();
    osInvalICache((void*)K0BASE, 64*1024);
    /* grant access to everything */
    IO_WRITE(PI_ACCESS_REG, PI_ACCESS_ALL);
    IO_WRITE(PI_ERROR_REG, PI_ERROR_KERNEL_INTR);
    IO_WRITE(USB0_SECURE_MODE_REG, USB_SECURE_MODE_OFF);
    IO_WRITE(USB1_SECURE_MODE_REG, USB_SECURE_MODE_OFF);
//    IO_WRITE(MI_CTRL_REG, MI_CTRL_SK_TRAP_PIF|MI_CTRL_BUS_ERROR_PIF|MI_CTRL_SK_TRAP_BNM|MI_CTRL_BUS_ERROR_BNM);
    /* leave secure mode */
    IO_WRITE(MI_SEC_MODE_REG, MI_SEC_MODE_IRAM_ACCESS|(__osBbIsBb > 1 ? MI_SEC_MODE_BUT_TRAP_EN : 0)/*|MI_SEC_MODE_MD_TRAP_EN*/);
    __osDisableInt();
    return (*f)();
}