int0.c 10.6 KB

/*---------------------------------------------------------------------*
        Copyright (C) 1998 Nintendo. (Originated by SGI)
        
        $RCSfile: int0.c,v $
        $Revision: 1.1.1.1 $
        $Date: 2002/05/02 03:27:20 $
 *---------------------------------------------------------------------*/
#include <os.h>
#include <os_internal.h>
#include <rmon.h>
#include <R4300.h>
#include <rcp.h>
#include "corefunc.h"

/*
 * int0
 *
 * Tests for:
 *	__osSetCause
 *	osSetEventMesg
 *	osSetIntMask
 *
 * Assumed working:
 *	osGetIntMask
 *	osCreateMesgQueue
 *	osRecvMessage
 *
 * Description:
 *	Register a message queue and message with the interrupt handler and
 *		check that the message is delivered when the interrupt occurs.
 *	Check that messages are dropped when the message queue fills up.
 *	Check that setting the interrupt mask delays the interrupt until
 *		the interrupt mask is lowered.
 */

#define	NUM_MESSAGE	4

static OSMesgQueue	sw1MesgQueue;
static OSMesg		sw1MesgBuf[NUM_MESSAGE];

static OSMesgQueue	sw2MesgQueue;
static OSMesg		sw2MesgBuf[NUM_MESSAGE];

static OSMesgQueue	counterMesgQueue;
static OSMesg		counterMesgBuf[NUM_MESSAGE];

static OSMesgQueue	spMesgQueue;
static OSMesg		spMesgBuf[NUM_MESSAGE];

static OSMesgQueue	piMesgQueue;
static OSMesg		piMesgBuf[NUM_MESSAGE];

int
int0(void)
{
    OSIntMask savedMask, currentMask;
    OSMesg actualMesg, expectedMesg;
    int i;
    int retValue;
    int numFailures = 0;
    volatile int loop;
    
    savedMask = osSetIntMask(OS_IM_SW1);

    /*
     * Associate a message and queue with the internal SW1 interrupt.
     */
    osCreateMesgQueue(&sw1MesgQueue, sw1MesgBuf, NUM_MESSAGE);
    expectedMesg = (OSMesg)0x11111111;
    osSetEventMesg(OS_EVENT_SW1, &sw1MesgQueue, expectedMesg);

    /*
     * Repeatedly trigger interrupts (one more than the queue size).
     */
    for (i = 0; i < NUM_MESSAGE+1; i++)
	__osSetCause(CAUSE_SW1);

    /*
     * Verify the message queue was filled with the appropriate messages.
     */
    for (i = 0; i < NUM_MESSAGE; i++) {
	retValue = osRecvMesg(&sw1MesgQueue, &actualMesg, OS_MESG_NOBLOCK);

	if (retValue != 0) {
	    osSyncPrintf("int0: expected return value %d, actual %d\n",
			0, retValue);
	    numFailures++;
	 }

	if (expectedMesg != actualMesg) {
	    osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
		       expectedMesg, actualMesg);
	    numFailures++;
	}
	currentMask = osGetIntMask();
	if (currentMask != OS_IM_SW1) {
	    osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SW1, currentMask);
	    numFailures++;
	}
    }

    /*
     * Verify that the message queue is now empty.
     */
    retValue = osRecvMesg(&sw1MesgQueue, &actualMesg, OS_MESG_NOBLOCK);

    if (retValue != -1) {
	osSyncPrintf("int0: expected return value %d, actual %d\n",
		-1, retValue);
	numFailures++;
    }

    currentMask = osSetIntMask(OS_IM_SW2);
    if (currentMask != OS_IM_SW1) {
	    osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SW1, currentMask);
	    numFailures++;
    }

    /*
     * Check out the SW2 interrupt.
     */
    osCreateMesgQueue(&sw2MesgQueue, sw2MesgBuf, NUM_MESSAGE);
    expectedMesg = (OSMesg)0x22222222;
    osSetEventMesg(OS_EVENT_SW2, &sw2MesgQueue, expectedMesg);

    __osSetCause(CAUSE_SW2);

    retValue = osRecvMesg(&sw2MesgQueue, &actualMesg, OS_MESG_NOBLOCK);

    if (retValue != 0) {
	osSyncPrintf("int0: expected return value %d, actual %d\n",
		   0, retValue);
	numFailures++;
    }

    if (expectedMesg != actualMesg) {
	osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
		expectedMesg, actualMesg);
	numFailures++;
    }
    currentMask = osGetIntMask();
    if (currentMask != OS_IM_SW2) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SW2, currentMask);
	numFailures++;
    }
    currentMask = osSetIntMask(OS_IM_SP);
    if (currentMask != OS_IM_SW2) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SW2, currentMask);
	    numFailures++;
    }

    /*
     * Check out the SP interrupt.
     */
    osCreateMesgQueue(&spMesgQueue, spMesgBuf, NUM_MESSAGE);
    expectedMesg = (OSMesg)0x44444444;
    osSetEventMesg(OS_EVENT_SP, &spMesgQueue, expectedMesg);

    __osSpSetStatus(SP_SET_SIG2);
    __osSpSetStatus(SP_SET_INTR);

    /*
     * Loop here a bit, since SP interrupt apparently takes some time ...
     */
     for (loop = 0; loop < 1000000; loop++);

    retValue = osRecvMesg(&spMesgQueue, &actualMesg, OS_MESG_NOBLOCK);

    if (retValue != 0) {
	osSyncPrintf("int0: expected return value %d, actual %d\n",
		   0, retValue);
	numFailures++;
    }

    if (expectedMesg != actualMesg) {
	osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
		expectedMesg, actualMesg);
	numFailures++;
    }

    currentMask = osGetIntMask();
    if (currentMask != OS_IM_SP) {
	    osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SP, currentMask);
	numFailures++;
    }

    currentMask = osSetIntMask(OS_IM_PI);
    if (currentMask != OS_IM_SP) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SP, currentMask);
	    numFailures++;
    }

    /*
     * Check out the PI interrupt.
     */
    osCreateMesgQueue(&piMesgQueue, piMesgBuf, NUM_MESSAGE);
    expectedMesg = (OSMesg)0x55555555;
    osSetEventMesg(OS_EVENT_PI, &piMesgQueue, expectedMesg);

    retValue = __osPiRawStartDma(OS_READ, (u32)0x0, buffer, 0x10);

    if (retValue != 0) {
	osSyncPrintf("int0: expected return value %d, actual %d\n",
		0, retValue);
	numFailures++;
    }

    /*
     * Spin here a bit and wait for the DMA to complete.
     */
    for (i = 0; i < 100000; i++);

    retValue = osRecvMesg(&piMesgQueue, &actualMesg, OS_MESG_NOBLOCK);

    if (retValue != 0) {
	osSyncPrintf("int0: expected return value %d, actual %d\n",
		   0, retValue);
	numFailures++;
    }

    if (expectedMesg != actualMesg) {
	osSyncPrintf("int0: jexpected message 0x%x, actual 0x%x\n",
                expectedMesg, actualMesg);
	numFailures++;
    }

    currentMask = osGetIntMask();
    if (currentMask != OS_IM_PI) {
	    osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		   OS_IM_PI, currentMask);
	numFailures++;
    }
    currentMask = osSetIntMask(OS_IM_COUNTER);
    if (currentMask != OS_IM_PI) {
	    osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		   OS_IM_SP, currentMask);
	    numFailures++;
    }

    /*
     * Check out the counter interrupt.
     */
    osCreateMesgQueue(&counterMesgQueue, counterMesgBuf, NUM_MESSAGE);
    expectedMesg = (OSMesg)0x33333333;
    osSetEventMesg(OS_EVENT_COUNTER, &counterMesgQueue, expectedMesg);

    __osSetCompare(0);
    __osSetCount(0);

    retValue = osRecvMesg(&counterMesgQueue, &actualMesg, OS_MESG_NOBLOCK);

    if (retValue != 0) {
	osSyncPrintf("int0: expected return value %d, actual %d\n",
		   0, retValue);
	numFailures++;
    }

    if (expectedMesg != actualMesg) {
	osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
		expectedMesg, actualMesg);
	numFailures++;
    }

    currentMask = osGetIntMask();
    if (currentMask != OS_IM_COUNTER) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_COUNTER, currentMask);
	numFailures++;
    }

    /*
     * Trigger another SW1 interrupt, but this time the interrupt
     * is not enabled; no message should have been delivered.
     */
    __osSetCause(CAUSE_SW1);
    retValue = osRecvMesg(&sw1MesgQueue, &actualMesg, OS_MESG_NOBLOCK);

    if (retValue != -1) {
	osSyncPrintf("int0: expected return value %d, actual %d\n",
		-1, retValue);
	numFailures++;
    }

    /*
     * Enable the interrupt; message should then be delivered.
     */
    currentMask = osSetIntMask(OS_IM_SW1);
    if (currentMask != OS_IM_COUNTER) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_COUNTER, currentMask);
	numFailures++;
    }

    expectedMesg = (OSMesg)0x11111111;
    (void)osRecvMesg(&sw1MesgQueue, &actualMesg, OS_MESG_NOBLOCK);
    if (actualMesg != expectedMesg) {
	osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
		expectedMesg, actualMesg);
	numFailures++;
    }

    /*
     * Perform a similar check with the SW2 interrupt.
     */
    __osSetCause(CAUSE_SW2);

    retValue = osRecvMesg(&sw2MesgQueue, &actualMesg, OS_MESG_NOBLOCK);
    if (retValue != -1) {
	osSyncPrintf("int0: expected return value %d, actual %d%x\n",
		-1, retValue);
	numFailures++;
    }

    currentMask = osSetIntMask(OS_IM_SW2);
    if (currentMask != OS_IM_SW1) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SW1, currentMask);
	numFailures++;
    }

    expectedMesg = (OSMesg)0x22222222;
    (void)osRecvMesg(&sw2MesgQueue, &actualMesg, OS_MESG_NOBLOCK);
    if (actualMesg != expectedMesg) {
	osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
		expectedMesg, actualMesg);
	numFailures++;
    }

    /*
     * Perform a similar check with the SP interrupt.
     */
    __osSpSetStatus(SP_SET_SIG2);
    __osSpSetStatus(SP_SET_INTR);

    retValue = osRecvMesg(&spMesgQueue, &actualMesg, OS_MESG_NOBLOCK);
    if (retValue != -1) {
	osSyncPrintf("int0: expected return value %d, actual %d%x\n",
		-1, retValue);
	numFailures++;
    }

    currentMask = osSetIntMask(OS_IM_SP);
    if (currentMask != OS_IM_SW2) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SW2, currentMask);
	numFailures++;
    }

    expectedMesg = (OSMesg)0x44444444;
    (void)osRecvMesg(&spMesgQueue, &actualMesg, OS_MESG_NOBLOCK);
    if (actualMesg != expectedMesg) {
	osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
	    expectedMesg, actualMesg);
	numFailures++;
    }
    /*
     * Perform a similar check with the counter interrupt.
     */
    __osSetCount(0);

    retValue = osRecvMesg(&counterMesgQueue, &actualMesg, OS_MESG_NOBLOCK);
    if (retValue != -1) {
	osSyncPrintf("int0: expected return value %d, actual %d%x\n",
		-1, retValue);
	numFailures++;
    }

    currentMask = osSetIntMask(OS_IM_COUNTER);
    if (currentMask != OS_IM_SP) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_SW2, currentMask);
	numFailures++;
    }

    expectedMesg = (OSMesg)0x33333333;
    (void)osRecvMesg(&counterMesgQueue, &actualMesg, OS_MESG_NOBLOCK);
    if (actualMesg != expectedMesg) {
	osSyncPrintf("int0: expected message 0x%x, actual 0x%x\n",
		expectedMesg, actualMesg);
	numFailures++;
    }

    /*
     * Restore original interrupt mask and check it once more.
     */
    currentMask = osSetIntMask(savedMask);
    if (currentMask != OS_IM_COUNTER) {
	osSyncPrintf("int0: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_COUNTER, currentMask);
	numFailures++;
    }
    return(numFailures);
}