error.c 9.88 KB
/**************************************************************************
 *                                                                        *
 *               Copyright (C) 1995, Silicon Graphics, Inc.               *
 *                                                                        *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright  law.  They  may not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *                                                                        *
 *************************************************************************/

/*---------------------------------------------------------------------*
        Copyright (C) 1998 Nintendo. (Originated by SGI)
        
        $RCSfile: error.c,v $
        $Revision: 1.2 $
        $Date: 2003/04/05 16:03:46 $
 *---------------------------------------------------------------------*/

#include <ultra64.h>
#include <PR/os_internal.h>
#include <PR/ramrom.h>
#include <assert.h>

#include "error.h"

/*
 * Stacks for the threads as well as message queues for synchronization
 * This stack is ridiculously large, and could also be reclaimed once
 * the main thread is started.
 */
u64	bootStack[STACKSIZE/sizeof(u64)];

static void		idle(void *);
static void		mainproc(void *);
static void		testproc(void *);

static OSThread		idleThread;
static u64		idleThreadStack[STACKSIZE/sizeof(u64)];

static OSThread		mainThread;
static u64		mainThreadStack[STACKSIZE/sizeof(u64)];

static OSThread		rmonThread;
static u64		rmonStack[RMON_STACKSIZE/sizeof(u64)];

static OSThread		testThread;
static u64		testThreadStack[STACKSIZE/sizeof(u64)];

static OSMesgQueue	testMesgQ;
static OSMesg		testMesgBuf;
static u64		testBuffer[1];

#define NUM_PI_MSGS     1

static OSMesgQueue	piMesgQ;
static OSMesg		piMesgBuf[NUM_PI_MSGS];
static OSIoMesg		ioMesgBuf;

static char		*region;
static char		regionBuf[512];

static OSTask		task;

static int	debugflag = 0;

OSPiHandle	*handler;

void
boot(void)
{
    int i;
    char *ap;
    u32 *argp;
    u32 argbuf[16];

    /* notice that you can't call rmonPrintf() until you set
     * up the rmon thread.
     */
    
    osInitialize();

    handler = osCartRomInit();

    argp = (u32 *)RAMROM_APP_WRITE_ADDR;
    for (i=0; i<sizeof(argbuf)/4; i++, argp++) {
	osEPiReadIo(handler, (u32)argp, &argbuf[i]); /* Assume no DMA */
    }
    /* Parse the options */
    ap = (char *)argbuf;
    while (*ap != '\0') {
	while (*ap == ' ')
	    ap++;
	if ( *ap == '-' && *(ap+1) == 'd') {
	    debugflag = 1;
	    ap += 2;
	}
    }
    
    osCreateThread(&idleThread, 1, idle, (void *)0,
		   idleThreadStack+STACKSIZE/sizeof(u64), 10);
    osStartThread(&idleThread);

    /* never reached */
}

static void
idle(void *arg)
{
    /*
     * Start PI Mgr for access to cartridge
     */
    osCreatePiManager((OSPri)OS_PRIORITY_PIMGR, &piMesgQ, piMesgBuf, 
		      NUM_PI_MSGS);
    
    /*
     * Start RMON for debugging & data xfer (make sure to start 
     * PI Mgr first)
     */
    osCreateThread(&rmonThread, 0, rmonMain, (void *)0,
		   (void *)(rmonStack+RMON_STACKSIZE/8), 
		   (OSPri) OS_PRIORITY_RMON);
    osStartThread(&rmonThread);

    /*
     * Create main thread
     */
    osCreateThread(&mainThread, 2, mainproc, arg,
		   mainThreadStack+STACKSIZE/sizeof(u64), 10);
    
    if (!debugflag)
	osStartThread(&mainThread);

    /*
     * Become the idle thread
     */
    osSetThreadPri(0, 0);

    for (;;);
}

/*
 * This is the main routine of the app.
 */
static void
mainproc(void *arg)
{
    u32 data;
    char *buf;
    OSTime time;
    OSTimer timer;

    osCreateThread(&testThread, 3, testproc, (void *)0, (void *)4, 10);
    osCreateThread(&testThread, 3, testproc, (void *)0,
		   testThreadStack+STACKSIZE/sizeof(u64), OS_PRIORITY_IDLE - 1);
    osCreateThread(&testThread, 3, testproc, (void *)0,
		   testThreadStack+STACKSIZE/sizeof(u64), OS_PRIORITY_MAX + 1);
    osCreateThread(&testThread, 3, testproc, (void *)0,
		   testThreadStack+STACKSIZE/sizeof(u64), 5);
    osStartThread(&testThread);
    osStartThread(&testThread);

    osSetThreadPri(&testThread, OS_PRIORITY_IDLE-1);
    osSetThreadPri(&testThread, OS_PRIORITY_MAX+1);

    osCreateMesgQueue(&testMesgQ, &testMesgBuf, -1);
    osCreateMesgQueue(&testMesgQ, &testMesgBuf, 0);

    osCreateMesgQueue(&testMesgQ, &testMesgBuf, 1);
    osSendMesg(&testMesgQ, NULL, OS_MESG_BLOCK+1);
    osJamMesg(&testMesgQ,  NULL, OS_MESG_BLOCK+1);
    osRecvMesg(&testMesgQ, NULL, OS_MESG_BLOCK+1);

    osSetEventMesg(OS_NUM_EVENTS, &testMesgQ, NULL);

    osMapTLB(-1, OS_PM_4K, (void *)0, -1, -1, 0);
    osMapTLB(32, OS_PM_4K, (void *)0, -1, -1, 0);
    osMapTLB(0, OS_PM_4K, (void *)0, -1, -1, -2);
    osMapTLB(0, OS_PM_4K, (void *)0, -1, -1, 256);

    osUnmapTLB(-1);
    osUnmapTLB(32);

    osSetTLBASID(-1);
    osSetTLBASID(256);

    osAiSetFrequency(AI_NTSC_MIN_FREQ-1);
    osAiSetFrequency(AI_NTSC_MAX_FREQ+1);

    osAiSetNextBuffer((void *)4, 8);
    osAiSetNextBuffer((void *)8, 4);

    osDpSetNextBuffer((void *)4,(u64) 8);
    osDpSetNextBuffer((void *)8,(u64) 4);

    (void)osEPiWriteIo(handler, 0x2, 0);
    (void)osEPiReadIo(handler, 0x2, &data);
    (void)__osPiRawStartDma(OS_WRITE+1, 0, testBuffer, 8);
    (void)__osPiRawStartDma(OS_READ, 1, testBuffer, 8);
    (void)__osPiRawStartDma(OS_READ, 0, (void *)4, 8);
    (void)__osPiRawStartDma(OS_READ, 0, testBuffer, 1);
    (void)__osPiRawStartDma(OS_READ, 0, testBuffer, 0);
    (void)__osPiRawStartDma(OS_READ, 0, testBuffer, 16*1024*1024+8);

    (void)osPiWriteIo(0x2, 0);
    (void)osPiReadIo(0x2, &data);


    ioMesgBuf.hdr.pri      = OS_MESG_PRI_HIGH+1;
    ioMesgBuf.hdr.retQueue = &testMesgQ;
    ioMesgBuf.dramAddr     = testBuffer;
    ioMesgBuf.devAddr      = 0;
    ioMesgBuf.size         = 8;

    osEPiStartDma(handler, &ioMesgBuf, OS_READ);

    ioMesgBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
    ioMesgBuf.hdr.retQueue = &testMesgQ;
    ioMesgBuf.dramAddr     = testBuffer;
    ioMesgBuf.devAddr      = 0;
    ioMesgBuf.size         = 8;

    osEPiStartDma(handler, &ioMesgBuf, OS_WRITE+1);

    ioMesgBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
    ioMesgBuf.hdr.retQueue = &testMesgQ;
    ioMesgBuf.dramAddr     = testBuffer;
    ioMesgBuf.devAddr      = 1;
    ioMesgBuf.size         = 8;

    osEPiStartDma(handler, &ioMesgBuf, OS_READ);

    ioMesgBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
    ioMesgBuf.hdr.retQueue = &testMesgQ;
    ioMesgBuf.dramAddr     = (void*)4;
    ioMesgBuf.devAddr      = 0;
    ioMesgBuf.size         = 8;

    osEPiStartDma(handler, &ioMesgBuf, OS_READ);

    ioMesgBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
    ioMesgBuf.hdr.retQueue = &testMesgQ;
    ioMesgBuf.dramAddr     = testBuffer;
    ioMesgBuf.devAddr      = 0;
    ioMesgBuf.size         = 1;

    osEPiStartDma(handler, &ioMesgBuf, OS_READ);

    ioMesgBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
    ioMesgBuf.hdr.retQueue = &testMesgQ;
    ioMesgBuf.dramAddr     = testBuffer;
    ioMesgBuf.devAddr      = 0;
    ioMesgBuf.size         = 0;

    osEPiStartDma(handler, &ioMesgBuf, OS_READ);

    ioMesgBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
    ioMesgBuf.hdr.retQueue = &testMesgQ;
    ioMesgBuf.dramAddr     = testBuffer;
    ioMesgBuf.devAddr      = 0;
    ioMesgBuf.size         = 16*1024*1024+8;

    osEPiStartDma(handler, &ioMesgBuf, OS_READ);
    
    osCreatePiManager(OS_PRIORITY_IDLE-1, &piMesgQ, piMesgBuf, NUM_PI_MSGS);
    osCreatePiManager(OS_PRIORITY_MAX+1, &piMesgQ, piMesgBuf, NUM_PI_MSGS);

    (void)osViGetCurrentMode();
    (void)osViGetCurrentFramebuffer();
    (void)osViGetNextFramebuffer();
    osViSetXScale(1.0);
    osViSetYScale(1.0);
    osViSetSpecialFeatures(OS_VI_GAMMA_ON);
    osViSetMode(&osViModeTable[OS_VI_NTSC_LAN1]);
    osViSetEvent(&testMesgQ, NULL, 1);
    osViSwapBuffer((void *)0x80100000);
    osCreateViManager(OS_PRIORITY_IDLE-1);
    osCreateViManager(OS_PRIORITY_MAX+1);

    time = osGetTime();
    osSetTime(time);
    osSetTimer(&timer, time, time, &testMesgQ, NULL);
    osStopTimer(&timer);

    osCreateViManager(OS_PRIORITY_VIMGR);
    osViSetXScale(0.0);
    osViSetXScale(2.0);
    osViSetYScale(0.0);
    osViSetYScale(2.0);
    osViSetSpecialFeatures(OS_VI_GAMMA_ON-1);
    osViSetSpecialFeatures(OS_VI_DIVOT_OFF+1);
    osViSwapBuffer((void *)32);

    region = osCreateRegion(regionBuf, sizeof(regionBuf), sizeof(regionBuf)/4,
		   OS_RG_ALIGN_16B+1);
    region = osCreateRegion(regionBuf, sizeof(regionBuf), sizeof(regionBuf),
		   OS_RG_ALIGN_16B);

    region = osCreateRegion(regionBuf, sizeof(regionBuf), sizeof(regionBuf)/4,
		   OS_RG_ALIGN_16B);

    (void)osMalloc(((char *)region)+8);

    buf = osMalloc(region);
    osFree(((char *)region)+8, buf);
    osFree(region, (void *)8);
    osFree(region, buf+1);

    (void)osGetRegionBufCount(((char *)region)+8);
    (void)osGetRegionBufSize(((char *)region)+8);

    task.t.ucode = NULL;
    task.t.ucode_data = NULL;
    task.t.data_ptr = NULL;

    task.t.dram_stack = (void *)8;
    task.t.output_buff = NULL;
    task.t.output_buff_size = NULL;
    task.t.yield_data_ptr = NULL;

    osSpTaskLoad(&task);

    task.t.dram_stack = NULL;
    task.t.output_buff = (void *)8;
    task.t.output_buff_size = NULL;
    task.t.yield_data_ptr = NULL;

    osSpTaskLoad(&task);

    task.t.dram_stack = NULL;
    task.t.output_buff = NULL;
    task.t.output_buff_size = (void *)8;
    task.t.yield_data_ptr = NULL;

    osSpTaskLoad(&task);

    task.t.dram_stack = NULL;
    task.t.output_buff = NULL;
    task.t.output_buff_size = NULL;
    task.t.yield_data_ptr = (void *)8;

    osSpTaskLoad(&task);

    osReadHost((void *)4, 4);
    osReadHost((void *)8, 0);
    osReadHost((void *)8, 2);

    osWriteHost((void *)4, 4);
    osWriteHost((void *)8, 0);
    osWriteHost((void *)8, 2);

    osExit();
}

static void
testproc(void *arg)
{
	for (;;);
}