⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vic068vme.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* vic068.c - VTC VMEbus Interface Controller (VIC068) *//* Copyright 1984-1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01h,20dec96,dat  fixed SPR 3430, bug in sysIntDisable.01g,11jul96,wlf  doc: more cleanup.01f,11jul96,wlf  doc: cleanup.01e,13jun96,wlf  doc: cleanup and spelling chgs to a printf and logMsg.01d,09Aug95,kkk  fix warnings for i960 (spr# 4177)01c,25apr94,wmd  Changed line to correctly test range of interrupt level.01b,02mar93,ccc  removed reference to HKV960, fixed warnings.01a,02oct92,ccc	 written.*//*DESCRIPTIONThis library provides VMEbus Interface Controller (VIC) routines.*//* LINTLIBRARY */#include "drv/vme/vic068.h"/* locals */struct mailbox    {    FUNCPTR  sysMailboxRoutine;         /* routine called upon interrupt */    int	     sysMailboxArg;             /* argument passed to routine */    BOOL     sysMailboxConnected;       /* mail connected state */    } mailTab[] =	{	{((FUNCPTR) logMsg), ((int) "mailbox0 interrupt\n"), FALSE},	{((FUNCPTR) logMsg), ((int) "mailbox1 interrupt\n"), FALSE},	{((FUNCPTR) logMsg), ((int) "mailbox2 interrupt\n"), FALSE},	{((FUNCPTR) logMsg), ((int) "mailbox3 interrupt\n"), FALSE},	{((FUNCPTR) logMsg), ((int) "mailbox4 interrupt\n"), FALSE},	{((FUNCPTR) logMsg), ((int) "mailbox5 interrupt\n"), FALSE},	{((FUNCPTR) logMsg), ((int) "mailbox6 interrupt\n"), FALSE},	{((FUNCPTR) logMsg), ((int) "mailbox7 interrupt\n"), FALSE}	};/* temp routines for sysMailboxConnect */LOCAL FUNCPTR	tmpMailboxRoutine = (FUNCPTR) logMsg;LOCAL int	tmpMailboxArg =  (int) "mailbox interrupt\n";LOCAL BOOL	tmpMailboxConnected = FALSE;LOCAL char *    sysMailboxBase      = 0;/* forward declarations */UINT8	sysVMEIntAck ();/******************************************************************************** sysBusIntGen - generate a bus interrupt** This routine generates a bus interrupt of a specified level with a* specified vector.** RETURNS: OK, or ERROR if <sysIntLvl> is out of range or the board cannot* generate a bus interrupt.** SEE ALSO: sysBusIntAck()*/STATUS sysBusIntGen    (    INT32 	sysIntLvl,      /* bus interrupt level to generate (1-7) */    INT32 	vector          /* interrupt vector to generate (0-255)  */    )    {    int sysIplNo = DEFAULT_IPL;    /* check to see if sysIntLvl and IPL are in range */    if ((sysIntLvl < 1) || (sysIntLvl > 7))         return (ERROR);    /* check for unacknowledged interrupt */    if (*VIC_VIRSR & (1 << sysIntLvl))	{	logMsg ("Unacknowledged interrupt present on VMEbus.\n");	return (ERROR);	}    /* write vector to appropriate location */    *(VIC_VIVR1 + (sysIntLvl - 1) * 4) = (UINT8) vector;    *VIC_VIRSR = (1 | (1 << sysIntLvl));    /* generate the VME interrupt */    *(VIC_VIICR) = 0x80 | sysIplNo;    return (OK);    }/********************************************************************************* sysMailboxInt - handle a mailbox interrupt** This routine handles mailbox interrupts. The icg and icm switches will * generate an interrupt on a  clear to set transition. The mailboxes are * numbered here from 0-7 (icgs 1-4: mailbox 0-3, icms 1-4: mailbox 4-7.** The icgs mailboxes are cleared by writing to the clear address of the * associated mailbox. This isn't necessary with the icms mailboxes but it* would function the same if the icms clear was written to.*/LOCAL void sysMailboxInt (void)    {    UINT8 iack = 0;   /* interrupt vector */    int    box;       /* mailbox pointer into the mailTab array */    UINT8  ipl;       /* ipl number of interrupting mailbox */    UINT8  switchReg; /* interrupting mailbox */    UINT32 ix;    /*     * Acknowledge the interrupt based on the ipl number. The ipl number is      * determined by which mailbox set (icgs or icms) caused the interrupt and      * the appropriate interrupt control register is read      */    switchReg = *VIC_ICSR;    /* retrieve the ipl number from the requested mailbox's Int control reg */    ipl = (switchReg & 0xf) ? (*VIC_ICMICR & ICMICR_IRQ_LVL_MASK) :			      (*VIC_ICGICR & ICGICR_IRQ_LVL_MASK);    switch (ipl)	{	case  TARGET_IPL0:	    iack = *VIC_IACK_IPL0;	    break;	case  TARGET_IPL1:	    iack = *VIC_IACK_IPL1;	    break;	case  TARGET_IPL2:	    iack = *VIC_IACK_IPL2;	    break;	default:	    logMsg ("VIC mailbox interrupt error. Wrong ipl number.\n");	}    /* determine the mailbox number based on the status register */    switch (switchReg)	{	case 0x1 :	case 0x2 :	case 0x4 :	case 0x8 :	    box = (iack & 0x3) + 4; /* the mailbox is passed in with the */	                            /* vector number (lower 2 bits) */	    break;	case 0x10:	    box = 3;	    break;	case 0x20:	    box = 2;	    break;	case 0x40:	    box = 1;	    break;	case 0x80:	    box = 0;	    break;	default:	    logMsg ("VIC mailbox interrupt error. Wrong switch number.\n");	    box = 7;	}    /* clear the the interrupt by writing to the clear address associated with     * the mailbox that got hit     */    if (box < 4)   /* clear the icgs box */	*VIC_ICSR &= 0x0f & ~(switchReg);    else	   /* clear the icms side of interrupt status register */	*VIC_ICSR &= 0xf0 & (~switchReg);    /* call mailbox service routine */    if (mailTab[box].sysMailboxRoutine != NULL)	(*mailTab[box].sysMailboxRoutine) (mailTab[box].sysMailboxArg);#ifdef DEBUG    if (*VIC_ICSR)	logMsg ("missed interrupt\n");   /**/#endif /* DEBUG */    vxIPNDClear (ipl);              /* clear pending bit in IPND reg */    for (ix = 0; ix < 16; ix++)	;    			    /* required to provide settling time */    }/******************************************************************************** sysMailboxEnable - enable the mailbox interrupt** This routine enables the mailbox interrupt.  It should be called* after sysMailboxConnect(). ** The mailbox table is filled in based on what was done in* sysMailboxConnect().  There are eight mailboxes to choose from.  The* mailbox used is determined from the address of the mailbox to be enabled.* Zero is reserved for the backplane driver.** RETURNS: OK, always.** SEE ALSO: sysMailboxConnect()*/STATUS sysMailboxEnable    (    char 	*mailboxAdrs 		/* mailbox address */    )    {    UINT8 	mask;    UINT8 	boxNum;             /* mailbox number to enable */    UINT8	boxSet;             /* interprocessor or global mailbox */    /* determine the mailbox number based on the A1-A3 address lines */    boxNum = (((UINT8) (int) mailboxAdrs & 0x0e) >> 1);    /* determine which mailbox set based on A4/A5 address lines */    boxSet = (UINT8) (int) mailboxAdrs & (VME_ICGS | VME_ICMS);    boxNum += (boxSet == VME_ICMS) ? 4 : 0;    if (mailTab[boxNum].sysMailboxConnected)	return (ERROR);                          /* already used try another */    mailTab[boxNum].sysMailboxRoutine   = tmpMailboxRoutine;    mailTab[boxNum].sysMailboxArg       = tmpMailboxArg;    mailTab[boxNum].sysMailboxConnected = tmpMailboxConnected;    /* reinitialize the temporary mailbox variables */    tmpMailboxRoutine   = (FUNCPTR) logMsg;    tmpMailboxArg       = (int) "mailbox interrupt\n";    tmpMailboxConnected = FALSE;    if (intConnect ((VOIDFUNCPTR *) INT_VEC_MBOX,		    (VOIDFUNCPTR) sysMailboxInt, 0) == ERROR)	{	printf ("had an error connecting to interrupt\n");	return (ERROR);	}    /* set mailbox base address and save for future reference */    sysMailboxBase = (char *) ((UINT32)mailboxAdrs & 0xffffff00);    if (boxSet == (UINT8) VME_ICMS)    /* read current mailbox configuration */        mask = *VIC_ICMICR;    else        mask = *VIC_ICGICR;#ifdef	DEBUG    if (bpDebug & 0x4)	printf ("BoxEnable -- mailboxAdrs: %#x mbox >> 8: %#x  mask: %#x boxSet: %#x\n",	    mailboxAdrs, (UINT32) mailboxAdrs >> 8, mask, boxSet);#endif	/* DEBUG */    /* set the box enable bit */    mask &= (boxSet == VME_ICMS) ? ~(1 << boxNum) : ~(1 << (boxNum + 4));#ifdef DEBUG    if (bpDebug & 0x4)	printf ("BoxEnable-- ~(1 << equ) : %#x\n",		(boxSet == VME_ICMS) ? ~(1 << boxNum) : ~(1 << (boxNum + 4)));#endif	/* DEBUG */    mask = (mask & 0xF8) + VIC_MAILBOX_IPL0;   /* set the IPL number */#ifdef DEBUG    if (bpDebug & 0x4)	printf ("sysMailboxBase: %#x   boxNum:  %#x    mask: %#x\n",		sysMailboxBase, boxNum, mask);#endif	/* DEBUG */    *VIC_ICSR  = 0x0;               /* clear mailbox flags */    if (boxSet == VME_ICMS)	        /* enable the selected mailbox */        *VIC_ICMICR = mask;    else        *VIC_ICGICR = mask;    *VIC_ICGIVBR = INT_VEC_MBOX;    *VIC_ICMIVBR = INT_VEC_MBOX;    /* enable the 960 interrupt mask register based on the ipl number in the     * interrupt control register.     */    vxIMRSet (mask & 0x3);    return (OK);    }/******************************************************************************** sysMailboxConnect - connect a routine to the mailbox interrupt** This routine specifies the interrupt service routine to be called at each* mailbox interrupt.  It should be called before* sysMailboxEnable().  ** This routine sets up temporary variables until the box number is* determined.  The mailbox number is determined from the address passed into* sysMailboxEnable().** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), sysMailboxEnable()*/STATUS sysMailboxConnect    (    FUNCPTR routine,    /* routine called at each mailbox interrupt */    int     arg         /* argument with which to call routine */    )    {#ifdef DEBUG    if (bpDebug & 0x4)        printf ("sysMailBoxConnect-- routine: %#x, arg: %#x\n", routine, arg);#endif	/* DEBUG */    if (tmpMailboxConnected)	return (ERROR); /* tried to connect another routine before enabling */			/* last routine connected. See sysMailboxEnable *//* put the passed parameters in temporary storage until mailbox is enabled */    tmpMailboxRoutine   = routine;    tmpMailboxArg       = arg;    tmpMailboxConnected = TRUE;    return (OK);    }/******************************************************************************** sysBusTas - test and set a location across the bus** This routine performs a 80960 test-and-set instruction across the backplane.** RETURNS: TRUE if the value had not been set but is now, or FALSE if the value* was set already.** SEE ALSO: vxTas()*/BOOL sysBusTas    (    char *addr         /* address to be tested and set */    )    {    volatile UINT  dummy;    UINT oldRelCntrl;    BOOL retVal;    /* get current state of release control register */    oldRelCntrl = *VIC_RCR;    /* tell the vic to release the bus only when done */    *VIC_RCR = RCR_RWD;    dummy = *addr; /* attempt to grab the bus for good measure */    retVal = vxTas (addr);    /* put release control register back to previous state */    *VIC_RCR = oldRelCntrl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -