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

📄 sysepic.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* initialize the interrupt table */

    for (vector = 0; vector < INTERRUPT_TABLESIZE; vector++)
        {
	sysIntTbl [vector] = NULL;
        }

    /*
     * connect the interrupt demultiplexer to the PowerPC external 
     * interrupt exception vector.
     * i. e.  put the address of this interrupt handler in
     * the PowerPC's only external interrupt exception vector
     * which is  _EXC_OFF_INTR = 0x500
     */

    excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, sysEpicIntHandler);

    /*  
     * set up the BSP specific interrupt routines
     * Attach the local routines to the VxWorks system calls
     *
     */

    _func_intConnectRtn  =  sysEpicIntConnect;
    _func_intEnableRtn   =  sysEpicIntEnable;
    _func_intDisableRtn  =  sysEpicIntDisable;

    epicCurTaskPrioSet (EPIC_PRIORITY_MIN); /* set it to lowest priority */
    
    return (OK);
    }


/*******************************************************************************
*
* sysEpicIntEnable - enable a EPIC interrupt level
*
* This routine enables a specified EPIC interrupt level.
*
* NOMANUAL
*
* RETURNS: OK.
*/

LOCAL int  sysEpicIntEnable
    (
    int intNum
    )
    {

	/* enable interrupt on vt82c686 */
    if ((intNum >= INT_NUM_IRQ0) && 	/* check of vt82c686 IRQs */
        (intNum != EPIC_DUART1_INT_VECT) && 
	(intNum != EPIC_DUART2_INT_VECT))
        {
        intNum = intNum - INT_NUM_IRQ0;
        
        if ((sysPciIbcIntEnable (intNum)) != OK)
            {
            return (ERROR);
            }

        return (OK);
        }

    /* enable interrupt on EPIC */

    if (((0 <= intNum)  && (intNum < EPIC_MAX_EXT_IRQS))  ||
        (intNum == EPIC_DUART1_INT_VECT)    || 
        (intNum == EPIC_DUART2_INT_VECT))
        {
        epicIntEnable (EPIC_VEC_REG (intNum));
        return OK;
        }
    else
    	{
        return (ERROR);
    	}
    }


/*******************************************************************************
*
* sysEpicIntDisable - disable a EPIC interrupt level
*
* This routine disables a specified EPIC interrupt level.
*
* NOMANUAL
*
* RETURNS: OK.
*/

LOCAL int  sysEpicIntDisable
    (
    int 	intNum
    )
    {
    int 	mask;
	
	 /* disable interrupt on vt82c686 */	
    if ((intNum >= INT_NUM_IRQ0) && 	/* check of vt82c686 IRQs */
        (intNum != EPIC_DUART1_INT_VECT) && 
	(intNum != EPIC_DUART2_INT_VECT))
        {
        intNum = intNum - INT_NUM_IRQ0;

        mask = sysPciIbcIntDisable (intNum);

        if (mask == ERROR)
            {
            return (ERROR);
            }

        return (OK);
        }

    /* disable interrupt on EPIC */
 
    if (((0 <= intNum)  && (intNum < EPIC_MAX_EXT_IRQS)) ||
        (intNum == EPIC_DUART1_INT_VECT)    || 
        (intNum == EPIC_DUART2_INT_VECT))
        {
        epicIntDisable (EPIC_VEC_REG(intNum));
        return OK;
        }
    else
    	{
        return (ERROR);
    	}
    }


/*******************************************************************************
*
* sysEpicIntConnect - connect an interrupt handler to the system vector table
*
* This function connects an interrupt handler to the system vector table.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sysEpicIntConnect
    (
    VOIDFUNCPTR * 	vector,		/* interrupt vector to attach */
    VOIDFUNCPTR		routine,	/* routine to be called */
    int			parameter	/* parameter to be passed to routine */
    )
    {
    INT_HANDLER_DESC *	pNewHandler;
    INT_HANDLER_DESC *	pCurrHandler;
    int			intVal;
    BOOL		sharing = FALSE;
	

    if (((int)vector < 0)  || ((int) vector > INTERRUPT_TABLESIZE)) 
	{
        return (ERROR);   /*  out of range  */
	}

    /* create a new interrupt handler */

    pNewHandler = malloc (sizeof (INT_HANDLER_DESC));

    /* check if the memory allocation succeed */

    if (pNewHandler == NULL)

	return (ERROR);

    /*  initialize the new handler  */

    pNewHandler->vec = routine;
    pNewHandler->arg = parameter;
    pNewHandler->next = NULL;

    /* install the handler in the system interrupt table  */

    intVal = intLock (); /* lock interrupts to prevent races */

    if (sysIntTbl [(int) vector] == NULL)
	{
        sysIntTbl [(int) vector] = pNewHandler;  /* single int. handler case */
	}
    else
	{
        pCurrHandler = sysIntTbl[(int) vector];/* multiple int. handler case */

        while (pCurrHandler->next != NULL)
            {
            pCurrHandler = pCurrHandler->next;
            }
        
        pCurrHandler->next = pNewHandler;

        sharing = TRUE;
	}

    if ((int)vector >= 0 && (int)vector < INT_VEC_IRQ0)
        {

        /* EPIC IRQ set EPIC registers, priority = WB_PRIO + vector */

        if (!sharing)
    	{
            epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY,
                      EPIC_SENSE_LVL, (int) (vector+6), (int) vector);

    	}
		
        }
    else
    	{
	    if ((int)vector == EPIC_DUART1_INT_VECT) /* setup duart 1 */ 
		{
		if (!sharing)
		    epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY, \
				      EPIC_SENSE_LVL, 0x03, (int)vector);
		}
	    else
	    if ((int)vector == EPIC_DUART2_INT_VECT) /* setup duart 2 */
		{
		if (!sharing)
		    epicIntSourceSet (EPIC_VEC_REG((int)vector), EPIC_INT_POLARITY, \
				      EPIC_SENSE_LVL, 0x05, (int)vector);
	        }
    	}

    intUnlock (intVal);

    return (OK);
    }

/*******************************************************************************
*
* sysEpicIntHandlerExec  - execute the handlers for a given vector
* 
* This routine executes all the handlers chained to a given vector.
* If a vector has no handlers attached to it, a logMsg is generated.
*
* NOMANUAL
*
* RETURNS: N/A
*
*/

void sysEpicIntHandlerExec
    (
    UCHAR intVec
    )
    {    
    INT_HANDLER_DESC * pCurrHandler;

    /*  call each respective interrupt handler */	

    if ((pCurrHandler = sysIntTbl [intVec]) == NULL)
        {
	logMsg ("uninitalized PIC interrupt vector %x\r\n",
                intVec, 0,0,0,0,0);
        }
    else
        {
	if (epicIntTrace)
	    {
            /* execute duart interrupts */
            if ((intVec == EPIC_DUART1_INT_VECT) || (intVec == EPIC_DUART2_INT_VECT))
	        logMsg ("sysEpicIntHandlerExec, duart interrupt vector %x\r\n",intVec, 0,0,0,0,0);
	    }

	/* call Each respective chained interrupt handler  */
	while (pCurrHandler != NULL)
            {
  	    (*pCurrHandler->vec) (pCurrHandler->arg);
	    pCurrHandler = pCurrHandler->next;
            }

        } /* else */
    }

/*******************************************************************************
*
* sysEpicIntHandler - handles the EPIC interrupts to the CPU
*
* This routine handles interrupts originating from the embedded interrupt
* controller on the MPC8240 Power PC processor.
* This handler is entered from the 0x500 exception.
*
* This routine is entered with CPU external interrupts enables.
*
* Since the EPIC is the primary interrupt controller this driver
* first initiates an Epic acknowledge call and reads the vector
* put out by the EPIC. Subsequent vectors have to be obtained if
* an external interrupt controller is connected to one of the
* epic handlers. 
*
* This routine then processes the interrupt by calling all the interrupt
* service routines chained to the vector.
*
* Finally, this routine re-arms the interrupt at the PIC by performing an 
* PIC EOI for both the EPIC and the 8259s.
*
* RETURNS:  N/A
*
*/

void  sysEpicIntHandler (void)
    {
    int		dontCare;
    UCHAR 	epicIntVec;
	INT32 oldLock;


#if FALSE
    int 	oldLevel;
#endif
    oldLock = intLock ();		/* LOCK INTERRUPT */


    epicIntVec = epicIntAck ();	/* clear int, return the vec for highest IRQ */

    /* loop till all interrupts are cleared */
    while (epicIntVec != 0xff)
        {
        if (epicIntTrace)
	    {
            /* execute duart interrupt handler */
            if ((epicIntVec == EPIC_DUART1_INT_VECT) || (epicIntVec == EPIC_DUART2_INT_VECT))
                logMsg ("sysEpicIntHandler: duart interrupt vector %x\r\n",epicIntVec, 0,0,0,0,0);
	    }

#ifdef INCLUDE_WINDVIEW
    WV_EVT_INT_ENT (epicIntVec);
#endif 

    #if FALSE
        /* block all lower priority interrupts */

        if ((oldLevel = epicCurTaskPrioSet (epicIntVec)) == EPIC_INV_PRIO_ERROR)
            {
            return;
            }
    #endif

        /* Allow external interrupts to the CPU. */

        /*CPU_INT_UNLOCK (_PPC_MSR_EE);*/

	/*if(epicIntVec == 4)
	logMsg("epicIntVec = 0x%x\n",epicIntVec,0,0,0,0,0);*/

        sysEpicIntHandlerExec (epicIntVec);

        /*
         * Disable External Interrupts
         * External Interrupts will be re-enabled in the kernel's wrapper
         * of this Interrupt.
         */
         
        /*CPU_INT_LOCK (&dontCare);*/

        WRS_ASM ("sync");
        epicEOI ();				/* signal end of interrupt on EPIC */
        WRS_ASM ("sync");

        epicIntVec = epicIntAck ();

    #if FALSE
        epicCurTaskPrioSet (oldLevel); 	/* Allow the next interrupt to occur */
    #endif

        } /* while */
    intUnlock (oldLock);				/* UNLOCK INTERRUPT */

⌨️ 快捷键说明

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