ddr.c 4.46 KB
#include "ultra64.h"
#include "os_bb.h"
#include "bcp.h"

#include "ddr.h"
#include "nu64sys.h"
#include "graph.h"

#define PRINTF osSyncPrintf

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


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

void
boot(void)
{

  __osBbVideoPllInit(OS_TV_NTSC);
    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);
#if	SCREEN_LOW
    osViSetMode(&osViModeTable[OS_VI_NTSC_LPN1]);
#else
    osViSetMode(&osViModeTable[OS_VI_NTSC_HPF1]);
#endif

    /*
     * 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 u16 cfb[SCREEN_WD*SCREEN_HT] __attribute__((aligned(64)));
static void clear(u16 bg) {
    int i;
    for (i = 0; i < SCREEN_WD*SCREEN_HT; ++i) {
            cfb[i] = bg;
    }
}

static void 
mainproc(char *argv)		{
    osCreateMesgQueue(&retraceMessageQ, &retraceMessageBuf, 1);
    osViSetEvent(&retraceMessageQ, dummyMessage, 1);
    osViBlack(1);
    osViSwapBuffer(cfb);
    clear(0);
    osViBlack(0);
    osWritebackDCacheAll();
    osViSwapBuffer(cfb);

    run();
    for(;;) ;
}

/*
 * Start somewhere above the program and framebuffer
 */
#define DDR_X36_START  (K0BASE + 0x100000)
#define DDR_X36_END    (K0BASE | 0x00800000)
#define DDR_X64_START  ((K0BASE | 0x01000000) + 0x100000)
#define DDR_X64_END    (K0BASE | 0x02000000)

static void run(void) 
{
    vu32 *p, *e;
    int nFailures = 0;
    char buf[512];
    int loops = 0;

    while (1) {
        loops++;
        sprintf(buf, "DDR Test %d, Failures %d", loops, nFailures);
        printstr(white, 3, 6, buf);
        osWritebackDCacheAll();

        p = (vu32*) DDR_X36_START;
        e = (vu32*) DDR_X36_END;
        while (p<e) *p++ = (vu32) p;
        
        p = (vu32*) DDR_X36_START;
        e = (vu32*) DDR_X36_END;

        while (p<e) {
            if (*p != (vu32) p) {
                nFailures++;
                sprintf(buf, "DDR36 Fail: exp %08lx got %08lx", (u32) p, *p);
                printstr(white, 3, 7, buf);
        	osWritebackDCacheAll();
                break;
            }
            p++;
        }
        
        p = (vu32*) DDR_X36_START;
        e = (vu32*) DDR_X36_END;
        while (p<e) *p++ = ~((vu32) p);
        
        p = (vu32*) DDR_X36_START;
        e = (vu32*) DDR_X36_END;
        while (p<e) {
            if (*p != (~((vu32) p))) {
                nFailures++;
                sprintf(buf, "DDR36 Fail: exp %08lx got %08lx", ~((vu32) p), *p);
                printstr(white, 3, 7, buf);
        	osWritebackDCacheAll();
                break;
            }
            p++;
        }

        p = (vu32*) DDR_X64_START;
        e = (vu32*) DDR_X64_END;
        while (p<e) *p++ = (vu32) p;
    
        p = (vu32*) DDR_X64_START;
        e = (vu32*) DDR_X64_END;
        while (p<e) {
            if (*p != (vu32) p) {
                nFailures++;
                sprintf(buf, "DDR64 Fail: exp %08lx got %08lx", (u32) p, (u32) *p);
                printstr(white, 3, 7, buf);
        	osWritebackDCacheAll();
                break;
            }
            p++;
        }

        p = (vu32*) DDR_X64_START;
        e = (vu32*) DDR_X64_END;
        while (p<e) *p++ = ~((vu32)p);
    
        p = (vu32*) DDR_X64_START;
        e = (vu32*) DDR_X64_END;
        while (p<e) {
            if (*p != (~((vu32) p))) {
                sprintf(buf, "DDR36 Fail: exp %08lx got %08lx", (u32) ~((vu32) p), (u32) *p);
                printstr(white, 3, 7, buf);
        	osWritebackDCacheAll();
                break;
            }
            *p++;
        }

    }
}