pimgr.c 5.52 KB

/*====================================================================
 * pimgr.c
 *
 * Copyright 1994-1995, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
 * Inc.; the contents of this file may not be disclosed to third
 * parties, copied or duplicated in any form, in whole or in part,
 * without the prior written permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to
 * restrictions as set forth in subdivision (c)(1)(ii) of the Rights
 * in Technical Data and Computer Software clause at DFARS
 * 252.227-7013, and/or in similar or successor clauses in the FAR,
 * DOD or NASA FAR Supplement. Unpublished - rights reserved under the
 * Copyright Laws of the United States.
 *====================================================================*/

/**************************************************************************
 *
 *  $Revision: 1.1.1.2 $
 *  $Date: 2002/10/29 08:06:43 $
 *  $Source: /root/leakn64/depot/rf/sw/n64os20l/libultra/nintendo/pi/pimgr.c,v $
 *
 *  Description:
 *	Peripheral Interface Manager (PIM)
 *	Create a high priority thread to handle Peripheral Interface (PI) 
 *	requests.
 *
 **************************************************************************/


#include "osint.h"
#include "piint.h"
#include "rcp.h"



/* Number of message entries in event queues */
#define	NUM_EV_MESG		1

#define PI_EVENT_MESG		0x22222222

/*
 * Static variables
 */
static OSThread		piThread;		/* PIM Thread structure */
static char		piThreadStack[OS_PIM_STACKSIZE];

#ifndef _FINALROM
#include <rdb.h>
#define OS_PIM_RAMROM_STACKSIZE   1024
static OSThread		ramromThread;		/* PIM Thread structure */
static char		ramromThreadStack[OS_PIM_RAMROM_STACKSIZE];
static OSMesgQueue      getRamromQ;
static OSMesg           getRamromBuf[1];
static OSMesgQueue      freeRamromQ;
static OSMesg           freeRamromBuf[1];
static void ramromMain(void *);
#endif

static OSMesgQueue	piEventQueue;		/* Event queue structure */
static OSMesg		piEventBuf[NUM_EV_MESG];

/*
 * Global variables
 */
OSDevMgr		__osPiDevMgr = {0};	/* Device Manager structure */
OSPiHandle *__osPiTable = (OSPiHandle*)NULL;	/* Device Table */
/* running PI device */
OSPiHandle		__Dom1SpeedParam, __Dom2SpeedParam;
OSPiHandle *__osCurrentHandle[2] = {&__Dom1SpeedParam, &__Dom2SpeedParam};

/* OSPiHandle		__LowSpeedDom1Handle; */


/*
 * Extern declarations
 */
extern OSMesgQueue	__osPiAccessQueue;
extern int		__osPiAccessQueueEnabled;
extern void		__osPiCreateAccessQueue(void);


/*
 * Name:   osCreatePiManager
 *
 * Description:
 *	Create and start the Peripheral Interface Manager (PIM).
 *	Caller specifies the necessary parameters to create PIM command queue.
 *
 * Globals Referenced: 
 *	__osPiDevMgr
 *	__osPiAccessQueueEnabled
 *	piEventQueue
 *	piEventBuf
 *	piThread
 *	piThreadStack
 *	osDevMgrMain
 */
void
osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt)
{
    u32		savedMask;
    OSPri	oldPri, myPri;

#ifdef _DEBUG
    if ((pri < OS_PRIORITY_IDLE) || (pri > OS_PRIORITY_MAX)) {
	__osError(ERR_OSCREATEPIMANAGER, 1, pri);
	return;
    }
#endif

    /* If PI Manager is already running, simply return */
    if (__osPiDevMgr.active) 
        return;


    /* Create the input I/O command queue, wait queue, and access queue */
    osCreateMesgQueue(cmdQ, cmdBuf, cmdMsgCnt);
    osCreateMesgQueue(&piEventQueue, piEventBuf, NUM_EV_MESG);
    if (!__osPiAccessQueueEnabled)
        __osPiCreateAccessQueue();

    /* Take over PI interrupt */
    osSetEventMesg(OS_EVENT_PI, &piEventQueue, (OSMesg)PI_EVENT_MESG);

    /*
     * Check the current thread priority against the PIM's priority.
     * If current is lower, temporarily increase it to same level as PIM
     */
    oldPri = -1;
	myPri = osGetThreadPri((OSThread *)NULL);
    if (myPri < pri) {
        oldPri = myPri;
        osSetThreadPri((OSThread *)NULL, pri);
    }

    /* Set global to tell that Peripheral Interface Manager is on and active */
    savedMask = __osDisableInt();

    __osPiDevMgr.active		= 1;
    __osPiDevMgr.thread		= &piThread;
    __osPiDevMgr.cmdQueue	= cmdQ;
    __osPiDevMgr.evtQueue	= &piEventQueue;
    __osPiDevMgr.acsQueue	= &__osPiAccessQueue;
    __osPiDevMgr.dma		= __osPiRawStartDma;
    __osPiDevMgr.edma		= __osEPiRawStartDma;

    osCreateThread(&piThread, 0, __osDevMgrMain, (void *)&__osPiDevMgr,
		   piThreadStack+OS_PIM_STACKSIZE, (OSPri)pri);

    osStartThread(&piThread);

#ifndef _FINALROM
    osCreateThread(&ramromThread, 0, ramromMain, NULL,
		   ramromThreadStack+OS_PIM_RAMROM_STACKSIZE, (OSPri)pri - 1);
    osStartThread(&ramromThread);

#endif /* ifndef _FINALROM */

    /* Restore original interrupt mask */
    __osRestoreInt(savedMask);

    /* Restore original thread priority */
    if (oldPri != -1)
        osSetThreadPri((OSThread *)NULL, oldPri);

}  /* osCreatePiManager */


#ifndef _FINALROM

static void ramromMain(void *arg)
{
    u32     sent;
    u8      tmp[3];

    osCreateMesgQueue(&getRamromQ, getRamromBuf, 1);
    osCreateMesgQueue(&freeRamromQ, freeRamromBuf, 1);
    osSetEventMesg(OS_EVENT_RDB_REQ_RAMROM, &getRamromQ, NULL);
    osSetEventMesg(OS_EVENT_RDB_FREE_RAMROM, &freeRamromQ, NULL);

    while(1)
    {
	osRecvMesg(&getRamromQ, NULL, OS_MESG_BLOCK);
	
	/* Block to get resource token */
	__osPiGetAccess();
	
	sent = 0;
	while(sent < 1)
	    sent += __osRdbSend(tmp,1,RDB_TYPE_GtoH_RAMROM);

	osRecvMesg(&freeRamromQ, NULL, OS_MESG_BLOCK);
	/* Return resource token */
	__osPiRelAccess();
    }
}

#endif